Skip to content

Commit 15c5452

Browse files
committed
Enhance SelectQueryBuilder to support base table name in order by and join clauses, ensuring correct SQL generation with double quotes for identifiers.
1 parent 84509e7 commit 15c5452

File tree

3 files changed

+13
-11
lines changed

3 files changed

+13
-11
lines changed

__tests__/select-builder.test.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ describe("SelectQueryBuilder", () => {
134134
const result = builder.join(join).build();
135135

136136
expect(result.sql).toContain(
137-
`INNER JOIN "roles" AS "roles" ON "roles"."id" = "roleId"`
137+
`INNER JOIN "roles" AS "roles" ON "roles"."id" = "users"."roleId"`
138138
);
139139
expect(result.values).toEqual([]);
140140
});
@@ -153,9 +153,9 @@ describe("SelectQueryBuilder", () => {
153153
const result = builder.join(join).build();
154154

155155
expect(result.sql).toContain(
156-
"LEFT JOIN roles ON users.role_id = roles.id"
156+
`LEFT JOIN "roles" AS "roles" ON "roles"."id" = "users"."roleId"`
157157
);
158-
expect(result.sql).toContain("roles.name,roles.description");
158+
expect(result.sql).toContain(`json_build_object('name', "roles"."name", 'description', "roles"."description") AS roles`);
159159
expect(result.values).toEqual([]);
160160
});
161161
});
@@ -169,7 +169,7 @@ describe("SelectQueryBuilder", () => {
169169

170170
const result = builder.orderBy(orderBy).build();
171171

172-
expect(result.sql).toContain("ORDER BY users.name ASC");
172+
expect(result.sql).toContain(`ORDER BY "users"."name" ASC`);
173173
expect(result.values).toEqual([]);
174174
});
175175

@@ -181,7 +181,7 @@ describe("SelectQueryBuilder", () => {
181181

182182
const result = builder.orderBy(orderBy).build();
183183

184-
expect(result.sql).toContain("ORDER BY users.name ASC, users.age DESC");
184+
expect(result.sql).toContain(`ORDER BY "users"."name" ASC NULLS FIRST, "users"."age" DESC NULLS LAST`);
185185
expect(result.values).toEqual([]);
186186
});
187187
});

src/query-builder/select.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,10 @@ export class SelectQueryBuilder<T> extends BaseQueryBuilder<T> {
7373
this.tableName
7474
);
7575

76-
const orderByClause = buildOrderByClause(this.payload.orderBy);
76+
const orderByClause = buildOrderByClause(this.payload.orderBy, this.tableName);
7777
const { joinConditionClause, joinSelectClause } = buildJoinClause(
78-
this.payload.joins
78+
this.payload.joins,
79+
this.tableName
7980
);
8081

8182
// Build the SQL query with LIMIT, OFFSET, and ORDER BY

src/utils/clauses.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ const processSimpleCondition = <T>(
108108
/**
109109
* Builds an ORDER BY clause for SQL queries
110110
*/
111-
export const buildOrderByClause = <T>(orderBy?: Array<OrderBy<T>>): string => {
111+
export const buildOrderByClause = <T>(orderBy?: Array<OrderBy<T>>, baseTableName?: string): string => {
112112
if (!orderBy || orderBy.length === 0) {
113113
return ""; // No order by clause
114114
}
@@ -126,7 +126,7 @@ export const buildOrderByClause = <T>(orderBy?: Array<OrderBy<T>>): string => {
126126
// Add NULLS LAST for better sorting behavior
127127
const nullsOrder = safeDirection === "DESC" ? "NULLS LAST" : "NULLS FIRST";
128128

129-
return `${safeColumn} ${safeDirection} ${nullsOrder}`;
129+
return `"${baseTableName}".${safeColumn} ${safeDirection} ${nullsOrder}`;
130130
});
131131

132132
return `ORDER BY ${orderByConditions.join(", ")}`;
@@ -136,7 +136,8 @@ export const buildOrderByClause = <T>(orderBy?: Array<OrderBy<T>>): string => {
136136
* Builds JOIN clauses for SQL queries
137137
*/
138138
export const buildJoinClause = <T>(
139-
joins?: Array<Join<T, any>>
139+
joins?: Array<Join<T, any>>,
140+
baseTableName?: string
140141
): { joinConditionClause: string; joinSelectClause: string[] } => {
141142
if (!joins || joins.length === 0) {
142143
return {
@@ -150,7 +151,7 @@ export const buildJoinClause = <T>(
150151
const alias = join.as || join.table;
151152
const foreignField = join.on.foreignField as any;
152153
const localField = join.on.localField as any;
153-
return `${joinType} JOIN "${join.table}" AS "${alias}" ON "${alias}"."${foreignField}" = "${localField}"`;
154+
return `${joinType} JOIN "${join.table}" AS "${alias}" ON "${alias}"."${foreignField}" = "${baseTableName}"."${localField}"`;
154155
});
155156

156157
const joinSelectClause = joins

0 commit comments

Comments
 (0)