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
@@ -1,274 +1,305 @@
1
- import type { SelectQueryNode, OrderByNode } from './query.js';
2
- import { SqlOperator } from '../sql/sql.js';
3
- import { ColumnRef } from './types.js';
4
-
5
- /**
6
- * AST node representing a literal value
7
- */
8
- export interface LiteralNode {
9
- type: 'Literal';
10
- /** The literal value (string, number, boolean, or null) */
11
- value: string | number | boolean | null;
12
- }
13
-
14
- /**
15
- * AST node representing a reference to a SELECT alias (for ORDER BY / GROUP BY).
16
- */
17
- export interface AliasRefNode {
18
- type: 'AliasRef';
19
- /** Alias name to reference */
20
- name: string;
21
- }
22
-
23
- /**
24
- * AST node representing a column reference
25
- */
26
- export interface ColumnNode {
27
- type: 'Column';
28
- /** Table name the column belongs to */
29
- table: string;
30
- /** Column name */
31
- name: string;
32
- /** Optional alias for the column */
33
- alias?: string;
34
- /** Optional scope marker (e.g., 'outer' for correlated references) */
35
- scope?: 'outer' | 'default';
36
- }
37
-
38
- /**
39
- * AST node representing a function call
40
- */
41
- export interface FunctionNode {
42
- type: 'Function';
43
- /** Function name (e.g., COUNT, SUM) */
44
- name: string;
45
- /** Optional canonical function key for dialect-aware rendering */
46
- fn?: string;
47
- /** Function arguments */
48
- args: OperandNode[];
49
- /** Optional alias for the function result */
50
- alias?: string;
51
- /** Optional ORDER BY clause used by aggregations like GROUP_CONCAT */
52
- orderBy?: OrderByNode[];
53
- /** Optional separator argument used by GROUP_CONCAT-like functions */
54
- separator?: OperandNode;
55
- /** Optional DISTINCT modifier */
56
- distinct?: boolean;
57
- }
58
-
59
- /**
60
- * AST node representing a JSON path expression
61
- */
62
- export interface JsonPathNode {
63
- type: 'JsonPath';
64
- /** Source column */
65
- column: ColumnNode;
66
- /** JSON path expression */
67
- path: string;
68
- /** Optional alias for the result */
69
- alias?: string;
70
- }
71
-
72
- /**
73
- * AST node representing a scalar subquery
74
- */
75
- export interface ScalarSubqueryNode {
76
- type: 'ScalarSubquery';
77
- /** Subquery to execute */
78
- query: SelectQueryNode;
79
- /** Optional alias for the subquery result */
80
- alias?: string;
81
- }
82
-
83
- export type InExpressionRight = OperandNode[] | ScalarSubqueryNode;
84
-
85
- /**
86
- * AST node representing a CASE expression
87
- */
88
- export interface CaseExpressionNode {
89
- type: 'CaseExpression';
90
- /** WHEN-THEN conditions */
91
- conditions: { when: ExpressionNode; then: OperandNode }[];
92
- /** Optional ELSE clause */
93
- else?: OperandNode;
94
- /** Optional alias for the result */
95
- alias?: string;
96
- }
97
-
98
- /**
99
- * AST node representing a CAST expression (CAST(value AS type)).
100
- */
101
- export interface CastExpressionNode {
102
- type: 'Cast';
103
- /** Expression being cast */
104
- expression: OperandNode;
105
- /** SQL type literal, e.g. "varchar(255)" */
106
- castType: string;
107
- /** Optional alias for the result */
108
- alias?: string;
109
- }
110
-
111
- /**
112
- * AST node representing a window function
113
- */
114
- export interface WindowFunctionNode {
115
- type: 'WindowFunction';
116
- /** Window function name (e.g., ROW_NUMBER, RANK) */
117
- name: string;
118
- /** Function arguments */
119
- args: (ColumnNode | LiteralNode | JsonPathNode)[];
120
- /** Optional PARTITION BY clause */
121
- partitionBy?: ColumnNode[];
122
- /** Optional ORDER BY clause */
123
- orderBy?: OrderByNode[];
124
- /** Optional alias for the result */
125
- alias?: string;
126
- }
127
-
128
- /**
129
- * AST node representing an arithmetic expression (e.g., a + b)
130
- */
131
- export interface ArithmeticExpressionNode {
132
- type: 'ArithmeticExpression';
133
- left: OperandNode;
134
- operator: '+' | '-' | '*' | '/';
135
- right: OperandNode;
136
- }
137
-
138
- /**
139
- * Union type representing any operand that can be used in expressions
140
- */
141
- export type OperandNode =
142
- | AliasRefNode
143
- | ColumnNode
144
- | LiteralNode
145
- | FunctionNode
146
- | JsonPathNode
147
- | ScalarSubqueryNode
148
- | CaseExpressionNode
149
- | CastExpressionNode
150
- | WindowFunctionNode
151
- | ArithmeticExpressionNode;
152
-
153
- const operandTypes = new Set<OperandNode['type']>([
154
- 'AliasRef',
155
- 'Column',
156
- 'Literal',
157
- 'Function',
158
- 'JsonPath',
159
- 'ScalarSubquery',
160
- 'CaseExpression',
161
- 'Cast',
162
- 'WindowFunction',
163
- 'ArithmeticExpression'
164
- ]);
165
-
166
- const hasTypeProperty = (value: unknown): value is { type?: string } =>
167
- typeof value === 'object' && value !== null && 'type' in value;
168
-
169
- export const isOperandNode = (node: unknown): node is OperandNode => {
170
- if (!hasTypeProperty(node)) return false;
171
- return operandTypes.has(node.type as OperandNode['type']);
172
- };
173
-
174
- export const isFunctionNode = (node: unknown): node is FunctionNode =>
175
- isOperandNode(node) && node.type === 'Function';
176
- export const isCaseExpressionNode = (node: unknown): node is CaseExpressionNode =>
177
- isOperandNode(node) && node.type === 'CaseExpression';
178
-
179
- export const isCastExpressionNode = (node: unknown): node is CastExpressionNode =>
180
- isOperandNode(node) && node.type === 'Cast';
181
- export const isWindowFunctionNode = (node: unknown): node is WindowFunctionNode =>
182
- isOperandNode(node) && node.type === 'WindowFunction';
183
- export const isExpressionSelectionNode = (
184
- node: ColumnRef | FunctionNode | CaseExpressionNode | CastExpressionNode | WindowFunctionNode
185
- ): node is FunctionNode | CaseExpressionNode | CastExpressionNode | WindowFunctionNode =>
186
- isFunctionNode(node) || isCaseExpressionNode(node) || isCastExpressionNode(node) || isWindowFunctionNode(node);
187
-
188
- /**
189
- * AST node representing a binary expression (e.g., column = value)
190
- */
191
- export interface BinaryExpressionNode {
192
- type: 'BinaryExpression';
193
- /** Left operand */
194
- left: OperandNode;
195
- /** Comparison operator */
196
- operator: SqlOperator;
197
- /** Right operand */
198
- right: OperandNode;
199
- /** Optional escape character for LIKE expressions */
200
- escape?: LiteralNode;
201
- }
202
-
203
- /**
204
- * AST node representing a logical expression (AND/OR)
205
- */
206
- export interface LogicalExpressionNode {
207
- type: 'LogicalExpression';
208
- /** Logical operator (AND or OR) */
209
- operator: 'AND' | 'OR';
210
- /** Operands to combine */
211
- operands: ExpressionNode[];
212
- }
213
-
214
- /**
215
- * AST node representing a null check expression
216
- */
217
- export interface NullExpressionNode {
218
- type: 'NullExpression';
219
- /** Operand to check for null */
220
- left: OperandNode;
221
- /** Null check operator */
222
- operator: 'IS NULL' | 'IS NOT NULL';
223
- }
224
-
225
- /**
226
- * AST node representing an IN/NOT IN expression
227
- */
228
- export interface InExpressionNode {
229
- type: 'InExpression';
230
- /** Left operand to check */
231
- left: OperandNode;
232
- /** IN/NOT IN operator */
233
- operator: 'IN' | 'NOT IN';
234
- /** Values to check against */
235
- right: InExpressionRight;
236
- }
237
-
238
- /**
239
- * AST node representing an EXISTS/NOT EXISTS expression
240
- */
241
- export interface ExistsExpressionNode {
242
- type: 'ExistsExpression';
243
- /** EXISTS/NOT EXISTS operator */
244
- operator: SqlOperator;
245
- /** Subquery to check */
246
- subquery: SelectQueryNode;
247
- }
248
-
249
- /**
250
- * AST node representing a BETWEEN/NOT BETWEEN expression
251
- */
252
- export interface BetweenExpressionNode {
253
- type: 'BetweenExpression';
254
- /** Operand to check */
255
- left: OperandNode;
256
- /** BETWEEN/NOT BETWEEN operator */
257
- operator: 'BETWEEN' | 'NOT BETWEEN';
258
- /** Lower bound */
259
- lower: OperandNode;
260
- /** Upper bound */
261
- upper: OperandNode;
262
- }
263
-
264
- /**
265
- * Union type representing any supported expression node
266
- */
267
- export type ExpressionNode =
268
- | BinaryExpressionNode
269
- | LogicalExpressionNode
270
- | NullExpressionNode
271
- | InExpressionNode
272
- | ExistsExpressionNode
273
- | BetweenExpressionNode
274
- | ArithmeticExpressionNode;
1
+ import type { SelectQueryNode, OrderByNode } from './query.js';
2
+ import { SqlOperator, BitwiseOperator } from '../sql/sql.js';
3
+ import { ColumnRef } from './types.js';
4
+
5
+ /**
6
+ * AST node representing a literal value
7
+ */
8
+ export interface LiteralNode {
9
+ type: 'Literal';
10
+ /** The literal value (string, number, boolean, or null) */
11
+ value: string | number | boolean | null;
12
+ }
13
+
14
+ /**
15
+ * AST node representing a reference to a SELECT alias (for ORDER BY / GROUP BY).
16
+ */
17
+ export interface AliasRefNode {
18
+ type: 'AliasRef';
19
+ /** Alias name to reference */
20
+ name: string;
21
+ }
22
+
23
+ /**
24
+ * AST node representing a column reference
25
+ */
26
+ export interface ColumnNode {
27
+ type: 'Column';
28
+ /** Table name the column belongs to */
29
+ table: string;
30
+ /** Column name */
31
+ name: string;
32
+ /** Optional alias for the column */
33
+ alias?: string;
34
+ /** Optional scope marker (e.g., 'outer' for correlated references) */
35
+ scope?: 'outer' | 'default';
36
+ }
37
+
38
+ /**
39
+ * AST node representing a function call
40
+ */
41
+ export interface FunctionNode {
42
+ type: 'Function';
43
+ /** Function name (e.g., COUNT, SUM) */
44
+ name: string;
45
+ /** Optional canonical function key for dialect-aware rendering */
46
+ fn?: string;
47
+ /** Function arguments */
48
+ args: OperandNode[];
49
+ /** Optional alias for the function result */
50
+ alias?: string;
51
+ /** Optional ORDER BY clause used by aggregations like GROUP_CONCAT */
52
+ orderBy?: OrderByNode[];
53
+ /** Optional separator argument used by GROUP_CONCAT-like functions */
54
+ separator?: OperandNode;
55
+ /** Optional DISTINCT modifier */
56
+ distinct?: boolean;
57
+ }
58
+
59
+ /**
60
+ * AST node representing a JSON path expression
61
+ */
62
+ export interface JsonPathNode {
63
+ type: 'JsonPath';
64
+ /** Source column */
65
+ column: ColumnNode;
66
+ /** JSON path expression */
67
+ path: string;
68
+ /** Optional alias for the result */
69
+ alias?: string;
70
+ }
71
+
72
+ /**
73
+ * AST node representing a scalar subquery
74
+ */
75
+ export interface ScalarSubqueryNode {
76
+ type: 'ScalarSubquery';
77
+ /** Subquery to execute */
78
+ query: SelectQueryNode;
79
+ /** Optional alias for the subquery result */
80
+ alias?: string;
81
+ }
82
+
83
+ export type InExpressionRight = OperandNode[] | ScalarSubqueryNode;
84
+
85
+ /**
86
+ * AST node representing a CASE expression
87
+ */
88
+ export interface CaseExpressionNode {
89
+ type: 'CaseExpression';
90
+ /** WHEN-THEN conditions */
91
+ conditions: { when: ExpressionNode; then: OperandNode }[];
92
+ /** Optional ELSE clause */
93
+ else?: OperandNode;
94
+ /** Optional alias for the result */
95
+ alias?: string;
96
+ }
97
+
98
+ /**
99
+ * AST node representing a CAST expression (CAST(value AS type)).
100
+ */
101
+ export interface CastExpressionNode {
102
+ type: 'Cast';
103
+ /** Expression being cast */
104
+ expression: OperandNode;
105
+ /** SQL type literal, e.g. "varchar(255)" */
106
+ castType: string;
107
+ /** Optional alias for the result */
108
+ alias?: string;
109
+ }
110
+
111
+ /**
112
+ * AST node representing a COLLATE expression (expression COLLATE collationName).
113
+ */
114
+ export interface CollateExpressionNode {
115
+ type: 'Collate';
116
+ /** Expression to be collated */
117
+ expression: OperandNode;
118
+ /** Collation name */
119
+ collation: string;
120
+ }
121
+
122
+ /**
123
+ * AST node representing a window function
124
+ */
125
+ export interface WindowFunctionNode {
126
+ type: 'WindowFunction';
127
+ /** Window function name (e.g., ROW_NUMBER, RANK) */
128
+ name: string;
129
+ /** Function arguments */
130
+ args: (ColumnNode | LiteralNode | JsonPathNode)[];
131
+ /** Optional PARTITION BY clause */
132
+ partitionBy?: ColumnNode[];
133
+ /** Optional ORDER BY clause */
134
+ orderBy?: OrderByNode[];
135
+ /** Optional alias for the result */
136
+ alias?: string;
137
+ }
138
+
139
+ /**
140
+ * AST node representing an arithmetic expression (e.g., a + b)
141
+ */
142
+ export interface ArithmeticExpressionNode {
143
+ type: 'ArithmeticExpression';
144
+ left: OperandNode;
145
+ operator: '+' | '-' | '*' | '/';
146
+ right: OperandNode;
147
+ }
148
+
149
+ /**
150
+ * Union type representing any operand that can be used in expressions
151
+ */
152
+ export type OperandNode =
153
+ | AliasRefNode
154
+ | ColumnNode
155
+ | LiteralNode
156
+ | FunctionNode
157
+ | JsonPathNode
158
+ | ScalarSubqueryNode
159
+ | CaseExpressionNode
160
+ | CastExpressionNode
161
+ | WindowFunctionNode
162
+ | ArithmeticExpressionNode
163
+ | BitwiseExpressionNode
164
+ | CollateExpressionNode;
165
+
166
+ const operandTypes = new Set<OperandNode['type']>([
167
+ 'AliasRef',
168
+ 'Column',
169
+ 'Literal',
170
+ 'Function',
171
+ 'JsonPath',
172
+ 'ScalarSubquery',
173
+ 'CaseExpression',
174
+ 'Cast',
175
+ 'WindowFunction',
176
+ 'ArithmeticExpression',
177
+ 'BitwiseExpression',
178
+ 'Collate'
179
+ ]);
180
+
181
+ const hasTypeProperty = (value: unknown): value is { type?: string } =>
182
+ typeof value === 'object' && value !== null && 'type' in value;
183
+
184
+ export const isOperandNode = (node: unknown): node is OperandNode => {
185
+ if (!hasTypeProperty(node)) return false;
186
+ return operandTypes.has(node.type as OperandNode['type']);
187
+ };
188
+
189
+ export const isFunctionNode = (node: unknown): node is FunctionNode =>
190
+ isOperandNode(node) && node.type === 'Function';
191
+ export const isCaseExpressionNode = (node: unknown): node is CaseExpressionNode =>
192
+ isOperandNode(node) && node.type === 'CaseExpression';
193
+
194
+ export const isCastExpressionNode = (node: unknown): node is CastExpressionNode =>
195
+ isOperandNode(node) && node.type === 'Cast';
196
+ export const isCollateExpressionNode = (node: unknown): node is CollateExpressionNode =>
197
+ isOperandNode(node) && node.type === 'Collate';
198
+ export const isWindowFunctionNode = (node: unknown): node is WindowFunctionNode =>
199
+ isOperandNode(node) && node.type === 'WindowFunction';
200
+ export const isExpressionSelectionNode = (
201
+ node: ColumnRef | FunctionNode | CaseExpressionNode | CastExpressionNode | WindowFunctionNode
202
+ ): node is FunctionNode | CaseExpressionNode | CastExpressionNode | WindowFunctionNode =>
203
+ isFunctionNode(node) || isCaseExpressionNode(node) || isCastExpressionNode(node) || isWindowFunctionNode(node);
204
+
205
+ /**
206
+ * AST node representing a binary expression (e.g., column = value)
207
+ */
208
+ export interface BinaryExpressionNode {
209
+ type: 'BinaryExpression';
210
+ /** Left operand */
211
+ left: OperandNode;
212
+ /** Comparison operator */
213
+ operator: SqlOperator;
214
+ /** Right operand */
215
+ right: OperandNode;
216
+ /** Optional escape character for LIKE expressions */
217
+ escape?: LiteralNode;
218
+ }
219
+
220
+ /**
221
+ * AST node representing a bitwise expression (e.g., a & b)
222
+ */
223
+ export interface BitwiseExpressionNode {
224
+ type: 'BitwiseExpression';
225
+ /** Left operand */
226
+ left: OperandNode;
227
+ /** Bitwise operator */
228
+ operator: BitwiseOperator;
229
+ /** Right operand */
230
+ right: OperandNode;
231
+ }
232
+
233
+ /**
234
+ * AST node representing a logical expression (AND/OR)
235
+ */
236
+ export interface LogicalExpressionNode {
237
+ type: 'LogicalExpression';
238
+ /** Logical operator (AND or OR) */
239
+ operator: 'AND' | 'OR';
240
+ /** Operands to combine */
241
+ operands: ExpressionNode[];
242
+ }
243
+
244
+ /**
245
+ * AST node representing a null check expression
246
+ */
247
+ export interface NullExpressionNode {
248
+ type: 'NullExpression';
249
+ /** Operand to check for null */
250
+ left: OperandNode;
251
+ /** Null check operator */
252
+ operator: 'IS NULL' | 'IS NOT NULL';
253
+ }
254
+
255
+ /**
256
+ * AST node representing an IN/NOT IN expression
257
+ */
258
+ export interface InExpressionNode {
259
+ type: 'InExpression';
260
+ /** Left operand to check */
261
+ left: OperandNode;
262
+ /** IN/NOT IN operator */
263
+ operator: 'IN' | 'NOT IN';
264
+ /** Values to check against */
265
+ right: InExpressionRight;
266
+ }
267
+
268
+ /**
269
+ * AST node representing an EXISTS/NOT EXISTS expression
270
+ */
271
+ export interface ExistsExpressionNode {
272
+ type: 'ExistsExpression';
273
+ /** EXISTS/NOT EXISTS operator */
274
+ operator: SqlOperator;
275
+ /** Subquery to check */
276
+ subquery: SelectQueryNode;
277
+ }
278
+
279
+ /**
280
+ * AST node representing a BETWEEN/NOT BETWEEN expression
281
+ */
282
+ export interface BetweenExpressionNode {
283
+ type: 'BetweenExpression';
284
+ /** Operand to check */
285
+ left: OperandNode;
286
+ /** BETWEEN/NOT BETWEEN operator */
287
+ operator: 'BETWEEN' | 'NOT BETWEEN';
288
+ /** Lower bound */
289
+ lower: OperandNode;
290
+ /** Upper bound */
291
+ upper: OperandNode;
292
+ }
293
+
294
+ /**
295
+ * Union type representing any supported expression node
296
+ */
297
+ export type ExpressionNode =
298
+ | BinaryExpressionNode
299
+ | LogicalExpressionNode
300
+ | NullExpressionNode
301
+ | InExpressionNode
302
+ | ExistsExpressionNode
303
+ | BetweenExpressionNode
304
+ | ArithmeticExpressionNode
305
+ | BitwiseExpressionNode;
@@ -16,7 +16,9 @@ import {
16
16
  CaseExpressionNode,
17
17
  CastExpressionNode,
18
18
  WindowFunctionNode,
19
- AliasRefNode
19
+ CollateExpressionNode,
20
+ AliasRefNode,
21
+ BitwiseExpressionNode
20
22
  } from './expression-nodes.js';
