metal-orm 1.0.89 → 1.0.90

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 (49) hide show
  1. package/dist/index.cjs +2968 -2983
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +765 -246
  4. package/dist/index.d.ts +765 -246
  5. package/dist/index.js +2913 -2975
  6. package/dist/index.js.map +1 -1
  7. package/package.json +3 -2
  8. package/src/codegen/typescript.ts +29 -40
  9. package/src/core/ast/expression-builders.ts +34 -53
  10. package/src/core/ast/expression-nodes.ts +51 -72
  11. package/src/core/ast/expression-visitor.ts +219 -252
  12. package/src/core/ast/expression.ts +20 -21
  13. package/src/core/dialect/abstract.ts +55 -81
  14. package/src/core/execution/db-executor.ts +4 -5
  15. package/src/core/execution/executors/mysql-executor.ts +7 -9
  16. package/src/decorators/bootstrap.ts +11 -8
  17. package/src/dto/apply-filter.ts +281 -0
  18. package/src/dto/dto-types.ts +229 -0
  19. package/src/dto/filter-types.ts +193 -0
  20. package/src/dto/index.ts +97 -0
  21. package/src/dto/openapi/generators/base.ts +29 -0
  22. package/src/dto/openapi/generators/column.ts +34 -0
  23. package/src/dto/openapi/generators/dto.ts +94 -0
  24. package/src/dto/openapi/generators/filter.ts +74 -0
  25. package/src/dto/openapi/generators/nested-dto.ts +532 -0
  26. package/src/dto/openapi/generators/pagination.ts +111 -0
  27. package/src/dto/openapi/generators/relation-filter.ts +210 -0
  28. package/src/dto/openapi/index.ts +17 -0
  29. package/src/dto/openapi/type-mappings.ts +191 -0
  30. package/src/dto/openapi/types.ts +83 -0
  31. package/src/dto/openapi/utilities.ts +45 -0
  32. package/src/dto/pagination-utils.ts +150 -0
  33. package/src/dto/transform.ts +193 -0
  34. package/src/index.ts +67 -65
  35. package/src/orm/unit-of-work.ts +13 -25
  36. package/src/query-builder/query-ast-service.ts +287 -300
  37. package/src/query-builder/relation-filter-utils.ts +159 -160
  38. package/src/query-builder/select.ts +137 -192
  39. package/src/core/ast/ast-validation.ts +0 -19
  40. package/src/core/ast/param-proxy.ts +0 -47
  41. package/src/core/ast/query-visitor.ts +0 -273
  42. package/src/openapi/index.ts +0 -4
  43. package/src/openapi/query-parameters.ts +0 -207
  44. package/src/openapi/schema-extractor-input.ts +0 -193
  45. package/src/openapi/schema-extractor-output.ts +0 -427
  46. package/src/openapi/schema-extractor-utils.ts +0 -110
  47. package/src/openapi/schema-extractor.ts +0 -120
  48. package/src/openapi/schema-types.ts +0 -187
  49. package/src/openapi/type-mappers.ts +0 -227
