metal-orm 1.0.82 → 1.0.85

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.d.cts CHANGED
@@ -1820,6 +1820,8 @@ interface CompilerContext {
1820
1820
  params: unknown[];
1821
1821
  /** Function to add a parameter and get its placeholder */
1822
1822
  addParameter(value: unknown): string;
1823
+ /** Whether Param operands are allowed (for schema generation) */
1824
+ allowParams?: boolean;
1823
1825
  }
1824
1826
  /**
1825
1827
  * Result of SQL compilation
@@ -1854,6 +1856,9 @@ declare abstract class Dialect implements SelectCompiler, InsertCompiler, Update
1854
1856
  * @returns Compiled query with SQL and parameters
1855
1857
  */
1856
1858
  compileSelect(ast: SelectQueryNode): CompiledQuery;
1859
+ compileSelectWithOptions(ast: SelectQueryNode, options?: {
1860
+ allowParams?: boolean;
1861
+ }): CompiledQuery;
1857
1862
  compileInsert(ast: InsertQueryNode): CompiledQuery;
1858
1863
  compileUpdate(ast: UpdateQueryNode): CompiledQuery;
1859
1864
  compileDelete(ast: DeleteQueryNode): CompiledQuery;
@@ -1894,9 +1899,12 @@ declare abstract class Dialect implements SelectCompiler, InsertCompiler, Update
1894
1899
  protected compileSelectForExists(ast: SelectQueryNode, ctx: CompilerContext): string;
1895
1900
  /**
1896
1901
  * Creates a new compiler context
1902
+ * @param options - Optional compiler context options
1897
1903
  * @returns Compiler context with parameter management
1898
1904
  */
1899
- protected createCompilerContext(): CompilerContext;
1905
+ protected createCompilerContext(options?: {
1906
+ allowParams?: boolean;
1907
+ }): CompilerContext;
1900
1908
  /**
1901
1909
  * Formats a parameter placeholder
1902
1910
  * @param index - Parameter index
@@ -2384,6 +2392,7 @@ declare class QueryAstService {
2384
2392
  * @returns Normalized ordering term
2385
2393
  */
2386
2394
  private normalizeOrderingTerm;
2395
+ private toParamNode;
2387
2396
  }
2388
2397
 
2389
2398
  /**
@@ -4312,6 +4321,11 @@ declare class SelectQueryBuilder<T = EntityInstance<TableDef>, TTable extends Ta
4312
4321
  * Ensures that if no columns are selected, all columns from the table are selected by default.
4313
4322
  */
4314
4323
  private ensureDefaultSelection;
4324
+ /**
4325
+ * Validates that the query does not contain Param operands.
4326
+ * Param proxies are only for schema generation, not execution.
4327
+ */
4328
+ private validateNoParamOperands;
4315
4329
  /**
4316
4330
  * Executes the query and returns hydrated results.
4317
4331
  * If the builder was created with an entity constructor (e.g. via selectFromEntity),
package/dist/index.d.ts CHANGED
@@ -1820,6 +1820,8 @@ interface CompilerContext {
1820
1820
  params: unknown[];
1821
1821
  /** Function to add a parameter and get its placeholder */
1822
1822
  addParameter(value: unknown): string;
1823
+ /** Whether Param operands are allowed (for schema generation) */
1824
+ allowParams?: boolean;
1823
1825
  }
1824
1826
  /**
1825
1827
  * Result of SQL compilation
@@ -1854,6 +1856,9 @@ declare abstract class Dialect implements SelectCompiler, InsertCompiler, Update
1854
1856
  * @returns Compiled query with SQL and parameters
1855
1857
  */
1856
1858
  compileSelect(ast: SelectQueryNode): CompiledQuery;
1859
+ compileSelectWithOptions(ast: SelectQueryNode, options?: {
1860
+ allowParams?: boolean;
1861
+ }): CompiledQuery;
1857
1862
  compileInsert(ast: InsertQueryNode): CompiledQuery;
1858
1863
  compileUpdate(ast: UpdateQueryNode): CompiledQuery;
1859
1864
  compileDelete(ast: DeleteQueryNode): CompiledQuery;
@@ -1894,9 +1899,12 @@ declare abstract class Dialect implements SelectCompiler, InsertCompiler, Update
1894
1899
  protected compileSelectForExists(ast: SelectQueryNode, ctx: CompilerContext): string;
