metal-orm 1.0.39 → 1.0.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +230 -75
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +71 -24
- package/dist/index.d.ts +71 -24
- package/dist/index.js +225 -75
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/codegen/typescript.ts +60 -3
- package/src/core/ast/aggregate-functions.ts +15 -15
- package/src/core/ast/expression-builders.ts +357 -316
- package/src/core/ast/expression-nodes.ts +208 -186
- package/src/core/ast/expression-visitor.ts +40 -30
- package/src/core/ast/query.ts +142 -132
- package/src/core/ast/window-functions.ts +86 -86
- package/src/core/dialect/abstract.ts +505 -479
- package/src/core/dialect/base/groupby-compiler.ts +6 -6
- package/src/core/dialect/base/orderby-compiler.ts +20 -6
- package/src/core/dialect/base/sql-dialect.ts +154 -136
- package/src/core/dialect/mssql/index.ts +172 -161
- package/src/core/functions/standard-strategy.ts +46 -37
- package/src/query-builder/hydration-manager.ts +93 -79
- package/src/query-builder/query-ast-service.ts +207 -170
- package/src/query-builder/select-query-state.ts +169 -162
- package/src/query-builder/select.ts +15 -23
|
@@ -1,19 +1,28 @@
|
|
|
1
1
|
import type { SelectQueryNode, OrderByNode } from './query.js';
|
|
2
2
|
import { SqlOperator } from '../sql/sql.js';
|
|
3
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
|
|
16
|
-
*/
|
|
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
|
+
*/
|
|
17
26
|
export interface ColumnNode {
|
|
18
27
|
type: 'Column';
|
|
19
28
|
/** Table name the column belongs to */
|
|
@@ -25,10 +34,10 @@ export interface ColumnNode {
|
|
|
25
34
|
/** Optional scope marker (e.g., 'outer' for correlated references) */
|
|
26
35
|
scope?: 'outer' | 'default';
|
|
27
36
|
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* AST node representing a function call
|
|
31
|
-
*/
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* AST node representing a function call
|
|
40
|
+
*/
|
|
32
41
|
export interface FunctionNode {
|
|
33
42
|
type: 'Function';
|
|
34
43
|
/** Function name (e.g., COUNT, SUM) */
|
|
@@ -46,176 +55,189 @@ export interface FunctionNode {
|
|
|
46
55
|
/** Optional DISTINCT modifier */
|
|
47
56
|
distinct?: boolean;
|
|
48
57
|
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* AST node representing a JSON path expression
|
|
52
|
-
*/
|
|
53
|
-
export interface JsonPathNode {
|
|
54
|
-
type: 'JsonPath';
|
|
55
|
-
/** Source column */
|
|
56
|
-
column: ColumnNode;
|
|
57
|
-
/** JSON path expression */
|
|
58
|
-
path: string;
|
|
59
|
-
/** Optional alias for the result */
|
|
60
|
-
alias?: string;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* AST node representing a scalar subquery
|
|
65
|
-
*/
|
|
66
|
-
export interface ScalarSubqueryNode {
|
|
67
|
-
type: 'ScalarSubquery';
|
|
68
|
-
/** Subquery to execute */
|
|
69
|
-
query: SelectQueryNode;
|
|
70
|
-
/** Optional alias for the subquery result */
|
|
71
|
-
alias?: string;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* AST node representing a CASE expression
|
|
76
|
-
*/
|
|
77
|
-
export interface CaseExpressionNode {
|
|
78
|
-
type: 'CaseExpression';
|
|
79
|
-
/** WHEN-THEN conditions */
|
|
80
|
-
conditions: { when: ExpressionNode; then: OperandNode }[];
|
|
81
|
-
/** Optional ELSE clause */
|
|
82
|
-
else?: OperandNode;
|
|
83
|
-
/** Optional alias for the result */
|
|
84
|
-
alias?: string;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* AST node representing a window function
|
|
89
|
-
*/
|
|
90
|
-
export interface WindowFunctionNode {
|
|
91
|
-
type: 'WindowFunction';
|
|
92
|
-
/** Window function name (e.g., ROW_NUMBER, RANK) */
|
|
93
|
-
name: string;
|
|
94
|
-
/** Function arguments */
|
|
95
|
-
args: (ColumnNode | LiteralNode | JsonPathNode)[];
|
|
96
|
-
/** Optional PARTITION BY clause */
|
|
97
|
-
partitionBy?: ColumnNode[];
|
|
98
|
-
/** Optional ORDER BY clause */
|
|
99
|
-
orderBy?: OrderByNode[];
|
|
100
|
-
/** Optional alias for the result */
|
|
101
|
-
alias?: string;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
*
|
|
106
|
-
*/
|
|
107
|
-
export
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
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
|
+
/**
|
|
84
|
+
* AST node representing a CASE expression
|
|
85
|
+
*/
|
|
86
|
+
export interface CaseExpressionNode {
|
|
87
|
+
type: 'CaseExpression';
|
|
88
|
+
/** WHEN-THEN conditions */
|
|
89
|
+
conditions: { when: ExpressionNode; then: OperandNode }[];
|
|
90
|
+
/** Optional ELSE clause */
|
|
91
|
+
else?: OperandNode;
|
|
92
|
+
/** Optional alias for the result */
|
|
93
|
+
alias?: string;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* AST node representing a window function
|
|
98
|
+
*/
|
|
99
|
+
export interface WindowFunctionNode {
|
|
100
|
+
type: 'WindowFunction';
|
|
101
|
+
/** Window function name (e.g., ROW_NUMBER, RANK) */
|
|
102
|
+
name: string;
|
|
103
|
+
/** Function arguments */
|
|
104
|
+
args: (ColumnNode | LiteralNode | JsonPathNode)[];
|
|
105
|
+
/** Optional PARTITION BY clause */
|
|
106
|
+
partitionBy?: ColumnNode[];
|
|
107
|
+
/** Optional ORDER BY clause */
|
|
108
|
+
orderBy?: OrderByNode[];
|
|
109
|
+
/** Optional alias for the result */
|
|
110
|
+
alias?: string;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* AST node representing an arithmetic expression (e.g., a + b)
|
|
115
|
+
*/
|
|
116
|
+
export interface ArithmeticExpressionNode {
|
|
117
|
+
type: 'ArithmeticExpression';
|
|
118
|
+
left: OperandNode;
|
|
119
|
+
operator: '+' | '-' | '*' | '/';
|
|
120
|
+
right: OperandNode;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Union type representing any operand that can be used in expressions
|
|
125
|
+
*/
|
|
126
|
+
export type OperandNode =
|
|
127
|
+
| AliasRefNode
|
|
128
|
+
| ColumnNode
|
|
129
|
+
| LiteralNode
|
|
130
|
+
| FunctionNode
|
|
131
|
+
| JsonPathNode
|
|
132
|
+
| ScalarSubqueryNode
|
|
133
|
+
| CaseExpressionNode
|
|
134
|
+
| WindowFunctionNode;
|
|
135
|
+
|
|
136
|
+
const operandTypes = new Set<OperandNode['type']>([
|
|
137
|
+
'AliasRef',
|
|
138
|
+
'Column',
|
|
139
|
+
'Literal',
|
|
140
|
+
'Function',
|
|
141
|
+
'JsonPath',
|
|
142
|
+
'ScalarSubquery',
|
|
143
|
+
'CaseExpression',
|
|
144
|
+
'WindowFunction'
|
|
145
|
+
]);
|
|
146
|
+
|
|
147
|
+
export const isOperandNode = (node: any): node is OperandNode => node && operandTypes.has(node.type);
|
|
148
|
+
|
|
149
|
+
export const isFunctionNode = (node: any): node is FunctionNode => node?.type === 'Function';
|
|
150
|
+
export const isCaseExpressionNode = (node: any): node is CaseExpressionNode => node?.type === 'CaseExpression';
|
|
151
|
+
export const isWindowFunctionNode = (node: any): node is WindowFunctionNode => node?.type === 'WindowFunction';
|
|
131
152
|
export const isExpressionSelectionNode = (
|
|
132
153
|
node: ColumnRef | FunctionNode | CaseExpressionNode | WindowFunctionNode
|
|
133
154
|
): node is FunctionNode | CaseExpressionNode | WindowFunctionNode =>
|
|
134
155
|
isFunctionNode(node) || isCaseExpressionNode(node) || isWindowFunctionNode(node);
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* AST node representing a binary expression (e.g., column = value)
|
|
138
|
-
*/
|
|
139
|
-
export interface BinaryExpressionNode {
|
|
140
|
-
type: 'BinaryExpression';
|
|
141
|
-
/** Left operand */
|
|
142
|
-
left: OperandNode;
|
|
143
|
-
/** Comparison operator */
|
|
144
|
-
operator: SqlOperator;
|
|
145
|
-
/** Right operand */
|
|
146
|
-
right: OperandNode;
|
|
147
|
-
/** Optional escape character for LIKE expressions */
|
|
148
|
-
escape?: LiteralNode;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* AST node representing a logical expression (AND/OR)
|
|
153
|
-
*/
|
|
154
|
-
export interface LogicalExpressionNode {
|
|
155
|
-
type: 'LogicalExpression';
|
|
156
|
-
/** Logical operator (AND or OR) */
|
|
157
|
-
operator: 'AND' | 'OR';
|
|
158
|
-
/** Operands to combine */
|
|
159
|
-
operands: ExpressionNode[];
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* AST node representing a null check expression
|
|
164
|
-
*/
|
|
165
|
-
export interface NullExpressionNode {
|
|
166
|
-
type: 'NullExpression';
|
|
167
|
-
/** Operand to check for null */
|
|
168
|
-
left: OperandNode;
|
|
169
|
-
/** Null check operator */
|
|
170
|
-
operator: 'IS NULL' | 'IS NOT NULL';
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* AST node representing an IN/NOT IN expression
|
|
175
|
-
*/
|
|
176
|
-
export interface InExpressionNode {
|
|
177
|
-
type: 'InExpression';
|
|
178
|
-
/** Left operand to check */
|
|
179
|
-
left: OperandNode;
|
|
180
|
-
/** IN/NOT IN operator */
|
|
181
|
-
operator: 'IN' | 'NOT IN';
|
|
182
|
-
/** Values to check against */
|
|
183
|
-
right: OperandNode[];
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* AST node representing an EXISTS/NOT EXISTS expression
|
|
188
|
-
*/
|
|
189
|
-
export interface ExistsExpressionNode {
|
|
190
|
-
type: 'ExistsExpression';
|
|
191
|
-
/** EXISTS/NOT EXISTS operator */
|
|
192
|
-
operator: SqlOperator;
|
|
193
|
-
/** Subquery to check */
|
|
194
|
-
subquery: SelectQueryNode;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* AST node representing a BETWEEN/NOT BETWEEN expression
|
|
199
|
-
*/
|
|
200
|
-
export interface BetweenExpressionNode {
|
|
201
|
-
type: 'BetweenExpression';
|
|
202
|
-
/** Operand to check */
|
|
203
|
-
left: OperandNode;
|
|
204
|
-
/** BETWEEN/NOT BETWEEN operator */
|
|
205
|
-
operator: 'BETWEEN' | 'NOT BETWEEN';
|
|
206
|
-
/** Lower bound */
|
|
207
|
-
lower: OperandNode;
|
|
208
|
-
/** Upper bound */
|
|
209
|
-
upper: OperandNode;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Union type representing any supported expression node
|
|
214
|
-
*/
|
|
215
|
-
export type ExpressionNode =
|
|
216
|
-
| BinaryExpressionNode
|
|
217
|
-
| LogicalExpressionNode
|
|
218
|
-
| NullExpressionNode
|
|
219
|
-
| InExpressionNode
|
|
220
|
-
| ExistsExpressionNode
|
|
221
|
-
| BetweenExpressionNode
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* AST node representing a binary expression (e.g., column = value)
|
|
159
|
+
*/
|
|
160
|
+
export interface BinaryExpressionNode {
|
|
161
|
+
type: 'BinaryExpression';
|
|
162
|
+
/** Left operand */
|
|
163
|
+
left: OperandNode;
|
|
164
|
+
/** Comparison operator */
|
|
165
|
+
operator: SqlOperator;
|
|
166
|
+
/** Right operand */
|
|
167
|
+
right: OperandNode;
|
|
168
|
+
/** Optional escape character for LIKE expressions */
|
|
169
|
+
escape?: LiteralNode;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* AST node representing a logical expression (AND/OR)
|
|
174
|
+
*/
|
|
175
|
+
export interface LogicalExpressionNode {
|
|
176
|
+
type: 'LogicalExpression';
|
|
177
|
+
/** Logical operator (AND or OR) */
|
|
178
|
+
operator: 'AND' | 'OR';
|
|
179
|
+
/** Operands to combine */
|
|
180
|
+
operands: ExpressionNode[];
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* AST node representing a null check expression
|
|
185
|
+
*/
|
|
186
|
+
export interface NullExpressionNode {
|
|
187
|
+
type: 'NullExpression';
|
|
188
|
+
/** Operand to check for null */
|
|
189
|
+
left: OperandNode;
|
|
190
|
+
/** Null check operator */
|
|
191
|
+
operator: 'IS NULL' | 'IS NOT NULL';
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* AST node representing an IN/NOT IN expression
|
|
196
|
+
*/
|
|
197
|
+
export interface InExpressionNode {
|
|
198
|
+
type: 'InExpression';
|
|
199
|
+
/** Left operand to check */
|
|
200
|
+
left: OperandNode;
|
|
201
|
+
/** IN/NOT IN operator */
|
|
202
|
+
operator: 'IN' | 'NOT IN';
|
|
203
|
+
/** Values to check against */
|
|
204
|
+
right: OperandNode[];
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* AST node representing an EXISTS/NOT EXISTS expression
|
|
209
|
+
*/
|
|
210
|
+
export interface ExistsExpressionNode {
|
|
211
|
+
type: 'ExistsExpression';
|
|
212
|
+
/** EXISTS/NOT EXISTS operator */
|
|
213
|
+
operator: SqlOperator;
|
|
214
|
+
/** Subquery to check */
|
|
215
|
+
subquery: SelectQueryNode;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* AST node representing a BETWEEN/NOT BETWEEN expression
|
|
220
|
+
*/
|
|
221
|
+
export interface BetweenExpressionNode {
|
|
222
|
+
type: 'BetweenExpression';
|
|
223
|
+
/** Operand to check */
|
|
224
|
+
left: OperandNode;
|
|
225
|
+
/** BETWEEN/NOT BETWEEN operator */
|
|
226
|
+
operator: 'BETWEEN' | 'NOT BETWEEN';
|
|
227
|
+
/** Lower bound */
|
|
228
|
+
lower: OperandNode;
|
|
229
|
+
/** Upper bound */
|
|
230
|
+
upper: OperandNode;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Union type representing any supported expression node
|
|
235
|
+
*/
|
|
236
|
+
export type ExpressionNode =
|
|
237
|
+
| BinaryExpressionNode
|
|
238
|
+
| LogicalExpressionNode
|
|
239
|
+
| NullExpressionNode
|
|
240
|
+
| InExpressionNode
|
|
241
|
+
| ExistsExpressionNode
|
|
242
|
+
| BetweenExpressionNode
|
|
243
|
+
| ArithmeticExpressionNode;
|
|
@@ -1,24 +1,26 @@
|
|
|
1
|
-
import {
|
|
2
|
-
BinaryExpressionNode,
|
|
3
|
-
LogicalExpressionNode,
|
|
4
|
-
NullExpressionNode,
|
|
5
|
-
InExpressionNode,
|
|
6
|
-
ExistsExpressionNode,
|
|
7
|
-
BetweenExpressionNode,
|
|
8
|
-
ExpressionNode,
|
|
9
|
-
OperandNode,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
1
|
+
import {
|
|
2
|
+
BinaryExpressionNode,
|
|
3
|
+
LogicalExpressionNode,
|
|
4
|
+
NullExpressionNode,
|
|
5
|
+
InExpressionNode,
|
|
6
|
+
ExistsExpressionNode,
|
|
7
|
+
BetweenExpressionNode,
|
|
8
|
+
ExpressionNode,
|
|
9
|
+
OperandNode,
|
|
10
|
+
ArithmeticExpressionNode,
|
|
11
|
+
ColumnNode,
|
|
12
|
+
LiteralNode,
|
|
13
|
+
FunctionNode,
|
|
14
|
+
JsonPathNode,
|
|
15
|
+
ScalarSubqueryNode,
|
|
16
|
+
CaseExpressionNode,
|
|
17
|
+
WindowFunctionNode,
|
|
18
|
+
AliasRefNode
|
|
19
|
+
} from './expression-nodes.js';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Visitor for expression nodes
|
|
23
|
+
*/
|
|
22
24
|
export interface ExpressionVisitor<R> {
|
|
23
25
|
visitBinaryExpression?(node: BinaryExpressionNode): R;
|
|
24
26
|
visitLogicalExpression?(node: LogicalExpressionNode): R;
|
|
@@ -26,6 +28,7 @@ export interface ExpressionVisitor<R> {
|
|
|
26
28
|
visitInExpression?(node: InExpressionNode): R;
|
|
27
29
|
visitExistsExpression?(node: ExistsExpressionNode): R;
|
|
28
30
|
visitBetweenExpression?(node: BetweenExpressionNode): R;
|
|
31
|
+
visitArithmeticExpression?(node: ArithmeticExpressionNode): R;
|
|
29
32
|
otherwise?(node: ExpressionNode): R;
|
|
30
33
|
}
|
|
31
34
|
|
|
@@ -40,6 +43,7 @@ export interface OperandVisitor<R> {
|
|
|
40
43
|
visitScalarSubquery?(node: ScalarSubqueryNode): R;
|
|
41
44
|
visitCaseExpression?(node: CaseExpressionNode): R;
|
|
42
45
|
visitWindowFunction?(node: WindowFunctionNode): R;
|
|
46
|
+
visitAliasRef?(node: AliasRefNode): R;
|
|
43
47
|
otherwise?(node: OperandNode): R;
|
|
44
48
|
}
|
|
45
49
|
|
|
@@ -74,12 +78,12 @@ export const clearOperandDispatchers = (): void => operandDispatchers.clear();
|
|
|
74
78
|
const unsupportedExpression = (node: ExpressionNode): never => {
|
|
75
79
|
throw new Error(`Unsupported expression type "${(node as any)?.type ?? 'unknown'}"`);
|
|
76
80
|
};
|
|
77
|
-
|
|
78
|
-
const unsupportedOperand = (node: OperandNode): never => {
|
|
79
|
-
throw new Error(`Unsupported operand type "${(node as any)?.type ?? 'unknown'}"`);
|
|
80
|
-
};
|
|
81
|
-
/**
|
|
82
|
-
* Dispatches an expression node to the visitor
|
|
81
|
+
|
|
82
|
+
const unsupportedOperand = (node: OperandNode): never => {
|
|
83
|
+
throw new Error(`Unsupported operand type "${(node as any)?.type ?? 'unknown'}"`);
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Dispatches an expression node to the visitor
|
|
83
87
|
* @param node - Expression node to visit
|
|
84
88
|
* @param visitor - Visitor implementation
|
|
85
89
|
*/
|
|
@@ -106,15 +110,18 @@ export const visitExpression = <R>(node: ExpressionNode, visitor: ExpressionVisi
|
|
|
106
110
|
case 'BetweenExpression':
|
|
107
111
|
if (visitor.visitBetweenExpression) return visitor.visitBetweenExpression(node);
|
|
108
112
|
break;
|
|
113
|
+
case 'ArithmeticExpression':
|
|
114
|
+
if (visitor.visitArithmeticExpression) return visitor.visitArithmeticExpression(node);
|
|
115
|
+
break;
|
|
109
116
|
default:
|
|
110
117
|
break;
|
|
111
118
|
}
|
|
112
119
|
if (visitor.otherwise) return visitor.otherwise(node);
|
|
113
120
|
return unsupportedExpression(node);
|
|
114
121
|
};
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Dispatches an operand node to the visitor
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Dispatches an operand node to the visitor
|
|
118
125
|
* @param node - Operand node to visit
|
|
119
126
|
* @param visitor - Visitor implementation
|
|
120
127
|
*/
|
|
@@ -144,6 +151,9 @@ export const visitOperand = <R>(node: OperandNode, visitor: OperandVisitor<R>):
|
|
|
144
151
|
case 'WindowFunction':
|
|
145
152
|
if (visitor.visitWindowFunction) return visitor.visitWindowFunction(node);
|
|
146
153
|
break;
|
|
154
|
+
case 'AliasRef':
|
|
155
|
+
if (visitor.visitAliasRef) return visitor.visitAliasRef(node);
|
|
156
|
+
break;
|
|
147
157
|
default:
|
|
148
158
|
break;
|
|
149
159
|
}
|