@@ -1,300 +1,287 @@
1
- import { TableDef } from '../schema/table.js';
2
- import { ColumnDef } from '../schema/column-types.js';
3
- import {
4
- SelectQueryNode,
5
- CommonTableExpressionNode,
6
- SetOperationKind,
7
- SetOperationNode,
8
- TableSourceNode,
9
- OrderingTerm
10
- } from '../core/ast/query.js';
11
- import { buildColumnNode } from '../core/ast/builders.js';
12
- import {
13
- AliasRefNode,
14
- ColumnNode,
15
- ExpressionNode,
16
- FunctionNode,
17
- CaseExpressionNode,
18
- CastExpressionNode,
19
- WindowFunctionNode,
20
- ScalarSubqueryNode,
21
- ParamNode,
22
- and,
23
- isExpressionSelectionNode,
24
- isOperandNode
25
- } from '../core/ast/expression.js';
26
- import { JoinNode } from '../core/ast/join.js';
27
- import { SelectQueryState, ProjectionNode } from './select-query-state.js';
28
- import { OrderDirection } from '../core/sql/sql.js';
29
- import { parseRawColumn } from './raw-column-parser.js';
30
-
31
- /**
32
- * Result of column selection operation
33
- */
34
- export interface ColumnSelectionResult {
35
- /**
36
- * Updated query state
37
- */
38
- state: SelectQueryState;
39
- /**
40
- * Columns that were added
41
- */
42
- addedColumns: ProjectionNode[];
43
- }
44
-
45
- /**
46
- * Service for manipulating query AST (Abstract Syntax Tree)
47
- */
48
- export class QueryAstService {
49
- /**
50
- * Creates a new QueryAstService instance
51
- * @param table - Table definition
52
- * @param state - Current query state
53
- */
54
- constructor(private readonly table: TableDef, private readonly state: SelectQueryState) { }
55
-
56
- /**
57
- * Selects columns for the query
58
- * @param columns - Columns to select (key: alias, value: column definition or expression)
59
- * @returns Column selection result with updated state and added columns
60
- */
61
- select(
62
- columns: Record<string, ColumnDef | FunctionNode | CaseExpressionNode | CastExpressionNode | WindowFunctionNode>
63
- ): ColumnSelectionResult {
64
- const existingAliases = new Set(
65
- this.state.ast.columns.map(c => (c as ColumnNode).alias || (c as ColumnNode).name)
66
- );
67
- const from = this.state.ast.from;
68
- const rootTableName = from.type === 'Table' && from.alias ? from.alias : this.table.name;
69
-
70
- const newCols = Object.entries(columns).reduce<ProjectionNode[]>((acc, [alias, val]) => {
71
- if (existingAliases.has(alias)) return acc;
72
-
73
- if (isExpressionSelectionNode(val)) {
74
- acc.push({ ...(val as FunctionNode | CaseExpressionNode | CastExpressionNode | WindowFunctionNode), alias } as ProjectionNode);
75
- return acc;
76
- }
77
-
78
- const colDef = val as ColumnDef;
79
- const resolvedTable =
80
- colDef.table && colDef.table === this.table.name && from.type === 'Table' && from.alias
81
- ? from.alias
82
- : colDef.table || rootTableName;
83
- acc.push({
84
- type: 'Column',
85
- table: resolvedTable,
86
- name: colDef.name,
87
- alias
88
- } as ColumnNode);
89
- return acc;
90
- }, []);
91
-
92
- const nextState = this.state.withColumns(newCols);
93
- return { state: nextState, addedColumns: newCols };
94
- }
95
-
96
- /**
97
- * Selects raw column expressions (best-effort parser for simple references/functions)
98
- * @param cols - Raw column expressions
99
- * @returns Column selection result with updated state and added columns
100
- */
101
- selectRaw(cols: string[]): ColumnSelectionResult {
102
- const from = this.state.ast.from;
103
- const defaultTable = from.type === 'Table' && from.alias ? from.alias : this.table.name;
104
- const newCols = cols.map(col => parseRawColumn(col, defaultTable, this.state.ast.ctes));
105
- const nextState = this.state.withColumns(newCols);
106
- return { state: nextState, addedColumns: newCols };
107
- }
108
-
109
- /**
110
- * Adds a Common Table Expression (CTE) to the query
111
- * @param name - Name of the CTE
112
- * @param query - Query for the CTE
113
- * @param columns - Optional column names for the CTE
114
- * @param recursive - Whether the CTE is recursive
115
- * @returns Updated query state with CTE
116
- */
117
- withCte(name: string, query: SelectQueryNode, columns?: string[], recursive = false): SelectQueryState {
118
- const cte: CommonTableExpressionNode = {
119
- type: 'CommonTableExpression',
120
- name,
121
- query,
122
- columns,
123
- recursive
124
- };
125
-
126
- return this.state.withCte(cte);
127
- }
128
-
129
- /**
130
- * Adds a set operation (UNION/UNION ALL/INTERSECT/EXCEPT) to the query
131
- * @param operator - Set operator
132
- * @param query - Right-hand side query
133
- * @returns Updated query state with set operation
134
- */
135
- withSetOperation(operator: SetOperationKind, query: SelectQueryNode): SelectQueryState {
136
- const op: SetOperationNode = {
137
- type: 'SetOperation',
138
- operator,
139
- query
140
- };
141
- return this.state.withSetOperation(op);
142
- }
143
-
144
- /**
145
- * Replaces the FROM clause for the current query.
146
- * @param from - Table source to use in the FROM clause
147
- * @returns Updated query state with new FROM
148
- */
149
- withFrom(from: TableSourceNode): SelectQueryState {
150
- return this.state.withFrom(from);
151
- }
152
-
153
- /**
154
- * Selects a subquery as a column
155
- * @param alias - Alias for the subquery
156
- * @param query - Subquery to select
157
- * @returns Updated query state with subquery selection
158
- */
159
- selectSubquery(alias: string, query: SelectQueryNode): SelectQueryState {
160
- const node: ScalarSubqueryNode = { type: 'ScalarSubquery', query, alias };
161
- return this.state.withColumns([node]);
162
- }
163
-
164
- /**
165
- * Adds a JOIN clause to the query
166
- * @param join - Join node to add
167
- * @returns Updated query state with JOIN
168
- */
169
- withJoin(join: JoinNode): SelectQueryState {
170
- return this.state.withJoin(join);
171
- }
172
-
173
- /**
174
- * Adds a WHERE clause to the query
175
- * @param expr - Expression for the WHERE clause
176
- * @returns Updated query state with WHERE clause
177
- */
178
- withWhere(expr: ExpressionNode): SelectQueryState {
179
- const combined = this.combineExpressions(this.state.ast.where, expr);
180
- return this.state.withWhere(combined);
181
- }
182
-
183
- /**
184
- * Adds a GROUP BY clause to the query
185
- * @param col - Column to group by
186
- * @returns Updated query state with GROUP BY clause
187
- */
188
- withGroupBy(col: ColumnDef | OrderingTerm): SelectQueryState {
189
- const term = this.normalizeOrderingTerm(col);
190
- return this.state.withGroupBy([term]);
191
- }
192
-
193
- /**
194
- * Adds a HAVING clause to the query
195
- * @param expr - Expression for the HAVING clause
196
- * @returns Updated query state with HAVING clause
197
- */
198
- withHaving(expr: ExpressionNode): SelectQueryState {
199
- const combined = this.combineExpressions(this.state.ast.having, expr);
200
- return this.state.withHaving(combined);
201
- }
202
-
203
- /**
204
- * Adds an ORDER BY clause to the query
205
- * @param col - Column to order by
206
- * @param direction - Order direction (ASC/DESC)
207
- * @returns Updated query state with ORDER BY clause
208
- */
209
- withOrderBy(
210
- term: ColumnDef | OrderingTerm,
211
- direction: OrderDirection,
212
- nulls?: 'FIRST' | 'LAST',
213
- collation?: string
214
- ): SelectQueryState {
215
- const normalized = this.normalizeOrderingTerm(term);
216
- return this.state.withOrderBy([{ type: 'OrderBy', term: normalized, direction, nulls, collation }]);
217
- }
218
-
219
- /**
220
- * Adds a DISTINCT clause to the query
221
- * @param cols - Columns to make distinct
222
- * @returns Updated query state with DISTINCT clause
223
- */
224
- withDistinct(cols: ColumnNode[]): SelectQueryState {
225
- return this.state.withDistinct(cols);
226
- }
227
-
228
- /**
229
- * Adds a LIMIT clause to the query
230
- * @param limit - Maximum number of rows to return
231
- * @returns Updated query state with LIMIT clause
232
- */
233
- withLimit(limit: number): SelectQueryState {
234
- return this.state.withLimit(limit);
235
- }
236
-
237
- /**
238
- * Adds an OFFSET clause to the query
239
- * @param offset - Number of rows to skip
240
- * @returns Updated query state with OFFSET clause
241
- */
242
- withOffset(offset: number): SelectQueryState {
243
- return this.state.withOffset(offset);
244
- }
245
-
246
- /**
247
- * Combines expressions with AND operator
248
- * @param existing - Existing expression
249
- * @param next - New expression to combine
250
- * @returns Combined expression
251
- */
252
- private combineExpressions(existing: ExpressionNode | undefined, next: ExpressionNode): ExpressionNode {
253
- return existing ? and(existing, next) : next;
254
- }
255
-
256
- /**
257
- * Normalizes an ordering term to a standard OrderingTerm
258
- * @param term - Column definition or ordering term to normalize
259
- * @returns Normalized ordering term
260
- */
261
- private normalizeOrderingTerm(term: ColumnDef | OrderingTerm): OrderingTerm {
262
- const paramNode = this.toParamNode(term);
263
- if (paramNode) {
264
- return paramNode;
265
- }
266
- const from = this.state.ast.from;
267
- const tableRef = from.type === 'Table' && from.alias ? { ...this.table, alias: from.alias } : this.table;
268
- const termType = (term as { type?: string }).type;
269
- if (termType === 'Column') {
270
- return term as ColumnNode;
271
- }
272
- if (termType === 'AliasRef') {
273
- return term as AliasRefNode;
274
- }
275
- if (isOperandNode(term)) {
276
- return term as OrderingTerm;
277
- }
278
- if (
279
- termType === 'BinaryExpression' ||
280
- termType === 'LogicalExpression' ||
281
- termType === 'NullExpression' ||
282
- termType === 'InExpression' ||
283
- termType === 'ExistsExpression' ||
284
- termType === 'BetweenExpression' ||
285
- termType === 'ArithmeticExpression'
286
- ) {
287
- return term as ExpressionNode;
288
- }
289
- return buildColumnNode(tableRef, term as ColumnDef);
290
- }
291
-
292
- private toParamNode(value: unknown): ParamNode | undefined {
293
- if (typeof value !== 'object' || value === null) return undefined;
294
- const type = Object.getOwnPropertyDescriptor(value, 'type')?.value;
295
- if (type !== 'Param') return undefined;
296
- const name = Object.getOwnPropertyDescriptor(value, 'name')?.value;
297
- if (typeof name !== 'string') return undefined;
298
- return { type: 'Param', name };
299
- }
300
- }
1
+ import { TableDef } from '../schema/table.js';
2
+ import { ColumnDef } from '../schema/column-types.js';
3
+ import {
4
+ SelectQueryNode,
5
+ CommonTableExpressionNode,
6
+ SetOperationKind,
7
+ SetOperationNode,
8
+ TableSourceNode,
9
+ OrderingTerm
10
+ } from '../core/ast/query.js';
11
+ import { buildColumnNode } from '../core/ast/builders.js';
12
+ import {
13
+ AliasRefNode,
14
+ ColumnNode,
15
+ ExpressionNode,
16
+ FunctionNode,
17
+ CaseExpressionNode,
18
+ CastExpressionNode,
19
+ WindowFunctionNode,
20
+ ScalarSubqueryNode,
21
+ and,
22
+ isExpressionSelectionNode,
23
+ isOperandNode
24
+ } from '../core/ast/expression.js';
25
+ import { JoinNode } from '../core/ast/join.js';
26
+ import { SelectQueryState, ProjectionNode } from './select-query-state.js';
27
+ import { OrderDirection } from '../core/sql/sql.js';
28
+ import { parseRawColumn } from './raw-column-parser.js';
29
+
30
+ /**
31
+ * Result of column selection operation
32
+ */
33
+ export interface ColumnSelectionResult {
34
+ /**
35
+ * Updated query state
36
+ */
37
+ state: SelectQueryState;
38
+ /**
39
+ * Columns that were added
40
+ */
41
+ addedColumns: ProjectionNode[];
42
+ }
43
+
44
+ /**
45
+ * Service for manipulating query AST (Abstract Syntax Tree)
46
+ */
47
+ export class QueryAstService {
48
+ /**
49
+ * Creates a new QueryAstService instance
50
+ * @param table - Table definition
51
+ * @param state - Current query state
52
+ */
53
+ constructor(private readonly table: TableDef, private readonly state: SelectQueryState) { }
54
+
55
+ /**
56
+ * Selects columns for the query
57
+ * @param columns - Columns to select (key: alias, value: column definition or expression)
58
+ * @returns Column selection result with updated state and added columns
59
+ */
60
+ select(
61
+ columns: Record<string, ColumnDef | FunctionNode | CaseExpressionNode | CastExpressionNode | WindowFunctionNode>
62
+ ): ColumnSelectionResult {
63
+ const existingAliases = new Set(
64
+ this.state.ast.columns.map(c => (c as ColumnNode).alias || (c as ColumnNode).name)
65
+ );
66
+ const from = this.state.ast.from;
67
+ const rootTableName = from.type === 'Table' && from.alias ? from.alias : this.table.name;
68
+
69
+ const newCols = Object.entries(columns).reduce<ProjectionNode[]>((acc, [alias, val]) => {
70
+ if (existingAliases.has(alias)) return acc;
71
+
72
+ if (isExpressionSelectionNode(val)) {
73
+ acc.push({ ...(val as FunctionNode | CaseExpressionNode | CastExpressionNode | WindowFunctionNode), alias } as ProjectionNode);
74
+ return acc;
75
+ }
76
+
77
+ const colDef = val as ColumnDef;
78
+ const resolvedTable =
79
+ colDef.table && colDef.table === this.table.name && from.type === 'Table' && from.alias
80
+ ? from.alias
81
+ : colDef.table || rootTableName;
82
+ acc.push({
83
+ type: 'Column',
84
+ table: resolvedTable,
85
+ name: colDef.name,
86
+ alias
87
+ } as ColumnNode);
88
+ return acc;
89
+ }, []);
90
+
91
+ const nextState = this.state.withColumns(newCols);
92
+ return { state: nextState, addedColumns: newCols };
93
+ }
94
+
95
+ /**
96
+ * Selects raw column expressions (best-effort parser for simple references/functions)
97
+ * @param cols - Raw column expressions
98
+ * @returns Column selection result with updated state and added columns
99
+ */
100
+ selectRaw(cols: string[]): ColumnSelectionResult {
101
+ const from = this.state.ast.from;
102
+ const defaultTable = from.type === 'Table' && from.alias ? from.alias : this.table.name;
103
+ const newCols = cols.map(col => parseRawColumn(col, defaultTable, this.state.ast.ctes));
104
+ const nextState = this.state.withColumns(newCols);
105
+ return { state: nextState, addedColumns: newCols };
106
+ }
107
+
108
+ /**
109
+ * Adds a Common Table Expression (CTE) to the query
110
+ * @param name - Name of the CTE
111
+ * @param query - Query for the CTE
112
+ * @param columns - Optional column names for the CTE
113
+ * @param recursive - Whether the CTE is recursive
114
+ * @returns Updated query state with CTE
115
+ */
116
+ withCte(name: string, query: SelectQueryNode, columns?: string[], recursive = false): SelectQueryState {
117
+ const cte: CommonTableExpressionNode = {
118
+ type: 'CommonTableExpression',
119
+ name,
120
+ query,
121
+ columns,
122
+ recursive
123
+ };
124
+
125
+ return this.state.withCte(cte);
126
+ }
127
+
128
+ /**
129
+ * Adds a set operation (UNION/UNION ALL/INTERSECT/EXCEPT) to the query
130
+ * @param operator - Set operator
131
+ * @param query - Right-hand side query
132
+ * @returns Updated query state with set operation
133
+ */
134
+ withSetOperation(operator: SetOperationKind, query: SelectQueryNode): SelectQueryState {
135
+ const op: SetOperationNode = {
136
+ type: 'SetOperation',
137
+ operator,
138
+ query
139
+ };
140
+ return this.state.withSetOperation(op);
141
+ }
142
+
143
+ /**
144
+ * Replaces the FROM clause for the current query.
145
+ * @param from - Table source to use in the FROM clause
146
+ * @returns Updated query state with new FROM
147
+ */
148
+ withFrom(from: TableSourceNode): SelectQueryState {
149
+ return this.state.withFrom(from);
150
+ }
151
+
152
+ /**
153
+ * Selects a subquery as a column
154
+ * @param alias - Alias for the subquery
155
+ * @param query - Subquery to select
156
+ * @returns Updated query state with subquery selection
157
+ */
158
+ selectSubquery(alias: string, query: SelectQueryNode): SelectQueryState {
159
+ const node: ScalarSubqueryNode = { type: 'ScalarSubquery', query, alias };
160
+ return this.state.withColumns([node]);
161
+ }
162
+
163
+ /**
164
+ * Adds a JOIN clause to the query
165
+ * @param join - Join node to add
166
+ * @returns Updated query state with JOIN
167
+ */
168
+ withJoin(join: JoinNode): SelectQueryState {
169
+ return this.state.withJoin(join);
170
+ }
171
+
172
+ /**
173
+ * Adds a WHERE clause to the query
174
+ * @param expr - Expression for the WHERE clause
175
+ * @returns Updated query state with WHERE clause
176
+ */
177
+ withWhere(expr: ExpressionNode): SelectQueryState {
178
+ const combined = this.combineExpressions(this.state.ast.where, expr);
179
+ return this.state.withWhere(combined);
180
+ }
181
+
182
+ /**
183
+ * Adds a GROUP BY clause to the query
184
+ * @param col - Column to group by
185
+ * @returns Updated query state with GROUP BY clause
186
+ */
187
+ withGroupBy(col: ColumnDef | OrderingTerm): SelectQueryState {
188
+ const term = this.normalizeOrderingTerm(col);
189
+ return this.state.withGroupBy([term]);
190
+ }
191
+
192
+ /**
193
+ * Adds a HAVING clause to the query
194
+ * @param expr - Expression for the HAVING clause
195
+ * @returns Updated query state with HAVING clause
196
+ */
197
+ withHaving(expr: ExpressionNode): SelectQueryState {
198
+ const combined = this.combineExpressions(this.state.ast.having, expr);
199
+ return this.state.withHaving(combined);
200
+ }
201
+
202
+ /**
203
+ * Adds an ORDER BY clause to the query
204
+ * @param col - Column to order by
205
+ * @param direction - Order direction (ASC/DESC)
206
+ * @returns Updated query state with ORDER BY clause
207
+ */
208
+ withOrderBy(
209
+ term: ColumnDef | OrderingTerm,
210
+ direction: OrderDirection,
211
+ nulls?: 'FIRST' | 'LAST',
212
+ collation?: string
213
+ ): SelectQueryState {
214
+ const normalized = this.normalizeOrderingTerm(term);
215
+ return this.state.withOrderBy([{ type: 'OrderBy', term: normalized, direction, nulls, collation }]);
216
+ }
217
+
218
+ /**
219
+ * Adds a DISTINCT clause to the query
220
+ * @param cols - Columns to make distinct
221
+ * @returns Updated query state with DISTINCT clause
222
+ */
223
+ withDistinct(cols: ColumnNode[]): SelectQueryState {
224
+ return this.state.withDistinct(cols);
225
+ }
226
+
227
+ /**
228
+ * Adds a LIMIT clause to the query
229
+ * @param limit - Maximum number of rows to return
230
+ * @returns Updated query state with LIMIT clause
231
+ */
232
+ withLimit(limit: number): SelectQueryState {
233
+ return this.state.withLimit(limit);
234
+ }
235
+
236
+ /**
237
+ * Adds an OFFSET clause to the query
238
+ * @param offset - Number of rows to skip
239
+ * @returns Updated query state with OFFSET clause
240
+ */
241
+ withOffset(offset: number): SelectQueryState {
242
+ return this.state.withOffset(offset);
243
+ }
244
+
245
+ /**
246
+ * Combines expressions with AND operator
247
+ * @param existing - Existing expression
248
+ * @param next - New expression to combine
249
+ * @returns Combined expression
250
+ */
251
+ private combineExpressions(existing: ExpressionNode | undefined, next: ExpressionNode): ExpressionNode {
252
+ return existing ? and(existing, next) : next;
253
+ }
254
+
255
+ /**
256
+ * Normalizes an ordering term to a standard OrderingTerm
257
+ * @param term - Column definition or ordering term to normalize
258
+ * @returns Normalized ordering term
259
+ */
260
+ private normalizeOrderingTerm(term: ColumnDef | OrderingTerm): OrderingTerm {
261
+ const from = this.state.ast.from;
262
+ const tableRef = from.type === 'Table' && from.alias ? { ...this.table, alias: from.alias } : this.table;
263
+ const termType = (term as { type?: string }).type;
264
+ if (termType === 'Column') {
265
+ return term as ColumnNode;
266
+ }
267
+ if (termType === 'AliasRef') {
268
+ return term as AliasRefNode;
269
+ }
270
+ if (isOperandNode(term)) {
271
+ return term as OrderingTerm;
272
+ }
273
+ if (
274
+ termType === 'BinaryExpression' ||
275
+ termType === 'LogicalExpression' ||
276
+ termType === 'NullExpression' ||
277
+ termType === 'InExpression' ||
278
+ termType === 'ExistsExpression' ||
279
+ termType === 'BetweenExpression' ||
280
+ termType === 'ArithmeticExpression'
281
+ ) {
282
+ return term as ExpressionNode;
283
+ }
284
+ return buildColumnNode(tableRef, term as ColumnDef);
285
+ }
286
+
287
+ }