drizzle-team / drizzle-team/drizzle-orm

[BUG]: ordering on related field tries to order on the root table

Open
#1,697 5 comments 3 reactions 0 assignees View on GitHub
enhancement rqb
Dominant language
TypeScript
Stars
35.8k
Forks
1.6k
Avg merge
2d 7h
Merged PRs (30d)
4

Description

### What version of `drizzle-orm` are you using?

0.29.1

### What version of `drizzle-kit` are you using?

0.20.7

### Describe the Bug

When ordering by a related field on a joined table using the `query` syntax the generated sql tries to order on the root table rather than the joined table.

I have a `groupMembership` object that has a related `user` (many to one):

```
export const users = pgTable("auth_users", {
id: varchar("id", { length: 255 }).notNull().primaryKey(),
name: varchar("name", { length: 255 }).notNull(),
email: varchar("email", { length: 255 }).notNull(),
emailVerified: timestamp("emailVerified").defaultNow(),
image: varchar("image", { length: 255 }),
role: userRoleEnum("role").default("MEMBER").notNull(),
});

export const userRelations = relations(users, ({ many }) => ({
groupMemberships: many(groupMemberships),
}));
```

```
export const groupMemberships = pgTable("groups_groupMemberships", {
id: varchar("id", { length: 25 }).notNull().primaryKey(),
createdAt: timestamp("createdAt").notNull().defaultNow(),
modifiedAt: timestamp("modifiedAt").notNull().defaultNow(),
groupId: varchar("groupId", { length: 25 }).notNull().references(() => groups.id),
userId: varchar("userId", { length: 255 }).notNull().references(() => users.id),
role: groupRoleEnum("role").default("NEW").notNull(),
})

export const groupMembershipRelatons = relations(groupMemberships, ({ one }) => ({
group: one(groups, {
fields: [groupMemberships.groupId],
references: [groups.id],
}),
user: one(users, {
fields: [groupMemberships.userId],
references: [users.id],
}),
}))
```

When creating a query with the `select` syntax I get the correct ordering:

```
const q1 = db.select().from(schema.groupMemberships)
.leftJoin(schema.users, eq(schema.users.id, schema.groupMemberships.id))
.orderBy(schema.users.name)

console.log(q1.toSQL().sql)
'''
select "groups_groupMemberships"."id", "groups_groupMemberships"."createdAt",
"groups_groupMemberships"."modifiedAt", "groups_groupMemberships"."groupId", "groups_groupMemberships"."userId",
"groups_groupMemberships"."role", "auth_users"."id", "auth_users"."name", "auth_users"."email",
"auth_users"."emailVerified", "auth_users"."image", "auth_users"."role" from "groups_groupMemberships" left join
"auth_users" on "auth_users"."id" = "groups_groupMemberships"."id" order by "auth_users"."name"
'''
```

using the `query` syntax

```
const q2 = db.query.groupMemberships.findMany({
with: {
user: true
},
orderBy: schema.users.name,
})

console.log(q2.toSQL().sql)
'''
select "groupMemberships"."id", "groupMemberships"."createdAt", "groupMemberships"."modifiedAt",
"groupMemberships"."groupId", "groupMemberships"."userId", "groupMemberships"."role",
"groupMemberships_user"."data" as "user" from "groups_groupMemberships" "groupMemberships" left join lateral (select
json_build_array("groupMemberships_user"."id", "groupMemberships_user"."name", "groupMemberships_user"."email",
"groupMemberships_user"."emailVerified", "groupMemberships_user"."image", "groupMemberships_user"."role") as "data"
from (select * from "auth_users" "groupMemberships_user" where "groupMemberships_user"."id" =
"groupMemberships"."userId" limit $1) "groupMemberships_user") "groupMemberships_user" on true order by
"groupMemberships"."name"
'''
```

If I resolve the later query I get an error `column groupMemberships.name does not exist`.

### Expected behavior

I would expect the `query` syntax to order on the joined table as with the `select` syntax.

### Environment & setup

Running against postgres with `drizzle-orm/node-postgres`

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the query-syntax example q2 against PostgreSQL and compare its generated SQL with the select-syntax example q1. Trace how the related user is joined and how orderBy resolves its column; done means the generated ORDER BY uses the joined user alias and the query executes without the missing-column error.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js, postgresql, typescript
Domain
backend, databases
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.