1895
1900
  /**
1896
1901
  * Creates a new compiler context
1902
+ * @param options - Optional compiler context options
1897
1903
  * @returns Compiler context with parameter management
1898
1904
  */
1899
- protected createCompilerContext(): CompilerContext;
1905
+ protected createCompilerContext(options?: {
1906
+ allowParams?: boolean;
1907
+ }): CompilerContext;
1900
1908
  /**
1901
1909
  * Formats a parameter placeholder
1902
1910
  * @param index - Parameter index
@@ -2384,6 +2392,7 @@ declare class QueryAstService {
2384
2392
  * @returns Normalized ordering term
2385
2393
  */
2386
2394
  private normalizeOrderingTerm;
2395
+ private toParamNode;
2387
2396
  }
2388
2397
 
2389
2398
  /**
@@ -4312,6 +4321,11 @@ declare class SelectQueryBuilder<T = EntityInstance<TableDef>, TTable extends Ta
4312
4321
  * Ensures that if no columns are selected, all columns from the table are selected by default.
4313
4322
  */
4314
4323
  private ensureDefaultSelection;
4324
+ /**
4325
+ * Validates that the query does not contain Param operands.
4326
+ * Param proxies are only for schema generation, not execution.
4327
+ */
4328
+ private validateNoParamOperands;
4315
4329
  /**
4316
4330
  * Executes the query and returns hydrated results.
4317
4331
  * If the builder was created with an entity constructor (e.g. via selectFromEntity),
package/dist/index.js CHANGED
@@ -371,16 +371,27 @@ var operandTypes = /* @__PURE__ */ new Set([
371
371
  "BitwiseExpression",
372
372
  "Collate"
373
373
  ]);
374
- var hasTypeProperty = (value) => typeof value === "object" && value !== null && "type" in value;
374
+ var getNodeType = (value) => {
375
+ if (typeof value !== "object" || value === null) return void 0;
376
+ const descriptor = Object.getOwnPropertyDescriptor(value, "type");
377
+ if (descriptor && typeof descriptor.value === "string") {
378
+ return descriptor.value;
379
+ }
380
+ if ("type" in value) {
381
+ const type = value.type;
382
+ return typeof type === "string" ? type : void 0;
383
+ }
384
+ return void 0;
385
+ };
375
386
  var isOperandNode = (node) => {
376
- if (!hasTypeProperty(node)) return false;
377
- return operandTypes.has(node.type);
378
- };
379
- var isFunctionNode = (node) => isOperandNode(node) && node.type === "Function";
380
- var isCaseExpressionNode = (node) => isOperandNode(node) && node.type === "CaseExpression";
381
- var isCastExpressionNode = (node) => isOperandNode(node) && node.type === "Cast";
382
- var isCollateExpressionNode = (node) => isOperandNode(node) && node.type === "Collate";
383
- var isWindowFunctionNode = (node) => isOperandNode(node) && node.type === "WindowFunction";
387
+ const type = getNodeType(node);
388
+ return type !== void 0 && operandTypes.has(type);
389
+ };
390
+ var isFunctionNode = (node) => isOperandNode(node) && getNodeType(node) === "Function";
391
+ var isCaseExpressionNode = (node) => isOperandNode(node) && getNodeType(node) === "CaseExpression";
392
+ var isCastExpressionNode = (node) => isOperandNode(node) && getNodeType(node) === "Cast";
393
+ var isCollateExpressionNode = (node) => isOperandNode(node) && getNodeType(node) === "Collate";
394
+ var isWindowFunctionNode = (node) => isOperandNode(node) && getNodeType(node) === "WindowFunction";
384
395
  var isExpressionSelectionNode = (node) => isFunctionNode(node) || isCaseExpressionNode(node) || isCastExpressionNode(node) || isWindowFunctionNode(node);
385
396
 
386
397
  // src/core/ast/expression-builders.ts
@@ -389,6 +400,14 @@ var toLiteralNode = (value) => ({
389
400
  type: "Literal",
390
401
  value: value instanceof Date ? value.toISOString() : value
391
402
  });