21
23
 
22
24
  /**
@@ -30,6 +32,7 @@ export interface ExpressionVisitor<R> {
30
32
  visitExistsExpression?(node: ExistsExpressionNode): R;
31
33
  visitBetweenExpression?(node: BetweenExpressionNode): R;
32
34
  visitArithmeticExpression?(node: ArithmeticExpressionNode): R;
35
+ visitBitwiseExpression?(node: BitwiseExpressionNode): R;
33
36
  otherwise?(node: ExpressionNode): R;
34
37
  }
35
38
 
@@ -45,6 +48,7 @@ export interface OperandVisitor<R> {
45
48
  visitCaseExpression?(node: CaseExpressionNode): R;
46
49
  visitCast?(node: CastExpressionNode): R;
47
50
  visitWindowFunction?(node: WindowFunctionNode): R;
51
+ visitCollate?(node: CollateExpressionNode): R;
48
52
  visitAliasRef?(node: AliasRefNode): R;
49
53
  otherwise?(node: OperandNode): R;
50
54
  }
@@ -157,6 +161,9 @@ export const visitExpression = <R>(node: ExpressionNode, visitor: ExpressionVisi
157
161
  case 'ArithmeticExpression':
158
162
  if (visitor.visitArithmeticExpression) return visitor.visitArithmeticExpression(node);
159
163
  break;
164
+ case 'BitwiseExpression':
165
+ if (visitor.visitBitwiseExpression) return visitor.visitBitwiseExpression(node);
166
+ break;
160
167
  default:
161
168
  break;
162
169
  }
@@ -201,6 +208,9 @@ export const visitOperand = <R>(node: OperandNode, visitor: OperandVisitor<R>):
201
208
  case 'Cast':
202
209
  if (visitor.visitCast) return visitor.visitCast(node);
203
210
  break;
211
+ case 'Collate':
212
+ if (visitor.visitCollate) return visitor.visitCollate(node);
213
+ break;
204
214
  default:
205
215
  break;
206
216
  }
@@ -1,3 +1,7 @@
1
+ /**
2
+ * Expression AST nodes and builders.
3
+ * Re-exports components for building and visiting SQL expression trees.
4
+ */
1
5
  export * from './expression-nodes.js';
2
6
  export * from './expression-builders.js';
3
7
  export * from './window-functions.js';
@@ -30,6 +30,9 @@ export interface TableNode {
30
30
  */
31
31
  export interface FunctionTableNode {
32
32
  type: 'FunctionTable';
33
+ // Canonical "intent" for dialect-aware table functions (tvf).
34
+ // If set, compiler resolves via TableFunctionStrategy and can fail fast.
35
+ key?: string;
33
36
  /** Function name */
34
37
  name: string;
35
38
  /** Optional schema for the function (some dialects) */