metal-orm 1.0.55 → 1.0.57

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.
Files changed (72) hide show
  1. package/README.md +21 -20
  2. package/dist/index.cjs +831 -113
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +524 -71
  5. package/dist/index.d.ts +524 -71
  6. package/dist/index.js +794 -113
  7. package/dist/index.js.map +1 -1
  8. package/package.json +1 -1
  9. package/src/codegen/naming-strategy.ts +3 -1
  10. package/src/codegen/typescript.ts +20 -10
  11. package/src/core/ast/aggregate-functions.ts +14 -0
  12. package/src/core/ast/builders.ts +38 -20
  13. package/src/core/ast/expression-builders.ts +70 -2
  14. package/src/core/ast/expression-nodes.ts +305 -274
  15. package/src/core/ast/expression-visitor.ts +11 -1
  16. package/src/core/ast/expression.ts +4 -0
  17. package/src/core/ast/query.ts +3 -0
  18. package/src/core/ddl/introspect/catalogs/mysql.ts +5 -0
  19. package/src/core/ddl/introspect/catalogs/sqlite.ts +3 -0
  20. package/src/core/ddl/introspect/functions/mssql.ts +13 -0
  21. package/src/core/ddl/introspect/mssql.ts +4 -0
  22. package/src/core/ddl/introspect/mysql.ts +4 -0
  23. package/src/core/ddl/introspect/sqlite.ts +4 -0
  24. package/src/core/dialect/abstract.ts +552 -531
  25. package/src/core/dialect/base/function-table-formatter.ts +9 -30
  26. package/src/core/dialect/base/sql-dialect.ts +24 -0
  27. package/src/core/dialect/mssql/functions.ts +40 -2
  28. package/src/core/dialect/mysql/functions.ts +16 -2
  29. package/src/core/dialect/postgres/functions.ts +66 -2
  30. package/src/core/dialect/postgres/index.ts +17 -4
  31. package/src/core/dialect/postgres/table-functions.ts +27 -0
  32. package/src/core/dialect/sqlite/functions.ts +34 -0
  33. package/src/core/dialect/sqlite/index.ts +17 -1
  34. package/src/core/driver/database-driver.ts +9 -1
  35. package/src/core/driver/mssql-driver.ts +3 -0
  36. package/src/core/driver/mysql-driver.ts +3 -0
  37. package/src/core/driver/postgres-driver.ts +3 -0
  38. package/src/core/driver/sqlite-driver.ts +3 -0
  39. package/src/core/execution/executors/mssql-executor.ts +5 -0
  40. package/src/core/execution/executors/mysql-executor.ts +5 -0
  41. package/src/core/execution/executors/postgres-executor.ts +5 -0
  42. package/src/core/execution/executors/sqlite-executor.ts +5 -0
  43. package/src/core/functions/array.ts +26 -0
  44. package/src/core/functions/control-flow.ts +69 -0
  45. package/src/core/functions/datetime.ts +50 -0
  46. package/src/core/functions/definitions/aggregate.ts +16 -0
  47. package/src/core/functions/definitions/control-flow.ts +24 -0
  48. package/src/core/functions/definitions/datetime.ts +36 -0
  49. package/src/core/functions/definitions/helpers.ts +29 -0
  50. package/src/core/functions/definitions/json.ts +49 -0
  51. package/src/core/functions/definitions/numeric.ts +55 -0
  52. package/src/core/functions/definitions/string.ts +43 -0
  53. package/src/core/functions/function-registry.ts +48 -0
  54. package/src/core/functions/group-concat-helpers.ts +57 -0
  55. package/src/core/functions/json.ts +38 -0
  56. package/src/core/functions/numeric.ts +14 -0
  57. package/src/core/functions/standard-strategy.ts +86 -115
  58. package/src/core/functions/standard-table-strategy.ts +13 -0
  59. package/src/core/functions/table-types.ts +15 -0
  60. package/src/core/functions/text.ts +57 -0
  61. package/src/core/sql/sql.ts +59 -38
  62. package/src/decorators/bootstrap.ts +5 -4
  63. package/src/index.ts +18 -11
  64. package/src/orm/hydration-context.ts +10 -0
  65. package/src/orm/identity-map.ts +19 -0
  66. package/src/orm/interceptor-pipeline.ts +4 -0
  67. package/src/orm/relations/belongs-to.ts +17 -0
  68. package/src/orm/relations/has-one.ts +17 -0
  69. package/src/orm/relations/many-to-many.ts +41 -0
  70. package/src/query-builder/select.ts +68 -68
  71. package/src/schema/table-guards.ts +6 -0
  72. package/src/schema/types.ts +8 -1
package/dist/index.cjs CHANGED
@@ -2,8 +2,8 @@ var __defProp = Object.defineProperty;
2
2
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
3
  var __getOwnPropNames = Object.getOwnPropertyNames;
4
4
  var __hasOwnProp = Object.prototype.hasOwnProperty;
