metal-orm 1.0.39 → 1.0.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +230 -75
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +71 -24
- package/dist/index.d.ts +71 -24
- package/dist/index.js +225 -75
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/codegen/typescript.ts +60 -3
- package/src/core/ast/aggregate-functions.ts +15 -15
- package/src/core/ast/expression-builders.ts +357 -316
- package/src/core/ast/expression-nodes.ts +208 -186
- package/src/core/ast/expression-visitor.ts +40 -30
- package/src/core/ast/query.ts +142 -132
- package/src/core/ast/window-functions.ts +86 -86
- package/src/core/dialect/abstract.ts +505 -479
- package/src/core/dialect/base/groupby-compiler.ts +6 -6
- package/src/core/dialect/base/orderby-compiler.ts +20 -6
- package/src/core/dialect/base/sql-dialect.ts +154 -136
- package/src/core/dialect/mssql/index.ts +172 -161
- package/src/core/functions/standard-strategy.ts +46 -37
- package/src/query-builder/hydration-manager.ts +93 -79
- package/src/query-builder/query-ast-service.ts +207 -170
- package/src/query-builder/select-query-state.ts +169 -162
- package/src/query-builder/select.ts +15 -23
package/dist/index.cjs
CHANGED
|
@@ -70,7 +70,9 @@ __export(index_exports, {
|
|
|
70
70
|
UpdateQueryBuilder: () => UpdateQueryBuilder,
|
|
71
71
|
abs: () => abs,
|
|
72
72
|
acos: () => acos,
|
|
73
|
+
add: () => add,
|
|
73
74
|
addDomainEvent: () => addDomainEvent,
|
|
75
|
+
aliasRef: () => aliasRef,
|
|
74
76
|
and: () => and,
|
|
75
77
|
ascii: () => ascii,
|
|
76
78
|
asin: () => asin,
|
|
@@ -121,6 +123,7 @@ __export(index_exports, {
|
|
|
121
123
|
degrees: () => degrees,
|
|
122
124
|
denseRank: () => denseRank,
|
|
123
125
|
diffSchema: () => diffSchema,
|
|
126
|
+
div: () => div,
|
|
124
127
|
endOfMonth: () => endOfMonth,
|
|
125
128
|
eq: () => eq,
|
|
126
129
|
esel: () => esel,
|
|
@@ -178,6 +181,7 @@ __export(index_exports, {
|
|
|
178
181
|
min: () => min,
|
|
179
182
|
mod: () => mod,
|
|
180
183
|
month: () => month,
|
|
184
|
+
mul: () => mul,
|
|
181
185
|
neq: () => neq,
|
|
182
186
|
notBetween: () => notBetween,
|
|
183
187
|
notExists: () => notExists,
|
|
@@ -213,6 +217,7 @@ __export(index_exports, {
|
|
|
213
217
|
sin: () => sin,
|
|
214
218
|
space: () => space,
|
|
215
219
|
sqrt: () => sqrt,
|
|
220
|
+
sub: () => sub,
|
|
216
221
|
substr: () => substr,
|
|
217
222
|
sum: () => sum,
|
|
218
223
|
synchronizeSchema: () => synchronizeSchema,
|
|
@@ -450,6 +455,7 @@ var belongsToMany = (target, pivotTable, options) => ({
|
|
|
450
455
|
|
|
451
456
|
// src/core/ast/expression-nodes.ts
|
|
452
457
|
var operandTypes = /* @__PURE__ */ new Set([
|
|
458
|
+
"AliasRef",
|
|
453
459
|
"Column",
|
|
454
460
|
"Literal",
|
|
455
461
|
"Function",
|
|
@@ -496,6 +502,10 @@ var outerRef = (col2) => ({
|
|
|
496
502
|
...columnOperand(col2),
|
|
497
503
|
scope: "outer"
|
|
498
504
|
});
|
|
505
|
+
var aliasRef = (name) => ({
|
|
506
|
+
type: "AliasRef",
|
|
507
|
+
name
|
|
508
|
+
});
|
|
499
509
|
var correlateBy = (table, column) => outerRef({ name: column, table });
|
|
500
510
|
var createBinaryExpression = (operator, left2, right2, escape) => {
|
|
501
511
|
const node = {
|
|
@@ -554,6 +564,16 @@ var createBetweenExpression = (operator, left2, lower2, upper2) => ({
|
|
|
554
564
|
});
|
|
555
565
|
var between = (left2, lower2, upper2) => createBetweenExpression("BETWEEN", left2, lower2, upper2);
|
|
556
566
|
var notBetween = (left2, lower2, upper2) => createBetweenExpression("NOT BETWEEN", left2, lower2, upper2);
|
|
567
|
+
var createArithmeticExpression = (operator, left2, right2) => ({
|
|
568
|
+
type: "ArithmeticExpression",
|
|
569
|
+
left: toOperand(left2),
|
|
570
|
+
operator,
|
|
571
|
+
right: toOperand(right2)
|
|
572
|
+
});
|
|
573
|
+
var add = (left2, right2) => createArithmeticExpression("+", left2, right2);
|
|
574
|
+
var sub = (left2, right2) => createArithmeticExpression("-", left2, right2);
|
|
575
|
+
var mul = (left2, right2) => createArithmeticExpression("*", left2, right2);
|
|
576
|
+
var div = (left2, right2) => createArithmeticExpression("/", left2, right2);
|
|
557
577
|
var jsonPath = (col2, path) => ({
|
|
558
578
|
type: "JsonPath",
|
|
559
579
|
column: columnOperand(col2),
|
|
@@ -632,7 +652,7 @@ var windowFunction = (name, args = [], partitionBy, orderBy) => {
|
|
|
632
652
|
const partitionNodes = partitionBy?.map((col2) => columnOperand(col2)) ?? void 0;
|
|
633
653
|
const orderNodes = orderBy?.map((o) => ({
|
|
634
654
|
type: "OrderBy",
|
|
635
|
-
|
|
655
|
+
term: columnOperand(o.column),
|
|
636
656
|
direction: o.direction
|
|
637
657
|
}));
|
|
638
658
|
return buildWindowFunction(name, nodeArgs, partitionNodes, orderNodes);
|
|
@@ -707,7 +727,7 @@ var min = buildAggregate("MIN");
|
|
|
707
727
|
var max = buildAggregate("MAX");
|
|
708
728
|
var toOrderByNode = (order) => ({
|
|
709
729
|
type: "OrderBy",
|
|
710
|
-
|
|
730
|
+
term: columnOperand(order.column),
|
|
711
731
|
direction: order.direction ?? ORDER_DIRECTIONS.ASC
|
|
712
732
|
});
|
|
713
733
|
var groupConcat = (col2, options) => ({
|
|
@@ -757,6 +777,9 @@ var visitExpression = (node, visitor) => {
|
|
|
757
777
|
case "BetweenExpression":
|
|
758
778
|
if (visitor.visitBetweenExpression) return visitor.visitBetweenExpression(node);
|
|
759
779
|
break;
|
|
780
|
+
case "ArithmeticExpression":
|
|
781
|
+
if (visitor.visitArithmeticExpression) return visitor.visitArithmeticExpression(node);
|
|
782
|
+
break;
|
|
760
783
|
default:
|
|
761
784
|
break;
|
|
762
785
|
}
|
|
@@ -788,6 +811,9 @@ var visitOperand = (node, visitor) => {
|
|
|
788
811
|
case "WindowFunction":
|
|
789
812
|
if (visitor.visitWindowFunction) return visitor.visitWindowFunction(node);
|
|
790
813
|
break;
|
|
814
|
+
case "AliasRef":
|
|
815
|
+
if (visitor.visitAliasRef) return visitor.visitAliasRef(node);
|
|
816
|
+
break;
|
|
791
817
|
default:
|
|
792
818
|
break;
|
|
793
819
|
}
|
|
@@ -904,7 +930,14 @@ var StandardFunctionStrategy = class _StandardFunctionStrategy {
|
|
|
904
930
|
if (!orderBy || orderBy.length === 0) {
|
|
905
931
|
return "";
|
|
906
932
|
}
|
|
907
|
-
const parts = orderBy.map((order) =>
|
|
933
|
+
const parts = orderBy.map((order) => {
|
|
934
|
+
const term = isOperandNode(order.term) ? ctx.compileOperand(order.term) : (() => {
|
|
935
|
+
throw new Error("ORDER BY expressions inside functions must be operands");
|
|
936
|
+
})();
|
|
937
|
+
const collation = order.collation ? ` COLLATE ${order.collation}` : "";
|
|
938
|
+
const nulls = order.nulls ? ` NULLS ${order.nulls}` : "";
|
|
939
|
+
return `${term} ${order.direction}${collation}${nulls}`;
|
|
940
|
+
});
|
|
908
941
|
return `ORDER BY ${parts.join(", ")}`;
|
|
909
942
|
}
|
|
910
943
|
formatGroupConcatSeparator(ctx) {
|
|
@@ -1169,6 +1202,16 @@ var Dialect = class _Dialect {
|
|
|
1169
1202
|
}
|
|
1170
1203
|
return compiler(node, ctx);
|
|
1171
1204
|
}
|
|
1205
|
+
/**
|
|
1206
|
+
* Compiles an ordering term (operand, expression, or alias reference).
|
|
1207
|
+
*/
|
|
1208
|
+
compileOrderingTerm(term, ctx) {
|
|
1209
|
+
if (isOperandNode(term)) {
|
|
1210
|
+
return this.compileOperand(term, ctx);
|
|
1211
|
+
}
|
|
1212
|
+
const expr = this.compileExpression(term, ctx);
|
|
1213
|
+
return `(${expr})`;
|
|
1214
|
+
}
|
|
1172
1215
|
registerDefaultExpressionCompilers() {
|
|
1173
1216
|
this.registerExpressionCompiler("BinaryExpression", (binary, ctx) => {
|
|
1174
1217
|
const left2 = this.compileOperand(binary.left, ctx);
|
|
@@ -1207,9 +1250,15 @@ var Dialect = class _Dialect {
|
|
|
1207
1250
|
const upper2 = this.compileOperand(betweenExpr.upper, ctx);
|
|
1208
1251
|
return `${left2} ${betweenExpr.operator} ${lower2} AND ${upper2}`;
|
|
1209
1252
|
});
|
|
1253
|
+
this.registerExpressionCompiler("ArithmeticExpression", (arith, ctx) => {
|
|
1254
|
+
const left2 = this.compileOperand(arith.left, ctx);
|
|
1255
|
+
const right2 = this.compileOperand(arith.right, ctx);
|
|
1256
|
+
return `${left2} ${arith.operator} ${right2}`;
|
|
1257
|
+
});
|
|
1210
1258
|
}
|
|
1211
1259
|
registerDefaultOperandCompilers() {
|
|
1212
1260
|
this.registerOperandCompiler("Literal", (literal, ctx) => ctx.addParameter(literal.value));
|
|
1261
|
+
this.registerOperandCompiler("AliasRef", (alias, _ctx) => this.quoteIdentifier(alias.name));
|
|
1213
1262
|
this.registerOperandCompiler("Column", (column, _ctx) => {
|
|
1214
1263
|
return `${this.quoteIdentifier(column.table)}.${this.quoteIdentifier(column.name)}`;
|
|
1215
1264
|
});
|
|
@@ -1247,9 +1296,12 @@ var Dialect = class _Dialect {
|
|
|
1247
1296
|
parts.push(partitionClause);
|
|
1248
1297
|
}
|
|
1249
1298
|
if (node.orderBy && node.orderBy.length > 0) {
|
|
1250
|
-
const orderClause = "ORDER BY " + node.orderBy.map(
|
|
1251
|
-
|
|
1252
|
-
|
|
1299
|
+
const orderClause = "ORDER BY " + node.orderBy.map((o) => {
|
|
1300
|
+
const term = this.compileOrderingTerm(o.term, ctx);
|
|
1301
|
+
const collation = o.collation ? ` COLLATE ${o.collation}` : "";
|
|
1302
|
+
const nulls = o.nulls ? ` NULLS ${o.nulls}` : "";
|
|
1303
|
+
return `${term} ${o.direction}${collation}${nulls}`;
|
|
1304
|
+
}).join(", ");
|
|
1253
1305
|
parts.push(orderClause);
|
|
1254
1306
|
}
|
|
1255
1307
|
result += parts.join(" ");
|
|
@@ -1468,12 +1520,12 @@ var GroupByCompiler = class {
|
|
|
1468
1520
|
/**
|
|
1469
1521
|
* Compiles GROUP BY clause from a SELECT query AST.
|
|
1470
1522
|
* @param ast - The SELECT query AST containing grouping columns.
|
|
1471
|
-
* @param
|
|
1523
|
+
* @param renderTerm - Function to render a grouping term.
|
|
1472
1524
|
* @returns SQL GROUP BY clause (e.g., " GROUP BY table.col1, table.col2") or empty string if no grouping.
|
|
1473
1525
|
*/
|
|
1474
|
-
static compileGroupBy(ast,
|
|
1526
|
+
static compileGroupBy(ast, renderTerm) {
|
|
1475
1527
|
if (!ast.groupBy || ast.groupBy.length === 0) return "";
|
|
1476
|
-
const cols = ast.groupBy.map(
|
|
1528
|
+
const cols = ast.groupBy.map(renderTerm).join(", ");
|
|
1477
1529
|
return ` GROUP BY ${cols}`;
|
|
1478
1530
|
}
|
|
1479
1531
|
};
|
|
@@ -1483,12 +1535,19 @@ var OrderByCompiler = class {
|
|
|
1483
1535
|
/**
|
|
1484
1536
|
* Compiles ORDER BY clause from a SELECT query AST.
|
|
1485
1537
|
* @param ast - The SELECT query AST containing sort specifications.
|
|
1486
|
-
* @param
|
|
1538
|
+
* @param renderTerm - Function to render an ordering term.
|
|
1539
|
+
* @param renderNulls - Optional function to render NULLS FIRST/LAST.
|
|
1540
|
+
* @param renderCollation - Optional function to render COLLATE clause.
|
|
1487
1541
|
* @returns SQL ORDER BY clause (e.g., " ORDER BY table.col1 ASC, table.col2 DESC") or empty string if no ordering.
|
|
1488
1542
|
*/
|
|
1489
|
-
static compileOrderBy(ast,
|
|
1543
|
+
static compileOrderBy(ast, renderTerm, renderNulls, renderCollation) {
|
|
1490
1544
|
if (!ast.orderBy || ast.orderBy.length === 0) return "";
|
|
1491
|
-
const parts = ast.orderBy.map((o) =>
|
|
1545
|
+
const parts = ast.orderBy.map((o) => {
|
|
1546
|
+
const term = renderTerm(o.term);
|
|
1547
|
+
const collation = renderCollation ? renderCollation(o) : o.collation ? ` COLLATE ${o.collation}` : "";
|
|
1548
|
+
const nulls = renderNulls ? renderNulls(o) : o.nulls ? ` NULLS ${o.nulls}` : "";
|
|
1549
|
+
return `${term} ${o.direction}${collation}${nulls}`;
|
|
1550
|
+
}).join(", ");
|
|
1492
1551
|
return ` ORDER BY ${parts}`;
|
|
1493
1552
|
}
|
|
1494
1553
|
};
|
|
@@ -1519,7 +1578,12 @@ var SqlDialectBase = class extends Dialect {
|
|
|
1519
1578
|
}
|
|
1520
1579
|
compileSelectWithSetOps(ast, baseSelect, ctes, ctx) {
|
|
1521
1580
|
const compound = ast.setOps.map((op) => `${op.operator} ${this.wrapSetOperand(this.compileSelectAst(op.query, ctx))}`).join(" ");
|
|
1522
|
-
const orderBy = OrderByCompiler.compileOrderBy(
|
|
1581
|
+
const orderBy = OrderByCompiler.compileOrderBy(
|
|
1582
|
+
ast,
|
|
1583
|
+
(term) => this.compileOrderingTerm(term, ctx),
|
|
1584
|
+
this.renderOrderByNulls.bind(this),
|
|
1585
|
+
this.renderOrderByCollation.bind(this)
|
|
1586
|
+
);
|
|
1523
1587
|
const pagination = this.paginationStrategy.compilePagination(ast.limit, ast.offset);
|
|
1524
1588
|
const combined = `${this.wrapSetOperand(baseSelect)} ${compound}`;
|
|
1525
1589
|
return `${ctes}${combined}${orderBy}${pagination}`;
|
|
@@ -1545,9 +1609,14 @@ var SqlDialectBase = class extends Dialect {
|
|
|
1545
1609
|
const from = this.compileFrom(ast.from, ctx);
|
|
1546
1610
|
const joins = JoinCompiler.compileJoins(ast, ctx, this.compileFrom.bind(this), this.compileExpression.bind(this));
|
|
1547
1611
|
const whereClause = this.compileWhere(ast.where, ctx);
|
|
1548
|
-
const groupBy = GroupByCompiler.compileGroupBy(ast, this.
|
|
1612
|
+
const groupBy = GroupByCompiler.compileGroupBy(ast, (term) => this.compileOrderingTerm(term, ctx));
|
|
1549
1613
|
const having = this.compileHaving(ast, ctx);
|
|
1550
|
-
const orderBy = OrderByCompiler.compileOrderBy(
|
|
1614
|
+
const orderBy = OrderByCompiler.compileOrderBy(
|
|
1615
|
+
ast,
|
|
1616
|
+
(term) => this.compileOrderingTerm(term, ctx),
|
|
1617
|
+
this.renderOrderByNulls.bind(this),
|
|
1618
|
+
this.renderOrderByCollation.bind(this)
|
|
1619
|
+
);
|
|
1551
1620
|
const pagination = this.paginationStrategy.compilePagination(ast.limit, ast.offset);
|
|
1552
1621
|
return `SELECT ${this.compileDistinct(ast)}${columns} FROM ${from}${joins}${whereClause}${groupBy}${having}${orderBy}${pagination}`;
|
|
1553
1622
|
}
|
|
@@ -1636,6 +1705,12 @@ var SqlDialectBase = class extends Dialect {
|
|
|
1636
1705
|
const trimmed = this.stripTrailingSemicolon(sql);
|
|
1637
1706
|
return `(${trimmed})`;
|
|
1638
1707
|
}
|
|
1708
|
+
renderOrderByNulls(order) {
|
|
1709
|
+
return order.nulls ? ` NULLS ${order.nulls}` : "";
|
|
1710
|
+
}
|
|
1711
|
+
renderOrderByCollation(order) {
|
|
1712
|
+
return order.collation ? ` COLLATE ${order.collation}` : "";
|
|
1713
|
+
}
|
|
1639
1714
|
};
|
|
1640
1715
|
|
|
1641
1716
|
// src/core/dialect/postgres/functions.ts
|
|
@@ -2152,7 +2227,7 @@ var SqlServerDialect = class extends Dialect {
|
|
|
2152
2227
|
return `${ctes}${baseSelect}`;
|
|
2153
2228
|
}
|
|
2154
2229
|
const compound = ast.setOps.map((op) => `${op.operator} ${this.wrapSetOperand(this.compileSelectAst(op.query, ctx))}`).join(" ");
|
|
2155
|
-
const orderBy = this.compileOrderBy(ast);
|
|
2230
|
+
const orderBy = this.compileOrderBy(ast, ctx);
|
|
2156
2231
|
const pagination = this.compilePagination(ast, orderBy);
|
|
2157
2232
|
const combined = `${this.wrapSetOperand(baseSelect)} ${compound}`;
|
|
2158
2233
|
const tail = pagination || orderBy;
|
|
@@ -2209,18 +2284,22 @@ var SqlServerDialect = class extends Dialect {
|
|
|
2209
2284
|
return `${j.kind} JOIN ${table} ON ${cond}`;
|
|
2210
2285
|
}).join(" ");
|
|
2211
2286
|
const whereClause = this.compileWhere(ast.where, ctx);
|
|
2212
|
-
const groupBy = ast.groupBy && ast.groupBy.length > 0 ? " GROUP BY " + ast.groupBy.map((
|
|
2287
|
+
const groupBy = ast.groupBy && ast.groupBy.length > 0 ? " GROUP BY " + ast.groupBy.map((term) => this.compileOrderingTerm(term, ctx)).join(", ") : "";
|
|
2213
2288
|
const having = ast.having ? ` HAVING ${this.compileExpression(ast.having, ctx)}` : "";
|
|
2214
|
-
const orderBy = this.compileOrderBy(ast);
|
|
2289
|
+
const orderBy = this.compileOrderBy(ast, ctx);
|
|
2215
2290
|
const pagination = this.compilePagination(ast, orderBy);
|
|
2216
2291
|
if (pagination) {
|
|
2217
2292
|
return `SELECT ${distinct}${columns} FROM ${from}${joins ? " " + joins : ""}${whereClause}${groupBy}${having}${pagination}`;
|
|
2218
2293
|
}
|
|
2219
2294
|
return `SELECT ${distinct}${columns} FROM ${from}${joins ? " " + joins : ""}${whereClause}${groupBy}${having}${orderBy}`;
|
|
2220
2295
|
}
|
|
2221
|
-
compileOrderBy(ast) {
|
|
2222
|
-
|
|
2223
|
-
|
|
2296
|
+
compileOrderBy(ast, ctx) {
|
|
2297
|
+
return OrderByCompiler.compileOrderBy(
|
|
2298
|
+
ast,
|
|
2299
|
+
(term) => this.compileOrderingTerm(term, ctx),
|
|
2300
|
+
this.renderOrderByNulls.bind(this),
|
|
2301
|
+
this.renderOrderByCollation.bind(this)
|
|
2302
|
+
);
|
|
2224
2303
|
}
|
|
2225
2304
|
compilePagination(ast, orderBy) {
|
|
2226
2305
|
const hasLimit = ast.limit !== void 0;
|
|
@@ -2234,6 +2313,12 @@ var SqlServerDialect = class extends Dialect {
|
|
|
2234
2313
|
}
|
|
2235
2314
|
return pagination;
|
|
2236
2315
|
}
|
|
2316
|
+
renderOrderByNulls(order) {
|
|
2317
|
+
return order.nulls ? ` NULLS ${order.nulls}` : "";
|
|
2318
|
+
}
|
|
2319
|
+
renderOrderByCollation(order) {
|
|
2320
|
+
return order.collation ? ` COLLATE ${order.collation}` : "";
|
|
2321
|
+
}
|
|
2237
2322
|
compileTableSource(table, ctx) {
|
|
2238
2323
|
if (table.type === "FunctionTable") {
|
|
2239
2324
|
return FunctionTableFormatter.format(table, ctx, this);
|
|
@@ -2245,9 +2330,9 @@ var SqlServerDialect = class extends Dialect {
|
|
|
2245
2330
|
return table.alias ? `${base} AS ${this.quoteIdentifier(table.alias)}` : base;
|
|
2246
2331
|
}
|
|
2247
2332
|
compileDerivedTable(table, ctx) {
|
|
2248
|
-
const
|
|
2333
|
+
const sub2 = this.compileSelectAst(this.normalizeSelectAst(table.query), ctx).trim().replace(/;$/, "");
|
|
2249
2334
|
const cols = table.columnAliases?.length ? ` (${table.columnAliases.map((c) => this.quoteIdentifier(c)).join(", ")})` : "";
|
|
2250
|
-
return `(${
|
|
2335
|
+
return `(${sub2}) AS ${this.quoteIdentifier(table.alias)}${cols}`;
|
|
2251
2336
|
}
|
|
2252
2337
|
compileCtes(ast, ctx) {
|
|
2253
2338
|
if (!ast.ctes || ast.ctes.length === 0) return "";
|
|
@@ -2412,7 +2497,7 @@ var SelectQueryState = class _SelectQueryState {
|
|
|
2412
2497
|
}
|
|
2413
2498
|
/**
|
|
2414
2499
|
* Adds GROUP BY columns to the query
|
|
2415
|
-
* @param columns -
|
|
2500
|
+
* @param columns - Terms to group by
|
|
2416
2501
|
* @returns New SelectQueryState with GROUP BY clause
|
|
2417
2502
|
*/
|
|
2418
2503
|
withGroupBy(columns) {
|
|
@@ -2695,31 +2780,38 @@ var HydrationManager = class _HydrationManager {
|
|
|
2695
2780
|
}
|
|
2696
2781
|
const mapped = [];
|
|
2697
2782
|
for (const ob of orderBy) {
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
}
|
|
2701
|
-
const alias = projectionAliases.get(`${ob.column.table}.${ob.column.name}`) ?? ob.column.name;
|
|
2702
|
-
if (!availableColumns.has(alias)) {
|
|
2703
|
-
return null;
|
|
2704
|
-
}
|
|
2705
|
-
mapped.push({
|
|
2706
|
-
type: "OrderBy",
|
|
2707
|
-
column: { type: "Column", table: baseAlias, name: alias },
|
|
2708
|
-
direction: ob.direction
|
|
2709
|
-
});
|
|
2783
|
+
const mappedTerm = this.mapOrderingTerm(ob.term, plan, projectionAliases, baseAlias, availableColumns);
|
|
2784
|
+
if (!mappedTerm) return null;
|
|
2785
|
+
mapped.push({ ...ob, term: mappedTerm });
|
|
2710
2786
|
}
|
|
2711
2787
|
return mapped;
|
|
2712
2788
|
}
|
|
2789
|
+
mapOrderingTerm(term, plan, projectionAliases, baseAlias, availableColumns) {
|
|
2790
|
+
if (term.type === "Column") {
|
|
2791
|
+
const col2 = term;
|
|
2792
|
+
if (col2.table !== plan.rootTable) return null;
|
|
2793
|
+
const alias = projectionAliases.get(`${col2.table}.${col2.name}`) ?? col2.name;
|
|
2794
|
+
if (!availableColumns.has(alias)) return null;
|
|
2795
|
+
return { type: "Column", table: baseAlias, name: alias };
|
|
2796
|
+
}
|
|
2797
|
+
if (term.type === "AliasRef") {
|
|
2798
|
+
const aliasName = term.name;
|
|
2799
|
+
if (!availableColumns.has(aliasName)) return null;
|
|
2800
|
+
return { type: "Column", table: baseAlias, name: aliasName };
|
|
2801
|
+
}
|
|
2802
|
+
return null;
|
|
2803
|
+
}
|
|
2713
2804
|
buildPagingColumns(primaryKey, orderBy, tableAlias) {
|
|
2714
2805
|
const columns = [{ type: "Column", table: tableAlias, name: primaryKey, alias: primaryKey }];
|
|
2715
2806
|
if (!orderBy) return columns;
|
|
2716
2807
|
for (const ob of orderBy) {
|
|
2717
|
-
|
|
2808
|
+
const term = ob.term;
|
|
2809
|
+
if (!columns.some((col2) => col2.name === term.name)) {
|
|
2718
2810
|
columns.push({
|
|
2719
2811
|
type: "Column",
|
|
2720
2812
|
table: tableAlias,
|
|
2721
|
-
name:
|
|
2722
|
-
alias:
|
|
2813
|
+
name: term.name,
|
|
2814
|
+
alias: term.name
|
|
2723
2815
|
});
|
|
2724
2816
|
}
|
|
2725
2817
|
}
|
|
@@ -3025,10 +3117,8 @@ var QueryAstService = class {
|
|
|
3025
3117
|
* @returns Updated query state with GROUP BY clause
|
|
3026
3118
|
*/
|
|
3027
3119
|
withGroupBy(col2) {
|
|
3028
|
-
const
|
|
3029
|
-
|
|
3030
|
-
const node = buildColumnNode(tableRef, col2);
|
|
3031
|
-
return this.state.withGroupBy([node]);
|
|
3120
|
+
const term = this.normalizeOrderingTerm(col2);
|
|
3121
|
+
return this.state.withGroupBy([term]);
|
|
3032
3122
|
}
|
|
3033
3123
|
/**
|
|
3034
3124
|
* Adds a HAVING clause to the query
|
|
@@ -3045,11 +3135,9 @@ var QueryAstService = class {
|
|
|
3045
3135
|
* @param direction - Order direction (ASC/DESC)
|
|
3046
3136
|
* @returns Updated query state with ORDER BY clause
|
|
3047
3137
|
*/
|
|
3048
|
-
withOrderBy(
|
|
3049
|
-
const
|
|
3050
|
-
|
|
3051
|
-
const node = buildColumnNode(tableRef, col2);
|
|
3052
|
-
return this.state.withOrderBy([{ type: "OrderBy", column: node, direction }]);
|
|
3138
|
+
withOrderBy(term, direction, nulls, collation) {
|
|
3139
|
+
const normalized = this.normalizeOrderingTerm(term);
|
|
3140
|
+
return this.state.withOrderBy([{ type: "OrderBy", term: normalized, direction, nulls, collation }]);
|
|
3053
3141
|
}
|
|
3054
3142
|
/**
|
|
3055
3143
|
* Adds a DISTINCT clause to the query
|
|
@@ -3084,6 +3172,24 @@ var QueryAstService = class {
|
|
|
3084
3172
|
combineExpressions(existing, next) {
|
|
3085
3173
|
return existing ? and(existing, next) : next;
|
|
3086
3174
|
}
|
|
3175
|
+
normalizeOrderingTerm(term) {
|
|
3176
|
+
const from = this.state.ast.from;
|
|
3177
|
+
const tableRef = from.type === "Table" && from.alias ? { ...this.table, alias: from.alias } : this.table;
|
|
3178
|
+
const termType = term?.type;
|
|
3179
|
+
if (termType === "Column") {
|
|
3180
|
+
return term;
|
|
3181
|
+
}
|
|
3182
|
+
if (termType === "AliasRef") {
|
|
3183
|
+
return term;
|
|
3184
|
+
}
|
|
3185
|
+
if (isOperandNode(term)) {
|
|
3186
|
+
return term;
|
|
3187
|
+
}
|
|
3188
|
+
if (termType === "BinaryExpression" || termType === "LogicalExpression" || termType === "NullExpression" || termType === "InExpression" || termType === "ExistsExpression" || termType === "BetweenExpression" || termType === "ArithmeticExpression") {
|
|
3189
|
+
return term;
|
|
3190
|
+
}
|
|
3191
|
+
return buildColumnNode(tableRef, term);
|
|
3192
|
+
}
|
|
3087
3193
|
};
|
|
3088
3194
|
|
|
3089
3195
|
// src/query-builder/relation-projection-helper.ts
|
|
@@ -4733,8 +4839,8 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4733
4839
|
* @returns New query builder instance with the subquery selection
|
|
4734
4840
|
|
|
4735
4841
|
*/
|
|
4736
|
-
selectSubquery(alias,
|
|
4737
|
-
const query = this.resolveQueryNode(
|
|
4842
|
+
selectSubquery(alias, sub2) {
|
|
4843
|
+
const query = this.resolveQueryNode(sub2);
|
|
4738
4844
|
return this.clone(this.columnSelector.selectSubquery(this.context, alias, query));
|
|
4739
4845
|
}
|
|
4740
4846
|
/**
|
|
@@ -4916,16 +5022,12 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4916
5022
|
return this.clone(nextContext);
|
|
4917
5023
|
}
|
|
4918
5024
|
/**
|
|
4919
|
-
|
|
4920
|
-
|
|
4921
|
-
|
|
4922
|
-
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
|
|
4926
|
-
*/
|
|
4927
|
-
groupBy(col2) {
|
|
4928
|
-
const nextContext = this.applyAst(this.context, (service) => service.withGroupBy(col2));
|
|
5025
|
+
* Adds a GROUP BY clause to the query
|
|
5026
|
+
* @param term - Column definition or ordering term to group by
|
|
5027
|
+
* @returns New query builder instance with the GROUP BY clause
|
|
5028
|
+
*/
|
|
5029
|
+
groupBy(term) {
|
|
5030
|
+
const nextContext = this.applyAst(this.context, (service) => service.withGroupBy(term));
|
|
4929
5031
|
return this.clone(nextContext);
|
|
4930
5032
|
}
|
|
4931
5033
|
/**
|
|
@@ -4942,18 +5044,18 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
4942
5044
|
return this.clone(nextContext);
|
|
4943
5045
|
}
|
|
4944
5046
|
/**
|
|
4945
|
-
|
|
4946
|
-
|
|
4947
|
-
|
|
4948
|
-
|
|
4949
|
-
|
|
4950
|
-
|
|
4951
|
-
|
|
4952
|
-
|
|
4953
|
-
|
|
4954
|
-
|
|
4955
|
-
|
|
4956
|
-
|
|
5047
|
+
* Adds an ORDER BY clause to the query
|
|
5048
|
+
* @param term - Column definition or ordering term to order by
|
|
5049
|
+
* @param directionOrOptions - Order direction or options (defaults to ASC)
|
|
5050
|
+
* @returns New query builder instance with the ORDER BY clause
|
|
5051
|
+
*/
|
|
5052
|
+
orderBy(term, directionOrOptions = ORDER_DIRECTIONS.ASC) {
|
|
5053
|
+
const options = typeof directionOrOptions === "string" ? { direction: directionOrOptions } : directionOrOptions;
|
|
5054
|
+
const dir = options.direction ?? ORDER_DIRECTIONS.ASC;
|
|
5055
|
+
const nextContext = this.applyAst(
|
|
5056
|
+
this.context,
|
|
5057
|
+
(service) => service.withOrderBy(term, dir, options.nulls, options.collation)
|
|
5058
|
+
);
|
|
4957
5059
|
return this.clone(nextContext);
|
|
4958
5060
|
}
|
|
4959
5061
|
/**
|
|
@@ -6781,7 +6883,7 @@ var TypeScriptGenerator = class {
|
|
|
6781
6883
|
lines.push(`.where(${this.printExpression(ast.where)})`);
|
|
6782
6884
|
}
|
|
6783
6885
|
if (ast.groupBy && ast.groupBy.length) {
|
|
6784
|
-
const cols = ast.groupBy.map((
|
|
6886
|
+
const cols = ast.groupBy.map((term) => this.printOrderingTerm(term)).join(", ");
|
|
6785
6887
|
lines.push(`.groupBy(${cols})`);
|
|
6786
6888
|
}
|
|
6787
6889
|
if (ast.having) {
|
|
@@ -6789,7 +6891,16 @@ var TypeScriptGenerator = class {
|
|
|
6789
6891
|
}
|
|
6790
6892
|
if (ast.orderBy && ast.orderBy.length) {
|
|
6791
6893
|
ast.orderBy.forEach((o) => {
|
|
6792
|
-
|
|
6894
|
+
const term = this.printOrderingTerm(o.term);
|
|
6895
|
+
const opts = [`direction: '${o.direction}'`];
|
|
6896
|
+
if (o.nulls) opts.push(`nulls: '${o.nulls}'`);
|
|
6897
|
+
if (o.collation) opts.push(`collation: '${o.collation}'`);
|
|
6898
|
+
const hasOpts = opts.length > 1;
|
|
6899
|
+
if (hasOpts) {
|
|
6900
|
+
lines.push(`.orderBy(${term}, { ${opts.join(", ")} })`);
|
|
6901
|
+
} else {
|
|
6902
|
+
lines.push(`.orderBy(${term}, '${o.direction}')`);
|
|
6903
|
+
}
|
|
6793
6904
|
});
|
|
6794
6905
|
}
|
|
6795
6906
|
if (ast.limit) lines.push(`.limit(${ast.limit})`);
|
|
@@ -6812,6 +6923,29 @@ var TypeScriptGenerator = class {
|
|
|
6812
6923
|
printOperand(node) {
|
|
6813
6924
|
return visitOperand(node, this);
|
|
6814
6925
|
}
|
|
6926
|
+
/**
|
|
6927
|
+
* Prints an ordering term (operand/expression/alias) to TypeScript code.
|
|
6928
|
+
*/
|
|
6929
|
+
printOrderingTerm(term) {
|
|
6930
|
+
if (!term || !term.type) {
|
|
6931
|
+
throw new Error("Unsupported ordering term");
|
|
6932
|
+
}
|
|
6933
|
+
switch (term.type) {
|
|
6934
|
+
case "Column":
|
|
6935
|
+
return `${this.namingStrategy.tableToSymbol(term.table)}.${term.name}`;
|
|
6936
|
+
case "AliasRef":
|
|
6937
|
+
return this.visitAliasRef(term);
|
|
6938
|
+
case "Literal":
|
|
6939
|
+
case "Function":
|
|
6940
|
+
case "JsonPath":
|
|
6941
|
+
case "ScalarSubquery":
|
|
6942
|
+
case "CaseExpression":
|
|
6943
|
+
case "WindowFunction":
|
|
6944
|
+
return this.printOperand(term);
|
|
6945
|
+
default:
|
|
6946
|
+
return this.printExpression(term);
|
|
6947
|
+
}
|
|
6948
|
+
}
|
|
6815
6949
|
visitBinaryExpression(binary) {
|
|
6816
6950
|
return this.printBinaryExpression(binary);
|
|
6817
6951
|
}
|
|
@@ -6830,6 +6964,9 @@ var TypeScriptGenerator = class {
|
|
|
6830
6964
|
visitBetweenExpression(betweenExpr) {
|
|
6831
6965
|
return this.printBetweenExpression(betweenExpr);
|
|
6832
6966
|
}
|
|
6967
|
+
visitArithmeticExpression(arithExpr) {
|
|
6968
|
+
return this.printArithmeticExpression(arithExpr);
|
|
6969
|
+
}
|
|
6833
6970
|
visitColumn(node) {
|
|
6834
6971
|
return this.printColumnOperand(node);
|
|
6835
6972
|
}
|
|
@@ -6851,6 +6988,9 @@ var TypeScriptGenerator = class {
|
|
|
6851
6988
|
visitWindowFunction(node) {
|
|
6852
6989
|
return this.printWindowFunctionOperand(node);
|
|
6853
6990
|
}
|
|
6991
|
+
visitAliasRef(node) {
|
|
6992
|
+
return `aliasRef('${node.name}')`;
|
|
6993
|
+
}
|
|
6854
6994
|
/**
|
|
6855
6995
|
* Prints a binary expression to TypeScript code
|
|
6856
6996
|
* @param binary - Binary expression node
|
|
@@ -6881,6 +7021,11 @@ var TypeScriptGenerator = class {
|
|
|
6881
7021
|
${parts.join(",\n ")}
|
|
6882
7022
|
)`;
|
|
6883
7023
|
}
|
|
7024
|
+
printArithmeticExpression(expr) {
|
|
7025
|
+
const left2 = this.printOperand(expr.left);
|
|
7026
|
+
const right2 = this.printOperand(expr.right);
|
|
7027
|
+
return `${left2} ${expr.operator} ${right2}`;
|
|
7028
|
+
}
|
|
6884
7029
|
/**
|
|
6885
7030
|
* Prints an IN expression to TypeScript code
|
|
6886
7031
|
* @param inExpr - IN expression node
|
|
@@ -6994,7 +7139,12 @@ var TypeScriptGenerator = class {
|
|
|
6994
7139
|
parts.push(partitionClause);
|
|
6995
7140
|
}
|
|
6996
7141
|
if (node.orderBy && node.orderBy.length > 0) {
|
|
6997
|
-
const orderClause = "ORDER BY " + node.orderBy.map((o) =>
|
|
7142
|
+
const orderClause = "ORDER BY " + node.orderBy.map((o) => {
|
|
7143
|
+
const term = this.printOrderingTerm(o.term);
|
|
7144
|
+
const collation = o.collation ? ` COLLATE ${o.collation}` : "";
|
|
7145
|
+
const nulls = o.nulls ? ` NULLS ${o.nulls}` : "";
|
|
7146
|
+
return `${term} ${o.direction}${collation}${nulls}`;
|
|
7147
|
+
}).join(", ");
|
|
6998
7148
|
parts.push(orderClause);
|
|
6999
7149
|
}
|
|
7000
7150
|
result += parts.join(" ");
|
|
@@ -8172,7 +8322,9 @@ function createTediousExecutor(connection, module2, options) {
|
|
|
8172
8322
|
UpdateQueryBuilder,
|
|
8173
8323
|
abs,
|
|
8174
8324
|
acos,
|
|
8325
|
+
add,
|
|
8175
8326
|
addDomainEvent,
|
|
8327
|
+
aliasRef,
|
|
8176
8328
|
and,
|
|
8177
8329
|
ascii,
|
|
8178
8330
|
asin,
|
|
@@ -8223,6 +8375,7 @@ function createTediousExecutor(connection, module2, options) {
|
|
|
8223
8375
|
degrees,
|
|
8224
8376
|
denseRank,
|
|
8225
8377
|
diffSchema,
|
|
8378
|
+
div,
|
|
8226
8379
|
endOfMonth,
|
|
8227
8380
|
eq,
|
|
8228
8381
|
esel,
|
|
@@ -8280,6 +8433,7 @@ function createTediousExecutor(connection, module2, options) {
|
|
|
8280
8433
|
min,
|
|
8281
8434
|
mod,
|
|
8282
8435
|
month,
|
|
8436
|
+
mul,
|
|
8283
8437
|
neq,
|
|
8284
8438
|
notBetween,
|
|
8285
8439
|
notExists,
|
|
@@ -8315,6 +8469,7 @@ function createTediousExecutor(connection, module2, options) {
|
|
|
8315
8469
|
sin,
|
|
8316
8470
|
space,
|
|
8317
8471
|
sqrt,
|
|
8472
|
+
sub,
|
|
8318
8473
|
substr,
|
|
8319
8474
|
sum,
|
|
8320
8475
|
synchronizeSchema,
|