403
+ var toParamNode = (value) => {
404
+ if (typeof value !== "object" || value === null) return void 0;
405
+ const type = Object.getOwnPropertyDescriptor(value, "type")?.value;
406
+ if (type !== "Param") return void 0;
407
+ const name = Object.getOwnPropertyDescriptor(value, "name")?.value;
408
+ if (typeof name !== "string") return void 0;
409
+ return { type: "Param", name };
410
+ };
392
411
  var columnRefToNode = (col2) => {
393
412
  if (!col2.table) {
394
413
  throw new Error(
@@ -398,6 +417,10 @@ var columnRefToNode = (col2) => {
398
417
  return { type: "Column", table: col2.table, name: col2.name };
399
418
  };
400
419
  var toOperandNode = (value) => {
420
+ const paramNode = toParamNode(value);
421
+ if (paramNode) {
422
+ return paramNode;
423
+ }
401
424
  if (isOperandNode(value)) {
402
425
  return value;
403
426
  }
@@ -407,6 +430,10 @@ var toOperandNode = (value) => {
407
430
  return columnRefToNode(value);
408
431
  };
409
432
  var valueToOperand = (value) => {
433
+ const paramNode = toParamNode(value);
434
+ if (paramNode) {
435
+ return paramNode;
436
+ }
410
437
  if (isOperandNode(value)) {
411
438
  return value;
412
439
  }
@@ -749,17 +776,26 @@ var clearExpressionDispatchers = () => {
749
776
  var clearOperandDispatchers = () => {
750
777
  operandRegistry = operandRegistry.clear();
751
778
  };
752
- var getNodeType = (node) => typeof node === "object" && node !== null && typeof node.type === "string" ? node.type : void 0;
779
+ var getNodeType2 = (node) => {
780
+ if (typeof node !== "object" || node === null) return void 0;
781
+ const descriptor = Object.getOwnPropertyDescriptor(node, "type");
782
+ if (descriptor && typeof descriptor.value === "string") {
783
+ return descriptor.value;
784
+ }
785
+ const type = node.type;
786
+ return typeof type === "string" ? type : void 0;
787
+ };
753
788
  var unsupportedExpression = (node) => {
754
- throw new Error(`Unsupported expression type "${getNodeType(node) ?? "unknown"}"`);
789
+ throw new Error(`Unsupported expression type "${getNodeType2(node) ?? "unknown"}"`);
755
790
  };
756
791
  var unsupportedOperand = (node) => {
757
- throw new Error(`Unsupported operand type "${getNodeType(node) ?? "unknown"}"`);
792
+ throw new Error(`Unsupported operand type "${getNodeType2(node) ?? "unknown"}"`);
758
793
  };
759
794
  var visitExpression = (node, visitor) => {
760
- const dynamic = expressionRegistry.get(node.type);
795
+ const type = getNodeType2(node);
796
+ const dynamic = type ? expressionRegistry.get(type) : void 0;
761
797
  if (dynamic) return dynamic(node, visitor);
762
- switch (node.type) {
798
+ switch (type) {
763
799
  case "BinaryExpression":
764
800
  if (visitor.visitBinaryExpression) return visitor.visitBinaryExpression(node);
765
801
  break;
@@ -791,9 +827,10 @@ var visitExpression = (node, visitor) => {
791
827
  return unsupportedExpression(node);
792
828
  };
793
829
  var visitOperand = (node, visitor) => {
794
- const dynamic = operandRegistry.get(node.type);
830
+ const type = getNodeType2(node);
831
+ const dynamic = type ? operandRegistry.get(type) : void 0;
795
832
  if (dynamic) return dynamic(node, visitor);
796
- switch (node.type) {
833
+ switch (type) {
797
834
  case "Column":
798
835
  if (visitor.visitColumn) return visitor.visitColumn(node);
799
836
  break;
@@ -848,7 +885,7 @@ var buildParamProxy = (name) => {
848
885
  const nextName2 = name ? `${name}.${trimmed}` : trimmed;
849
886
  return buildParamProxy(nextName2);
850
887
  }
851
- if (prop in t) {
888
+ if (prop in t && name === "") {
852
889
  return t[prop];
853
890
  }
854
891
  const nextName = name ? `${name}.${prop}` : prop;
@@ -867,9 +904,6 @@ var createParamProxy = () => {
867
904
  if (typeof prop === "string" && prop.startsWith("$")) {
868
905
  return buildParamProxy(prop.slice(1));
869
906
  }
870
- if (prop in t) {
871
- return t[prop];
872
- }
873
907
  return buildParamProxy(String(prop));
874
908
  }
875
909
  });
@@ -1286,6 +1320,16 @@ var Dialect = class _Dialect {
1286
1320
  params: [...ctx.params]
1287
1321
  };
1288
1322
  }
1323
+ compileSelectWithOptions(ast, options = {}) {
1324
+ const ctx = this.createCompilerContext(options);
1325
+ const normalized = this.normalizeSelectAst(ast);
1326
+ const rawSql = this.compileSelectAst(normalized, ctx).trim();
1327
+ const sql = rawSql.endsWith(";") ? rawSql : `${rawSql};`;
1328
+ return {
1329
+ sql,
1330
+ params: [...ctx.params]
1331
+ };
1332
+ }
1289
1333
  compileInsert(ast) {
1290
1334
  const ctx = this.createCompilerContext();
1291
1335
  const rawSql = this.compileInsertAst(ast, ctx).trim();
@@ -1356,13 +1400,15 @@ var Dialect = class _Dialect {
1356
1400
  }
1357
1401
  /**
1358
1402
  * Creates a new compiler context
1403
+ * @param options - Optional compiler context options
1359
1404
  * @returns Compiler context with parameter management
1360
1405
  */
1361
- createCompilerContext() {
1406
+ createCompilerContext(options = {}) {
1362
1407
  const params = [];
1363
1408
  let counter = 0;
1364
1409
  return {
1365
1410
  params,
1411
+ allowParams: options.allowParams ?? false,
1366
1412
  addParameter: (value) => {
1367
1413
  counter += 1;
1368
1414
  params.push(value);
@@ -1513,9 +1559,11 @@ var Dialect = class _Dialect {
1513
1559
  * @returns Compiled SQL operand
1514
1560
  */
1515
1561
  compileOperand(node, ctx) {
1516
- const compiler = this.operandCompilers.get(node.type);
1562
+ const descriptor = Object.getOwnPropertyDescriptor(node, "type");
1563
+ const nodeType = typeof descriptor?.value === "string" ? descriptor.value : typeof node.type === "string" ? node.type : void 0;
1564
+ const compiler = nodeType ? this.operandCompilers.get(nodeType) : void 0;
1517
1565
  if (!compiler) {
1518
- throw new Error(`Unsupported operand node type "${node.type}" for ${this.constructor.name}`);
1566
+ throw new Error(`Unsupported operand node type "${nodeType ?? "unknown"}" for ${this.constructor.name}`);
1519
1567
  }
1520
1568
  return compiler(node, ctx);
1521
1569
  }
@@ -1584,7 +1632,12 @@ var Dialect = class _Dialect {
1584
1632
  }
1585
1633
  registerDefaultOperandCompilers() {
1586
1634
  this.registerOperandCompiler("Literal", (literal, ctx) => ctx.addParameter(literal.value));
1587
- this.registerOperandCompiler("Param", (_param, ctx) => ctx.addParameter(null));
1635
+ this.registerOperandCompiler("Param", (_param, ctx) => {
1636
+ if (!ctx.allowParams) {
1637
+ throw new Error("Cannot compile query with Param operands. Param proxies are only for schema generation (getSchema()). If you need real parameters, use literal values.");
1638
+ }
1639
+ return ctx.addParameter(null);
1640
+ });
1588
1641
  this.registerOperandCompiler("AliasRef", (alias, _ctx) => {
1589
1642
  void _ctx;
1590
1643
  return this.quoteIdentifier(alias.name);
@@ -3831,6 +3884,10 @@ var QueryAstService = class {
3831
3884
  * @returns Normalized ordering term
3832
3885
  */
3833
3886
  normalizeOrderingTerm(term) {
3887
+ const paramNode = this.toParamNode(term);
3888
+ if (paramNode) {
3889
+ return paramNode;
3890
+ }
3834
3891
  const from = this.state.ast.from;
3835
3892
  const tableRef2 = from.type === "Table" && from.alias ? { ...this.table, alias: from.alias } : this.table;
3836
3893
  const termType = term.type;
@@ -3848,6 +3905,14 @@ var QueryAstService = class {
3848
3905
  }
3849
3906
  return buildColumnNode(tableRef2, term);
3850
3907
  }
3908
+ toParamNode(value) {
3909
+ if (typeof value !== "object" || value === null) return void 0;
3910
+ const type = Object.getOwnPropertyDescriptor(value, "type")?.value;
3911
+ if (type !== "Param") return void 0;
3912
+ const name = Object.getOwnPropertyDescriptor(value, "name")?.value;
3913
+ if (typeof name !== "string") return void 0;
3914
+ return { type: "Param", name };
3915
+ }
3851
3916
  };
3852
3917
 
3853
3918
  // src/query-builder/relation-projection-helper.ts
@@ -7302,7 +7367,7 @@ var collectFilterColumns = (expr, table, rootTables) => {
7302
7367
  columns.add(node.name);
7303
7368
  }
7304
7369
  };
7305
- const visitOrderingTerm = (term) => {
7370
+ const visitOrderingTerm2 = (term) => {
7306
7371
  if (!term || typeof term !== "object") return;
7307
7372
  if (isOperandNode(term)) {
7308
7373
  visitOperand2(term);
@@ -7314,7 +7379,7 @@ var collectFilterColumns = (expr, table, rootTables) => {
7314
7379
  };
7315
7380
  const visitOrderBy = (orderBy) => {
7316
7381
  if (!orderBy) return;
7317
- orderBy.forEach((node) => visitOrderingTerm(node.term));
7382
+ orderBy.forEach((node) => visitOrderingTerm2(node.term));
7318
7383
  };
7319
7384
  const visitOperand2 = (node) => {
7320
7385
  switch (node.type) {
@@ -7453,6 +7518,198 @@ var buildFilterParameters = (table, where, from, options = {}) => {
7453
7518
  }];
7454
7519
  };
7455
7520
 
7521
+ // src/core/ast/query-visitor.ts
7522
+ var getNodeType3 = (value) => {
7523
+ if (typeof value !== "object" || value === null) return void 0;
7524
+ const descriptor = Object.getOwnPropertyDescriptor(value, "type");
7525
+ if (descriptor && typeof descriptor.value === "string") {
7526
+ return descriptor.value;
7527
+ }
7528
+ if ("type" in value) {
7529
+ const type = value.type;
7530
+ return typeof type === "string" ? type : void 0;
7531
+ }
7532
+ return void 0;
7533
+ };
7534
+ var visitOrderingTerm = (term, visitor) => {
7535
+ if (isOperandNode(term)) {
7536
+ visitOperandNode(term, visitor);
7537
+ return;
7538
+ }
7539
+ visitExpressionNode(term, visitor);
7540
+ };
7541
+ var visitOrderByNode = (node, visitor) => {
7542
+ visitor.visitOrderBy?.(node);
7543
+ visitOrderingTerm(node.term, visitor);
7544
+ };
7545
+ var visitTableSource = (source, visitor) => {
7546
+ visitor.visitTableSource?.(source);
7547
+ if (source.type === "DerivedTable") {
7548
+ visitor.visitDerivedTable?.(source);
7549
+ visitSelectQuery(source.query, visitor);
7550
+ return;
7551
+ }
7552
+ if (source.type === "FunctionTable") {
7553
+ visitor.visitFunctionTable?.(source);
7554
+ source.args?.forEach((arg) => visitOperandNode(arg, visitor));
7555
+ }
7556
+ };
7557
+ var visitExpressionNode = (node, visitor) => {
7558
+ visitor.visitExpression?.(node);
7559
+ const type = getNodeType3(node);
7560
+ if (!type) return;
7561
+ switch (type) {
7562
+ case "BinaryExpression":
7563
+ visitOperandNode(node.left, visitor);
7564
+ visitOperandNode(node.right, visitor);
7565
+ if (node.escape) {
7566
+ visitOperandNode(node.escape, visitor);
7567
+ }
7568
+ return;
7569
+ case "LogicalExpression":
7570
+ node.operands.forEach((operand) => visitExpressionNode(operand, visitor));
7571
+ return;
7572
+ case "NullExpression":
7573
+ visitOperandNode(node.left, visitor);
7574
+ return;
7575
+ case "InExpression":
7576
+ visitOperandNode(node.left, visitor);
7577
+ if (Array.isArray(node.right)) {
7578
+ node.right.forEach((operand) => visitOperandNode(operand, visitor));
7579
+ } else {
7580
+ visitOperandNode(node.right, visitor);
7581
+ }
7582
+ return;
7583
+ case "ExistsExpression":
7584
+ visitSelectQuery(node.subquery, visitor);
7585
+ return;
7586
+ case "BetweenExpression":
7587
+ visitOperandNode(node.left, visitor);
7588
+ visitOperandNode(node.lower, visitor);
7589
+ visitOperandNode(node.upper, visitor);
7590
+ return;
7591
+ case "ArithmeticExpression":
7592
+ visitOperandNode(node.left, visitor);
7593
+ visitOperandNode(node.right, visitor);
7594
+ return;
7595
+ case "BitwiseExpression":
7596
+ visitOperandNode(node.left, visitor);
7597
+ visitOperandNode(node.right, visitor);
7598
+ return;
7599
+ default: {
7600
+ return;
7601
+ }
7602
+ }
7603
+ };
7604
+ var visitOperandNode = (node, visitor) => {
7605
+ visitor.visitOperand?.(node);
7606
+ const type = getNodeType3(node);
7607
+ if (type === "Param") {
7608
+ visitor.visitParam?.(node);
7609
+ }
7610
+ if (!type) return;
7611
+ switch (type) {
7612
+ case "Column":
7613
+ case "Literal":
7614
+ case "Param":
7615
+ case "AliasRef":
7616
+ return;
7617
+ case "Function":
7618
+ node.args?.forEach((arg) => visitOperandNode(arg, visitor));
7619
+ node.orderBy?.forEach((order) => visitOrderByNode(order, visitor));
7620
+ if (node.separator) {
7621
+ visitOperandNode(node.separator, visitor);
7622
+ }
7623
+ return;
7624
+ case "JsonPath":
7625
+ visitOperandNode(node.column, visitor);
7626
+ return;
7627
+ case "ScalarSubquery":
7628
+ visitSelectQuery(node.query, visitor);
7629
+ return;
7630
+ case "CaseExpression":
7631
+ node.conditions.forEach((cond) => {
7632
+ visitExpressionNode(cond.when, visitor);
7633
+ visitOperandNode(cond.then, visitor);
7634
+ });
7635
+ if (node.else) {
7636
+ visitOperandNode(node.else, visitor);
7637
+ }
7638
+ return;
7639
+ case "Cast":
7640
+ visitOperandNode(node.expression, visitor);
7641
+ return;
7642
+ case "WindowFunction":
7643
+ node.args?.forEach((arg) => visitOperandNode(arg, visitor));
7644
+ node.partitionBy?.forEach((term) => visitOperandNode(term, visitor));
7645
+ node.orderBy?.forEach((order) => visitOrderByNode(order, visitor));
7646
+ return;
7647
+ case "ArithmeticExpression":
7648
+ visitOperandNode(node.left, visitor);
7649
+ visitOperandNode(node.right, visitor);
7650
+ return;
7651
+ case "BitwiseExpression":
7652
+ visitOperandNode(node.left, visitor);
7653
+ visitOperandNode(node.right, visitor);
7654
+ return;
7655
+ case "Collate":
7656
+ visitOperandNode(node.expression, visitor);
7657
+ return;
7658
+ default: {
7659
+ const _exhaustive = node;
7660
+ return _exhaustive;
7661
+ }
7662
+ }
7663
+ };
7664
+ var visitSelectQuery = (ast, visitor) => {
7665
+ visitor.visitSelectQuery?.(ast);
7666
+ if (ast.ctes) {
7667
+ for (const cte of ast.ctes) {
7668
+ visitor.visitCte?.(cte);
7669
+ visitSelectQuery(cte.query, visitor);
7670
+ }
7671
+ }
7672
+ visitTableSource(ast.from, visitor);
7673
+ ast.columns?.forEach((col2) => {
7674
+ visitOperandNode(col2, visitor);
7675
+ });
7676
+ ast.joins?.forEach((join) => {
7677
+ visitor.visitJoin?.(join);
7678
+ visitTableSource(join.table, visitor);
7679
+ visitExpressionNode(join.condition, visitor);
7680
+ });
7681
+ if (ast.where) {
7682
+ visitExpressionNode(ast.where, visitor);
7683
+ }
7684
+ ast.groupBy?.forEach((term) => {
7685
+ visitOrderingTerm(term, visitor);
7686
+ });
7687
+ if (ast.having) {
7688
+ visitExpressionNode(ast.having, visitor);
7689
+ }
7690
+ ast.orderBy?.forEach((order) => {
7691
+ visitOrderByNode(order, visitor);
7692
+ });
7693
+ ast.distinct?.forEach((col2) => {
7694
+ visitOperandNode(col2, visitor);
7695
+ });
7696
+ ast.setOps?.forEach((op) => {
7697
+ visitor.visitSetOperation?.(op);
7698
+ visitSelectQuery(op.query, visitor);
7699
+ });
7700
+ };
7701
+
7702
+ // src/core/ast/ast-validation.ts
7703
+ var hasParamOperandsInQuery = (ast) => {
7704
+ let hasParams = false;
7705
+ visitSelectQuery(ast, {
7706
+ visitParam: () => {
7707
+ hasParams = true;
7708
+ }
7709
+ });
7710
+ return hasParams;
7711
+ };
7712
+
7456
7713
  // src/query-builder/select.ts
7457
7714
  var SelectQueryBuilder = class _SelectQueryBuilder {
7458
7715
  env;
@@ -7926,6 +8183,17 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
7926
8183
  }
7927
8184
  return this;
7928
8185
  }
8186
+ /**
8187
+ * Validates that the query does not contain Param operands.
8188
+ * Param proxies are only for schema generation, not execution.
8189
+ */
8190
+ validateNoParamOperands() {
8191
+ const ast = this.context.hydration.applyToAst(this.context.state.ast);
8192
+ const hasParams = hasParamOperandsInQuery(ast);
8193
+ if (hasParams) {
8194
+ throw new Error("Cannot execute query containing Param operands. Param proxies are only for schema generation (getSchema()). If you need real parameters, use literal values.");
8195
+ }
8196
+ }
7929
8197
  /**
7930
8198
  * Executes the query and returns hydrated results.
7931
8199
  * If the builder was created with an entity constructor (e.g. via selectFromEntity),
@@ -7939,6 +8207,7 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
7939
8207
  * users[0] instanceof User; // true
7940
8208
  */
7941
8209
  async execute(ctx) {
8210
+ this.validateNoParamOperands();
7942
8211
  if (this.entityConstructor) {
7943
8212
  return this.executeAs(this.entityConstructor, ctx);
7944
8213
  }
@@ -7957,6 +8226,7 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
7957
8226
  * rows[0] instanceof User; // false
7958
8227
  */
7959
8228
  async executePlain(ctx) {
8229
+ this.validateNoParamOperands();
7960
8230
  const builder = this.ensureDefaultSelection();
7961
8231
  const rows = await executeHydratedPlain(ctx, builder);
7962
8232
  return rows;
@@ -7976,6 +8246,7 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
7976
8246
  * users[0].getFullName(); // works!
7977
8247
  */
7978
8248
  async executeAs(entityClass, ctx) {
8249
+ this.validateNoParamOperands();
7979
8250
  const builder = this.ensureDefaultSelection();
7980
8251
  const results = await executeHydrated(ctx, builder);
7981
8252
  return materializeAs(entityClass, results);
@@ -7987,6 +8258,7 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
7987
8258
  * const total = await qb.count(session);
7988
8259
  */
7989
8260
  async count(session) {
8261
+ this.validateNoParamOperands();
7990
8262
  return executeCount(this.context, this.env, session);
7991
8263
  }
7992
8264
  /**
@@ -7996,6 +8268,7 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
7996
8268
  * const { items, totalItems, page, pageSize } = await qb.executePaged(session, { page: 1, pageSize: 20 });
7997
8269
  */
7998
8270
  async executePaged(session, options) {
8271
+ this.validateNoParamOperands();
7999
8272
  const builder = this.ensureDefaultSelection();
8000
8273
  return executePagedQuery(builder, session, options, (sess) => builder.count(sess));
8001
8274
  }
@@ -8010,6 +8283,7 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
8010
8283
  * const users = await qb.executeWithContexts(execCtx, hydCtx);
8011
8284
  */
8012
8285
  async executeWithContexts(execCtx, hydCtx) {
8286
+ this.validateNoParamOperands();
8013
8287
  const builder = this.ensureDefaultSelection();
8014
8288
  const results = await executeHydratedWithContexts(execCtx, hydCtx, builder);
8015
8289
  if (this.entityConstructor) {