5
- var __esm = (fn5, res) => function __init() {
6
- return fn5 && (res = (0, fn5[__getOwnPropNames(fn5)[0]])(fn5 = 0)), res;
5
+ var __esm = (fn8, res) => function __init() {
6
+ return fn8 && (res = (0, fn8[__getOwnPropNames(fn8)[0]])(fn8 = 0)), res;
7
7
  };
8
8
  var __export = (target, all) => {
9
9
  for (var name in all)
@@ -74,8 +74,10 @@ __export(index_exports, {
74
74
  acos: () => acos,
75
75
  add: () => add,
76
76
  addDomainEvent: () => addDomainEvent,
77
+ age: () => age,
77
78
  aliasRef: () => aliasRef,
78
79
  and: () => and,
80
+ arrayAppend: () => arrayAppend,
79
81
  ascii: () => ascii,
80
82
  asin: () => asin,
81
83
  atan: () => atan,
@@ -84,16 +86,24 @@ __export(index_exports, {
84
86
  belongsTo: () => belongsTo,
85
87
  belongsToMany: () => belongsToMany,
86
88
  between: () => between,
89
+ bitAnd: () => bitAnd,
90
+ bitLength: () => bitLength,
91
+ bitOr: () => bitOr,
92
+ bitXor: () => bitXor,
87
93
  bootstrapEntities: () => bootstrapEntities,
88
94
  caseWhen: () => caseWhen,
89
95
  cast: () => cast,
96
+ cbrt: () => cbrt,
90
97
  ceil: () => ceil,
91
98
  ceiling: () => ceiling,
92
99
  char: () => char,
93
100
  charLength: () => charLength,
101
+ chr: () => chr,
94
102
  clearExpressionDispatchers: () => clearExpressionDispatchers,
95
103
  clearOperandDispatchers: () => clearOperandDispatchers,
104
+ coalesce: () => coalesce,
96
105
  col: () => col,
106
+ collate: () => collate,
97
107
  columnOperand: () => columnOperand,
98
108
  concat: () => concat,
99
109
  concatWs: () => concatWs,
@@ -142,20 +152,26 @@ __export(index_exports, {
142
152
  generateCreateTableSql: () => generateCreateTableSql,
143
153
  generateSchemaSql: () => generateSchemaSql,
144
154
  getColumn: () => getColumn,
155
+ getDecoratorMetadata: () => getDecoratorMetadata,
145
156
  getSchemaIntrospector: () => getSchemaIntrospector,
146
157
  getTableDefFromEntity: () => getTableDefFromEntity,
158
+ greatest: () => greatest,
147
159
  groupConcat: () => groupConcat,
148
160
  gt: () => gt,
149
161
  gte: () => gte,
150
162
  hasMany: () => hasMany,
151
163
  hasOne: () => hasOne,
164
+ hour: () => hour,
152
165
  hydrateRows: () => hydrateRows,
166
+ ifNull: () => ifNull,
153
167
  inList: () => inList,
154
168
  inSubquery: () => inSubquery,
169
+ initcap: () => initcap,
155
170
  instr: () => instr,
156
171
  introspectSchema: () => introspectSchema,
157
172
  isCaseExpressionNode: () => isCaseExpressionNode,
158
173
  isCastExpressionNode: () => isCastExpressionNode,
174
+ isCollateExpressionNode: () => isCollateExpressionNode,
159
175
  isExpressionSelectionNode: () => isExpressionSelectionNode,
160
176
  isFunctionNode: () => isFunctionNode,
161
177
  isNotNull: () => isNotNull,
@@ -163,11 +179,16 @@ __export(index_exports, {
163
179
  isOperandNode: () => isOperandNode,
164
180
  isValueOperandInput: () => isValueOperandInput,
165
181
  isWindowFunctionNode: () => isWindowFunctionNode,
182
+ jsonArrayAgg: () => jsonArrayAgg,
183
+ jsonContains: () => jsonContains,
184
+ jsonLength: () => jsonLength,
166
185
  jsonPath: () => jsonPath,
186
+ jsonSet: () => jsonSet,
167
187
  jsonify: () => jsonify,
168
188
  lag: () => lag,
169
189
  lastValue: () => lastValue,
170
190
  lead: () => lead,
191
+ least: () => least,
171
192
  left: () => left,
172
193
  length: () => length,
173
194
  like: () => like,
@@ -176,9 +197,12 @@ __export(index_exports, {
176
197
  loadBelongsToRelation: () => loadBelongsToRelation,
177
198
  loadHasManyRelation: () => loadHasManyRelation,
178
199
  loadHasOneRelation: () => loadHasOneRelation,
200
+ localTime: () => localTime,
201
+ localTimestamp: () => localTimestamp,
179
202
  locate: () => locate,
180
203
  log: () => log,
181
204
  log10: () => log10,
205
+ log2: () => log2,
182
206
  logBase: () => logBase,
183
207
  lower: () => lower,
184
208
  lpad: () => lpad,
@@ -186,7 +210,9 @@ __export(index_exports, {
186
210
  lte: () => lte,
187
211
  ltrim: () => ltrim,
188
212
  max: () => max,
213
+ md5: () => md5,
189
214
  min: () => min,
215
+ minute: () => minute,
190
216
  mod: () => mod,
191
217
  month: () => month,
192
218
  mul: () => mul,
@@ -199,12 +225,15 @@ __export(index_exports, {
199
225
  notLike: () => notLike,
200
226
  now: () => now,
201
227
  ntile: () => ntile,
228
+ nullif: () => nullif,
229
+ octetLength: () => octetLength,
202
230
  or: () => or,
203
231
  outerRef: () => outerRef,
204
232
  pi: () => pi,
205
233
  position: () => position,
206
234
  pow: () => pow,
207
235
  power: () => power,
236
+ quarter: () => quarter,
208
237
  radians: () => radians,
209
238
  rand: () => rand,
210
239
  random: () => random,
@@ -216,18 +245,25 @@ __export(index_exports, {
216
245
  renderTypeWithArgs: () => renderTypeWithArgs,
217
246
  repeat: () => repeat,
218
247
  replace: () => replace,
248
+ reverse: () => reverse,
219
249
  right: () => right,
220
250
  round: () => round,
221
251
  rowNumber: () => rowNumber,
222
252
  rowsToQueryResult: () => rowsToQueryResult,
223
253
  rpad: () => rpad,
224
254
  rtrim: () => rtrim,
255
+ second: () => second,
225
256
  sel: () => sel,
226
257
  selectFromEntity: () => selectFromEntity,
258
+ sha1: () => sha1,
259
+ sha2: () => sha2,
260
+ shiftLeft: () => shiftLeft,
261
+ shiftRight: () => shiftRight,
227
262
  sign: () => sign,
228
263
  sin: () => sin,
229
264
  space: () => space,
230
265
  sqrt: () => sqrt,
266
+ stddev: () => stddev,
231
267
  sub: () => sub,
232
268
  substr: () => substr,
233
269
  sum: () => sum,
@@ -243,6 +279,7 @@ __export(index_exports, {
243
279
  upper: () => upper,
244
280
  utcNow: () => utcNow,
245
281
  valueToOperand: () => valueToOperand,
282
+ variance: () => variance,
246
283
  visitExpression: () => visitExpression,
247
284
  visitOperand: () => visitOperand,
248
285
  weekOfYear: () => weekOfYear,
@@ -585,7 +622,9 @@ var operandTypes = /* @__PURE__ */ new Set([
585
622
  "CaseExpression",
586
623
  "Cast",
587
624
  "WindowFunction",
588
- "ArithmeticExpression"
625
+ "ArithmeticExpression",
626
+ "BitwiseExpression",
627
+ "Collate"
589
628
  ]);
590
629
  var hasTypeProperty = (value) => typeof value === "object" && value !== null && "type" in value;
591
630
  var isOperandNode = (node) => {
@@ -595,6 +634,7 @@ var isOperandNode = (node) => {
595
634
  var isFunctionNode = (node) => isOperandNode(node) && node.type === "Function";
596
635
  var isCaseExpressionNode = (node) => isOperandNode(node) && node.type === "CaseExpression";
597
636
  var isCastExpressionNode = (node) => isOperandNode(node) && node.type === "Cast";
637
+ var isCollateExpressionNode = (node) => isOperandNode(node) && node.type === "Collate";
598
638
  var isWindowFunctionNode = (node) => isOperandNode(node) && node.type === "WindowFunction";
599
639
  var isExpressionSelectionNode = (node) => isFunctionNode(node) || isCaseExpressionNode(node) || isCastExpressionNode(node) || isWindowFunctionNode(node);
600
640
 
@@ -719,6 +759,17 @@ var add = (left2, right2) => createArithmeticExpression("+", left2, right2);
719
759
  var sub = (left2, right2) => createArithmeticExpression("-", left2, right2);
720
760
  var mul = (left2, right2) => createArithmeticExpression("*", left2, right2);
721
761
  var div = (left2, right2) => createArithmeticExpression("/", left2, right2);
762
+ var createBitwiseExpression = (operator, left2, right2) => ({
763
+ type: "BitwiseExpression",
764
+ left: toOperand(left2),
765
+ operator,
766
+ right: toOperand(right2)
767
+ });
768
+ var bitAnd = (left2, right2) => createBitwiseExpression("&", left2, right2);
769
+ var bitOr = (left2, right2) => createBitwiseExpression("|", left2, right2);
770
+ var bitXor = (left2, right2) => createBitwiseExpression("^", left2, right2);
771
+ var shiftLeft = (left2, right2) => createBitwiseExpression("<<", left2, right2);
772
+ var shiftRight = (left2, right2) => createBitwiseExpression(">>", left2, right2);
722
773
  var jsonPath = (col2, path) => ({
723
774
  type: "JsonPath",
724
775
  column: columnOperand(col2),
@@ -747,6 +798,11 @@ var notExists = (subquery) => ({
747
798
  operator: "NOT EXISTS",
748
799
  subquery
749
800
  });
801
+ var collate = (expression, collation) => ({
802
+ type: "Collate",
803
+ expression: toOperand(expression),
804
+ collation
805
+ });
750
806
 
751
807
  // src/core/ast/window-functions.ts
752
808
  var buildWindowFunction = (name, args = [], partitionBy, orderBy) => {
@@ -892,6 +948,8 @@ var groupConcat = (col2, options) => ({
892
948
  orderBy: options?.orderBy?.map(toOrderByNode),
893
949
  separator: options?.separator !== void 0 ? valueToOperand(options.separator) : void 0
894
950
  });
951
+ var stddev = buildAggregate("STDDEV");
952
+ var variance = buildAggregate("VARIANCE");
895
953
 
896
954
  // src/core/ast/expression-visitor.ts
897
955
  var DispatcherRegistry = class _DispatcherRegistry {
@@ -965,6 +1023,9 @@ var visitExpression = (node, visitor) => {
965
1023
  case "ArithmeticExpression":
966
1024
  if (visitor.visitArithmeticExpression) return visitor.visitArithmeticExpression(node);
967
1025
  break;
1026
+ case "BitwiseExpression":
1027
+ if (visitor.visitBitwiseExpression) return visitor.visitBitwiseExpression(node);
1028
+ break;
968
1029
  default:
969
1030
  break;
970
1031
  }
@@ -1002,6 +1063,9 @@ var visitOperand = (node, visitor) => {
1002
1063
  case "Cast":
1003
1064
  if (visitor.visitCast) return visitor.visitCast(node);
1004
1065
  break;
1066
+ case "Collate":
1067
+ if (visitor.visitCollate) return visitor.visitCollate(node);
1068
+ break;
1005
1069
  default:
1006
1070
  break;
1007
1071
  }
@@ -1072,62 +1136,337 @@ var derivedTable = (query, alias, columnAliases) => ({
1072
1136
  columnAliases
1073
1137
  });
1074
1138
 
1139
+ // src/core/functions/function-registry.ts
1140
+ var FunctionRegistry = class {
1141
+ constructor() {
1142
+ this.renderers = /* @__PURE__ */ new Map();
1143
+ }
1144
+ /**
1145
+ * Registers or overrides a renderer for the given function name.
1146
+ */
1147
+ add(name, renderer) {
1148
+ this.renderers.set(name, renderer);
1149
+ }
1150
+ /**
1151
+ * Registers a batch of definitions.
1152
+ */
1153
+ register(definitions) {
1154
+ for (const definition of definitions) {
1155
+ this.add(definition.name, definition.renderer);
1156
+ }
1157
+ }
1158
+ /**
1159
+ * Merges another registry into this one, allowing overrides from the other source.
1160
+ */
1161
+ merge(other) {
1162
+ for (const [name, renderer] of other.renderers.entries()) {
1163
+ this.renderers.set(name, renderer);
1164
+ }
1165
+ }
1166
+ /**
1167
+ * Retrieves a renderer by function name.
1168
+ */
1169
+ get(name) {
1170
+ return this.renderers.get(name);
1171
+ }
1172
+ };
1173
+
1174
+ // src/core/functions/definitions/helpers.ts
1175
+ function unaryRenderer(name) {
1176
+ return ({ compiledArgs }) => `${name}(${compiledArgs[0]})`;
1177
+ }
1178
+ function binaryRenderer(name) {
1179
+ return ({ compiledArgs }) => `${name}(${compiledArgs[0]}, ${compiledArgs[1]})`;
1180
+ }
1181
+ function variadicRenderer(name) {
1182
+ return ({ compiledArgs }) => `${name}(${compiledArgs.join(", ")})`;
1183
+ }
1184
+ function noArgsRenderer(name) {
1185
+ return () => `${name}()`;
1186
+ }
1187
+
1188
+ // src/core/functions/definitions/aggregate.ts
1189
+ var aggregateFunctionDefinitions = [
1190
+ {
1191
+ name: "COUNT",
1192
+ renderer: ({ compiledArgs }) => compiledArgs.length ? `COUNT(${compiledArgs.join(", ")})` : "COUNT(*)"
1193
+ },
1194
+ { name: "SUM", renderer: unaryRenderer("SUM") },
1195
+ { name: "AVG", renderer: unaryRenderer("AVG") },
1196
+ { name: "MIN", renderer: unaryRenderer("MIN") },
1197
+ { name: "MAX", renderer: unaryRenderer("MAX") },
1198
+ { name: "STDDEV", renderer: unaryRenderer("STDDEV") },
1199
+ { name: "VARIANCE", renderer: unaryRenderer("VARIANCE") }
1200
+ ];
1201
+
1202
+ // src/core/functions/definitions/string.ts
1203
+ var stringFunctionDefinitions = [
1204
+ { name: "UPPER", renderer: unaryRenderer("UPPER") },
1205
+ { name: "LOWER", renderer: unaryRenderer("LOWER") },
1206
+ { name: "LENGTH", renderer: unaryRenderer("LENGTH") },
1207
+ { name: "CHAR_LENGTH", renderer: unaryRenderer("CHAR_LENGTH") },
1208
+ { name: "CHARACTER_LENGTH", renderer: unaryRenderer("CHARACTER_LENGTH") },
1209
+ { name: "TRIM", renderer: unaryRenderer("TRIM") },
1210
+ { name: "LTRIM", renderer: unaryRenderer("LTRIM") },
1211
+ { name: "RTRIM", renderer: unaryRenderer("RTRIM") },
1212
+ { name: "SUBSTRING", renderer: variadicRenderer("SUBSTRING") },
1213
+ { name: "SUBSTR", renderer: variadicRenderer("SUBSTR") },
1214
+ { name: "CONCAT", renderer: variadicRenderer("CONCAT") },
1215
+ { name: "CONCAT_WS", renderer: variadicRenderer("CONCAT_WS") },
1216
+ { name: "ASCII", renderer: unaryRenderer("ASCII") },
1217
+ { name: "CHAR", renderer: variadicRenderer("CHAR") },
1218
+ {
1219
+ name: "POSITION",
1220
+ renderer: ({ compiledArgs }) => `POSITION(${compiledArgs[0]} IN ${compiledArgs[1]})`
1221
+ },
1222
+ { name: "REPLACE", renderer: ({ compiledArgs }) => `REPLACE(${compiledArgs[0]}, ${compiledArgs[1]}, ${compiledArgs[2]})` },
1223
+ { name: "REPEAT", renderer: binaryRenderer("REPEAT") },
1224
+ { name: "LPAD", renderer: ({ compiledArgs }) => `LPAD(${compiledArgs[0]}, ${compiledArgs[1]}, ${compiledArgs[2]})` },
1225
+ { name: "RPAD", renderer: ({ compiledArgs }) => `RPAD(${compiledArgs[0]}, ${compiledArgs[1]}, ${compiledArgs[2]})` },
1226
+ { name: "LEFT", renderer: binaryRenderer("LEFT") },
1227
+ { name: "RIGHT", renderer: binaryRenderer("RIGHT") },
1228
+ { name: "INSTR", renderer: binaryRenderer("INSTR") },
1229
+ {
1230
+ name: "LOCATE",
1231
+ renderer: ({ compiledArgs }) => compiledArgs.length === 3 ? `LOCATE(${compiledArgs[0]}, ${compiledArgs[1]}, ${compiledArgs[2]})` : `LOCATE(${compiledArgs[0]}, ${compiledArgs[1]})`
1232
+ },
1233
+ { name: "SPACE", renderer: unaryRenderer("SPACE") },
1234
+ { name: "REVERSE", renderer: unaryRenderer("REVERSE") },
1235
+ { name: "INITCAP", renderer: unaryRenderer("INITCAP") },
1236
+ { name: "MD5", renderer: unaryRenderer("MD5") },
1237
+ { name: "SHA1", renderer: unaryRenderer("SHA1") },
1238
+ { name: "SHA2", renderer: ({ compiledArgs }) => `SHA2(${compiledArgs[0]}, ${compiledArgs[1]})` }
1239
+ ];
1240
+
1241
+ // src/core/functions/definitions/datetime.ts
1242
+ var dateTimeFunctionDefinitions = [
1243
+ { name: "NOW", renderer: noArgsRenderer("NOW") },
1244
+ { name: "CURRENT_DATE", renderer: () => "CURRENT_DATE" },
1245
+ { name: "CURRENT_TIME", renderer: () => "CURRENT_TIME" },
1246
+ {
1247
+ name: "EXTRACT",
1248
+ renderer: ({ compiledArgs }) => `EXTRACT(${compiledArgs[0]} FROM ${compiledArgs[1]})`
1249
+ },
1250
+ { name: "YEAR", renderer: ({ compiledArgs }) => `EXTRACT(YEAR FROM ${compiledArgs[0]})` },
1251
+ { name: "MONTH", renderer: ({ compiledArgs }) => `EXTRACT(MONTH FROM ${compiledArgs[0]})` },
1252
+ { name: "DAY", renderer: ({ compiledArgs }) => `EXTRACT(DAY FROM ${compiledArgs[0]})` },
1253
+ { name: "HOUR", renderer: ({ compiledArgs }) => `EXTRACT(HOUR FROM ${compiledArgs[0]})` },
1254
+ { name: "MINUTE", renderer: ({ compiledArgs }) => `EXTRACT(MINUTE FROM ${compiledArgs[0]})` },
1255
+ { name: "SECOND", renderer: ({ compiledArgs }) => `EXTRACT(SECOND FROM ${compiledArgs[0]})` },
1256
+ { name: "QUARTER", renderer: ({ compiledArgs }) => `EXTRACT(QUARTER FROM ${compiledArgs[0]})` },
1257
+ { name: "DATE_ADD", renderer: ({ compiledArgs }) => `(${compiledArgs[0]} + INTERVAL ${compiledArgs[1]} ${compiledArgs[2]})` },
1258
+ { name: "DATE_SUB", renderer: ({ compiledArgs }) => `(${compiledArgs[0]} - INTERVAL ${compiledArgs[1]} ${compiledArgs[2]})` },
1259
+ { name: "DATE_DIFF", renderer: ({ compiledArgs }) => `DATEDIFF(${compiledArgs[0]}, ${compiledArgs[1]})` },
1260
+ { name: "DATE_FORMAT", renderer: ({ compiledArgs }) => `DATE_FORMAT(${compiledArgs[0]}, ${compiledArgs[1]})` },
1261
+ { name: "UNIX_TIMESTAMP", renderer: noArgsRenderer("UNIX_TIMESTAMP") },
1262
+ { name: "FROM_UNIXTIME", renderer: ({ compiledArgs }) => `FROM_UNIXTIME(${compiledArgs[0]})` },
1263
+ { name: "END_OF_MONTH", renderer: ({ compiledArgs }) => `LAST_DAY(${compiledArgs[0]})` },
1264
+ { name: "DAY_OF_WEEK", renderer: ({ compiledArgs }) => `DAYOFWEEK(${compiledArgs[0]})` },
1265
+ { name: "WEEK_OF_YEAR", renderer: ({ compiledArgs }) => `WEEKOFYEAR(${compiledArgs[0]})` },
1266
+ { name: "DATE_TRUNC", renderer: ({ compiledArgs }) => `DATE_TRUNC(${compiledArgs[0]}, ${compiledArgs[1]})` },
1267
+ {
1268
+ name: "AGE",
1269
+ renderer: ({ compiledArgs }) => compiledArgs.length === 1 ? `AGE(${compiledArgs[0]})` : `AGE(${compiledArgs[0]}, ${compiledArgs[1]})`
1270
+ },
1271
+ { name: "LOCALTIME", renderer: () => "LOCALTIME" },
1272
+ { name: "LOCALTIMESTAMP", renderer: () => "LOCALTIMESTAMP" }
1273
+ ];
1274
+
1275
+ // src/core/functions/definitions/numeric.ts
1276
+ var numericFunctionDefinitions = [
1277
+ { name: "ABS", renderer: unaryRenderer("ABS") },
1278
+ { name: "BIT_LENGTH", renderer: unaryRenderer("BIT_LENGTH") },
1279
+ { name: "OCTET_LENGTH", renderer: unaryRenderer("OCTET_LENGTH") },
1280
+ { name: "CHR", renderer: unaryRenderer("CHR") },
1281
+ { name: "LOG2", renderer: unaryRenderer("LOG2") },
1282
+ { name: "CBRT", renderer: unaryRenderer("CBRT") },
1283
+ { name: "ACOS", renderer: unaryRenderer("ACOS") },
1284
+ { name: "ASIN", renderer: unaryRenderer("ASIN") },
1285
+ { name: "ATAN", renderer: unaryRenderer("ATAN") },
1286
+ { name: "ATAN2", renderer: binaryRenderer("ATAN2") },
1287
+ { name: "CEIL", renderer: unaryRenderer("CEIL") },
1288
+ { name: "CEILING", renderer: unaryRenderer("CEILING") },
1289
+ { name: "COS", renderer: unaryRenderer("COS") },
1290
+ { name: "COT", renderer: unaryRenderer("COT") },
1291
+ { name: "DEGREES", renderer: unaryRenderer("DEGREES") },
1292
+ { name: "EXP", renderer: unaryRenderer("EXP") },
1293
+ { name: "FLOOR", renderer: unaryRenderer("FLOOR") },
1294
+ { name: "LN", renderer: unaryRenderer("LN") },
1295
+ {
1296
+ name: "LOG",
1297
+ renderer: ({ compiledArgs }) => compiledArgs.length === 2 ? `LOG(${compiledArgs[0]}, ${compiledArgs[1]})` : `LOG(${compiledArgs[0]})`
1298
+ },
1299
+ { name: "LOG10", renderer: unaryRenderer("LOG10") },
1300
+ { name: "LOG_BASE", renderer: binaryRenderer("LOG") },
1301
+ { name: "MOD", renderer: binaryRenderer("MOD") },
1302
+ { name: "PI", renderer: noArgsRenderer("PI") },
1303
+ { name: "POWER", renderer: binaryRenderer("POWER") },
1304
+ { name: "POW", renderer: binaryRenderer("POW") },
1305
+ { name: "RADIANS", renderer: unaryRenderer("RADIANS") },
1306
+ { name: "RANDOM", renderer: noArgsRenderer("RANDOM") },
1307
+ { name: "RAND", renderer: noArgsRenderer("RAND") },
1308
+ {
1309
+ name: "ROUND",
1310
+ renderer: ({ compiledArgs }) => compiledArgs.length === 2 ? `ROUND(${compiledArgs[0]}, ${compiledArgs[1]})` : `ROUND(${compiledArgs[0]})`
1311
+ },
1312
+ { name: "SIGN", renderer: unaryRenderer("SIGN") },
1313
+ { name: "SIN", renderer: unaryRenderer("SIN") },
1314
+ { name: "SQRT", renderer: unaryRenderer("SQRT") },
1315
+ { name: "TAN", renderer: unaryRenderer("TAN") },
1316
+ {
1317
+ name: "TRUNC",
1318
+ renderer: ({ compiledArgs }) => compiledArgs.length === 2 ? `TRUNC(${compiledArgs[0]}, ${compiledArgs[1]})` : `TRUNC(${compiledArgs[0]})`
1319
+ },
1320
+ {
1321
+ name: "TRUNCATE",
1322
+ renderer: ({ compiledArgs }) => `TRUNCATE(${compiledArgs[0]}, ${compiledArgs[1]})`
1323
+ }
1324
+ ];
1325
+
1326
+ // src/core/functions/definitions/control-flow.ts
1327
+ var controlFlowFunctionDefinitions = [
1328
+ {
1329
+ name: "COALESCE",
1330
+ renderer: ({ compiledArgs }) => `COALESCE(${compiledArgs.join(", ")})`
1331
+ },
1332
+ {
1333
+ name: "NULLIF",
1334
+ renderer: ({ compiledArgs }) => `NULLIF(${compiledArgs[0]}, ${compiledArgs[1]})`
1335
+ },
1336
+ {
1337
+ name: "GREATEST",
1338
+ renderer: ({ compiledArgs }) => `GREATEST(${compiledArgs.join(", ")})`
1339
+ },
1340
+ {
1341
+ name: "LEAST",
1342
+ renderer: ({ compiledArgs }) => `LEAST(${compiledArgs.join(", ")})`
1343
+ },
1344
+ {
1345
+ name: "IFNULL",
1346
+ renderer: ({ compiledArgs }) => `IFNULL(${compiledArgs[0]}, ${compiledArgs[1]})`
1347
+ }
1348
+ ];
1349
+
1350
+ // src/core/functions/definitions/json.ts
1351
+ var jsonFunctionDefinitions = [
1352
+ {
1353
+ name: "JSON_LENGTH",
1354
+ renderer: ({ compiledArgs }) => {
1355
+ if (compiledArgs.length === 0 || compiledArgs.length > 2) {
1356
+ throw new Error("JSON_LENGTH expects 1 or 2 arguments");
1357
+ }
1358
+ return `JSON_LENGTH(${compiledArgs.join(", ")})`;
1359
+ }
1360
+ },
1361
+ {
1362
+ name: "JSON_SET",
1363
+ renderer: ({ compiledArgs }) => {
1364
+ if (compiledArgs.length < 3 || (compiledArgs.length - 1) % 2 !== 0) {
1365
+ throw new Error("JSON_SET expects a JSON document followed by one or more path/value pairs");
1366
+ }
1367
+ return `JSON_SET(${compiledArgs.join(", ")})`;
1368
+ }
1369
+ },
1370
+ {
1371
+ name: "JSON_ARRAYAGG",
1372
+ renderer: ({ compiledArgs }) => {
1373
+ if (compiledArgs.length !== 1) {
1374
+ throw new Error("JSON_ARRAYAGG expects exactly one argument");
1375
+ }
1376
+ return `JSON_ARRAYAGG(${compiledArgs[0]})`;
1377
+ }
1378
+ },
1379
+ {
1380
+ name: "JSON_CONTAINS",
1381
+ renderer: ({ compiledArgs }) => {
1382
+ if (compiledArgs.length < 2 || compiledArgs.length > 3) {
1383
+ throw new Error("JSON_CONTAINS expects two or three arguments");
1384
+ }
1385
+ return `JSON_CONTAINS(${compiledArgs.join(", ")})`;
1386
+ }
1387
+ },
1388
+ {
1389
+ name: "ARRAY_APPEND",
1390
+ renderer: ({ compiledArgs }) => {
1391
+ if (compiledArgs.length !== 2) {
1392
+ throw new Error("ARRAY_APPEND expects exactly two arguments");
1393
+ }
1394
+ return `ARRAY_APPEND(${compiledArgs[0]}, ${compiledArgs[1]})`;
1395
+ }
1396
+ }
1397
+ ];
1398
+
1399
+ // src/core/functions/group-concat-helpers.ts
1400
+ var DEFAULT_GROUP_CONCAT_SEPARATOR = {
1401
+ type: "Literal",
1402
+ value: ","
1403
+ };
1404
+ function buildGroupConcatOrderBy(ctx) {
1405
+ const orderBy = ctx.node.orderBy;
1406
+ if (!orderBy || orderBy.length === 0) {
1407
+ return "";
1408
+ }
1409
+ const parts = orderBy.map((order) => {
1410
+ const term = isOperandNode(order.term) ? ctx.compileOperand(order.term) : (() => {
1411
+ throw new Error("ORDER BY expressions inside functions must be operands");
1412
+ })();
1413
+ const collation = order.collation ? ` COLLATE ${order.collation}` : "";
1414
+ const nulls = order.nulls ? ` NULLS ${order.nulls}` : "";
1415
+ return `${term} ${order.direction}${collation}${nulls}`;
1416
+ });
1417
+ return `ORDER BY ${parts.join(", ")}`;
1418
+ }
1419
+ function formatGroupConcatSeparator(ctx) {
1420
+ if (!ctx.node.separator) {
1421
+ return "";
1422
+ }
1423
+ return ` SEPARATOR ${ctx.compileOperand(ctx.node.separator)}`;
1424
+ }
1425
+ function getGroupConcatSeparatorOperand(ctx) {
1426
+ return ctx.node.separator ?? DEFAULT_GROUP_CONCAT_SEPARATOR;
1427
+ }
1428
+ function renderStandardGroupConcat(ctx) {
1429
+ const arg = ctx.compiledArgs[0];
1430
+ const orderClause = buildGroupConcatOrderBy(ctx);
1431
+ const orderSegment = orderClause ? ` ${orderClause}` : "";
1432
+ const separatorClause = formatGroupConcatSeparator(ctx);
1433
+ return `GROUP_CONCAT(${arg}${orderSegment}${separatorClause})`;
1434
+ }
1435
+
1075
1436
  // src/core/functions/standard-strategy.ts
1076
- var StandardFunctionStrategy = class _StandardFunctionStrategy {
1437
+ var StandardFunctionStrategy = class {
1077
1438
  /**
1078
1439
  * Creates a new StandardFunctionStrategy and registers standard functions.
1079
1440
  */
1080
- constructor() {
1081
- this.renderers = /* @__PURE__ */ new Map();
1441
+ constructor(registry2) {
1442
+ this.registry = registry2 ?? new FunctionRegistry();
1082
1443
  this.registerStandard();
1083
1444
  }
1084
1445
  registerStandard() {
1085
- this.add("COUNT", ({ compiledArgs }) => compiledArgs.length ? `COUNT(${compiledArgs.join(", ")})` : "COUNT(*)");
1086
- this.add("SUM", ({ compiledArgs }) => `SUM(${compiledArgs[0]})`);
1087
- this.add("AVG", ({ compiledArgs }) => `AVG(${compiledArgs[0]})`);
1088
- this.add("MIN", ({ compiledArgs }) => `MIN(${compiledArgs[0]})`);
1089
- this.add("MAX", ({ compiledArgs }) => `MAX(${compiledArgs[0]})`);
1090
- this.add("ABS", ({ compiledArgs }) => `ABS(${compiledArgs[0]})`);
1091
- this.add("UPPER", ({ compiledArgs }) => `UPPER(${compiledArgs[0]})`);
1092
- this.add("LOWER", ({ compiledArgs }) => `LOWER(${compiledArgs[0]})`);
1093
- this.add("LENGTH", ({ compiledArgs }) => `LENGTH(${compiledArgs[0]})`);
1094
- this.add("TRIM", ({ compiledArgs }) => `TRIM(${compiledArgs[0]})`);
1095
- this.add("LTRIM", ({ compiledArgs }) => `LTRIM(${compiledArgs[0]})`);
1096
- this.add("RTRIM", ({ compiledArgs }) => `RTRIM(${compiledArgs[0]})`);
1097
- this.add("SUBSTRING", ({ compiledArgs }) => `SUBSTRING(${compiledArgs.join(", ")})`);
1098
- this.add("CONCAT", ({ compiledArgs }) => `CONCAT(${compiledArgs.join(", ")})`);
1099
- this.add("NOW", () => `NOW()`);
1100
- this.add("CURRENT_DATE", () => `CURRENT_DATE`);
1101
- this.add("CURRENT_TIME", () => `CURRENT_TIME`);
1102
- this.add("EXTRACT", ({ compiledArgs }) => `EXTRACT(${compiledArgs[0]} FROM ${compiledArgs[1]})`);
1103
- this.add("YEAR", ({ compiledArgs }) => `EXTRACT(YEAR FROM ${compiledArgs[0]})`);
1104
- this.add("MONTH", ({ compiledArgs }) => `EXTRACT(MONTH FROM ${compiledArgs[0]})`);
1105
- this.add("DAY", ({ compiledArgs }) => `EXTRACT(DAY FROM ${compiledArgs[0]})`);
1106
- this.add("DATE_ADD", ({ compiledArgs }) => `(${compiledArgs[0]} + INTERVAL ${compiledArgs[1]} ${compiledArgs[2]})`);
1107
- this.add("DATE_SUB", ({ compiledArgs }) => `(${compiledArgs[0]} - INTERVAL ${compiledArgs[1]} ${compiledArgs[2]})`);
1108
- this.add("DATE_DIFF", ({ compiledArgs }) => `DATEDIFF(${compiledArgs[0]}, ${compiledArgs[1]})`);
1109
- this.add("DATE_FORMAT", ({ compiledArgs }) => `DATE_FORMAT(${compiledArgs[0]}, ${compiledArgs[1]})`);
1110
- this.add("UNIX_TIMESTAMP", () => `UNIX_TIMESTAMP()`);
1111
- this.add("FROM_UNIXTIME", ({ compiledArgs }) => `FROM_UNIXTIME(${compiledArgs[0]})`);
1112
- this.add("END_OF_MONTH", ({ compiledArgs }) => `LAST_DAY(${compiledArgs[0]})`);
1113
- this.add("DAY_OF_WEEK", ({ compiledArgs }) => `DAYOFWEEK(${compiledArgs[0]})`);
1114
- this.add("WEEK_OF_YEAR", ({ compiledArgs }) => `WEEKOFYEAR(${compiledArgs[0]})`);
1115
- this.add("DATE_TRUNC", ({ compiledArgs }) => `DATE_TRUNC(${compiledArgs[0]}, ${compiledArgs[1]})`);
1446
+ this.registerDefinitions(aggregateFunctionDefinitions);
1447
+ this.registerDefinitions(stringFunctionDefinitions);
1448
+ this.registerDefinitions(dateTimeFunctionDefinitions);
1449
+ this.registerDefinitions(numericFunctionDefinitions);
1450
+ this.registerDefinitions(controlFlowFunctionDefinitions);
1451
+ this.registerDefinitions(jsonFunctionDefinitions);
1116
1452
  this.add("GROUP_CONCAT", (ctx) => this.renderGroupConcat(ctx));
1117
1453
  }
1454
+ registerDefinitions(definitions) {
1455
+ this.registry.register(definitions);
1456
+ }
1118
1457
  /**
1119
1458
  * Registers a renderer for a function name.
1120
1459
  * @param name - The function name.
1121
1460
  * @param renderer - The renderer function.
1122
1461
  */
1123
1462
  add(name, renderer) {
1124
- this.renderers.set(name, renderer);
1463
+ this.registry.add(name, renderer);
1125
1464
  }
1126
1465
  /**
1127
1466
  * @inheritDoc
1128
1467
  */
1129
1468
  getRenderer(name) {
1130
- return this.renderers.get(name);
1469
+ return this.registry.get(name);
1131
1470
  }
1132
1471
  /**
1133
1472
  * Renders the GROUP_CONCAT function with optional ORDER BY and SEPARATOR.
@@ -1135,11 +1474,7 @@ var StandardFunctionStrategy = class _StandardFunctionStrategy {
1135
1474
  * @returns The rendered SQL string.
1136
1475
  */
1137
1476
  renderGroupConcat(ctx) {
1138
- const arg = ctx.compiledArgs[0];
1139
- const orderClause = this.buildOrderByExpression(ctx);
1140
- const orderSegment = orderClause ? ` ${orderClause}` : "";
1141
- const separatorClause = this.formatGroupConcatSeparator(ctx);
1142
- return `GROUP_CONCAT(${arg}${orderSegment}${separatorClause})`;
1477
+ return renderStandardGroupConcat(ctx);
1143
1478
  }
1144
1479
  /**
1145
1480
  * Builds the ORDER BY clause for functions like GROUP_CONCAT.
@@ -1147,19 +1482,7 @@ var StandardFunctionStrategy = class _StandardFunctionStrategy {
1147
1482
  * @returns The ORDER BY SQL clause or empty string.
1148
1483
  */
1149
1484
  buildOrderByExpression(ctx) {
1150
- const orderBy = ctx.node.orderBy;
1151
- if (!orderBy || orderBy.length === 0) {
1152
- return "";
1153
- }
1154
- const parts = orderBy.map((order) => {
1155
- const term = isOperandNode(order.term) ? ctx.compileOperand(order.term) : (() => {
1156
- throw new Error("ORDER BY expressions inside functions must be operands");
1157
- })();
1158
- const collation = order.collation ? ` COLLATE ${order.collation}` : "";
1159
- const nulls = order.nulls ? ` NULLS ${order.nulls}` : "";
1160
- return `${term} ${order.direction}${collation}${nulls}`;
1161
- });
1162
- return `ORDER BY ${parts.join(", ")}`;
1485
+ return buildGroupConcatOrderBy(ctx);
1163
1486
  }
1164
1487
  /**
1165
1488
  * Formats the SEPARATOR clause for GROUP_CONCAT.
@@ -1167,10 +1490,7 @@ var StandardFunctionStrategy = class _StandardFunctionStrategy {
1167
1490
  * @returns The SEPARATOR SQL clause or empty string.
1168
1491
  */
1169
1492
  formatGroupConcatSeparator(ctx) {
1170
- if (!ctx.node.separator) {
1171
- return "";
1172
- }
1173
- return ` SEPARATOR ${ctx.compileOperand(ctx.node.separator)}`;
1493
+ return formatGroupConcatSeparator(ctx);
1174
1494
  }
1175
1495
  /**
1176
1496
  * Gets the separator operand for GROUP_CONCAT, defaulting to comma.
@@ -1178,14 +1498,24 @@ var StandardFunctionStrategy = class _StandardFunctionStrategy {
1178
1498
  * @returns The separator operand.
1179
1499
  */
1180
1500
  getGroupConcatSeparatorOperand(ctx) {
1181
- return ctx.node.separator ?? _StandardFunctionStrategy.DEFAULT_GROUP_CONCAT_SEPARATOR;
1501
+ return getGroupConcatSeparatorOperand(ctx);
1182
1502
  }
1183
1503
  static {
1184
1504
  /** Default separator for GROUP_CONCAT, a comma. */
1185
- this.DEFAULT_GROUP_CONCAT_SEPARATOR = {
1186
- type: "Literal",
1187
- value: ","
1188
- };
1505
+ this.DEFAULT_GROUP_CONCAT_SEPARATOR = DEFAULT_GROUP_CONCAT_SEPARATOR;
1506
+ }
1507
+ };
1508
+
1509
+ // src/core/functions/standard-table-strategy.ts
1510
+ var StandardTableFunctionStrategy = class {
1511
+ constructor() {
1512
+ this.renderers = /* @__PURE__ */ new Map();
1513
+ }
1514
+ add(key, renderer) {
1515
+ this.renderers.set(key, renderer);
1516
+ }
1517
+ getRenderer(key) {
1518
+ return this.renderers.get(key);
1189
1519
  }
1190
1520
  };
1191
1521
 
@@ -1359,10 +1689,11 @@ var Dialect = class _Dialect {
1359
1689
  const combinedCtes = [...normalized.ctes ?? [], ...hoistedCtes];
1360
1690
  return combinedCtes.length ? { ...normalized, ctes: combinedCtes } : normalized;
1361
1691
  }
1362
- constructor(functionStrategy) {
1692
+ constructor(functionStrategy, tableFunctionStrategy) {
1363
1693
  this.expressionCompilers = /* @__PURE__ */ new Map();
1364
1694
  this.operandCompilers = /* @__PURE__ */ new Map();
1365
1695
  this.functionStrategy = functionStrategy || new StandardFunctionStrategy();
1696
+ this.tableFunctionStrategy = tableFunctionStrategy || new StandardTableFunctionStrategy();
1366
1697
  this.registerDefaultOperandCompilers();
1367
1698
  this.registerDefaultExpressionCompilers();
1368
1699
  }
@@ -1371,7 +1702,7 @@ var Dialect = class _Dialect {
1371
1702
  * @param functionStrategy - Optional function strategy
1372
1703
  * @returns New Dialect instance
1373
1704
  */
1374
- static create(functionStrategy) {
1705
+ static create(functionStrategy, tableFunctionStrategy) {
1375
1706
  class TestDialect extends _Dialect {
1376
1707
  constructor() {
1377
1708
  super(...arguments);
@@ -1393,7 +1724,7 @@ var Dialect = class _Dialect {
1393
1724
  throw new Error("Not implemented");
1394
1725
  }
1395
1726
  }
1396
- return new TestDialect(functionStrategy);
1727
+ return new TestDialect(functionStrategy, tableFunctionStrategy);
1397
1728
  }
1398
1729
  /**
1399
1730
  * Registers an expression compiler for a specific node type
@@ -1494,6 +1825,11 @@ var Dialect = class _Dialect {
1494
1825
  const right2 = this.compileOperand(arith.right, ctx);
1495
1826
  return `${left2} ${arith.operator} ${right2}`;
1496
1827
  });
1828
+ this.registerExpressionCompiler("BitwiseExpression", (bitwise, ctx) => {
1829
+ const left2 = this.compileOperand(bitwise.left, ctx);
1830
+ const right2 = this.compileOperand(bitwise.right, ctx);
1831
+ return `${left2} ${bitwise.operator} ${right2}`;
1832
+ });
1497
1833
  }
1498
1834
  registerDefaultOperandCompilers() {
1499
1835
  this.registerOperandCompiler("Literal", (literal, ctx) => ctx.addParameter(literal.value));
@@ -1563,6 +1899,15 @@ var Dialect = class _Dialect {
1563
1899
  const right2 = this.compileOperand(node.right, ctx);
1564
1900
  return `(${left2} ${node.operator} ${right2})`;
1565
1901
  });
1902
+ this.registerOperandCompiler("BitwiseExpression", (node, ctx) => {
1903
+ const left2 = this.compileOperand(node.left, ctx);
1904
+ const right2 = this.compileOperand(node.right, ctx);
1905
+ return `(${left2} ${node.operator} ${right2})`;
1906
+ });
1907
+ this.registerOperandCompiler("Collate", (node, ctx) => {
1908
+ const expr = this.compileOperand(node.expression, ctx);
1909
+ return `${expr} COLLATE ${node.collation}`;
1910
+ });
1566
1911
  }
1567
1912
  // Default fallback, should be overridden by dialects if supported
1568
1913
  compileJsonPath(_node) {
@@ -1595,13 +1940,13 @@ var FunctionTableFormatter = class {
1595
1940
  * @param dialect - The dialect instance for compiling operands.
1596
1941
  * @returns SQL function table expression (e.g., "LATERAL schema.func(args) WITH ORDINALITY AS alias(col1, col2)").
1597
1942
  */
1598
- static format(fn5, ctx, dialect) {
1599
- const schemaPart = this.formatSchema(fn5, dialect);
1600
- const args = this.formatArgs(fn5, ctx, dialect);
1601
- const base = this.formatBase(fn5, schemaPart, args, dialect);
1602
- const lateral = this.formatLateral(fn5);
1603
- const alias = this.formatAlias(fn5, dialect);
1604
- const colAliases = this.formatColumnAliases(fn5, dialect);
1943
+ static format(fn8, ctx, dialect) {
1944
+ const schemaPart = this.formatSchema(fn8, dialect);
1945
+ const args = this.formatArgs(fn8, ctx, dialect);
1946
+ const base = this.formatBase(fn8, schemaPart, args);
1947
+ const lateral = this.formatLateral(fn8);
1948
+ const alias = this.formatAlias(fn8, dialect);
1949
+ const colAliases = this.formatColumnAliases(fn8, dialect);
1605
1950
  return `${lateral}${base}${alias}${colAliases}`;
1606
1951
  }
1607
1952
  /**
@@ -1611,9 +1956,9 @@ var FunctionTableFormatter = class {
1611
1956
  * @returns Schema prefix (e.g., "schema.") or empty string.
1612
1957
  * @internal
1613
1958
  */
1614
- static formatSchema(fn5, dialect) {
1615
- if (!fn5.schema) return "";
1616
- const quoted = dialect ? dialect.quoteIdentifier(fn5.schema) : fn5.schema;
1959
+ static formatSchema(fn8, dialect) {
1960
+ if (!fn8.schema) return "";
1961
+ const quoted = dialect ? dialect.quoteIdentifier(fn8.schema) : fn8.schema;
1617
1962
  return `${quoted}.`;
1618
1963
  }
1619
1964
  /**
@@ -1624,8 +1969,8 @@ var FunctionTableFormatter = class {
1624
1969
  * @returns Comma-separated function arguments.
1625
1970
  * @internal
1626
1971
  */
1627
- static formatArgs(fn5, ctx, dialect) {
1628
- return (fn5.args || []).map((a) => {
1972
+ static formatArgs(fn8, ctx, dialect) {
1973
+ return (fn8.args || []).map((a) => {
1629
1974
  if (ctx && dialect) {
1630
1975
  return dialect.compileOperand(a, ctx);
1631
1976
  }
@@ -1641,10 +1986,9 @@ var FunctionTableFormatter = class {
1641
1986
  * @returns Base function call expression (e.g., "schema.func(args) WITH ORDINALITY").
1642
1987
  * @internal
1643
1988
  */
1644
- static formatBase(fn5, schemaPart, args, dialect) {
1645
- const ordinality = fn5.withOrdinality ? " WITH ORDINALITY" : "";
1646
- const quoted = dialect ? dialect.quoteIdentifier(fn5.name) : fn5.name;
1647
- return `${schemaPart}${quoted}(${args})${ordinality}`;
1989
+ static formatBase(fn8, schemaPart, args) {
1990
+ const ordinality = fn8.withOrdinality ? " WITH ORDINALITY" : "";
1991
+ return `${schemaPart}${fn8.name}(${args})${ordinality}`;
1648
1992
  }
1649
1993
  /**
1650
1994
  * Formats the LATERAL keyword if present.
@@ -1652,8 +1996,8 @@ var FunctionTableFormatter = class {
1652
1996
  * @returns "LATERAL " or empty string.
1653
1997
  * @internal
1654
1998
  */
1655
- static formatLateral(fn5) {
1656
- return fn5.lateral ? "LATERAL " : "";
1999
+ static formatLateral(fn8) {
2000
+ return fn8.lateral ? "LATERAL " : "";
1657
2001
  }
1658
2002
  /**
1659
2003
  * Formats the table alias for the function table.
@@ -1662,9 +2006,9 @@ var FunctionTableFormatter = class {
1662
2006
  * @returns " AS alias" or empty string.
1663
2007
  * @internal
1664
2008
  */
1665
- static formatAlias(fn5, dialect) {
1666
- if (!fn5.alias) return "";
1667
- const quoted = dialect ? dialect.quoteIdentifier(fn5.alias) : fn5.alias;
2009
+ static formatAlias(fn8, dialect) {
2010
+ if (!fn8.alias) return "";
2011
+ const quoted = dialect ? dialect.quoteIdentifier(fn8.alias) : fn8.alias;
1668
2012
  return ` AS ${quoted}`;
1669
2013
  }
1670
2014
  /**
@@ -1674,9 +2018,9 @@ var FunctionTableFormatter = class {
1674
2018
  * @returns "(col1, col2, ...)" or empty string.
1675
2019
  * @internal
1676
2020
  */
1677
- static formatColumnAliases(fn5, dialect) {
1678
- if (!fn5.columnAliases || !fn5.columnAliases.length) return "";
1679
- const aliases = fn5.columnAliases.map((col2) => dialect ? dialect.quoteIdentifier(col2) : col2).join(", ");
2021
+ static formatColumnAliases(fn8, dialect) {
2022
+ if (!fn8.columnAliases || !fn8.columnAliases.length) return "";
2023
+ const aliases = fn8.columnAliases.map((col2) => dialect ? dialect.quoteIdentifier(col2) : col2).join(", ");
1680
2024
  return `(${aliases})`;
1681
2025
  }
1682
2026
  };
@@ -1944,8 +2288,24 @@ var SqlDialectBase = class extends Dialect {
1944
2288
  }
1945
2289
  return this.compileTableSource(tableSource);
1946
2290
  }
1947
- compileFunctionTable(fn5, ctx) {
1948
- return FunctionTableFormatter.format(fn5, ctx, this);
2291
+ compileFunctionTable(fn8, ctx) {
2292
+ const key = fn8.key ?? fn8.name;
2293
+ if (ctx) {
2294
+ const renderer = this.tableFunctionStrategy.getRenderer(key);
2295
+ if (renderer) {
2296
+ const compiledArgs = (fn8.args ?? []).map((arg) => this.compileOperand(arg, ctx));
2297
+ return renderer({
2298
+ node: fn8,
2299
+ compiledArgs,
2300
+ compileOperand: (operand) => this.compileOperand(operand, ctx),
2301
+ quoteIdentifier: this.quoteIdentifier.bind(this)
2302
+ });
2303
+ }
2304
+ if (fn8.key) {
2305
+ throw new Error(`Table function "${key}" is not supported by dialect "${this.dialect}".`);
2306
+ }
2307
+ }
2308
+ return FunctionTableFormatter.format(fn8, ctx, this);
1949
2309
  }
1950
2310
  compileDerivedTable(table, ctx) {
1951
2311
  if (!table.alias) {
@@ -2104,6 +2464,76 @@ var PostgresFunctionStrategy = class extends StandardFunctionStrategy {
2104
2464
  const separator = ctx.compileOperand(separatorOperand);
2105
2465
  return `STRING_AGG(${arg}, ${separator}${orderSegment})`;
2106
2466
  });
2467
+ this.add("CHR", ({ compiledArgs }) => `CHR(${compiledArgs[0]})`);
2468
+ this.add("HOUR", ({ compiledArgs }) => `EXTRACT(HOUR FROM ${compiledArgs[0]})`);
2469
+ this.add("MINUTE", ({ compiledArgs }) => `EXTRACT(MINUTE FROM ${compiledArgs[0]})`);
2470
+ this.add("SECOND", ({ compiledArgs }) => `EXTRACT(SECOND FROM ${compiledArgs[0]})`);
2471
+ this.add("QUARTER", ({ compiledArgs }) => `EXTRACT(QUARTER FROM ${compiledArgs[0]})`);
2472
+ this.add("JSON_LENGTH", ({ compiledArgs }) => {
2473
+ if (compiledArgs.length !== 1) throw new Error("JSON_LENGTH expects 1 argument on PostgreSQL");
2474
+ return `jsonb_array_length(${compiledArgs[0]})`;
2475
+ });
2476
+ this.add("JSON_ARRAYAGG", ({ compiledArgs }) => {
2477
+ if (compiledArgs.length !== 1) throw new Error("JSON_ARRAYAGG expects 1 argument on PostgreSQL");
2478
+ return `jsonb_agg(${compiledArgs[0]})`;
2479
+ });
2480
+ this.add("JSON_CONTAINS", ({ compiledArgs }) => {
2481
+ if (compiledArgs.length !== 2) throw new Error("JSON_CONTAINS expects 2 arguments on PostgreSQL");
2482
+ return `(${compiledArgs[0]}::jsonb @> ${compiledArgs[1]}::jsonb)`;
2483
+ });
2484
+ this.add("ARRAY_APPEND", ({ compiledArgs }) => {
2485
+ if (compiledArgs.length !== 2) throw new Error("ARRAY_APPEND expects 2 arguments on PostgreSQL");
2486
+ return `array_append(${compiledArgs[0]}, ${compiledArgs[1]})`;
2487
+ });
2488
+ this.add("JSON_SET", ({ node, compiledArgs }) => {
2489
+ if (compiledArgs.length !== 3) throw new Error("JSON_SET expects exactly 3 arguments on PostgreSQL");
2490
+ const pathNode = node.args[1];
2491
+ if (pathNode.type !== "Literal") {
2492
+ throw new Error("PostgreSQL JSON_SET currently supports literal paths only");
2493
+ }
2494
+ const pathArray = this.formatJsonbPathArray(pathNode);
2495
+ return `jsonb_set(${compiledArgs[0]}, ${pathArray}, ${compiledArgs[2]}::jsonb, true)`;
2496
+ });
2497
+ }
2498
+ formatJsonbPathArray(pathNode) {
2499
+ const rawPath = String(pathNode.value ?? "");
2500
+ if (!rawPath.startsWith("$")) {
2501
+ throw new Error('PostgreSQL JSON_SET paths must start with "$"');
2502
+ }
2503
+ const trimmed = rawPath === "$" ? "" : rawPath.startsWith("$.") ? rawPath.slice(2) : rawPath.slice(1);
2504
+ if (!trimmed) {
2505
+ throw new Error("PostgreSQL JSON_SET requires a non-root path");
2506
+ }
2507
+ if (trimmed.includes("[") || trimmed.includes("]")) {
2508
+ throw new Error("PostgreSQL JSON_SET currently only supports simple dot-separated paths");
2509
+ }
2510
+ const segments = trimmed.split(".").map((segment) => segment.replace(/^['"]?/, "").replace(/['"]?$/, "").trim()).filter(Boolean);
2511
+ if (!segments.length) {
2512
+ throw new Error("PostgreSQL JSON_SET requires at least one path segment");
2513
+ }
2514
+ const escapedSegments = segments.map((segment) => `'${segment.replace(/'/g, "''")}'`);
2515
+ return `ARRAY[${escapedSegments.join(", ")}]`;
2516
+ }
2517
+ };
2518
+
2519
+ // src/core/dialect/postgres/table-functions.ts
2520
+ var PostgresTableFunctionStrategy = class extends StandardTableFunctionStrategy {
2521
+ constructor() {
2522
+ super();
2523
+ this.registerOverrides();
2524
+ }
2525
+ registerOverrides() {
2526
+ this.add("ARRAY_UNNEST", ({ node, compiledArgs, quoteIdentifier }) => {
2527
+ const lateral = node.lateral ?? true;
2528
+ const withOrd = node.withOrdinality ?? false;
2529
+ const base = `unnest(${compiledArgs.join(", ")})${withOrd ? " WITH ORDINALITY" : ""}`;
2530
+ if (node.columnAliases?.length && !node.alias) {
2531
+ throw new Error("tvf(ARRAY_UNNEST) with columnAliases requires an alias.");
2532
+ }
2533
+ const alias = node.alias ? ` AS ${quoteIdentifier(node.alias)}` : "";
2534
+ const cols = node.columnAliases?.length ? `(${node.columnAliases.map(quoteIdentifier).join(", ")})` : "";
2535
+ return `${lateral ? "LATERAL " : ""}${base}${alias}${cols}`;
2536
+ });
2107
2537
  }
2108
2538
  };
2109
2539
 
@@ -2113,8 +2543,20 @@ var PostgresDialect = class extends SqlDialectBase {
2113
2543
  * Creates a new PostgresDialect instance
2114
2544
  */
2115
2545
  constructor() {
2116
- super(new PostgresFunctionStrategy());
2546
+ super(new PostgresFunctionStrategy(), new PostgresTableFunctionStrategy());
2117
2547
  this.dialect = "postgres";
2548
+ this.registerExpressionCompiler("BitwiseExpression", (node, ctx) => {
2549
+ const left2 = this.compileOperand(node.left, ctx);
2550
+ const right2 = this.compileOperand(node.right, ctx);
2551
+ const op = node.operator === "^" ? "#" : node.operator;
2552
+ return `${left2} ${op} ${right2}`;
2553
+ });
2554
+ this.registerOperandCompiler("BitwiseExpression", (node, ctx) => {
2555
+ const left2 = this.compileOperand(node.left, ctx);
2556
+ const right2 = this.compileOperand(node.right, ctx);
2557
+ const op = node.operator === "^" ? "#" : node.operator;
2558
+ return `(${left2} ${op} ${right2})`;
2559
+ });
2118
2560
  }
2119
2561
  /**
2120
2562
  * Quotes an identifier using PostgreSQL double-quote syntax
@@ -2223,6 +2665,14 @@ var MysqlFunctionStrategy = class extends StandardFunctionStrategy {
2223
2665
  }
2224
2666
  return `DATE(${date})`;
2225
2667
  });
2668
+ this.add("HOUR", ({ compiledArgs }) => `HOUR(${compiledArgs[0]})`);
2669
+ this.add("MINUTE", ({ compiledArgs }) => `MINUTE(${compiledArgs[0]})`);
2670
+ this.add("SECOND", ({ compiledArgs }) => `SECOND(${compiledArgs[0]})`);
2671
+ this.add("QUARTER", ({ compiledArgs }) => `QUARTER(${compiledArgs[0]})`);
2672
+ this.add("ARRAY_APPEND", ({ compiledArgs }) => {
2673
+ if (compiledArgs.length !== 2) throw new Error("ARRAY_APPEND expects 2 arguments (array, value)");
2674
+ return `JSON_ARRAY_APPEND(${compiledArgs[0]}, '$', ${compiledArgs[1]})`;
2675
+ });
2226
2676
  }
2227
2677
  };
2228
2678
 
@@ -2355,6 +2805,30 @@ var SqliteFunctionStrategy = class extends StandardFunctionStrategy {
2355
2805
  const separator = ctx.compileOperand(separatorOperand);
2356
2806
  return `GROUP_CONCAT(${arg}, ${separator})`;
2357
2807
  });
2808
+ this.add("HOUR", ({ compiledArgs }) => `CAST(strftime('%H', ${compiledArgs[0]}) AS INTEGER)`);
2809
+ this.add("MINUTE", ({ compiledArgs }) => `CAST(strftime('%M', ${compiledArgs[0]}) AS INTEGER)`);
2810
+ this.add("SECOND", ({ compiledArgs }) => `CAST(strftime('%S', ${compiledArgs[0]}) AS INTEGER)`);
2811
+ this.add("QUARTER", ({ compiledArgs }) => `((CAST(strftime('%m', ${compiledArgs[0]}) AS INTEGER) + 2) / 3)`);
2812
+ this.add("JSON_LENGTH", ({ compiledArgs }) => {
2813
+ if (compiledArgs.length === 0 || compiledArgs.length > 2) {
2814
+ throw new Error("JSON_LENGTH expects 1 or 2 arguments on SQLite");
2815
+ }
2816
+ return `json_array_length(${compiledArgs.join(", ")})`;
2817
+ });
2818
+ this.add("JSON_ARRAYAGG", ({ compiledArgs }) => {
2819
+ if (compiledArgs.length !== 1) {
2820
+ throw new Error("JSON_ARRAYAGG expects 1 argument on SQLite");
2821
+ }
2822
+ return `json_group_array(${compiledArgs[0]})`;
2823
+ });
2824
+ this.add("JSON_CONTAINS", () => {
2825
+ throw new Error("JSON_CONTAINS is not supported on SQLite");
2826
+ });
2827
+ this.add("ARRAY_APPEND", ({ compiledArgs }) => {
2828
+ if (compiledArgs.length !== 2) throw new Error("ARRAY_APPEND expects 2 arguments (array, value)");
2829
+ return `json_array_append(${compiledArgs[0]}, '$', ${compiledArgs[1]})`;
2830
+ });
2831
+ this.add("CHR", ({ compiledArgs }) => `CHAR(${compiledArgs[0]})`);
2358
2832
  }
2359
2833
  };
2360
2834
 
@@ -2366,6 +2840,22 @@ var SqliteDialect = class extends SqlDialectBase {
2366
2840
  constructor() {
2367
2841
  super(new SqliteFunctionStrategy());
2368
2842
  this.dialect = "sqlite";
2843
+ this.registerExpressionCompiler("BitwiseExpression", (node, ctx) => {
2844
+ const left2 = this.compileOperand(node.left, ctx);
2845
+ const right2 = this.compileOperand(node.right, ctx);
2846
+ if (node.operator === "^") {
2847
+ return `(${left2} | ${right2}) & ~(${left2} & ${right2})`;
2848
+ }
2849
+ return `${left2} ${node.operator} ${right2}`;
2850
+ });
2851
+ this.registerOperandCompiler("BitwiseExpression", (node, ctx) => {
2852
+ const left2 = this.compileOperand(node.left, ctx);
2853
+ const right2 = this.compileOperand(node.right, ctx);
2854
+ if (node.operator === "^") {
2855
+ return `((${left2} | ${right2}) & ~(${left2} & ${right2}))`;
2856
+ }
2857
+ return `(${left2} ${node.operator} ${right2})`;
2858
+ });
2369
2859
  }
2370
2860
  /**
2371
2861
  * Quotes an identifier using SQLite double-quote syntax
@@ -2490,6 +2980,33 @@ var MssqlFunctionStrategy = class extends StandardFunctionStrategy {
2490
2980
  const withinGroup = orderClause ? ` WITHIN GROUP (${orderClause})` : "";
2491
2981
  return `STRING_AGG(${arg}, ${separator})${withinGroup}`;
2492
2982
  });
2983
+ this.add("LENGTH", ({ compiledArgs }) => `LEN(${compiledArgs[0]})`);
2984
+ this.add("CHAR_LENGTH", ({ compiledArgs }) => `LEN(${compiledArgs[0]})`);
2985
+ this.add("CHARACTER_LENGTH", ({ compiledArgs }) => `LEN(${compiledArgs[0]})`);
2986
+ this.add("POSITION", ({ compiledArgs }) => `CHARINDEX(${compiledArgs[0]}, ${compiledArgs[1]})`);
2987
+ this.add("LOCATE", ({ compiledArgs }) => compiledArgs.length === 3 ? `CHARINDEX(${compiledArgs[0]}, ${compiledArgs[1]}, ${compiledArgs[2]})` : `CHARINDEX(${compiledArgs[0]}, ${compiledArgs[1]})`);
2988
+ this.add("INSTR", ({ compiledArgs }) => `CHARINDEX(${compiledArgs[1]}, ${compiledArgs[0]})`);
2989
+ this.add("CHR", ({ compiledArgs }) => `CHAR(${compiledArgs[0]})`);
2990
+ this.add("HOUR", ({ compiledArgs }) => `DATEPART(hour, ${compiledArgs[0]})`);
2991
+ this.add("MINUTE", ({ compiledArgs }) => `DATEPART(minute, ${compiledArgs[0]})`);
2992
+ this.add("SECOND", ({ compiledArgs }) => `DATEPART(second, ${compiledArgs[0]})`);
2993
+ this.add("QUARTER", ({ compiledArgs }) => `DATEPART(quarter, ${compiledArgs[0]})`);
2994
+ this.add("JSON_SET", ({ compiledArgs }) => {
2995
+ if (compiledArgs.length !== 3) throw new Error("JSON_SET expects 3 arguments on SQL Server");
2996
+ return `JSON_MODIFY(${compiledArgs[0]}, ${compiledArgs[1]}, ${compiledArgs[2]})`;
2997
+ });
2998
+ this.add("JSON_LENGTH", () => {
2999
+ throw new Error("JSON_LENGTH is not supported on SQL Server");
3000
+ });
3001
+ this.add("JSON_ARRAYAGG", () => {
3002
+ throw new Error("JSON_ARRAYAGG is not supported on SQL Server");
3003
+ });
3004
+ this.add("JSON_CONTAINS", () => {
3005
+ throw new Error("JSON_CONTAINS is not supported on SQL Server");
3006
+ });
3007
+ this.add("ARRAY_APPEND", () => {
3008
+ throw new Error("ARRAY_APPEND is not supported on SQL Server");
3009
+ });
2493
3010
  }
2494
3011
  };
2495
3012
 
@@ -4287,6 +4804,17 @@ var hideInternal2 = (obj, keys) => {
4287
4804
  }
4288
4805
  };
4289
4806
  var DefaultHasOneReference = class {
4807
+ /**
4808
+ * @param ctx The entity context for tracking changes.
4809
+ * @param meta Metadata for the parent entity.
4810
+ * @param root The parent entity instance.
4811
+ * @param relationName The name of the relation.
4812
+ * @param relation Relation definition.
4813
+ * @param rootTable Table definition of the parent entity.
4814
+ * @param loader Function to load the child entity.
4815
+ * @param createEntity Function to create entity instances from rows.
4816
+ * @param localKey The local key on the parent entity used for the relation.
4817
+ */
4290
4818
  constructor(ctx, meta, root, relationName, relation, rootTable, loader, createEntity, localKey) {
4291
4819
  this.ctx = ctx;
4292
4820
  this.meta = meta;
@@ -4404,6 +4932,17 @@ var hideInternal3 = (obj, keys) => {
4404
4932
  }
4405
4933
  };
4406
4934
  var DefaultBelongsToReference = class {
4935
+ /**
4936
+ * @param ctx The entity context for tracking changes.
4937
+ * @param meta Metadata for the child entity.
4938
+ * @param root The child entity instance (carrying the foreign key).
4939
+ * @param relationName The name of the relation.
4940
+ * @param relation Relation definition.
4941
+ * @param rootTable Table definition of the child entity.
4942
+ * @param loader Function to load the parent entity.
4943
+ * @param createEntity Function to create entity instances from rows.
4944
+ * @param targetKey The primary key of the target (parent) table.
4945
+ */
4407
4946
  constructor(ctx, meta, root, relationName, relation, rootTable, loader, createEntity, targetKey) {
4408
4947
  this.ctx = ctx;
4409
4948
  this.meta = meta;
@@ -4495,6 +5034,17 @@ var hideInternal4 = (obj, keys) => {
4495
5034
  }
4496
5035
  };
4497
5036
  var DefaultManyToManyCollection = class {
5037
+ /**
5038
+ * @param ctx The entity context for tracking changes.
5039
+ * @param meta Metadata for the root entity.
5040
+ * @param root The root entity instance.
5041
+ * @param relationName The name of the relation.
5042
+ * @param relation Relation definition.
5043
+ * @param rootTable Table definition of the root entity.
5044
+ * @param loader Function to load the collection items.
5045
+ * @param createEntity Function to create entity instances from rows.
5046
+ * @param localKey The local key used for joining.
5047
+ */
4498
5048
  constructor(ctx, meta, root, relationName, relation, rootTable, loader, createEntity, localKey) {
4499
5049
  this.ctx = ctx;
4500
5050
  this.meta = meta;
@@ -4510,6 +5060,10 @@ var DefaultManyToManyCollection = class {
4510
5060
  hideInternal4(this, ["ctx", "meta", "root", "relationName", "relation", "rootTable", "loader", "createEntity", "localKey"]);
4511
5061
  this.hydrateFromCache();
4512
5062
  }
5063
+ /**
5064
+ * Loads the collection items if not already loaded.
5065
+ * @returns A promise that resolves to the array of target entities.
5066
+ */
4513
5067
  async load() {
4514
5068
  if (this.loaded) return this.items;
4515
5069
  const map = await this.loader();
@@ -4525,9 +5079,18 @@ var DefaultManyToManyCollection = class {
4525
5079
  this.loaded = true;
4526
5080
  return this.items;
4527
5081
  }
5082
+ /**
5083
+ * Returns the currently loaded items.
5084
+ * @returns Array of target entities.
5085
+ */
4528
5086
  getItems() {
4529
5087
  return this.items;
4530
5088
  }
5089
+ /**
5090
+ * Attaches an entity to the collection.
5091
+ * Registers an 'attach' change in the entity context.
5092
+ * @param target Entity instance or its primary key value.
5093
+ */
4531
5094
  attach(target) {
4532
5095
  const entity = this.ensureEntity(target);
4533
5096
  const id = this.extractId(entity);
@@ -4547,6 +5110,11 @@ var DefaultManyToManyCollection = class {
4547
5110
  { kind: "attach", entity }
4548
5111
  );
4549
5112
  }
5113
+ /**
5114
+ * Detaches an entity from the collection.
5115
+ * Registers a 'detach' change in the entity context.
5116
+ * @param target Entity instance or its primary key value.
5117
+ */
4550
5118
  detach(target) {
4551
5119
  const id = typeof target === "number" || typeof target === "string" ? target : this.extractId(target);
4552
5120
  if (id == null) return;
@@ -4562,6 +5130,11 @@ var DefaultManyToManyCollection = class {
4562
5130
  { kind: "detach", entity: existing }
4563
5131
  );
4564
5132
  }
5133
+ /**
5134
+ * Syncs the collection with a list of IDs.
5135
+ * Attaches missing IDs and detaches IDs not in the list.
5136
+ * @param ids Array of primary key values to sync with.
5137
+ */
4565
5138
  async syncByIds(ids) {
4566
5139
  await this.load();
4567
5140
  const normalized = new Set(ids.map((id) => toKey5(id)));
@@ -7790,6 +8363,14 @@ var repeat = (value, count2) => fn("REPEAT", [value, count2]);
7790
8363
  var lpad = (value, len, pad) => fn("LPAD", [value, len, pad]);
7791
8364
  var rpad = (value, len, pad) => fn("RPAD", [value, len, pad]);
7792
8365
  var space = (count2) => fn("SPACE", [count2]);
8366
+ var reverse = (value) => fn("REVERSE", [value]);
8367
+ var initcap = (value) => fn("INITCAP", [value]);
8368
+ var md5 = (value) => fn("MD5", [value]);
8369
+ var sha1 = (value) => fn("SHA1", [value]);
8370
+ var sha2 = (value, bits) => fn("SHA2", [value, bits]);
8371
+ var bitLength = (value) => fn("BIT_LENGTH", [value]);
8372
+ var octetLength = (value) => fn("OCTET_LENGTH", [value]);
8373
+ var chr = (code) => fn("CHR", [code]);
7793
8374
 
7794
8375
  // src/core/ddl/introspect/functions/mssql.ts
7795
8376
  var isColumnReference = (value) => typeof value === "object" && value !== null && !("type" in value) && "name" in value && typeof value.name === "string";
@@ -8348,6 +8929,8 @@ var sqrt = (value) => fn3("SQRT", [value]);
8348
8929
  var tan = (value) => fn3("TAN", [value]);
8349
8930
  var trunc = (value, decimals) => decimals === void 0 ? fn3("TRUNC", [value]) : fn3("TRUNC", [value, decimals]);
8350
8931
  var truncate = (value, decimals) => fn3("TRUNCATE", [value, decimals]);
8932
+ var log2 = (value) => fn3("LOG2", [value]);
8933
+ var cbrt = (value) => fn3("CBRT", [value]);
8351
8934
 
8352
8935
  // src/core/functions/datetime.ts
8353
8936
  var isColumnDef3 = (val) => !!val && typeof val === "object" && "type" in val && "name" in val;
@@ -8359,12 +8942,15 @@ var toOperand4 = (input) => {
8359
8942
  var fn4 = (key, args) => ({
8360
8943
  type: "Function",
8361
8944
  name: key,
8945
+ fn: key,
8362
8946
  args: args.map(toOperand4)
8363
8947
  });
8364
8948
  var now = () => fn4("NOW", []);
8365
8949
  var currentDate = () => fn4("CURRENT_DATE", []);
8366
8950
  var currentTime = () => fn4("CURRENT_TIME", []);
8367
8951
  var utcNow = () => fn4("UTC_NOW", []);
8952
+ var localTime = () => fn4("LOCALTIME", []);
8953
+ var localTimestamp = () => fn4("LOCALTIMESTAMP", []);
8368
8954
  var extract = (part, date) => fn4("EXTRACT", [part, date]);
8369
8955
  var year = (date) => fn4("YEAR", [date]);
8370
8956
  var month = (date) => fn4("MONTH", [date]);
@@ -8379,6 +8965,72 @@ var endOfMonth = (date) => fn4("END_OF_MONTH", [date]);
8379
8965
  var dayOfWeek = (date) => fn4("DAY_OF_WEEK", [date]);
8380
8966
  var weekOfYear = (date) => fn4("WEEK_OF_YEAR", [date]);
8381
8967
  var dateTrunc = (part, date) => fn4("DATE_TRUNC", [part, date]);
8968
+ var age = (timestamp, baseTimestamp) => baseTimestamp === void 0 ? fn4("AGE", [timestamp]) : fn4("AGE", [timestamp, baseTimestamp]);
8969
+ var hour = (date) => fn4("HOUR", [date]);
8970
+ var minute = (date) => fn4("MINUTE", [date]);
8971
+ var second = (date) => fn4("SECOND", [date]);
8972
+ var quarter = (date) => fn4("QUARTER", [date]);
8973
+
8974
+ // src/core/functions/control-flow.ts
8975
+ var isColumnDef4 = (val) => !!val && typeof val === "object" && "type" in val && "name" in val;
8976
+ var toOperand5 = (input) => {
8977
+ if (isOperandNode(input)) return input;
8978
+ if (isColumnDef4(input)) return columnOperand(input);
8979
+ return valueToOperand(input);
8980
+ };
8981
+ var fn5 = (key, args) => ({
8982
+ type: "Function",
8983
+ name: key,
8984
+ fn: key,
8985
+ args: args.map(toOperand5)
8986
+ });
8987
+ var coalesce = (...args) => {
8988
+ if (args.length < 2) throw new Error("coalesce() expects at least 2 arguments");
8989
+ return fn5("COALESCE", args);
8990
+ };
8991
+ var nullif = (val1, val2) => fn5("NULLIF", [val1, val2]);
8992
+ var greatest = (...args) => {
8993
+ if (args.length < 2) throw new Error("greatest() expects at least 2 arguments");
8994
+ return fn5("GREATEST", args);
8995
+ };
8996
+ var least = (...args) => {
8997
+ if (args.length < 2) throw new Error("least() expects at least 2 arguments");
8998
+ return fn5("LEAST", args);
8999
+ };
9000
+ var ifNull = (val, defaultValue) => coalesce(val, defaultValue);
9001
+
9002
+ // src/core/functions/json.ts
9003
+ var isColumnDef5 = (val) => !!val && typeof val === "object" && "type" in val && "name" in val;
9004
+ var toOperand6 = (input) => {
9005
+ if (isOperandNode(input)) return input;
9006
+ if (isColumnDef5(input)) return columnOperand(input);
9007
+ return valueToOperand(input);
9008
+ };
9009
+ var fn6 = (key, args) => ({
9010
+ type: "Function",
9011
+ name: key,
9012
+ fn: key,
9013
+ args: args.map(toOperand6)
9014
+ });
9015
+ var jsonLength = (target, path) => path === void 0 ? fn6("JSON_LENGTH", [target]) : fn6("JSON_LENGTH", [target, path]);
9016
+ var jsonSet = (target, path, value) => fn6("JSON_SET", [target, path, value]);
9017
+ var jsonArrayAgg = (value) => fn6("JSON_ARRAYAGG", [value]);
9018
+ var jsonContains = (target, candidate, path) => path === void 0 ? fn6("JSON_CONTAINS", [target, candidate]) : fn6("JSON_CONTAINS", [target, candidate, path]);
9019
+
9020
+ // src/core/functions/array.ts
9021
+ var isColumnDef6 = (val) => !!val && typeof val === "object" && "type" in val && "name" in val;
9022
+ var toOperand7 = (input) => {
9023
+ if (isOperandNode(input)) return input;
9024
+ if (isColumnDef6(input)) return columnOperand(input);
9025
+ return valueToOperand(input);
9026
+ };
9027
+ var fn7 = (key, args) => ({
9028
+ type: "Function",
9029
+ name: key,
9030
+ fn: key,
9031
+ args: args.map(toOperand7)
9032
+ });
9033
+ var arrayAppend = (array, value) => fn7("ARRAY_APPEND", [array, value]);
8382
9034
 
8383
9035
  // src/orm/als.ts
8384
9036
  var AsyncLocalStorage = class {
@@ -8458,7 +9110,7 @@ var DefaultNamingStrategy = class {
8458
9110
  * @returns Capitalized table name (handles schema-qualified names)
8459
9111
  */
8460
9112
  tableToSymbol(table) {
8461
- const tableName = typeof table === "string" ? table : table.type === "DerivedTable" ? table.alias : table.name;
9113
+ const tableName = typeof table === "string" ? table : table.type === "DerivedTable" ? table.alias : table.type === "FunctionTable" ? table.alias ?? table.name : table.name;
8462
9114
  if (tableName.includes(".")) {
8463
9115
  return tableName.split(".").map((part) => this.capitalize(part)).join("");
8464
9116
  }
@@ -8614,6 +9266,7 @@ var TypeScriptGenerator = class {
8614
9266
  case "CaseExpression":
8615
9267
  case "WindowFunction":
8616
9268
  case "Cast":
9269
+ case "Collate":
8617
9270
  return this.printOperand(term);
8618
9271
  default:
8619
9272
  return this.printExpression(term);
@@ -8676,6 +9329,9 @@ var TypeScriptGenerator = class {
8676
9329
  visitCast(node) {
8677
9330
  return this.printCastOperand(node);
8678
9331
  }
9332
+ visitCollate(node) {
9333
+ return this.printCollateOperand(node);
9334
+ }
8679
9335
  visitAliasRef(node) {
8680
9336
  return `aliasRef('${node.name}')`;
8681
9337
  }
@@ -8687,12 +9343,12 @@ var TypeScriptGenerator = class {
8687
9343
  printBinaryExpression(binary) {
8688
9344
  const left2 = this.printOperand(binary.left);
8689
9345
  const right2 = this.printOperand(binary.right);
8690
- const fn5 = this.mapOp(binary.operator);
9346
+ const fn8 = this.mapOp(binary.operator);
8691
9347
  const args = [left2, right2];
8692
9348
  if (binary.escape) {
8693
9349
  args.push(this.printOperand(binary.escape));
8694
9350
  }
8695
- return `${fn5}(${args.join(", ")})`;
9351
+ return `${fn8}(${args.join(", ")})`;
8696
9352
  }
8697
9353
  /**
8698
9354
  * Prints a logical expression to TypeScript code
@@ -8721,13 +9377,13 @@ var TypeScriptGenerator = class {
8721
9377
  */
8722
9378
  printInExpression(inExpr) {
8723
9379
  const left2 = this.printOperand(inExpr.left);
8724
- const fn5 = this.mapOp(inExpr.operator);
9380
+ const fn8 = this.mapOp(inExpr.operator);
8725
9381
  if (Array.isArray(inExpr.right)) {
8726
9382
  const values = inExpr.right.map((v) => this.printOperand(v)).join(", ");
8727
- return `${fn5}(${left2}, [${values}])`;
9383
+ return `${fn8}(${left2}, [${values}])`;
8728
9384
  }
8729
9385
  const subquery = this.inlineChain(this.buildSelectLines(inExpr.right.query));
8730
- return `${fn5}(${left2}, (${subquery}))`;
9386
+ return `${fn8}(${left2}, (${subquery}))`;
8731
9387
  }
8732
9388
  /**
8733
9389
  * Prints a null expression to TypeScript code
@@ -8736,8 +9392,8 @@ var TypeScriptGenerator = class {
8736
9392
  */
8737
9393
  printNullExpression(nullExpr) {
8738
9394
  const left2 = this.printOperand(nullExpr.left);
8739
- const fn5 = this.mapOp(nullExpr.operator);
8740
- return `${fn5}(${left2})`;
9395
+ const fn8 = this.mapOp(nullExpr.operator);
9396
+ return `${fn8}(${left2})`;
8741
9397
  }
8742
9398
  /**
8743
9399
  * Prints a BETWEEN expression to TypeScript code
@@ -8781,9 +9437,9 @@ var TypeScriptGenerator = class {
8781
9437
  * @param fn - Function node
8782
9438
  * @returns TypeScript code representation
8783
9439
  */
8784
- printFunctionOperand(fn5) {
8785
- const args = fn5.args.map((a) => this.printOperand(a)).join(", ");
8786
- return `${fn5.name.toLowerCase()}(${args})`;
9440
+ printFunctionOperand(fn8) {
9441
+ const args = fn8.args.map((a) => this.printOperand(a)).join(", ");
9442
+ return `${fn8.name.toLowerCase()}(${args})`;
8787
9443
  }
8788
9444
  /**
8789
9445
  * Prints a JSON path operand to TypeScript code
@@ -8847,6 +9503,9 @@ var TypeScriptGenerator = class {
8847
9503
  const typeLiteral = node.castType.replace(/'/g, "\\'");
8848
9504
  return `cast(${this.printOperand(node.expression)}, '${typeLiteral}')`;
8849
9505
  }
9506
+ printCollateOperand(node) {
9507
+ return `collate(${this.printOperand(node.expression)}, '${node.collation}')`;
9508
+ }
8850
9509
  /**
8851
9510
  * Converts method chain lines to inline format
8852
9511
  * @param lines - Method chain lines
@@ -8877,10 +9536,20 @@ var IdentityMap = class {
8877
9536
  get bucketsMap() {
8878
9537
  return this.buckets;
8879
9538
  }
9539
+ /**
9540
+ * Retrieves an entity from the identity map if it exists.
9541
+ * @param table The table definition of the entity.
9542
+ * @param pk The primary key value.
9543
+ * @returns The entity instance if found, undefined otherwise.
9544
+ */
8880
9545
  getEntity(table, pk) {
8881
9546
  const bucket = this.buckets.get(table.name);
8882
9547
  return bucket?.get(this.toIdentityKey(pk))?.entity;
8883
9548
  }
9549
+ /**
9550
+ * Registers a tracked entity in the identity map.
9551
+ * @param tracked The tracked entity metadata and instance.
9552
+ */
8884
9553
  register(tracked) {
8885
9554
  if (tracked.pk == null) return;
8886
9555
  const bucket = this.buckets.get(tracked.table.name) ?? /* @__PURE__ */ new Map();
@@ -8892,6 +9561,11 @@ var IdentityMap = class {
8892
9561
  const bucket = this.buckets.get(tracked.table.name);
8893
9562
  bucket?.delete(this.toIdentityKey(tracked.pk));
8894
9563
  }
9564
+ /**
9565
+ * Returns all tracked entities for a specific table.
9566
+ * @param table The table definition.
9567
+ * @returns Array of tracked entities.
9568
+ */
8895
9569
  getEntitiesForTable(table) {
8896
9570
  const bucket = this.buckets.get(table.name);
8897
9571
  return bucket ? Array.from(bucket.values()) : [];
@@ -9981,7 +10655,7 @@ var OrmSession = class {
9981
10655
  this.markRemoved(entity);
9982
10656
  }
9983
10657
  /**
9984
- * Flushes pending changes to the database.
10658
+ * Flushes pending changes to the database without session hooks, relation processing, or domain events.
9985
10659
  */
9986
10660
  async flush() {
9987
10661
  await this.unitOfWork.flush();
@@ -10016,15 +10690,15 @@ var OrmSession = class {
10016
10690
  * @returns The result of the function
10017
10691
  * @throws If the transaction fails
10018
10692
  */
10019
- async transaction(fn5) {
10693
+ async transaction(fn8) {
10020
10694
  if (!this.executor.capabilities.transactions) {
10021
- const result = await fn5(this);
10695
+ const result = await fn8(this);
10022
10696
  await this.commit();
10023
10697
  return result;
10024
10698
  }
10025
10699
  await this.executor.beginTransaction();
10026
10700
  try {
10027
- const result = await fn5(this);
10701
+ const result = await fn8(this);
10028
10702
  await this.flushWithHooks();
10029
10703
  await this.executor.commitTransaction();
10030
10704
  await this.domainEvents.dispatch(this.unitOfWork.getTracked(), this);
@@ -10127,11 +10801,11 @@ var Orm = class {
10127
10801
  * @returns The result of the function
10128
10802
  * @throws If the transaction fails
10129
10803
  */
10130
- async transaction(fn5) {
10804
+ async transaction(fn8) {
10131
10805
  const executor = this.executorFactory.createTransactionalExecutor();
10132
10806
  const session = new OrmSession({ orm: this, executor });
10133
10807
  try {
10134
- return await session.transaction(() => fn5(session));
10808
+ return await session.transaction(() => fn8(session));
10135
10809
  } finally {
10136
10810
  await session.dispose();
10137
10811
  }
@@ -10173,6 +10847,13 @@ var getOrCreateMetadataBag = (context) => {
10173
10847
  var readMetadataBag = (context) => {
10174
10848
  return context.metadata?.[METADATA_KEY];
10175
10849
  };
10850
+ var readMetadataBagFromConstructor = (ctor) => {
10851
+ const metadataSymbol = Symbol.metadata;
10852
+ if (!metadataSymbol) return void 0;
10853
+ const metadata = Reflect.get(ctor, metadataSymbol);
10854
+ return metadata?.[METADATA_KEY];
10855
+ };
10856
+ var getDecoratorMetadata = (ctor) => readMetadataBagFromConstructor(ctor);
10176
10857
 
10177
10858
  // src/decorators/entity.ts
10178
10859
  var toSnakeCase = (value) => {
@@ -10950,8 +11631,10 @@ function createPooledExecutorFactory(opts) {
10950
11631
  acos,
10951
11632
  add,
10952
11633
  addDomainEvent,
11634
+ age,
10953
11635
  aliasRef,
10954
11636
  and,
11637
+ arrayAppend,
10955
11638
  ascii,
10956
11639
  asin,
10957
11640
  atan,
@@ -10960,16 +11643,24 @@ function createPooledExecutorFactory(opts) {
10960
11643
  belongsTo,
10961
11644
  belongsToMany,
10962
11645
  between,
11646
+ bitAnd,
11647
+ bitLength,
11648
+ bitOr,
11649
+ bitXor,
10963
11650
  bootstrapEntities,
10964
11651
  caseWhen,
10965
11652
  cast,
11653
+ cbrt,
10966
11654
  ceil,
10967
11655
  ceiling,
10968
11656
  char,
10969
11657
  charLength,
11658
+ chr,
10970
11659
  clearExpressionDispatchers,
10971
11660
  clearOperandDispatchers,
11661
+ coalesce,
10972
11662
  col,
11663
+ collate,
10973
11664
  columnOperand,
10974
11665
  concat,
10975
11666
  concatWs,
@@ -11018,20 +11709,26 @@ function createPooledExecutorFactory(opts) {
11018
11709
  generateCreateTableSql,
11019
11710
  generateSchemaSql,
11020
11711
  getColumn,
11712
+ getDecoratorMetadata,
11021
11713
  getSchemaIntrospector,
11022
11714
  getTableDefFromEntity,
11715
+ greatest,
11023
11716
  groupConcat,
11024
11717
  gt,
11025
11718
  gte,
11026
11719
  hasMany,
11027
11720
  hasOne,
11721
+ hour,
11028
11722
  hydrateRows,
11723
+ ifNull,
11029
11724
  inList,
11030
11725
  inSubquery,
11726
+ initcap,
11031
11727
  instr,
11032
11728
  introspectSchema,
11033
11729
  isCaseExpressionNode,
11034
11730
  isCastExpressionNode,
11731
+ isCollateExpressionNode,
11035
11732
  isExpressionSelectionNode,
11036
11733
  isFunctionNode,
11037
11734
  isNotNull,
@@ -11039,11 +11736,16 @@ function createPooledExecutorFactory(opts) {
11039
11736
  isOperandNode,
11040
11737
  isValueOperandInput,
11041
11738
  isWindowFunctionNode,
11739
+ jsonArrayAgg,
11740
+ jsonContains,
11741
+ jsonLength,
11042
11742
  jsonPath,
11743
+ jsonSet,
11043
11744
  jsonify,
11044
11745
  lag,
11045
11746
  lastValue,
11046
11747
  lead,
11748
+ least,
11047
11749
  left,
11048
11750
  length,
11049
11751
  like,
@@ -11052,9 +11754,12 @@ function createPooledExecutorFactory(opts) {
11052
11754
  loadBelongsToRelation,
11053
11755
  loadHasManyRelation,
11054
11756
  loadHasOneRelation,
11757
+ localTime,
11758
+ localTimestamp,
11055
11759
  locate,
11056
11760
  log,
11057
11761
  log10,
11762
+ log2,
11058
11763
  logBase,
11059
11764
  lower,
11060
11765
  lpad,
@@ -11062,7 +11767,9 @@ function createPooledExecutorFactory(opts) {
11062
11767
  lte,
11063
11768
  ltrim,
11064
11769
  max,
11770
+ md5,
11065
11771
  min,
11772
+ minute,
11066
11773
  mod,
11067
11774
  month,
11068
11775
  mul,
@@ -11075,12 +11782,15 @@ function createPooledExecutorFactory(opts) {
11075
11782
  notLike,
11076
11783
  now,
11077
11784
  ntile,
11785
+ nullif,
11786
+ octetLength,
11078
11787
  or,
11079
11788
  outerRef,
11080
11789
  pi,
11081
11790
  position,
11082
11791
  pow,
11083
11792
  power,
11793
+ quarter,
11084
11794
  radians,
11085
11795
  rand,
11086
11796
  random,
@@ -11092,18 +11802,25 @@ function createPooledExecutorFactory(opts) {
11092
11802
  renderTypeWithArgs,
11093
11803
  repeat,
11094
11804
  replace,
11805
+ reverse,
11095
11806
  right,
11096
11807
  round,
11097
11808
  rowNumber,
11098
11809
  rowsToQueryResult,
11099
11810
  rpad,
11100
11811
  rtrim,
11812
+ second,
11101
11813
  sel,
11102
11814
  selectFromEntity,
11815
+ sha1,
11816
+ sha2,
11817
+ shiftLeft,
11818
+ shiftRight,
11103
11819
  sign,
11104
11820
  sin,
11105
11821
  space,
11106
11822
  sqrt,
11823
+ stddev,
11107
11824
  sub,
11108
11825
  substr,
11109
11826
  sum,
@@ -11119,6 +11836,7 @@ function createPooledExecutorFactory(opts) {
11119
11836
  upper,
11120
11837
  utcNow,
11121
11838
  valueToOperand,
11839
+ variance,
11122
11840
  visitExpression,
11123
11841
  visitOperand,
11124
11842
  weekOfYear,