metal-orm 1.0.56 → 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 +821 -112
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +429 -70
  5. package/dist/index.d.ts +429 -70
  6. package/dist/index.js +785 -112
  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,
@@ -145,18 +155,23 @@ __export(index_exports, {
145
155
  getDecoratorMetadata: () => getDecoratorMetadata,
146
156
  getSchemaIntrospector: () => getSchemaIntrospector,
147
157
  getTableDefFromEntity: () => getTableDefFromEntity,
158
+ greatest: () => greatest,
148
159
  groupConcat: () => groupConcat,
149
160
  gt: () => gt,
150
161
  gte: () => gte,
151
162
  hasMany: () => hasMany,
152
163
  hasOne: () => hasOne,
164
+ hour: () => hour,
153
165
  hydrateRows: () => hydrateRows,
166
+ ifNull: () => ifNull,
154
167
  inList: () => inList,
155
168
  inSubquery: () => inSubquery,
169
+ initcap: () => initcap,
156
170
  instr: () => instr,
157
171
  introspectSchema: () => introspectSchema,
158
172
  isCaseExpressionNode: () => isCaseExpressionNode,
159
173
  isCastExpressionNode: () => isCastExpressionNode,
174
+ isCollateExpressionNode: () => isCollateExpressionNode,
160
175
  isExpressionSelectionNode: () => isExpressionSelectionNode,
161
176
  isFunctionNode: () => isFunctionNode,
162
177
  isNotNull: () => isNotNull,
@@ -164,11 +179,16 @@ __export(index_exports, {
164
179
  isOperandNode: () => isOperandNode,
165
180
  isValueOperandInput: () => isValueOperandInput,
166
181
  isWindowFunctionNode: () => isWindowFunctionNode,
182
+ jsonArrayAgg: () => jsonArrayAgg,
183
+ jsonContains: () => jsonContains,
184
+ jsonLength: () => jsonLength,
167
185
  jsonPath: () => jsonPath,
186
+ jsonSet: () => jsonSet,
168
187
  jsonify: () => jsonify,
169
188
  lag: () => lag,
170
189
  lastValue: () => lastValue,
171
190
  lead: () => lead,
191
+ least: () => least,
172
192
  left: () => left,
173
193
  length: () => length,
174
194
  like: () => like,
@@ -177,9 +197,12 @@ __export(index_exports, {
177
197
  loadBelongsToRelation: () => loadBelongsToRelation,
178
198
  loadHasManyRelation: () => loadHasManyRelation,
179
199
  loadHasOneRelation: () => loadHasOneRelation,
200
+ localTime: () => localTime,
201
+ localTimestamp: () => localTimestamp,
180
202
  locate: () => locate,
181
203
  log: () => log,
182
204
  log10: () => log10,
205
+ log2: () => log2,
183
206
  logBase: () => logBase,
184
207
  lower: () => lower,
185
208
  lpad: () => lpad,
@@ -187,7 +210,9 @@ __export(index_exports, {
187
210
  lte: () => lte,
188
211
  ltrim: () => ltrim,
189
212
  max: () => max,
213
+ md5: () => md5,
190
214
  min: () => min,
215
+ minute: () => minute,
191
216
  mod: () => mod,
192
217
  month: () => month,
193
218
  mul: () => mul,
@@ -200,12 +225,15 @@ __export(index_exports, {
200
225
  notLike: () => notLike,
201
226
  now: () => now,
202
227
  ntile: () => ntile,
228
+ nullif: () => nullif,
229
+ octetLength: () => octetLength,
203
230
  or: () => or,
204
231
  outerRef: () => outerRef,
205
232
  pi: () => pi,
206
233
  position: () => position,
207
234
  pow: () => pow,
208
235
  power: () => power,
236
+ quarter: () => quarter,
209
237
  radians: () => radians,
210
238
  rand: () => rand,
211
239
  random: () => random,
@@ -217,18 +245,25 @@ __export(index_exports, {
217
245
  renderTypeWithArgs: () => renderTypeWithArgs,
218
246
  repeat: () => repeat,
219
247
  replace: () => replace,
248
+ reverse: () => reverse,
220
249
  right: () => right,
221
250
  round: () => round,
222
251
  rowNumber: () => rowNumber,
223
252
  rowsToQueryResult: () => rowsToQueryResult,
224
253
  rpad: () => rpad,
225
254
  rtrim: () => rtrim,
255
+ second: () => second,
226
256
  sel: () => sel,
227
257
  selectFromEntity: () => selectFromEntity,
258
+ sha1: () => sha1,
259
+ sha2: () => sha2,
260
+ shiftLeft: () => shiftLeft,
261
+ shiftRight: () => shiftRight,
228
262
  sign: () => sign,
229
263
  sin: () => sin,
230
264
  space: () => space,
231
265
  sqrt: () => sqrt,
266
+ stddev: () => stddev,
232
267
  sub: () => sub,
233
268
  substr: () => substr,
234
269
  sum: () => sum,
@@ -244,6 +279,7 @@ __export(index_exports, {
244
279
  upper: () => upper,
245
280
  utcNow: () => utcNow,
246
281
  valueToOperand: () => valueToOperand,
282
+ variance: () => variance,
247
283
  visitExpression: () => visitExpression,
248
284
  visitOperand: () => visitOperand,
249
285
  weekOfYear: () => weekOfYear,
@@ -586,7 +622,9 @@ var operandTypes = /* @__PURE__ */ new Set([
586
622
  "CaseExpression",
587
623
  "Cast",
588
624
  "WindowFunction",
589
- "ArithmeticExpression"
625
+ "ArithmeticExpression",
626
+ "BitwiseExpression",
627
+ "Collate"
590
628
  ]);
591
629
  var hasTypeProperty = (value) => typeof value === "object" && value !== null && "type" in value;
592
630
  var isOperandNode = (node) => {
@@ -596,6 +634,7 @@ var isOperandNode = (node) => {
596
634
  var isFunctionNode = (node) => isOperandNode(node) && node.type === "Function";
597
635
  var isCaseExpressionNode = (node) => isOperandNode(node) && node.type === "CaseExpression";
598
636
  var isCastExpressionNode = (node) => isOperandNode(node) && node.type === "Cast";
637
+ var isCollateExpressionNode = (node) => isOperandNode(node) && node.type === "Collate";
599
638
  var isWindowFunctionNode = (node) => isOperandNode(node) && node.type === "WindowFunction";
600
639
  var isExpressionSelectionNode = (node) => isFunctionNode(node) || isCaseExpressionNode(node) || isCastExpressionNode(node) || isWindowFunctionNode(node);
601
640
 
@@ -720,6 +759,17 @@ var add = (left2, right2) => createArithmeticExpression("+", left2, right2);
720
759
  var sub = (left2, right2) => createArithmeticExpression("-", left2, right2);
721
760
  var mul = (left2, right2) => createArithmeticExpression("*", left2, right2);
722
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);
723
773
  var jsonPath = (col2, path) => ({
724
774
  type: "JsonPath",
725
775
  column: columnOperand(col2),
@@ -748,6 +798,11 @@ var notExists = (subquery) => ({
748
798
  operator: "NOT EXISTS",
749
799
  subquery
750
800
  });
801
+ var collate = (expression, collation) => ({
802
+ type: "Collate",
803
+ expression: toOperand(expression),
804
+ collation
805
+ });
751
806
 
752
807
  // src/core/ast/window-functions.ts
753
808
  var buildWindowFunction = (name, args = [], partitionBy, orderBy) => {
@@ -893,6 +948,8 @@ var groupConcat = (col2, options) => ({
893
948
  orderBy: options?.orderBy?.map(toOrderByNode),
894
949
  separator: options?.separator !== void 0 ? valueToOperand(options.separator) : void 0
895
950
  });
951
+ var stddev = buildAggregate("STDDEV");
952
+ var variance = buildAggregate("VARIANCE");
896
953
 
897
954
  // src/core/ast/expression-visitor.ts
898
955
  var DispatcherRegistry = class _DispatcherRegistry {
@@ -966,6 +1023,9 @@ var visitExpression = (node, visitor) => {
966
1023
  case "ArithmeticExpression":
967
1024
  if (visitor.visitArithmeticExpression) return visitor.visitArithmeticExpression(node);
968
1025
  break;
1026
+ case "BitwiseExpression":
1027
+ if (visitor.visitBitwiseExpression) return visitor.visitBitwiseExpression(node);
1028
+ break;
969
1029
  default:
970
1030
  break;
971
1031
  }
@@ -1003,6 +1063,9 @@ var visitOperand = (node, visitor) => {
1003
1063
  case "Cast":
1004
1064
  if (visitor.visitCast) return visitor.visitCast(node);
1005
1065
  break;
1066
+ case "Collate":
1067
+ if (visitor.visitCollate) return visitor.visitCollate(node);
1068
+ break;
1006
1069
  default:
1007
1070
  break;
1008
1071
  }
@@ -1073,62 +1136,337 @@ var derivedTable = (query, alias, columnAliases) => ({
1073
1136
  columnAliases
1074
1137
  });
1075
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
+
1076
1436
  // src/core/functions/standard-strategy.ts
1077
- var StandardFunctionStrategy = class _StandardFunctionStrategy {
1437
+ var StandardFunctionStrategy = class {
1078
1438
  /**
1079
1439
  * Creates a new StandardFunctionStrategy and registers standard functions.
1080
1440
  */
1081
- constructor() {
1082
- this.renderers = /* @__PURE__ */ new Map();
1441
+ constructor(registry2) {
1442
+ this.registry = registry2 ?? new FunctionRegistry();
1083
1443
  this.registerStandard();
1084
1444
  }
1085
1445
  registerStandard() {
1086
- this.add("COUNT", ({ compiledArgs }) => compiledArgs.length ? `COUNT(${compiledArgs.join(", ")})` : "COUNT(*)");
1087
- this.add("SUM", ({ compiledArgs }) => `SUM(${compiledArgs[0]})`);
1088
- this.add("AVG", ({ compiledArgs }) => `AVG(${compiledArgs[0]})`);
1089
- this.add("MIN", ({ compiledArgs }) => `MIN(${compiledArgs[0]})`);
1090
- this.add("MAX", ({ compiledArgs }) => `MAX(${compiledArgs[0]})`);
1091
- this.add("ABS", ({ compiledArgs }) => `ABS(${compiledArgs[0]})`);
1092
- this.add("UPPER", ({ compiledArgs }) => `UPPER(${compiledArgs[0]})`);
1093
- this.add("LOWER", ({ compiledArgs }) => `LOWER(${compiledArgs[0]})`);
1094
- this.add("LENGTH", ({ compiledArgs }) => `LENGTH(${compiledArgs[0]})`);
1095
- this.add("TRIM", ({ compiledArgs }) => `TRIM(${compiledArgs[0]})`);
1096
- this.add("LTRIM", ({ compiledArgs }) => `LTRIM(${compiledArgs[0]})`);
1097
- this.add("RTRIM", ({ compiledArgs }) => `RTRIM(${compiledArgs[0]})`);
1098
- this.add("SUBSTRING", ({ compiledArgs }) => `SUBSTRING(${compiledArgs.join(", ")})`);
1099
- this.add("CONCAT", ({ compiledArgs }) => `CONCAT(${compiledArgs.join(", ")})`);
1100
- this.add("NOW", () => `NOW()`);
1101
- this.add("CURRENT_DATE", () => `CURRENT_DATE`);
1102
- this.add("CURRENT_TIME", () => `CURRENT_TIME`);
1103
- this.add("EXTRACT", ({ compiledArgs }) => `EXTRACT(${compiledArgs[0]} FROM ${compiledArgs[1]})`);
1104
- this.add("YEAR", ({ compiledArgs }) => `EXTRACT(YEAR FROM ${compiledArgs[0]})`);
1105
- this.add("MONTH", ({ compiledArgs }) => `EXTRACT(MONTH FROM ${compiledArgs[0]})`);
1106
- this.add("DAY", ({ compiledArgs }) => `EXTRACT(DAY FROM ${compiledArgs[0]})`);
1107
- this.add("DATE_ADD", ({ compiledArgs }) => `(${compiledArgs[0]} + INTERVAL ${compiledArgs[1]} ${compiledArgs[2]})`);
1108
- this.add("DATE_SUB", ({ compiledArgs }) => `(${compiledArgs[0]} - INTERVAL ${compiledArgs[1]} ${compiledArgs[2]})`);
1109
- this.add("DATE_DIFF", ({ compiledArgs }) => `DATEDIFF(${compiledArgs[0]}, ${compiledArgs[1]})`);
1110
- this.add("DATE_FORMAT", ({ compiledArgs }) => `DATE_FORMAT(${compiledArgs[0]}, ${compiledArgs[1]})`);
1111
- this.add("UNIX_TIMESTAMP", () => `UNIX_TIMESTAMP()`);
1112
- this.add("FROM_UNIXTIME", ({ compiledArgs }) => `FROM_UNIXTIME(${compiledArgs[0]})`);
1113
- this.add("END_OF_MONTH", ({ compiledArgs }) => `LAST_DAY(${compiledArgs[0]})`);
1114
- this.add("DAY_OF_WEEK", ({ compiledArgs }) => `DAYOFWEEK(${compiledArgs[0]})`);
1115
- this.add("WEEK_OF_YEAR", ({ compiledArgs }) => `WEEKOFYEAR(${compiledArgs[0]})`);
1116
- 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);
1117
1452
  this.add("GROUP_CONCAT", (ctx) => this.renderGroupConcat(ctx));
1118
1453
  }
1454
+ registerDefinitions(definitions) {
1455
+ this.registry.register(definitions);
1456
+ }
1119
1457
  /**
1120
1458
  * Registers a renderer for a function name.
1121
1459
  * @param name - The function name.
1122
1460
  * @param renderer - The renderer function.
1123
1461
  */
1124
1462
  add(name, renderer) {
1125
- this.renderers.set(name, renderer);
1463
+ this.registry.add(name, renderer);
1126
1464
  }
1127
1465
  /**
1128
1466
  * @inheritDoc
1129
1467
  */
1130
1468
  getRenderer(name) {
1131
- return this.renderers.get(name);
1469
+ return this.registry.get(name);
1132
1470
  }
1133
1471
  /**
1134
1472
  * Renders the GROUP_CONCAT function with optional ORDER BY and SEPARATOR.
@@ -1136,11 +1474,7 @@ var StandardFunctionStrategy = class _StandardFunctionStrategy {
1136
1474
  * @returns The rendered SQL string.
1137
1475
  */
1138
1476
  renderGroupConcat(ctx) {
1139
- const arg = ctx.compiledArgs[0];
1140
- const orderClause = this.buildOrderByExpression(ctx);
1141
- const orderSegment = orderClause ? ` ${orderClause}` : "";
1142
- const separatorClause = this.formatGroupConcatSeparator(ctx);
1143
- return `GROUP_CONCAT(${arg}${orderSegment}${separatorClause})`;
1477
+ return renderStandardGroupConcat(ctx);
1144
1478
  }
1145
1479
  /**
1146
1480
  * Builds the ORDER BY clause for functions like GROUP_CONCAT.
@@ -1148,19 +1482,7 @@ var StandardFunctionStrategy = class _StandardFunctionStrategy {
1148
1482
  * @returns The ORDER BY SQL clause or empty string.
1149
1483
  */
1150
1484
  buildOrderByExpression(ctx) {
1151
- const orderBy = ctx.node.orderBy;
1152
- if (!orderBy || orderBy.length === 0) {
1153
- return "";
1154
- }
1155
- const parts = orderBy.map((order) => {
1156
- const term = isOperandNode(order.term) ? ctx.compileOperand(order.term) : (() => {
1157
- throw new Error("ORDER BY expressions inside functions must be operands");
1158
- })();
1159
- const collation = order.collation ? ` COLLATE ${order.collation}` : "";
1160
- const nulls = order.nulls ? ` NULLS ${order.nulls}` : "";
1161
- return `${term} ${order.direction}${collation}${nulls}`;
1162
- });
1163
- return `ORDER BY ${parts.join(", ")}`;
1485
+ return buildGroupConcatOrderBy(ctx);
1164
1486
  }
1165
1487
  /**
1166
1488
  * Formats the SEPARATOR clause for GROUP_CONCAT.
@@ -1168,10 +1490,7 @@ var StandardFunctionStrategy = class _StandardFunctionStrategy {
1168
1490
  * @returns The SEPARATOR SQL clause or empty string.
1169
1491
  */
1170
1492
  formatGroupConcatSeparator(ctx) {
1171
- if (!ctx.node.separator) {
1172
- return "";
1173
- }
1174
- return ` SEPARATOR ${ctx.compileOperand(ctx.node.separator)}`;
1493
+ return formatGroupConcatSeparator(ctx);
1175
1494
  }
1176
1495
  /**
1177
1496
  * Gets the separator operand for GROUP_CONCAT, defaulting to comma.
@@ -1179,14 +1498,24 @@ var StandardFunctionStrategy = class _StandardFunctionStrategy {
1179
1498
  * @returns The separator operand.
1180
1499
  */
1181
1500
  getGroupConcatSeparatorOperand(ctx) {
1182
- return ctx.node.separator ?? _StandardFunctionStrategy.DEFAULT_GROUP_CONCAT_SEPARATOR;
1501
+ return getGroupConcatSeparatorOperand(ctx);
1183
1502
  }
1184
1503
  static {
1185
1504
  /** Default separator for GROUP_CONCAT, a comma. */
1186
- this.DEFAULT_GROUP_CONCAT_SEPARATOR = {
1187
- type: "Literal",
1188
- value: ","
1189
- };
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);
1190
1519
  }
1191
1520
  };
1192
1521
 
@@ -1360,10 +1689,11 @@ var Dialect = class _Dialect {
1360
1689
  const combinedCtes = [...normalized.ctes ?? [], ...hoistedCtes];
1361
1690
  return combinedCtes.length ? { ...normalized, ctes: combinedCtes } : normalized;
1362
1691
  }
1363
- constructor(functionStrategy) {
1692
+ constructor(functionStrategy, tableFunctionStrategy) {
1364
1693
  this.expressionCompilers = /* @__PURE__ */ new Map();
1365
1694
  this.operandCompilers = /* @__PURE__ */ new Map();
1366
1695
  this.functionStrategy = functionStrategy || new StandardFunctionStrategy();
1696
+ this.tableFunctionStrategy = tableFunctionStrategy || new StandardTableFunctionStrategy();
1367
1697
  this.registerDefaultOperandCompilers();
1368
1698
  this.registerDefaultExpressionCompilers();
1369
1699
  }
@@ -1372,7 +1702,7 @@ var Dialect = class _Dialect {
1372
1702
  * @param functionStrategy - Optional function strategy
1373
1703
  * @returns New Dialect instance
1374
1704
  */
1375
- static create(functionStrategy) {
1705
+ static create(functionStrategy, tableFunctionStrategy) {
1376
1706
  class TestDialect extends _Dialect {
1377
1707
  constructor() {
1378
1708
  super(...arguments);
@@ -1394,7 +1724,7 @@ var Dialect = class _Dialect {
1394
1724
  throw new Error("Not implemented");
1395
1725
  }
1396
1726
  }
1397
- return new TestDialect(functionStrategy);
1727
+ return new TestDialect(functionStrategy, tableFunctionStrategy);
1398
1728
  }
1399
1729
  /**
1400
1730
  * Registers an expression compiler for a specific node type
@@ -1495,6 +1825,11 @@ var Dialect = class _Dialect {
1495
1825
  const right2 = this.compileOperand(arith.right, ctx);
1496
1826
  return `${left2} ${arith.operator} ${right2}`;
1497
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
+ });
1498
1833
  }
1499
1834
  registerDefaultOperandCompilers() {
1500
1835
  this.registerOperandCompiler("Literal", (literal, ctx) => ctx.addParameter(literal.value));
@@ -1564,6 +1899,15 @@ var Dialect = class _Dialect {
1564
1899
  const right2 = this.compileOperand(node.right, ctx);
1565
1900
  return `(${left2} ${node.operator} ${right2})`;
1566
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
+ });
1567
1911
  }
1568
1912
  // Default fallback, should be overridden by dialects if supported
1569
1913
  compileJsonPath(_node) {
@@ -1596,13 +1940,13 @@ var FunctionTableFormatter = class {
1596
1940
  * @param dialect - The dialect instance for compiling operands.
1597
1941
  * @returns SQL function table expression (e.g., "LATERAL schema.func(args) WITH ORDINALITY AS alias(col1, col2)").
1598
1942
  */
1599
- static format(fn5, ctx, dialect) {
1600
- const schemaPart = this.formatSchema(fn5, dialect);
1601
- const args = this.formatArgs(fn5, ctx, dialect);
1602
- const base = this.formatBase(fn5, schemaPart, args, dialect);
1603
- const lateral = this.formatLateral(fn5);
1604
- const alias = this.formatAlias(fn5, dialect);
1605
- 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);
1606
1950
  return `${lateral}${base}${alias}${colAliases}`;
1607
1951
  }
1608
1952
  /**
@@ -1612,9 +1956,9 @@ var FunctionTableFormatter = class {
1612
1956
  * @returns Schema prefix (e.g., "schema.") or empty string.
1613
1957
  * @internal
1614
1958
  */
1615
- static formatSchema(fn5, dialect) {
1616
- if (!fn5.schema) return "";
1617
- 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;
1618
1962
  return `${quoted}.`;
1619
1963
  }
1620
1964
  /**
@@ -1625,8 +1969,8 @@ var FunctionTableFormatter = class {
1625
1969
  * @returns Comma-separated function arguments.
1626
1970
  * @internal
1627
1971
  */
1628
- static formatArgs(fn5, ctx, dialect) {
1629
- return (fn5.args || []).map((a) => {
1972
+ static formatArgs(fn8, ctx, dialect) {
1973
+ return (fn8.args || []).map((a) => {
1630
1974
  if (ctx && dialect) {
1631
1975
  return dialect.compileOperand(a, ctx);
1632
1976
  }
@@ -1642,10 +1986,9 @@ var FunctionTableFormatter = class {
1642
1986
  * @returns Base function call expression (e.g., "schema.func(args) WITH ORDINALITY").
1643
1987
  * @internal
1644
1988
  */
1645
- static formatBase(fn5, schemaPart, args, dialect) {
1646
- const ordinality = fn5.withOrdinality ? " WITH ORDINALITY" : "";
1647
- const quoted = dialect ? dialect.quoteIdentifier(fn5.name) : fn5.name;
1648
- 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}`;
1649
1992
  }
1650
1993
  /**
1651
1994
  * Formats the LATERAL keyword if present.
@@ -1653,8 +1996,8 @@ var FunctionTableFormatter = class {
1653
1996
  * @returns "LATERAL " or empty string.
1654
1997
  * @internal
1655
1998
  */
1656
- static formatLateral(fn5) {
1657
- return fn5.lateral ? "LATERAL " : "";
1999
+ static formatLateral(fn8) {
2000
+ return fn8.lateral ? "LATERAL " : "";
1658
2001
  }
1659
2002
  /**
1660
2003
  * Formats the table alias for the function table.
@@ -1663,9 +2006,9 @@ var FunctionTableFormatter = class {
1663
2006
  * @returns " AS alias" or empty string.
1664
2007
  * @internal
1665
2008
  */
1666
- static formatAlias(fn5, dialect) {
1667
- if (!fn5.alias) return "";
1668
- 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;
1669
2012
  return ` AS ${quoted}`;
1670
2013
  }
1671
2014
  /**
@@ -1675,9 +2018,9 @@ var FunctionTableFormatter = class {
1675
2018
  * @returns "(col1, col2, ...)" or empty string.
1676
2019
  * @internal
1677
2020
  */
1678
- static formatColumnAliases(fn5, dialect) {
1679
- if (!fn5.columnAliases || !fn5.columnAliases.length) return "";
1680
- 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(", ");
1681
2024
  return `(${aliases})`;
1682
2025
  }
1683
2026
  };
@@ -1945,8 +2288,24 @@ var SqlDialectBase = class extends Dialect {
1945
2288
  }
1946
2289
  return this.compileTableSource(tableSource);
1947
2290
  }
1948
- compileFunctionTable(fn5, ctx) {
1949
- 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);
1950
2309
  }
1951
2310
  compileDerivedTable(table, ctx) {
1952
2311
  if (!table.alias) {
@@ -2105,6 +2464,76 @@ var PostgresFunctionStrategy = class extends StandardFunctionStrategy {
2105
2464
  const separator = ctx.compileOperand(separatorOperand);
2106
2465
  return `STRING_AGG(${arg}, ${separator}${orderSegment})`;
2107
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
+ });
2108
2537
  }
2109
2538
  };
2110
2539
 
@@ -2114,8 +2543,20 @@ var PostgresDialect = class extends SqlDialectBase {
2114
2543
  * Creates a new PostgresDialect instance
2115
2544
  */
2116
2545
  constructor() {
2117
- super(new PostgresFunctionStrategy());
2546
+ super(new PostgresFunctionStrategy(), new PostgresTableFunctionStrategy());
2118
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
+ });
2119
2560
  }
2120
2561
  /**
2121
2562
  * Quotes an identifier using PostgreSQL double-quote syntax
@@ -2224,6 +2665,14 @@ var MysqlFunctionStrategy = class extends StandardFunctionStrategy {
2224
2665
  }
2225
2666
  return `DATE(${date})`;
2226
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
+ });
2227
2676
  }
2228
2677
  };
2229
2678
 
@@ -2356,6 +2805,30 @@ var SqliteFunctionStrategy = class extends StandardFunctionStrategy {
2356
2805
  const separator = ctx.compileOperand(separatorOperand);
2357
2806
  return `GROUP_CONCAT(${arg}, ${separator})`;
2358
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]})`);
2359
2832
  }
2360
2833
  };
2361
2834
 
@@ -2367,6 +2840,22 @@ var SqliteDialect = class extends SqlDialectBase {
2367
2840
  constructor() {
2368
2841
  super(new SqliteFunctionStrategy());
2369
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
+ });
2370
2859
  }
2371
2860
  /**
2372
2861
  * Quotes an identifier using SQLite double-quote syntax
@@ -2491,6 +2980,33 @@ var MssqlFunctionStrategy = class extends StandardFunctionStrategy {
2491
2980
  const withinGroup = orderClause ? ` WITHIN GROUP (${orderClause})` : "";
2492
2981
  return `STRING_AGG(${arg}, ${separator})${withinGroup}`;
2493
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
+ });
2494
3010
  }
2495
3011
  };
2496
3012
 
@@ -4288,6 +4804,17 @@ var hideInternal2 = (obj, keys) => {
4288
4804
  }
4289
4805
  };
4290
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
+ */
4291
4818
  constructor(ctx, meta, root, relationName, relation, rootTable, loader, createEntity, localKey) {
4292
4819
  this.ctx = ctx;
4293
4820
  this.meta = meta;
@@ -4405,6 +4932,17 @@ var hideInternal3 = (obj, keys) => {
4405
4932
  }
4406
4933
  };
4407
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
+ */
4408
4946
  constructor(ctx, meta, root, relationName, relation, rootTable, loader, createEntity, targetKey) {
4409
4947
  this.ctx = ctx;
4410
4948
  this.meta = meta;
@@ -4496,6 +5034,17 @@ var hideInternal4 = (obj, keys) => {
4496
5034
  }
4497
5035
  };
4498
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
+ */
4499
5048
  constructor(ctx, meta, root, relationName, relation, rootTable, loader, createEntity, localKey) {
4500
5049
  this.ctx = ctx;
4501
5050
  this.meta = meta;
@@ -4511,6 +5060,10 @@ var DefaultManyToManyCollection = class {
4511
5060
  hideInternal4(this, ["ctx", "meta", "root", "relationName", "relation", "rootTable", "loader", "createEntity", "localKey"]);
4512
5061
  this.hydrateFromCache();
4513
5062
  }
5063
+ /**
5064
+ * Loads the collection items if not already loaded.
5065
+ * @returns A promise that resolves to the array of target entities.
5066
+ */
4514
5067
  async load() {
4515
5068
  if (this.loaded) return this.items;
4516
5069
  const map = await this.loader();
@@ -4526,9 +5079,18 @@ var DefaultManyToManyCollection = class {
4526
5079
  this.loaded = true;
4527
5080
  return this.items;
4528
5081
  }
5082
+ /**
5083
+ * Returns the currently loaded items.
5084
+ * @returns Array of target entities.
5085
+ */
4529
5086
  getItems() {
4530
5087
  return this.items;
4531
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
+ */
4532
5094
  attach(target) {
4533
5095
  const entity = this.ensureEntity(target);
4534
5096
  const id = this.extractId(entity);
@@ -4548,6 +5110,11 @@ var DefaultManyToManyCollection = class {
4548
5110
  { kind: "attach", entity }
4549
5111
  );
4550
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
+ */
4551
5118
  detach(target) {
4552
5119
  const id = typeof target === "number" || typeof target === "string" ? target : this.extractId(target);
4553
5120
  if (id == null) return;
@@ -4563,6 +5130,11 @@ var DefaultManyToManyCollection = class {
4563
5130
  { kind: "detach", entity: existing }
4564
5131
  );
4565
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
+ */
4566
5138
  async syncByIds(ids) {
4567
5139
  await this.load();
4568
5140
  const normalized = new Set(ids.map((id) => toKey5(id)));
@@ -7791,6 +8363,14 @@ var repeat = (value, count2) => fn("REPEAT", [value, count2]);
7791
8363
  var lpad = (value, len, pad) => fn("LPAD", [value, len, pad]);
7792
8364
  var rpad = (value, len, pad) => fn("RPAD", [value, len, pad]);
7793
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]);
7794
8374
 
7795
8375
  // src/core/ddl/introspect/functions/mssql.ts
7796
8376
  var isColumnReference = (value) => typeof value === "object" && value !== null && !("type" in value) && "name" in value && typeof value.name === "string";
@@ -8349,6 +8929,8 @@ var sqrt = (value) => fn3("SQRT", [value]);
8349
8929
  var tan = (value) => fn3("TAN", [value]);
8350
8930
  var trunc = (value, decimals) => decimals === void 0 ? fn3("TRUNC", [value]) : fn3("TRUNC", [value, decimals]);
8351
8931
  var truncate = (value, decimals) => fn3("TRUNCATE", [value, decimals]);
8932
+ var log2 = (value) => fn3("LOG2", [value]);
8933
+ var cbrt = (value) => fn3("CBRT", [value]);
8352
8934
 
8353
8935
  // src/core/functions/datetime.ts
8354
8936
  var isColumnDef3 = (val) => !!val && typeof val === "object" && "type" in val && "name" in val;
@@ -8360,12 +8942,15 @@ var toOperand4 = (input) => {
8360
8942
  var fn4 = (key, args) => ({
8361
8943
  type: "Function",
8362
8944
  name: key,
8945
+ fn: key,
8363
8946
  args: args.map(toOperand4)
8364
8947
  });
8365
8948
  var now = () => fn4("NOW", []);
8366
8949
  var currentDate = () => fn4("CURRENT_DATE", []);
8367
8950
  var currentTime = () => fn4("CURRENT_TIME", []);
8368
8951
  var utcNow = () => fn4("UTC_NOW", []);
8952
+ var localTime = () => fn4("LOCALTIME", []);
8953
+ var localTimestamp = () => fn4("LOCALTIMESTAMP", []);
8369
8954
  var extract = (part, date) => fn4("EXTRACT", [part, date]);
8370
8955
  var year = (date) => fn4("YEAR", [date]);
8371
8956
  var month = (date) => fn4("MONTH", [date]);
@@ -8380,6 +8965,72 @@ var endOfMonth = (date) => fn4("END_OF_MONTH", [date]);
8380
8965
  var dayOfWeek = (date) => fn4("DAY_OF_WEEK", [date]);
8381
8966
  var weekOfYear = (date) => fn4("WEEK_OF_YEAR", [date]);
8382
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]);
8383
9034
 
8384
9035
  // src/orm/als.ts
8385
9036
  var AsyncLocalStorage = class {
@@ -8459,7 +9110,7 @@ var DefaultNamingStrategy = class {
8459
9110
  * @returns Capitalized table name (handles schema-qualified names)
8460
9111
  */
8461
9112
  tableToSymbol(table) {
8462
- 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;
8463
9114
  if (tableName.includes(".")) {
8464
9115
  return tableName.split(".").map((part) => this.capitalize(part)).join("");
8465
9116
  }
@@ -8615,6 +9266,7 @@ var TypeScriptGenerator = class {
8615
9266
  case "CaseExpression":
8616
9267
  case "WindowFunction":
8617
9268
  case "Cast":
9269
+ case "Collate":
8618
9270
  return this.printOperand(term);
8619
9271
  default:
8620
9272
  return this.printExpression(term);
@@ -8677,6 +9329,9 @@ var TypeScriptGenerator = class {
8677
9329
  visitCast(node) {
8678
9330
  return this.printCastOperand(node);
8679
9331
  }
9332
+ visitCollate(node) {
9333
+ return this.printCollateOperand(node);
9334
+ }
8680
9335
  visitAliasRef(node) {
8681
9336
  return `aliasRef('${node.name}')`;
8682
9337
  }
@@ -8688,12 +9343,12 @@ var TypeScriptGenerator = class {
8688
9343
  printBinaryExpression(binary) {
8689
9344
  const left2 = this.printOperand(binary.left);
8690
9345
  const right2 = this.printOperand(binary.right);
8691
- const fn5 = this.mapOp(binary.operator);
9346
+ const fn8 = this.mapOp(binary.operator);
8692
9347
  const args = [left2, right2];
8693
9348
  if (binary.escape) {
8694
9349
  args.push(this.printOperand(binary.escape));
8695
9350
  }
8696
- return `${fn5}(${args.join(", ")})`;
9351
+ return `${fn8}(${args.join(", ")})`;
8697
9352
  }
8698
9353
  /**
8699
9354
  * Prints a logical expression to TypeScript code
@@ -8722,13 +9377,13 @@ var TypeScriptGenerator = class {
8722
9377
  */
8723
9378
  printInExpression(inExpr) {
8724
9379
  const left2 = this.printOperand(inExpr.left);
8725
- const fn5 = this.mapOp(inExpr.operator);
9380
+ const fn8 = this.mapOp(inExpr.operator);
8726
9381
  if (Array.isArray(inExpr.right)) {
8727
9382
  const values = inExpr.right.map((v) => this.printOperand(v)).join(", ");
8728
- return `${fn5}(${left2}, [${values}])`;
9383
+ return `${fn8}(${left2}, [${values}])`;
8729
9384
  }
8730
9385
  const subquery = this.inlineChain(this.buildSelectLines(inExpr.right.query));
8731
- return `${fn5}(${left2}, (${subquery}))`;
9386
+ return `${fn8}(${left2}, (${subquery}))`;
8732
9387
  }
8733
9388
  /**
8734
9389
  * Prints a null expression to TypeScript code
@@ -8737,8 +9392,8 @@ var TypeScriptGenerator = class {
8737
9392
  */
8738
9393
  printNullExpression(nullExpr) {
8739
9394
  const left2 = this.printOperand(nullExpr.left);
8740
- const fn5 = this.mapOp(nullExpr.operator);
8741
- return `${fn5}(${left2})`;
9395
+ const fn8 = this.mapOp(nullExpr.operator);
9396
+ return `${fn8}(${left2})`;
8742
9397
  }
8743
9398
  /**
8744
9399
  * Prints a BETWEEN expression to TypeScript code
@@ -8782,9 +9437,9 @@ var TypeScriptGenerator = class {
8782
9437
  * @param fn - Function node
8783
9438
  * @returns TypeScript code representation
8784
9439
  */
8785
- printFunctionOperand(fn5) {
8786
- const args = fn5.args.map((a) => this.printOperand(a)).join(", ");
8787
- 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})`;
8788
9443
  }
8789
9444
  /**
8790
9445
  * Prints a JSON path operand to TypeScript code
@@ -8848,6 +9503,9 @@ var TypeScriptGenerator = class {
8848
9503
  const typeLiteral = node.castType.replace(/'/g, "\\'");
8849
9504
  return `cast(${this.printOperand(node.expression)}, '${typeLiteral}')`;
8850
9505
  }
9506
+ printCollateOperand(node) {
9507
+ return `collate(${this.printOperand(node.expression)}, '${node.collation}')`;
9508
+ }
8851
9509
  /**
8852
9510
  * Converts method chain lines to inline format
8853
9511
  * @param lines - Method chain lines
@@ -8878,10 +9536,20 @@ var IdentityMap = class {
8878
9536
  get bucketsMap() {
8879
9537
  return this.buckets;
8880
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
+ */
8881
9545
  getEntity(table, pk) {
8882
9546
  const bucket = this.buckets.get(table.name);
8883
9547
  return bucket?.get(this.toIdentityKey(pk))?.entity;
8884
9548
  }
9549
+ /**
9550
+ * Registers a tracked entity in the identity map.
9551
+ * @param tracked The tracked entity metadata and instance.
9552
+ */
8885
9553
  register(tracked) {
8886
9554
  if (tracked.pk == null) return;
8887
9555
  const bucket = this.buckets.get(tracked.table.name) ?? /* @__PURE__ */ new Map();
@@ -8893,6 +9561,11 @@ var IdentityMap = class {
8893
9561
  const bucket = this.buckets.get(tracked.table.name);
8894
9562
  bucket?.delete(this.toIdentityKey(tracked.pk));
8895
9563
  }
9564
+ /**
9565
+ * Returns all tracked entities for a specific table.
9566
+ * @param table The table definition.
9567
+ * @returns Array of tracked entities.
9568
+ */
8896
9569
  getEntitiesForTable(table) {
8897
9570
  const bucket = this.buckets.get(table.name);
8898
9571
  return bucket ? Array.from(bucket.values()) : [];
@@ -10017,15 +10690,15 @@ var OrmSession = class {
10017
10690
  * @returns The result of the function
10018
10691
  * @throws If the transaction fails
10019
10692
  */
10020
- async transaction(fn5) {
10693
+ async transaction(fn8) {
10021
10694
  if (!this.executor.capabilities.transactions) {
10022
- const result = await fn5(this);
10695
+ const result = await fn8(this);
10023
10696
  await this.commit();
10024
10697
  return result;
10025
10698
  }
10026
10699
  await this.executor.beginTransaction();
10027
10700
  try {
10028
- const result = await fn5(this);
10701
+ const result = await fn8(this);
10029
10702
  await this.flushWithHooks();
10030
10703
  await this.executor.commitTransaction();
10031
10704
  await this.domainEvents.dispatch(this.unitOfWork.getTracked(), this);
@@ -10128,11 +10801,11 @@ var Orm = class {
10128
10801
  * @returns The result of the function
10129
10802
  * @throws If the transaction fails
10130
10803
  */
10131
- async transaction(fn5) {
10804
+ async transaction(fn8) {
10132
10805
  const executor = this.executorFactory.createTransactionalExecutor();
10133
10806
  const session = new OrmSession({ orm: this, executor });
10134
10807
  try {
10135
- return await session.transaction(() => fn5(session));
10808
+ return await session.transaction(() => fn8(session));
10136
10809
  } finally {
10137
10810
  await session.dispose();
10138
10811
  }
@@ -10958,8 +11631,10 @@ function createPooledExecutorFactory(opts) {
10958
11631
  acos,
10959
11632
  add,
10960
11633
  addDomainEvent,
11634
+ age,
10961
11635
  aliasRef,
10962
11636
  and,
11637
+ arrayAppend,
10963
11638
  ascii,
10964
11639
  asin,
10965
11640
  atan,
@@ -10968,16 +11643,24 @@ function createPooledExecutorFactory(opts) {
10968
11643
  belongsTo,
10969
11644
  belongsToMany,
10970
11645
  between,
11646
+ bitAnd,
11647
+ bitLength,
11648
+ bitOr,
11649
+ bitXor,
10971
11650
  bootstrapEntities,
10972
11651
  caseWhen,
10973
11652
  cast,
11653
+ cbrt,
10974
11654
  ceil,
10975
11655
  ceiling,
10976
11656
  char,
10977
11657
  charLength,
11658
+ chr,
10978
11659
  clearExpressionDispatchers,
10979
11660
  clearOperandDispatchers,
11661
+ coalesce,
10980
11662
  col,
11663
+ collate,
10981
11664
  columnOperand,
10982
11665
  concat,
10983
11666
  concatWs,
@@ -11029,18 +11712,23 @@ function createPooledExecutorFactory(opts) {
11029
11712
  getDecoratorMetadata,
11030
11713
  getSchemaIntrospector,
11031
11714
  getTableDefFromEntity,
11715
+ greatest,
11032
11716
  groupConcat,
11033
11717
  gt,
11034
11718
  gte,
11035
11719
  hasMany,
11036
11720
  hasOne,
11721
+ hour,
11037
11722
  hydrateRows,
11723
+ ifNull,
11038
11724
  inList,
11039
11725
  inSubquery,
11726
+ initcap,
11040
11727
  instr,
11041
11728
  introspectSchema,
11042
11729
  isCaseExpressionNode,
11043
11730
  isCastExpressionNode,
11731
+ isCollateExpressionNode,
11044
11732
  isExpressionSelectionNode,
11045
11733
  isFunctionNode,
11046
11734
  isNotNull,
@@ -11048,11 +11736,16 @@ function createPooledExecutorFactory(opts) {
11048
11736
  isOperandNode,
11049
11737
  isValueOperandInput,
11050
11738
  isWindowFunctionNode,
11739
+ jsonArrayAgg,
11740
+ jsonContains,
11741
+ jsonLength,
11051
11742
  jsonPath,
11743
+ jsonSet,
11052
11744
  jsonify,
11053
11745
  lag,
11054
11746
  lastValue,
11055
11747
  lead,
11748
+ least,
11056
11749
  left,
11057
11750
  length,
11058
11751
  like,
@@ -11061,9 +11754,12 @@ function createPooledExecutorFactory(opts) {
11061
11754
  loadBelongsToRelation,
11062
11755
  loadHasManyRelation,
11063
11756
  loadHasOneRelation,
11757
+ localTime,
11758
+ localTimestamp,
11064
11759
  locate,
11065
11760
  log,
11066
11761
  log10,
11762
+ log2,
11067
11763
  logBase,
11068
11764
  lower,
11069
11765
  lpad,
@@ -11071,7 +11767,9 @@ function createPooledExecutorFactory(opts) {
11071
11767
  lte,
11072
11768
  ltrim,
11073
11769
  max,
11770
+ md5,
11074
11771
  min,
11772
+ minute,
11075
11773
  mod,
11076
11774
  month,
11077
11775
  mul,
@@ -11084,12 +11782,15 @@ function createPooledExecutorFactory(opts) {
11084
11782
  notLike,
11085
11783
  now,
11086
11784
  ntile,
11785
+ nullif,
11786
+ octetLength,
11087
11787
  or,
11088
11788
  outerRef,
11089
11789
  pi,
11090
11790
  position,
11091
11791
  pow,
11092
11792
  power,
11793
+ quarter,
11093
11794
  radians,
11094
11795
  rand,
11095
11796
  random,
@@ -11101,18 +11802,25 @@ function createPooledExecutorFactory(opts) {
11101
11802
  renderTypeWithArgs,
11102
11803
  repeat,
11103
11804
  replace,
11805
+ reverse,
11104
11806
  right,
11105
11807
  round,
11106
11808
  rowNumber,
11107
11809
  rowsToQueryResult,
11108
11810
  rpad,
11109
11811
  rtrim,
11812
+ second,
11110
11813
  sel,
11111
11814
  selectFromEntity,
11815
+ sha1,
11816
+ sha2,
11817
+ shiftLeft,
11818
+ shiftRight,
11112
11819
  sign,
11113
11820
  sin,
11114
11821
  space,
11115
11822
  sqrt,
11823
+ stddev,
11116
11824
  sub,
11117
11825
  substr,
11118
11826
  sum,
@@ -11128,6 +11836,7 @@ function createPooledExecutorFactory(opts) {
11128
11836
  upper,
11129
11837
  utcNow,
11130
11838
  valueToOperand,
11839
+ variance,
11131
11840
  visitExpression,
11132
11841
  visitOperand,
11133
11842
  weekOfYear,