sumak 0.0.4 → 0.0.6
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/README.md +409 -5
- package/dist/ast/expression.d.mts +26 -0
- package/dist/ast/expression.mjs +140 -0
- package/dist/ast/nodes.d.mts +309 -0
- package/dist/ast/nodes.mjs +59 -0
- package/dist/ast/transformer.d.mts +10 -0
- package/dist/ast/transformer.mjs +140 -0
- package/dist/ast/typed-expression.d.mts +37 -0
- package/dist/ast/typed-expression.mjs +77 -0
- package/dist/ast/visitor.d.mts +13 -0
- package/dist/ast/visitor.mjs +11 -0
- package/dist/builder/delete.d.mts +20 -0
- package/dist/builder/delete.mjs +113 -0
- package/dist/builder/eb.d.mts +312 -0
- package/dist/builder/eb.mjs +641 -0
- package/dist/builder/expression.d.mts +5 -0
- package/dist/builder/expression.mjs +10 -0
- package/dist/builder/insert.d.mts +40 -0
- package/dist/builder/insert.mjs +146 -0
- package/dist/builder/merge.d.mts +20 -0
- package/dist/builder/merge.mjs +100 -0
- package/dist/builder/raw.d.mts +2 -0
- package/dist/builder/raw.mjs +4 -0
- package/dist/builder/select.d.mts +41 -0
- package/dist/builder/select.mjs +280 -0
- package/dist/builder/typed-delete.d.mts +49 -0
- package/dist/builder/typed-delete.mjs +89 -0
- package/dist/builder/typed-insert.d.mts +86 -0
- package/dist/builder/typed-insert.mjs +159 -0
- package/dist/builder/typed-merge.d.mts +31 -0
- package/dist/builder/typed-merge.mjs +93 -0
- package/dist/builder/typed-select.d.mts +164 -0
- package/dist/builder/typed-select.mjs +309 -0
- package/dist/builder/typed-update.d.mts +59 -0
- package/dist/builder/typed-update.mjs +110 -0
- package/dist/builder/update.d.mts +20 -0
- package/dist/builder/update.mjs +121 -0
- package/dist/dialect/mssql.d.mts +2 -0
- package/dist/dialect/mssql.mjs +9 -0
- package/dist/dialect/mysql.d.mts +2 -0
- package/dist/dialect/mysql.mjs +9 -0
- package/dist/dialect/pg.d.mts +2 -0
- package/dist/dialect/pg.mjs +9 -0
- package/dist/dialect/sqlite.d.mts +2 -0
- package/dist/dialect/sqlite.mjs +9 -0
- package/dist/dialect/types.d.mts +6 -0
- package/dist/dialect/types.mjs +1 -0
- package/dist/errors.d.mts +12 -0
- package/dist/errors.mjs +24 -0
- package/dist/index.d.mts +50 -806
- package/dist/index.mjs +48 -3
- package/dist/mssql.d.mts +2 -2
- package/dist/mssql.mjs +2 -1
- package/dist/mysql.d.mts +2 -2
- package/dist/mysql.mjs +2 -1
- package/dist/pg.d.mts +2 -2
- package/dist/pg.mjs +2 -1
- package/dist/plugin/camel-case.d.mts +11 -0
- package/dist/plugin/camel-case.mjs +16 -0
- package/dist/plugin/hooks.d.mts +72 -0
- package/dist/plugin/hooks.mjs +49 -0
- package/dist/plugin/plugin-manager.d.mts +17 -0
- package/dist/plugin/plugin-manager.mjs +37 -0
- package/dist/plugin/soft-delete.d.mts +27 -0
- package/dist/plugin/soft-delete.mjs +52 -0
- package/dist/plugin/types.d.mts +19 -0
- package/dist/plugin/types.mjs +1 -0
- package/dist/plugin/with-schema.d.mts +21 -0
- package/dist/plugin/with-schema.mjs +53 -0
- package/dist/printer/base.d.mts +49 -0
- package/dist/printer/base.mjs +472 -0
- package/dist/printer/document.d.mts +45 -0
- package/dist/printer/document.mjs +153 -0
- package/dist/printer/formatter.d.mts +5 -0
- package/dist/printer/formatter.mjs +134 -0
- package/dist/printer/mssql.d.mts +10 -0
- package/dist/printer/mssql.mjs +161 -0
- package/dist/printer/mysql.d.mts +8 -0
- package/dist/printer/mysql.mjs +41 -0
- package/dist/printer/pg.d.mts +6 -0
- package/dist/printer/pg.mjs +9 -0
- package/dist/printer/sqlite.d.mts +8 -0
- package/dist/printer/sqlite.mjs +29 -0
- package/dist/printer/types.d.mts +11 -0
- package/dist/printer/types.mjs +1 -0
- package/dist/schema/column.d.mts +52 -0
- package/dist/schema/column.mjs +120 -0
- package/dist/schema/index.d.mts +6 -0
- package/dist/schema/index.mjs +4 -0
- package/dist/schema/table.d.mts +37 -0
- package/dist/schema/table.mjs +7 -0
- package/dist/schema/type-utils.d.mts +46 -0
- package/dist/schema/type-utils.mjs +1 -0
- package/dist/schema/types.d.mts +64 -0
- package/dist/schema/types.mjs +1 -0
- package/dist/schema.d.mts +2 -2
- package/dist/schema.mjs +1 -1
- package/dist/sqlite.d.mts +2 -2
- package/dist/sqlite.mjs +2 -1
- package/dist/sumak.d.mts +110 -0
- package/dist/sumak.mjs +141 -0
- package/dist/types.d.mts +14 -0
- package/dist/types.mjs +1 -0
- package/dist/utils/identifier.d.mts +3 -0
- package/dist/utils/identifier.mjs +14 -0
- package/dist/utils/param.d.mts +2 -0
- package/dist/utils/param.mjs +8 -0
- package/package.json +1 -1
- package/dist/_chunks/base.mjs +0 -1
- package/dist/_chunks/errors.mjs +0 -1
- package/dist/_chunks/index.d.mts +0 -136
- package/dist/_chunks/mssql.d.mts +0 -11
- package/dist/_chunks/mssql.mjs +0 -1
- package/dist/_chunks/mysql.d.mts +0 -9
- package/dist/_chunks/mysql.mjs +0 -1
- package/dist/_chunks/pg.d.mts +0 -7
- package/dist/_chunks/pg.mjs +0 -1
- package/dist/_chunks/schema.mjs +0 -1
- package/dist/_chunks/sqlite.d.mts +0 -9
- package/dist/_chunks/sqlite.mjs +0 -1
- package/dist/_chunks/types.d.mts +0 -338
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
import type { JoinType, OrderDirection, SetOperator } from "../types.mjs";
|
|
2
|
+
export type ASTNode = SelectNode | InsertNode | UpdateNode | DeleteNode | MergeNode | ExplainNode | ExpressionNode;
|
|
3
|
+
export interface ExplainNode {
|
|
4
|
+
type: "explain";
|
|
5
|
+
statement: SelectNode | InsertNode | UpdateNode | DeleteNode;
|
|
6
|
+
analyze?: boolean;
|
|
7
|
+
format?: "TEXT" | "JSON" | "YAML" | "XML";
|
|
8
|
+
}
|
|
9
|
+
export type ExpressionNode = ColumnRefNode | LiteralNode | BinaryOpNode | UnaryOpNode | FunctionCallNode | ParamNode | RawNode | SubqueryNode | BetweenNode | InNode | IsNullNode | CaseNode | CastNode | ExistsNode | StarNode | JsonAccessNode | ArrayExprNode | WindowFunctionNode | AliasedExprNode | FullTextSearchNode | TupleNode;
|
|
10
|
+
export interface ColumnRefNode {
|
|
11
|
+
type: "column_ref";
|
|
12
|
+
table?: string;
|
|
13
|
+
column: string;
|
|
14
|
+
alias?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface LiteralNode {
|
|
17
|
+
type: "literal";
|
|
18
|
+
value: string | number | boolean | null;
|
|
19
|
+
}
|
|
20
|
+
export interface BinaryOpNode {
|
|
21
|
+
type: "binary_op";
|
|
22
|
+
op: string;
|
|
23
|
+
left: ExpressionNode;
|
|
24
|
+
right: ExpressionNode;
|
|
25
|
+
}
|
|
26
|
+
export interface UnaryOpNode {
|
|
27
|
+
type: "unary_op";
|
|
28
|
+
op: string;
|
|
29
|
+
operand: ExpressionNode;
|
|
30
|
+
position: "prefix" | "postfix";
|
|
31
|
+
}
|
|
32
|
+
export interface FunctionCallNode {
|
|
33
|
+
type: "function_call";
|
|
34
|
+
name: string;
|
|
35
|
+
args: ExpressionNode[];
|
|
36
|
+
distinct?: boolean;
|
|
37
|
+
filter?: ExpressionNode;
|
|
38
|
+
orderBy?: OrderByNode[];
|
|
39
|
+
alias?: string;
|
|
40
|
+
}
|
|
41
|
+
export interface ParamNode {
|
|
42
|
+
type: "param";
|
|
43
|
+
index: number;
|
|
44
|
+
value: unknown;
|
|
45
|
+
}
|
|
46
|
+
export interface RawNode {
|
|
47
|
+
type: "raw";
|
|
48
|
+
sql: string;
|
|
49
|
+
params: unknown[];
|
|
50
|
+
}
|
|
51
|
+
export interface SubqueryNode {
|
|
52
|
+
type: "subquery";
|
|
53
|
+
query: SelectNode;
|
|
54
|
+
alias?: string;
|
|
55
|
+
}
|
|
56
|
+
export interface BetweenNode {
|
|
57
|
+
type: "between";
|
|
58
|
+
expr: ExpressionNode;
|
|
59
|
+
low: ExpressionNode;
|
|
60
|
+
high: ExpressionNode;
|
|
61
|
+
negated: boolean;
|
|
62
|
+
symmetric?: boolean;
|
|
63
|
+
}
|
|
64
|
+
export interface InNode {
|
|
65
|
+
type: "in";
|
|
66
|
+
expr: ExpressionNode;
|
|
67
|
+
values: ExpressionNode[] | SelectNode;
|
|
68
|
+
negated: boolean;
|
|
69
|
+
}
|
|
70
|
+
export interface IsNullNode {
|
|
71
|
+
type: "is_null";
|
|
72
|
+
expr: ExpressionNode;
|
|
73
|
+
negated: boolean;
|
|
74
|
+
}
|
|
75
|
+
export interface CaseNode {
|
|
76
|
+
type: "case";
|
|
77
|
+
operand?: ExpressionNode;
|
|
78
|
+
whens: {
|
|
79
|
+
condition: ExpressionNode;
|
|
80
|
+
result: ExpressionNode;
|
|
81
|
+
}[];
|
|
82
|
+
else_?: ExpressionNode;
|
|
83
|
+
}
|
|
84
|
+
export interface CastNode {
|
|
85
|
+
type: "cast";
|
|
86
|
+
expr: ExpressionNode;
|
|
87
|
+
dataType: string;
|
|
88
|
+
}
|
|
89
|
+
export interface ExistsNode {
|
|
90
|
+
type: "exists";
|
|
91
|
+
query: SelectNode;
|
|
92
|
+
negated: boolean;
|
|
93
|
+
}
|
|
94
|
+
export interface StarNode {
|
|
95
|
+
type: "star";
|
|
96
|
+
table?: string;
|
|
97
|
+
}
|
|
98
|
+
export type FullTextSearchMode = "natural" | "boolean" | "expansion";
|
|
99
|
+
export interface FullTextSearchNode {
|
|
100
|
+
type: "full_text_search";
|
|
101
|
+
columns: ExpressionNode[];
|
|
102
|
+
query: ExpressionNode;
|
|
103
|
+
mode?: FullTextSearchMode;
|
|
104
|
+
language?: string;
|
|
105
|
+
alias?: string;
|
|
106
|
+
}
|
|
107
|
+
export interface TupleNode {
|
|
108
|
+
type: "tuple";
|
|
109
|
+
elements: ExpressionNode[];
|
|
110
|
+
}
|
|
111
|
+
export interface AliasedExprNode {
|
|
112
|
+
type: "aliased_expr";
|
|
113
|
+
expr: ExpressionNode;
|
|
114
|
+
alias: string;
|
|
115
|
+
}
|
|
116
|
+
export type TemporalClause = {
|
|
117
|
+
kind: "as_of";
|
|
118
|
+
timestamp: ExpressionNode;
|
|
119
|
+
} | {
|
|
120
|
+
kind: "from_to";
|
|
121
|
+
start: ExpressionNode;
|
|
122
|
+
end: ExpressionNode;
|
|
123
|
+
} | {
|
|
124
|
+
kind: "between";
|
|
125
|
+
start: ExpressionNode;
|
|
126
|
+
end: ExpressionNode;
|
|
127
|
+
} | {
|
|
128
|
+
kind: "contained_in";
|
|
129
|
+
start: ExpressionNode;
|
|
130
|
+
end: ExpressionNode;
|
|
131
|
+
} | {
|
|
132
|
+
kind: "all";
|
|
133
|
+
};
|
|
134
|
+
export interface TableRefNode {
|
|
135
|
+
type: "table_ref";
|
|
136
|
+
name: string;
|
|
137
|
+
alias?: string;
|
|
138
|
+
schema?: string;
|
|
139
|
+
temporal?: TemporalClause;
|
|
140
|
+
}
|
|
141
|
+
export interface JoinNode {
|
|
142
|
+
type: "join";
|
|
143
|
+
joinType: JoinType;
|
|
144
|
+
table: TableRefNode | SubqueryNode;
|
|
145
|
+
on?: ExpressionNode;
|
|
146
|
+
lateral?: boolean;
|
|
147
|
+
}
|
|
148
|
+
export interface JsonAccessNode {
|
|
149
|
+
type: "json_access";
|
|
150
|
+
expr: ExpressionNode;
|
|
151
|
+
path: string;
|
|
152
|
+
operator: "->" | "->>" | "#>" | "#>>";
|
|
153
|
+
alias?: string;
|
|
154
|
+
}
|
|
155
|
+
export interface ArrayExprNode {
|
|
156
|
+
type: "array_expr";
|
|
157
|
+
elements: ExpressionNode[];
|
|
158
|
+
}
|
|
159
|
+
export type FrameKind = "ROWS" | "RANGE" | "GROUPS";
|
|
160
|
+
export type FrameBound = {
|
|
161
|
+
type: "unbounded_preceding";
|
|
162
|
+
} | {
|
|
163
|
+
type: "preceding";
|
|
164
|
+
value: number;
|
|
165
|
+
} | {
|
|
166
|
+
type: "current_row";
|
|
167
|
+
} | {
|
|
168
|
+
type: "following";
|
|
169
|
+
value: number;
|
|
170
|
+
} | {
|
|
171
|
+
type: "unbounded_following";
|
|
172
|
+
};
|
|
173
|
+
export interface FrameSpec {
|
|
174
|
+
kind: FrameKind;
|
|
175
|
+
start: FrameBound;
|
|
176
|
+
end?: FrameBound;
|
|
177
|
+
}
|
|
178
|
+
export interface WindowFunctionNode {
|
|
179
|
+
type: "window_function";
|
|
180
|
+
fn: FunctionCallNode;
|
|
181
|
+
partitionBy: ExpressionNode[];
|
|
182
|
+
orderBy: OrderByNode[];
|
|
183
|
+
frame?: FrameSpec;
|
|
184
|
+
alias?: string;
|
|
185
|
+
}
|
|
186
|
+
export interface OrderByNode {
|
|
187
|
+
expr: ExpressionNode;
|
|
188
|
+
direction: OrderDirection;
|
|
189
|
+
nulls?: "FIRST" | "LAST";
|
|
190
|
+
}
|
|
191
|
+
export interface CTENode {
|
|
192
|
+
name: string;
|
|
193
|
+
query: SelectNode;
|
|
194
|
+
recursive: boolean;
|
|
195
|
+
}
|
|
196
|
+
export interface WindowNode {
|
|
197
|
+
partitionBy: ExpressionNode[];
|
|
198
|
+
orderBy: OrderByNode[];
|
|
199
|
+
}
|
|
200
|
+
export type LockMode = "UPDATE" | "SHARE" | "NO KEY UPDATE" | "KEY SHARE";
|
|
201
|
+
export interface LockClause {
|
|
202
|
+
mode: LockMode;
|
|
203
|
+
skipLocked?: boolean;
|
|
204
|
+
noWait?: boolean;
|
|
205
|
+
}
|
|
206
|
+
export interface SelectNode {
|
|
207
|
+
type: "select";
|
|
208
|
+
distinct: boolean;
|
|
209
|
+
distinctOn?: ExpressionNode[];
|
|
210
|
+
columns: ExpressionNode[];
|
|
211
|
+
from?: TableRefNode | SubqueryNode;
|
|
212
|
+
joins: JoinNode[];
|
|
213
|
+
where?: ExpressionNode;
|
|
214
|
+
groupBy: ExpressionNode[];
|
|
215
|
+
having?: ExpressionNode;
|
|
216
|
+
orderBy: OrderByNode[];
|
|
217
|
+
limit?: ExpressionNode;
|
|
218
|
+
offset?: ExpressionNode;
|
|
219
|
+
ctes: CTENode[];
|
|
220
|
+
setOp?: {
|
|
221
|
+
op: SetOperator;
|
|
222
|
+
query: SelectNode;
|
|
223
|
+
};
|
|
224
|
+
lock?: LockClause;
|
|
225
|
+
}
|
|
226
|
+
export type InsertMode = "INSERT" | "INSERT OR IGNORE" | "INSERT OR REPLACE" | "INSERT OR ABORT" | "INSERT OR ROLLBACK" | "INSERT OR FAIL";
|
|
227
|
+
export interface InsertNode {
|
|
228
|
+
type: "insert";
|
|
229
|
+
insertMode?: InsertMode;
|
|
230
|
+
table: TableRefNode;
|
|
231
|
+
columns: string[];
|
|
232
|
+
values: ExpressionNode[][];
|
|
233
|
+
returning: ExpressionNode[];
|
|
234
|
+
onConflict?: OnConflictNode;
|
|
235
|
+
onDuplicateKeyUpdate?: {
|
|
236
|
+
column: string;
|
|
237
|
+
value: ExpressionNode;
|
|
238
|
+
}[];
|
|
239
|
+
ctes: CTENode[];
|
|
240
|
+
source?: SelectNode;
|
|
241
|
+
defaultValues?: boolean;
|
|
242
|
+
}
|
|
243
|
+
export interface OnConflictNode {
|
|
244
|
+
columns: string[];
|
|
245
|
+
constraint?: string;
|
|
246
|
+
action: "nothing" | {
|
|
247
|
+
set: {
|
|
248
|
+
column: string;
|
|
249
|
+
value: ExpressionNode;
|
|
250
|
+
}[];
|
|
251
|
+
};
|
|
252
|
+
where?: ExpressionNode;
|
|
253
|
+
}
|
|
254
|
+
export interface UpdateNode {
|
|
255
|
+
type: "update";
|
|
256
|
+
table: TableRefNode;
|
|
257
|
+
set: {
|
|
258
|
+
column: string;
|
|
259
|
+
value: ExpressionNode;
|
|
260
|
+
}[];
|
|
261
|
+
where?: ExpressionNode;
|
|
262
|
+
returning: ExpressionNode[];
|
|
263
|
+
from?: TableRefNode;
|
|
264
|
+
joins: JoinNode[];
|
|
265
|
+
ctes: CTENode[];
|
|
266
|
+
orderBy?: OrderByNode[];
|
|
267
|
+
limit?: ExpressionNode;
|
|
268
|
+
}
|
|
269
|
+
export interface DeleteNode {
|
|
270
|
+
type: "delete";
|
|
271
|
+
table: TableRefNode;
|
|
272
|
+
where?: ExpressionNode;
|
|
273
|
+
returning: ExpressionNode[];
|
|
274
|
+
ctes: CTENode[];
|
|
275
|
+
using?: TableRefNode;
|
|
276
|
+
joins: JoinNode[];
|
|
277
|
+
orderBy?: OrderByNode[];
|
|
278
|
+
limit?: ExpressionNode;
|
|
279
|
+
}
|
|
280
|
+
export interface MergeWhenMatched {
|
|
281
|
+
type: "matched";
|
|
282
|
+
condition?: ExpressionNode;
|
|
283
|
+
action: "update" | "delete";
|
|
284
|
+
set?: {
|
|
285
|
+
column: string;
|
|
286
|
+
value: ExpressionNode;
|
|
287
|
+
}[];
|
|
288
|
+
}
|
|
289
|
+
export interface MergeWhenNotMatched {
|
|
290
|
+
type: "not_matched";
|
|
291
|
+
condition?: ExpressionNode;
|
|
292
|
+
columns: string[];
|
|
293
|
+
values: ExpressionNode[];
|
|
294
|
+
}
|
|
295
|
+
export interface MergeNode {
|
|
296
|
+
type: "merge";
|
|
297
|
+
target: TableRefNode;
|
|
298
|
+
source: TableRefNode | SubqueryNode;
|
|
299
|
+
sourceAlias: string;
|
|
300
|
+
on: ExpressionNode;
|
|
301
|
+
whens: (MergeWhenMatched | MergeWhenNotMatched)[];
|
|
302
|
+
ctes: CTENode[];
|
|
303
|
+
}
|
|
304
|
+
export declare function createMergeNode(target: TableRefNode, source: TableRefNode | SubqueryNode, sourceAlias: string, on: ExpressionNode): MergeNode;
|
|
305
|
+
export declare function tableRef(name: string, alias?: string, schema?: string): TableRefNode;
|
|
306
|
+
export declare function createSelectNode(): SelectNode;
|
|
307
|
+
export declare function createInsertNode(table: TableRefNode): InsertNode;
|
|
308
|
+
export declare function createUpdateNode(table: TableRefNode): UpdateNode;
|
|
309
|
+
export declare function createDeleteNode(table: TableRefNode): DeleteNode;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export function createMergeNode(target, source, sourceAlias, on) {
|
|
2
|
+
return {
|
|
3
|
+
type: "merge",
|
|
4
|
+
target,
|
|
5
|
+
source,
|
|
6
|
+
sourceAlias,
|
|
7
|
+
on,
|
|
8
|
+
whens: [],
|
|
9
|
+
ctes: []
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export function tableRef(name, alias, schema) {
|
|
13
|
+
return Object.freeze({
|
|
14
|
+
type: "table_ref",
|
|
15
|
+
name,
|
|
16
|
+
alias,
|
|
17
|
+
schema
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
export function createSelectNode() {
|
|
21
|
+
return {
|
|
22
|
+
type: "select",
|
|
23
|
+
distinct: false,
|
|
24
|
+
columns: [],
|
|
25
|
+
joins: [],
|
|
26
|
+
groupBy: [],
|
|
27
|
+
orderBy: [],
|
|
28
|
+
ctes: []
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export function createInsertNode(table) {
|
|
32
|
+
return {
|
|
33
|
+
type: "insert",
|
|
34
|
+
table,
|
|
35
|
+
columns: [],
|
|
36
|
+
values: [],
|
|
37
|
+
returning: [],
|
|
38
|
+
ctes: []
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export function createUpdateNode(table) {
|
|
42
|
+
return {
|
|
43
|
+
type: "update",
|
|
44
|
+
table,
|
|
45
|
+
set: [],
|
|
46
|
+
returning: [],
|
|
47
|
+
joins: [],
|
|
48
|
+
ctes: []
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export function createDeleteNode(table) {
|
|
52
|
+
return {
|
|
53
|
+
type: "delete",
|
|
54
|
+
table,
|
|
55
|
+
returning: [],
|
|
56
|
+
ctes: [],
|
|
57
|
+
joins: []
|
|
58
|
+
};
|
|
59
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ASTNode, DeleteNode, ExpressionNode, InsertNode, MergeNode, SelectNode, UpdateNode } from "./nodes.mjs";
|
|
2
|
+
export declare class ASTTransformer {
|
|
3
|
+
transform(node: ASTNode): ASTNode;
|
|
4
|
+
transformSelect(node: SelectNode): SelectNode;
|
|
5
|
+
transformInsert(node: InsertNode): InsertNode;
|
|
6
|
+
transformUpdate(node: UpdateNode): UpdateNode;
|
|
7
|
+
transformDelete(node: DeleteNode): DeleteNode;
|
|
8
|
+
transformMerge(node: MergeNode): MergeNode;
|
|
9
|
+
transformExpression(node: ExpressionNode): ExpressionNode;
|
|
10
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
export class ASTTransformer {
|
|
2
|
+
transform(node) {
|
|
3
|
+
switch (node.type) {
|
|
4
|
+
case "select": return this.transformSelect(node);
|
|
5
|
+
case "insert": return this.transformInsert(node);
|
|
6
|
+
case "update": return this.transformUpdate(node);
|
|
7
|
+
case "delete": return this.transformDelete(node);
|
|
8
|
+
case "merge": return this.transformMerge(node);
|
|
9
|
+
case "explain": return {
|
|
10
|
+
...node,
|
|
11
|
+
statement: this.transform(node.statement)
|
|
12
|
+
};
|
|
13
|
+
default: return this.transformExpression(node);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
transformSelect(node) {
|
|
17
|
+
return {
|
|
18
|
+
...node,
|
|
19
|
+
columns: node.columns.map((c) => this.transformExpression(c)),
|
|
20
|
+
where: node.where ? this.transformExpression(node.where) : undefined,
|
|
21
|
+
having: node.having ? this.transformExpression(node.having) : undefined,
|
|
22
|
+
joins: node.joins.map((j) => ({
|
|
23
|
+
...j,
|
|
24
|
+
on: j.on ? this.transformExpression(j.on) : undefined
|
|
25
|
+
})),
|
|
26
|
+
orderBy: node.orderBy.map((o) => ({
|
|
27
|
+
...o,
|
|
28
|
+
expr: this.transformExpression(o.expr)
|
|
29
|
+
}))
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
transformInsert(node) {
|
|
33
|
+
return {
|
|
34
|
+
...node,
|
|
35
|
+
values: node.values.map((row) => row.map((v) => this.transformExpression(v)))
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
transformUpdate(node) {
|
|
39
|
+
return {
|
|
40
|
+
...node,
|
|
41
|
+
set: node.set.map((s) => ({
|
|
42
|
+
...s,
|
|
43
|
+
value: this.transformExpression(s.value)
|
|
44
|
+
})),
|
|
45
|
+
where: node.where ? this.transformExpression(node.where) : undefined
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
transformDelete(node) {
|
|
49
|
+
return {
|
|
50
|
+
...node,
|
|
51
|
+
where: node.where ? this.transformExpression(node.where) : undefined
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
transformMerge(node) {
|
|
55
|
+
return {
|
|
56
|
+
...node,
|
|
57
|
+
on: this.transformExpression(node.on),
|
|
58
|
+
whens: node.whens.map((w) => {
|
|
59
|
+
if (w.type === "matched") {
|
|
60
|
+
return {
|
|
61
|
+
...w,
|
|
62
|
+
condition: w.condition ? this.transformExpression(w.condition) : undefined,
|
|
63
|
+
set: w.set?.map((s) => ({
|
|
64
|
+
...s,
|
|
65
|
+
value: this.transformExpression(s.value)
|
|
66
|
+
}))
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
...w,
|
|
71
|
+
condition: w.condition ? this.transformExpression(w.condition) : undefined,
|
|
72
|
+
values: w.values.map((v) => this.transformExpression(v))
|
|
73
|
+
};
|
|
74
|
+
})
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
transformExpression(node) {
|
|
78
|
+
switch (node.type) {
|
|
79
|
+
case "binary_op": return {
|
|
80
|
+
...node,
|
|
81
|
+
left: this.transformExpression(node.left),
|
|
82
|
+
right: this.transformExpression(node.right)
|
|
83
|
+
};
|
|
84
|
+
case "unary_op": return {
|
|
85
|
+
...node,
|
|
86
|
+
operand: this.transformExpression(node.operand)
|
|
87
|
+
};
|
|
88
|
+
case "function_call": return {
|
|
89
|
+
...node,
|
|
90
|
+
args: node.args.map((a) => this.transformExpression(a))
|
|
91
|
+
};
|
|
92
|
+
case "between": return {
|
|
93
|
+
...node,
|
|
94
|
+
expr: this.transformExpression(node.expr),
|
|
95
|
+
low: this.transformExpression(node.low),
|
|
96
|
+
high: this.transformExpression(node.high)
|
|
97
|
+
};
|
|
98
|
+
case "in": return {
|
|
99
|
+
...node,
|
|
100
|
+
expr: this.transformExpression(node.expr),
|
|
101
|
+
values: Array.isArray(node.values) ? node.values.map((v) => this.transformExpression(v)) : node.values
|
|
102
|
+
};
|
|
103
|
+
case "is_null": return {
|
|
104
|
+
...node,
|
|
105
|
+
expr: this.transformExpression(node.expr)
|
|
106
|
+
};
|
|
107
|
+
case "cast": return {
|
|
108
|
+
...node,
|
|
109
|
+
expr: this.transformExpression(node.expr)
|
|
110
|
+
};
|
|
111
|
+
case "json_access": return {
|
|
112
|
+
...node,
|
|
113
|
+
expr: this.transformExpression(node.expr)
|
|
114
|
+
};
|
|
115
|
+
case "array_expr": return {
|
|
116
|
+
...node,
|
|
117
|
+
elements: node.elements.map((e) => this.transformExpression(e))
|
|
118
|
+
};
|
|
119
|
+
case "window_function": return {
|
|
120
|
+
...node,
|
|
121
|
+
fn: this.transformExpression(node.fn),
|
|
122
|
+
partitionBy: node.partitionBy.map((p) => this.transformExpression(p)),
|
|
123
|
+
orderBy: node.orderBy.map((o) => ({
|
|
124
|
+
...o,
|
|
125
|
+
expr: this.transformExpression(o.expr)
|
|
126
|
+
}))
|
|
127
|
+
};
|
|
128
|
+
case "aliased_expr": return {
|
|
129
|
+
...node,
|
|
130
|
+
expr: this.transformExpression(node.expr)
|
|
131
|
+
};
|
|
132
|
+
case "full_text_search": return {
|
|
133
|
+
...node,
|
|
134
|
+
columns: node.columns.map((c) => this.transformExpression(c)),
|
|
135
|
+
query: this.transformExpression(node.query)
|
|
136
|
+
};
|
|
137
|
+
default: return node;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { ExpressionNode } from "./nodes.mjs";
|
|
2
|
+
/**
|
|
3
|
+
* Type-safe expression wrapper. The T parameter tracks the expression's
|
|
4
|
+
* output type at compile time. At runtime, this is just an ExpressionNode.
|
|
5
|
+
*
|
|
6
|
+
* The `__type` field is a phantom — it never exists at runtime.
|
|
7
|
+
*/
|
|
8
|
+
export interface Expression<T> {
|
|
9
|
+
readonly __type: T;
|
|
10
|
+
readonly node: ExpressionNode;
|
|
11
|
+
}
|
|
12
|
+
/** Unwrap an Expression to its underlying AST node */
|
|
13
|
+
export declare function unwrap<T>(e: Expression<T>): ExpressionNode;
|
|
14
|
+
/** Reference a column — type-safe version */
|
|
15
|
+
export declare function typedCol<T>(column: string, table?: string): Expression<T>;
|
|
16
|
+
/** Wrap a literal value */
|
|
17
|
+
export declare function typedLit<T extends string | number | boolean | null>(value: T): Expression<T>;
|
|
18
|
+
/** Wrap a parameter value */
|
|
19
|
+
export declare function typedParam<T>(index: number, value: T): Expression<T>;
|
|
20
|
+
export declare function typedEq<T>(left: Expression<T>, right: Expression<T>): Expression<boolean>;
|
|
21
|
+
export declare function typedNeq<T>(left: Expression<T>, right: Expression<T>): Expression<boolean>;
|
|
22
|
+
export declare function typedGt<T>(left: Expression<T>, right: Expression<T>): Expression<boolean>;
|
|
23
|
+
export declare function typedGte<T>(left: Expression<T>, right: Expression<T>): Expression<boolean>;
|
|
24
|
+
export declare function typedLt<T>(left: Expression<T>, right: Expression<T>): Expression<boolean>;
|
|
25
|
+
export declare function typedLte<T>(left: Expression<T>, right: Expression<T>): Expression<boolean>;
|
|
26
|
+
export declare function typedLike(left: Expression<string>, right: Expression<string>): Expression<boolean>;
|
|
27
|
+
export declare function typedBetween<T>(value: Expression<T>, low: Expression<T>, high: Expression<T>): Expression<boolean>;
|
|
28
|
+
export declare function typedIn<T>(value: Expression<T>, list: Expression<T>[]): Expression<boolean>;
|
|
29
|
+
export declare function typedIsNull<T>(value: Expression<T>): Expression<boolean>;
|
|
30
|
+
export declare function typedIsNotNull<T>(value: Expression<T>): Expression<boolean>;
|
|
31
|
+
export declare function typedAnd(left: Expression<boolean>, right: Expression<boolean>): Expression<boolean>;
|
|
32
|
+
export declare function typedOr(left: Expression<boolean>, right: Expression<boolean>): Expression<boolean>;
|
|
33
|
+
export declare function typedNot(operand: Expression<boolean>): Expression<boolean>;
|
|
34
|
+
export declare function typedAdd(left: Expression<number>, right: Expression<number>): Expression<number>;
|
|
35
|
+
export declare function typedSub(left: Expression<number>, right: Expression<number>): Expression<number>;
|
|
36
|
+
export declare function typedMul(left: Expression<number>, right: Expression<number>): Expression<number>;
|
|
37
|
+
export declare function typedDiv(left: Expression<number>, right: Expression<number>): Expression<number>;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { and as rawAnd, between as rawBetween, binOp as rawBinOp, col as rawCol, eq as rawEq, gt as rawGt, gte as rawGte, inList as rawInList, isNull as rawIsNull, like as rawLike, lit as rawLit, lt as rawLt, lte as rawLte, neq as rawNeq, not as rawNot, or as rawOr, param as rawParam } from "./expression.mjs";
|
|
2
|
+
function expr(node) {
|
|
3
|
+
return { node };
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export function unwrap(e) {
|
|
7
|
+
return e.node;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function typedCol(column, table) {
|
|
11
|
+
return expr(rawCol(column, table));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function typedLit(value) {
|
|
15
|
+
return expr(rawLit(value));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function typedParam(index, value) {
|
|
19
|
+
return expr(rawParam(index, value));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function typedEq(left, right) {
|
|
23
|
+
return expr(rawEq(left.node, right.node));
|
|
24
|
+
}
|
|
25
|
+
export function typedNeq(left, right) {
|
|
26
|
+
return expr(rawNeq(left.node, right.node));
|
|
27
|
+
}
|
|
28
|
+
export function typedGt(left, right) {
|
|
29
|
+
return expr(rawGt(left.node, right.node));
|
|
30
|
+
}
|
|
31
|
+
export function typedGte(left, right) {
|
|
32
|
+
return expr(rawGte(left.node, right.node));
|
|
33
|
+
}
|
|
34
|
+
export function typedLt(left, right) {
|
|
35
|
+
return expr(rawLt(left.node, right.node));
|
|
36
|
+
}
|
|
37
|
+
export function typedLte(left, right) {
|
|
38
|
+
return expr(rawLte(left.node, right.node));
|
|
39
|
+
}
|
|
40
|
+
export function typedLike(left, right) {
|
|
41
|
+
return expr(rawLike(left.node, right.node));
|
|
42
|
+
}
|
|
43
|
+
export function typedBetween(value, low, high) {
|
|
44
|
+
return expr(rawBetween(value.node, low.node, high.node));
|
|
45
|
+
}
|
|
46
|
+
export function typedIn(value, list) {
|
|
47
|
+
return expr(rawInList(value.node, list.map((e) => e.node)));
|
|
48
|
+
}
|
|
49
|
+
export function typedIsNull(value) {
|
|
50
|
+
return expr(rawIsNull(value.node));
|
|
51
|
+
}
|
|
52
|
+
export function typedIsNotNull(value) {
|
|
53
|
+
return expr(rawIsNull(value.node, true));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function typedAnd(left, right) {
|
|
57
|
+
return expr(rawAnd(left.node, right.node));
|
|
58
|
+
}
|
|
59
|
+
export function typedOr(left, right) {
|
|
60
|
+
return expr(rawOr(left.node, right.node));
|
|
61
|
+
}
|
|
62
|
+
export function typedNot(operand) {
|
|
63
|
+
return expr(rawNot(operand.node));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function typedAdd(left, right) {
|
|
67
|
+
return expr(rawBinOp("+", left.node, right.node));
|
|
68
|
+
}
|
|
69
|
+
export function typedSub(left, right) {
|
|
70
|
+
return expr(rawBinOp("-", left.node, right.node));
|
|
71
|
+
}
|
|
72
|
+
export function typedMul(left, right) {
|
|
73
|
+
return expr(rawBinOp("*", left.node, right.node));
|
|
74
|
+
}
|
|
75
|
+
export function typedDiv(left, right) {
|
|
76
|
+
return expr(rawBinOp("/", left.node, right.node));
|
|
77
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ASTNode, CTENode, DeleteNode, ExpressionNode, InsertNode, JoinNode, MergeNode, OrderByNode, SelectNode, UpdateNode } from "./nodes.mjs";
|
|
2
|
+
export interface ASTVisitor<R = void> {
|
|
3
|
+
visitSelect(node: SelectNode): R;
|
|
4
|
+
visitInsert(node: InsertNode): R;
|
|
5
|
+
visitUpdate(node: UpdateNode): R;
|
|
6
|
+
visitDelete(node: DeleteNode): R;
|
|
7
|
+
visitMerge(node: MergeNode): R;
|
|
8
|
+
visitExpression(node: ExpressionNode): R;
|
|
9
|
+
visitJoin(node: JoinNode): R;
|
|
10
|
+
visitOrderBy(node: OrderByNode): R;
|
|
11
|
+
visitCTE(node: CTENode): R;
|
|
12
|
+
}
|
|
13
|
+
export declare function visitNode<R>(node: ASTNode, visitor: ASTVisitor<R>): R;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function visitNode(node, visitor) {
|
|
2
|
+
switch (node.type) {
|
|
3
|
+
case "select": return visitor.visitSelect(node);
|
|
4
|
+
case "insert": return visitor.visitInsert(node);
|
|
5
|
+
case "update": return visitor.visitUpdate(node);
|
|
6
|
+
case "delete": return visitor.visitDelete(node);
|
|
7
|
+
case "merge": return visitor.visitMerge(node);
|
|
8
|
+
case "explain": return visitNode(node.statement, visitor);
|
|
9
|
+
default: return visitor.visitExpression(node);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { DeleteNode, ExpressionNode, SelectNode, TableRefNode } from "../ast/nodes.mjs";
|
|
2
|
+
import type { JoinType } from "../types.mjs";
|
|
3
|
+
export declare class DeleteBuilder {
|
|
4
|
+
private node;
|
|
5
|
+
constructor(node?: DeleteNode);
|
|
6
|
+
from(table: string | TableRefNode): DeleteBuilder;
|
|
7
|
+
where(expr: ExpressionNode): DeleteBuilder;
|
|
8
|
+
/** USING clause (PG: DELETE FROM t USING other WHERE ...) */
|
|
9
|
+
using(table: string | TableRefNode): DeleteBuilder;
|
|
10
|
+
/** Generic JOIN (MySQL pattern: DELETE t FROM t JOIN other ON ...) */
|
|
11
|
+
join(type: JoinType, table: string | TableRefNode, on?: ExpressionNode): DeleteBuilder;
|
|
12
|
+
innerJoin(table: string | TableRefNode, on: ExpressionNode): DeleteBuilder;
|
|
13
|
+
leftJoin(table: string | TableRefNode, on: ExpressionNode): DeleteBuilder;
|
|
14
|
+
orderBy(expr: string | ExpressionNode, direction?: "ASC" | "DESC"): DeleteBuilder;
|
|
15
|
+
limit(n: ExpressionNode): DeleteBuilder;
|
|
16
|
+
returning(...exprs: ExpressionNode[]): DeleteBuilder;
|
|
17
|
+
with(name: string, query: SelectNode, recursive?: boolean): DeleteBuilder;
|
|
18
|
+
build(): DeleteNode;
|
|
19
|
+
}
|
|
20
|
+
export declare function deleteFrom(table: string | TableRefNode): DeleteBuilder;
|