bqsqlparse 0.1.0__py3-none-any.whl
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.
- bqsqlparse/__init__.py +62 -0
- bqsqlparse/errors.py +30 -0
- bqsqlparse/functions.py +159 -0
- bqsqlparse/lexer.py +242 -0
- bqsqlparse/lineage.py +902 -0
- bqsqlparse/nodes.py +728 -0
- bqsqlparse/parser.py +1715 -0
- bqsqlparse/py.typed +0 -0
- bqsqlparse/unparse.py +766 -0
- bqsqlparse-0.1.0.dist-info/METADATA +722 -0
- bqsqlparse-0.1.0.dist-info/RECORD +13 -0
- bqsqlparse-0.1.0.dist-info/WHEEL +4 -0
- bqsqlparse-0.1.0.dist-info/licenses/LICENSE +21 -0
bqsqlparse/nodes.py
ADDED
|
@@ -0,0 +1,728 @@
|
|
|
1
|
+
"""AST node definitions for bqsqlparse.
|
|
2
|
+
|
|
3
|
+
Every node is a dataclass inheriting from :class:`Node`, which provides
|
|
4
|
+
generic child iteration (``children``), tree walking (``walk``) and SQL
|
|
5
|
+
re-generation (``sql``).
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from dataclasses import dataclass, field, fields
|
|
11
|
+
from typing import Iterator, List, Optional, Tuple, Union
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Node:
|
|
15
|
+
"""Base class for all AST nodes."""
|
|
16
|
+
|
|
17
|
+
def children(self) -> Iterator["Node"]:
|
|
18
|
+
for f in fields(self): # type: ignore[arg-type]
|
|
19
|
+
v = getattr(self, f.name)
|
|
20
|
+
if isinstance(v, Node):
|
|
21
|
+
yield v
|
|
22
|
+
elif isinstance(v, (list, tuple)):
|
|
23
|
+
for x in v:
|
|
24
|
+
if isinstance(x, Node):
|
|
25
|
+
yield x
|
|
26
|
+
elif isinstance(x, (list, tuple)):
|
|
27
|
+
for y in x:
|
|
28
|
+
if isinstance(y, Node):
|
|
29
|
+
yield y
|
|
30
|
+
|
|
31
|
+
def walk(self) -> Iterator["Node"]:
|
|
32
|
+
yield self
|
|
33
|
+
for c in self.children():
|
|
34
|
+
yield from c.walk()
|
|
35
|
+
|
|
36
|
+
def find_all(self, *types) -> Iterator["Node"]:
|
|
37
|
+
for n in self.walk():
|
|
38
|
+
if isinstance(n, types):
|
|
39
|
+
yield n
|
|
40
|
+
|
|
41
|
+
def sql(self) -> str:
|
|
42
|
+
from .unparse import to_sql
|
|
43
|
+
|
|
44
|
+
return to_sql(self)
|
|
45
|
+
|
|
46
|
+
def __repr__(self) -> str: # pragma: no cover - debugging aid
|
|
47
|
+
parts = []
|
|
48
|
+
for f in fields(self): # type: ignore[arg-type]
|
|
49
|
+
v = getattr(self, f.name)
|
|
50
|
+
if v in (None, [], (), False):
|
|
51
|
+
continue
|
|
52
|
+
parts.append(f"{f.name}={v!r}")
|
|
53
|
+
return f"{type(self).__name__}({', '.join(parts)})"
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
Expr = Node # alias for readability
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
# ---------------------------------------------------------------------------
|
|
60
|
+
# Types
|
|
61
|
+
# ---------------------------------------------------------------------------
|
|
62
|
+
|
|
63
|
+
@dataclass(repr=False)
|
|
64
|
+
class StructFieldType(Node):
|
|
65
|
+
name: Optional[str]
|
|
66
|
+
type: "TypeNode"
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@dataclass(repr=False)
|
|
70
|
+
class TypeNode(Node):
|
|
71
|
+
name: str
|
|
72
|
+
params: List[str] = field(default_factory=list)
|
|
73
|
+
element: Optional["TypeNode"] = None # ARRAY<T> / RANGE<T>
|
|
74
|
+
fields_: List[StructFieldType] = field(default_factory=list) # STRUCT<...>
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
# ---------------------------------------------------------------------------
|
|
78
|
+
# Expressions
|
|
79
|
+
# ---------------------------------------------------------------------------
|
|
80
|
+
|
|
81
|
+
@dataclass(repr=False)
|
|
82
|
+
class Literal(Node):
|
|
83
|
+
value: object
|
|
84
|
+
kind: str # 'string' | 'bytes' | 'number' | 'bool' | 'null' | 'default'
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@dataclass(repr=False)
|
|
88
|
+
class TypedLiteral(Node):
|
|
89
|
+
"""DATE '2024-01-01', TIMESTAMP '...', NUMERIC '1.5', JSON '{"a":1}' ..."""
|
|
90
|
+
|
|
91
|
+
type_name: str
|
|
92
|
+
value: str
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
@dataclass(repr=False)
|
|
96
|
+
class ColumnRef(Node):
|
|
97
|
+
"""A dotted identifier path: column, table.column, alias.struct.field ..."""
|
|
98
|
+
|
|
99
|
+
path: List[str]
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@dataclass(repr=False)
|
|
103
|
+
class Param(Node):
|
|
104
|
+
name: str # '@name', '@@sysvar' or '?'
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
@dataclass(repr=False)
|
|
108
|
+
class ReplaceItem(Node):
|
|
109
|
+
expr: Expr
|
|
110
|
+
name: str
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
@dataclass(repr=False)
|
|
114
|
+
class Star(Node):
|
|
115
|
+
prefix: List[str] = field(default_factory=list) # for t.* / t.struct.*
|
|
116
|
+
except_: List[str] = field(default_factory=list)
|
|
117
|
+
replace: List[ReplaceItem] = field(default_factory=list)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
@dataclass(repr=False)
|
|
121
|
+
class BinaryOp(Node):
|
|
122
|
+
op: str
|
|
123
|
+
left: Expr
|
|
124
|
+
right: Expr
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
@dataclass(repr=False)
|
|
128
|
+
class UnaryOp(Node):
|
|
129
|
+
op: str # '-', '+', '~', 'NOT'
|
|
130
|
+
operand: Expr
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
@dataclass(repr=False)
|
|
134
|
+
class Between(Node):
|
|
135
|
+
expr: Expr
|
|
136
|
+
low: Expr
|
|
137
|
+
high: Expr
|
|
138
|
+
negated: bool = False
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
@dataclass(repr=False)
|
|
142
|
+
class InExpr(Node):
|
|
143
|
+
expr: Expr
|
|
144
|
+
values: Optional[List[Expr]] = None
|
|
145
|
+
query: Optional["Query"] = None
|
|
146
|
+
unnest: Optional[Expr] = None
|
|
147
|
+
negated: bool = False
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
@dataclass(repr=False)
|
|
151
|
+
class LikeExpr(Node):
|
|
152
|
+
expr: Expr
|
|
153
|
+
patterns: List[Expr]
|
|
154
|
+
quantifier: Optional[str] = None # ANY | ALL | SOME
|
|
155
|
+
negated: bool = False
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
@dataclass(repr=False)
|
|
159
|
+
class IsExpr(Node):
|
|
160
|
+
expr: Expr
|
|
161
|
+
value: str # NULL | TRUE | FALSE | UNKNOWN
|
|
162
|
+
negated: bool = False
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
@dataclass(repr=False)
|
|
166
|
+
class WhenClause(Node):
|
|
167
|
+
condition: Expr
|
|
168
|
+
result: Expr
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
@dataclass(repr=False)
|
|
172
|
+
class Case(Node):
|
|
173
|
+
operand: Optional[Expr]
|
|
174
|
+
whens: List[WhenClause]
|
|
175
|
+
else_: Optional[Expr] = None
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
@dataclass(repr=False)
|
|
179
|
+
class Cast(Node):
|
|
180
|
+
expr: Expr
|
|
181
|
+
to_type: TypeNode
|
|
182
|
+
safe: bool = False
|
|
183
|
+
format: Optional[Expr] = None
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
@dataclass(repr=False)
|
|
187
|
+
class Extract(Node):
|
|
188
|
+
part: str
|
|
189
|
+
expr: Expr
|
|
190
|
+
at_time_zone: Optional[Expr] = None
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
@dataclass(repr=False)
|
|
194
|
+
class IntervalExpr(Node):
|
|
195
|
+
value: Expr
|
|
196
|
+
unit: str
|
|
197
|
+
to_unit: Optional[str] = None
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
@dataclass(repr=False)
|
|
201
|
+
class ArrayExpr(Node):
|
|
202
|
+
elements: List[Expr]
|
|
203
|
+
elem_type: Optional[TypeNode] = None
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
@dataclass(repr=False)
|
|
207
|
+
class StructFieldValue(Node):
|
|
208
|
+
expr: Expr
|
|
209
|
+
name: Optional[str] = None
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
@dataclass(repr=False)
|
|
213
|
+
class StructExpr(Node):
|
|
214
|
+
fields_: List[StructFieldValue]
|
|
215
|
+
type_fields: Optional[List[StructFieldType]] = None
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
@dataclass(repr=False)
|
|
219
|
+
class Subscript(Node):
|
|
220
|
+
base: Expr
|
|
221
|
+
index: Expr
|
|
222
|
+
mode: Optional[str] = None # OFFSET | ORDINAL | SAFE_OFFSET | SAFE_ORDINAL | None
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
@dataclass(repr=False)
|
|
226
|
+
class FieldAccess(Node):
|
|
227
|
+
base: Expr
|
|
228
|
+
field_name: str
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
@dataclass(repr=False)
|
|
232
|
+
class OrderItem(Node):
|
|
233
|
+
expr: Expr
|
|
234
|
+
desc: Optional[bool] = None
|
|
235
|
+
nulls: Optional[str] = None # FIRST | LAST
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
@dataclass(repr=False)
|
|
239
|
+
class FrameBound(Node):
|
|
240
|
+
kind: str # 'UNBOUNDED PRECEDING' | 'CURRENT ROW' | 'PRECEDING' | 'FOLLOWING'
|
|
241
|
+
value: Optional[Expr] = None
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
@dataclass(repr=False)
|
|
245
|
+
class WindowFrame(Node):
|
|
246
|
+
unit: str # ROWS | RANGE | GROUPS
|
|
247
|
+
start: FrameBound
|
|
248
|
+
end: Optional[FrameBound] = None
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
@dataclass(repr=False)
|
|
252
|
+
class WindowSpec(Node):
|
|
253
|
+
name: Optional[str] = None # base named window
|
|
254
|
+
partition_by: List[Expr] = field(default_factory=list)
|
|
255
|
+
order_by: List[OrderItem] = field(default_factory=list)
|
|
256
|
+
frame: Optional[WindowFrame] = None
|
|
257
|
+
is_ref: bool = False # OVER window_name (no parens)
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
@dataclass(repr=False)
|
|
261
|
+
class NamedArg(Node):
|
|
262
|
+
name: str
|
|
263
|
+
value: Expr
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
@dataclass(repr=False)
|
|
267
|
+
class HavingModifier(Node):
|
|
268
|
+
kind: str # MAX | MIN
|
|
269
|
+
expr: Expr
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
@dataclass(repr=False)
|
|
273
|
+
class FuncCall(Node):
|
|
274
|
+
name: List[str] # e.g. ['SAFE', 'SUBSTR'] or ['my_ds', 'my_udf']
|
|
275
|
+
args: List[Expr] = field(default_factory=list)
|
|
276
|
+
distinct: bool = False
|
|
277
|
+
nulls: Optional[str] = None # IGNORE | RESPECT
|
|
278
|
+
order_by: List[OrderItem] = field(default_factory=list)
|
|
279
|
+
limit: Optional[Expr] = None
|
|
280
|
+
having: Optional[HavingModifier] = None
|
|
281
|
+
over: Optional[WindowSpec] = None
|
|
282
|
+
|
|
283
|
+
@property
|
|
284
|
+
def name_str(self) -> str:
|
|
285
|
+
return ".".join(self.name).upper()
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
@dataclass(repr=False)
|
|
289
|
+
class ScalarSubquery(Node):
|
|
290
|
+
query: "Query"
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
@dataclass(repr=False)
|
|
294
|
+
class ArraySubquery(Node):
|
|
295
|
+
query: "Query"
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
@dataclass(repr=False)
|
|
299
|
+
class ExistsSubquery(Node):
|
|
300
|
+
query: "Query"
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
# ---------------------------------------------------------------------------
|
|
304
|
+
# Query structure
|
|
305
|
+
# ---------------------------------------------------------------------------
|
|
306
|
+
|
|
307
|
+
@dataclass(repr=False)
|
|
308
|
+
class SelectItem(Node):
|
|
309
|
+
expr: Expr
|
|
310
|
+
alias: Optional[str] = None
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
@dataclass(repr=False)
|
|
314
|
+
class GroupBy(Node):
|
|
315
|
+
kind: str # 'exprs' | 'rollup' | 'cube' | 'sets' | 'all'
|
|
316
|
+
exprs: List[Expr] = field(default_factory=list)
|
|
317
|
+
sets: List[List[Expr]] = field(default_factory=list)
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
@dataclass(repr=False)
|
|
321
|
+
class NamedWindow(Node):
|
|
322
|
+
name: str
|
|
323
|
+
spec: WindowSpec
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
@dataclass(repr=False)
|
|
327
|
+
class Select(Node):
|
|
328
|
+
items: List[Node] # SelectItem | Star
|
|
329
|
+
distinct: bool = False
|
|
330
|
+
as_mode: Optional[str] = None # STRUCT | VALUE
|
|
331
|
+
from_: Optional[Node] = None
|
|
332
|
+
where: Optional[Expr] = None
|
|
333
|
+
group_by: Optional[GroupBy] = None
|
|
334
|
+
having: Optional[Expr] = None
|
|
335
|
+
qualify: Optional[Expr] = None
|
|
336
|
+
windows: List[NamedWindow] = field(default_factory=list)
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
@dataclass(repr=False)
|
|
340
|
+
class SetOp(Node):
|
|
341
|
+
op: str # UNION | INTERSECT | EXCEPT
|
|
342
|
+
all: bool
|
|
343
|
+
left: Node
|
|
344
|
+
right: Node
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
@dataclass(repr=False)
|
|
348
|
+
class CTE(Node):
|
|
349
|
+
name: str
|
|
350
|
+
query: "Query"
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
@dataclass(repr=False)
|
|
354
|
+
class Query(Node):
|
|
355
|
+
body: Node # Select | SetOp | Query
|
|
356
|
+
ctes: List[CTE] = field(default_factory=list)
|
|
357
|
+
recursive: bool = False
|
|
358
|
+
order_by: List[OrderItem] = field(default_factory=list)
|
|
359
|
+
limit: Optional[Expr] = None
|
|
360
|
+
offset: Optional[Expr] = None
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
# ---------------------------------------------------------------------------
|
|
364
|
+
# FROM clause items
|
|
365
|
+
# ---------------------------------------------------------------------------
|
|
366
|
+
|
|
367
|
+
@dataclass(repr=False)
|
|
368
|
+
class TableSample(Node):
|
|
369
|
+
method: str
|
|
370
|
+
value: Expr
|
|
371
|
+
unit: str = "PERCENT"
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
@dataclass(repr=False)
|
|
375
|
+
class TableRef(Node):
|
|
376
|
+
path: List[str]
|
|
377
|
+
alias: Optional[str] = None
|
|
378
|
+
system_time: Optional[Expr] = None
|
|
379
|
+
sample: Optional[TableSample] = None
|
|
380
|
+
|
|
381
|
+
@property
|
|
382
|
+
def full_name(self) -> str:
|
|
383
|
+
return ".".join(self.path)
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
@dataclass(repr=False)
|
|
387
|
+
class SubqueryRef(Node):
|
|
388
|
+
query: Query
|
|
389
|
+
alias: Optional[str] = None
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
@dataclass(repr=False)
|
|
393
|
+
class UnnestRef(Node):
|
|
394
|
+
expr: Expr
|
|
395
|
+
alias: Optional[str] = None
|
|
396
|
+
with_offset: bool = False
|
|
397
|
+
offset_alias: Optional[str] = None
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
@dataclass(repr=False)
|
|
401
|
+
class TableFuncRef(Node):
|
|
402
|
+
name: List[str]
|
|
403
|
+
args: List[Expr] = field(default_factory=list)
|
|
404
|
+
alias: Optional[str] = None
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
@dataclass(repr=False)
|
|
408
|
+
class Join(Node):
|
|
409
|
+
kind: str # INNER | LEFT | RIGHT | FULL | CROSS
|
|
410
|
+
left: Node
|
|
411
|
+
right: Node
|
|
412
|
+
on: Optional[Expr] = None
|
|
413
|
+
using: List[str] = field(default_factory=list)
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
@dataclass(repr=False)
|
|
417
|
+
class PivotAgg(Node):
|
|
418
|
+
func: FuncCall
|
|
419
|
+
alias: Optional[str] = None
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
@dataclass(repr=False)
|
|
423
|
+
class PivotValue(Node):
|
|
424
|
+
value: Expr
|
|
425
|
+
alias: Optional[str] = None
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
@dataclass(repr=False)
|
|
429
|
+
class PivotRef(Node):
|
|
430
|
+
input: Node
|
|
431
|
+
aggregates: List[PivotAgg]
|
|
432
|
+
for_col: Expr
|
|
433
|
+
in_values: List[PivotValue]
|
|
434
|
+
alias: Optional[str] = None
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
@dataclass(repr=False)
|
|
438
|
+
class UnpivotGroup(Node):
|
|
439
|
+
columns: List[List[str]] # one or more column paths per group
|
|
440
|
+
label: Optional[Expr] = None
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
@dataclass(repr=False)
|
|
444
|
+
class UnpivotRef(Node):
|
|
445
|
+
input: Node
|
|
446
|
+
value_columns: List[str]
|
|
447
|
+
name_column: str
|
|
448
|
+
groups: List[UnpivotGroup]
|
|
449
|
+
include_nulls: Optional[bool] = None
|
|
450
|
+
alias: Optional[str] = None
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
# ---------------------------------------------------------------------------
|
|
454
|
+
# Statements
|
|
455
|
+
# ---------------------------------------------------------------------------
|
|
456
|
+
|
|
457
|
+
@dataclass(repr=False)
|
|
458
|
+
class ColumnDef(Node):
|
|
459
|
+
name: str
|
|
460
|
+
type: Optional[TypeNode] = None
|
|
461
|
+
options_sql: Optional[str] = None
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
@dataclass(repr=False)
|
|
465
|
+
class CreateTableAsSelect(Node):
|
|
466
|
+
kind: str # TABLE | VIEW | MATERIALIZED VIEW
|
|
467
|
+
name: List[str]
|
|
468
|
+
query: Optional[Query] = None
|
|
469
|
+
replace: bool = False
|
|
470
|
+
temp: bool = False
|
|
471
|
+
if_not_exists: bool = False
|
|
472
|
+
columns: List[ColumnDef] = field(default_factory=list)
|
|
473
|
+
partition_by: Optional[Expr] = None
|
|
474
|
+
cluster_by: List[Expr] = field(default_factory=list)
|
|
475
|
+
options_sql: Optional[str] = None
|
|
476
|
+
|
|
477
|
+
@property
|
|
478
|
+
def full_name(self) -> str:
|
|
479
|
+
return ".".join(self.name)
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
@dataclass(repr=False)
|
|
483
|
+
class InsertStmt(Node):
|
|
484
|
+
table: List[str]
|
|
485
|
+
columns: List[str] = field(default_factory=list)
|
|
486
|
+
query: Optional[Query] = None
|
|
487
|
+
values: List[List[Expr]] = field(default_factory=list)
|
|
488
|
+
|
|
489
|
+
@property
|
|
490
|
+
def full_name(self) -> str:
|
|
491
|
+
return ".".join(self.table)
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
@dataclass(repr=False)
|
|
495
|
+
class Assignment(Node):
|
|
496
|
+
target: List[str]
|
|
497
|
+
value: Expr
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
@dataclass(repr=False)
|
|
501
|
+
class UpdateStmt(Node):
|
|
502
|
+
table: List[str]
|
|
503
|
+
assignments: List[Assignment]
|
|
504
|
+
alias: Optional[str] = None
|
|
505
|
+
from_: Optional[Node] = None
|
|
506
|
+
where: Optional[Expr] = None
|
|
507
|
+
|
|
508
|
+
@property
|
|
509
|
+
def full_name(self) -> str:
|
|
510
|
+
return ".".join(self.table)
|
|
511
|
+
|
|
512
|
+
|
|
513
|
+
@dataclass(repr=False)
|
|
514
|
+
class DeleteStmt(Node):
|
|
515
|
+
table: List[str]
|
|
516
|
+
alias: Optional[str] = None
|
|
517
|
+
where: Optional[Expr] = None
|
|
518
|
+
|
|
519
|
+
@property
|
|
520
|
+
def full_name(self) -> str:
|
|
521
|
+
return ".".join(self.table)
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
@dataclass(repr=False)
|
|
525
|
+
class MergeWhen(Node):
|
|
526
|
+
match_kind: str # MATCHED | NOT_MATCHED | NOT_MATCHED_BY_SOURCE
|
|
527
|
+
action_kind: str # UPDATE | DELETE | INSERT | INSERT_ROW
|
|
528
|
+
condition: Optional[Expr] = None
|
|
529
|
+
assignments: List[Assignment] = field(default_factory=list)
|
|
530
|
+
columns: List[str] = field(default_factory=list)
|
|
531
|
+
values: List[Expr] = field(default_factory=list)
|
|
532
|
+
|
|
533
|
+
|
|
534
|
+
@dataclass(repr=False)
|
|
535
|
+
class MergeStmt(Node):
|
|
536
|
+
target: List[str]
|
|
537
|
+
source: Node # TableRef | SubqueryRef
|
|
538
|
+
on: Expr
|
|
539
|
+
whens: List[MergeWhen]
|
|
540
|
+
alias: Optional[str] = None
|
|
541
|
+
|
|
542
|
+
@property
|
|
543
|
+
def full_name(self) -> str:
|
|
544
|
+
return ".".join(self.target)
|
|
545
|
+
|
|
546
|
+
|
|
547
|
+
# ---------------------------------------------------------------------------
|
|
548
|
+
# Scripting (procedural language)
|
|
549
|
+
# ---------------------------------------------------------------------------
|
|
550
|
+
|
|
551
|
+
@dataclass(repr=False)
|
|
552
|
+
class DeclareStmt(Node):
|
|
553
|
+
names: List[str]
|
|
554
|
+
type: Optional[TypeNode] = None
|
|
555
|
+
default: Optional[Expr] = None
|
|
556
|
+
|
|
557
|
+
|
|
558
|
+
@dataclass(repr=False)
|
|
559
|
+
class SetStmt(Node):
|
|
560
|
+
targets: List[str] # variable names (or @@system vars)
|
|
561
|
+
value: Expr # a StructExpr models the (a, b) = (1, 2) form
|
|
562
|
+
|
|
563
|
+
|
|
564
|
+
@dataclass(repr=False)
|
|
565
|
+
class ScriptBlock(Node):
|
|
566
|
+
"""BEGIN ... [EXCEPTION WHEN ERROR THEN ...] END"""
|
|
567
|
+
|
|
568
|
+
statements: List[Node]
|
|
569
|
+
exception_statements: List[Node] = field(default_factory=list)
|
|
570
|
+
has_exception_handler: bool = False
|
|
571
|
+
label: Optional[str] = None
|
|
572
|
+
|
|
573
|
+
|
|
574
|
+
@dataclass(repr=False)
|
|
575
|
+
class IfBranch(Node):
|
|
576
|
+
condition: Expr
|
|
577
|
+
statements: List[Node]
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
@dataclass(repr=False)
|
|
581
|
+
class IfStmt(Node):
|
|
582
|
+
branches: List[IfBranch] # IF + ELSEIFs, in order
|
|
583
|
+
else_statements: List[Node] = field(default_factory=list)
|
|
584
|
+
|
|
585
|
+
|
|
586
|
+
@dataclass(repr=False)
|
|
587
|
+
class LoopStmt(Node):
|
|
588
|
+
statements: List[Node]
|
|
589
|
+
label: Optional[str] = None
|
|
590
|
+
|
|
591
|
+
|
|
592
|
+
@dataclass(repr=False)
|
|
593
|
+
class WhileStmt(Node):
|
|
594
|
+
condition: Expr
|
|
595
|
+
statements: List[Node]
|
|
596
|
+
label: Optional[str] = None
|
|
597
|
+
|
|
598
|
+
|
|
599
|
+
@dataclass(repr=False)
|
|
600
|
+
class RepeatStmt(Node):
|
|
601
|
+
statements: List[Node]
|
|
602
|
+
until: Expr = None
|
|
603
|
+
label: Optional[str] = None
|
|
604
|
+
|
|
605
|
+
|
|
606
|
+
@dataclass(repr=False)
|
|
607
|
+
class ForInStmt(Node):
|
|
608
|
+
var: str
|
|
609
|
+
query: "Query"
|
|
610
|
+
statements: List[Node]
|
|
611
|
+
label: Optional[str] = None
|
|
612
|
+
|
|
613
|
+
|
|
614
|
+
@dataclass(repr=False)
|
|
615
|
+
class BreakContinueStmt(Node):
|
|
616
|
+
kind: str # BREAK | LEAVE | CONTINUE | ITERATE
|
|
617
|
+
label: Optional[str] = None
|
|
618
|
+
|
|
619
|
+
|
|
620
|
+
@dataclass(repr=False)
|
|
621
|
+
class CallStmt(Node):
|
|
622
|
+
name: List[str]
|
|
623
|
+
args: List[Expr] = field(default_factory=list)
|
|
624
|
+
|
|
625
|
+
@property
|
|
626
|
+
def full_name(self) -> str:
|
|
627
|
+
return ".".join(self.name)
|
|
628
|
+
|
|
629
|
+
|
|
630
|
+
@dataclass(repr=False)
|
|
631
|
+
class ReturnStmt(Node):
|
|
632
|
+
pass
|
|
633
|
+
|
|
634
|
+
|
|
635
|
+
@dataclass(repr=False)
|
|
636
|
+
class RaiseStmt(Node):
|
|
637
|
+
message: Optional[Expr] = None
|
|
638
|
+
|
|
639
|
+
|
|
640
|
+
@dataclass(repr=False)
|
|
641
|
+
class ExecuteImmediate(Node):
|
|
642
|
+
sql_expr: Expr
|
|
643
|
+
into: List[str] = field(default_factory=list)
|
|
644
|
+
using: List[Tuple[Expr, Optional[str]]] = field(default_factory=list)
|
|
645
|
+
|
|
646
|
+
|
|
647
|
+
@dataclass(repr=False)
|
|
648
|
+
class AssertStmt(Node):
|
|
649
|
+
condition: Expr
|
|
650
|
+
message: Optional[Expr] = None
|
|
651
|
+
|
|
652
|
+
|
|
653
|
+
@dataclass(repr=False)
|
|
654
|
+
class TransactionStmt(Node):
|
|
655
|
+
kind: str # BEGIN | COMMIT | ROLLBACK
|
|
656
|
+
|
|
657
|
+
|
|
658
|
+
@dataclass(repr=False)
|
|
659
|
+
class TruncateStmt(Node):
|
|
660
|
+
table: List[str]
|
|
661
|
+
|
|
662
|
+
@property
|
|
663
|
+
def full_name(self) -> str:
|
|
664
|
+
return ".".join(self.table)
|
|
665
|
+
|
|
666
|
+
|
|
667
|
+
@dataclass(repr=False)
|
|
668
|
+
class DropStmt(Node):
|
|
669
|
+
kind: str # TABLE | VIEW | MATERIALIZED VIEW | FUNCTION | PROCEDURE | ...
|
|
670
|
+
name: List[str]
|
|
671
|
+
if_exists: bool = False
|
|
672
|
+
|
|
673
|
+
@property
|
|
674
|
+
def full_name(self) -> str:
|
|
675
|
+
return ".".join(self.name)
|
|
676
|
+
|
|
677
|
+
|
|
678
|
+
@dataclass(repr=False)
|
|
679
|
+
class RoutineParam(Node):
|
|
680
|
+
name: str
|
|
681
|
+
type: Optional[TypeNode] = None
|
|
682
|
+
mode: Optional[str] = None # IN | OUT | INOUT (procedures only)
|
|
683
|
+
|
|
684
|
+
|
|
685
|
+
@dataclass(repr=False)
|
|
686
|
+
class CreateProcedure(Node):
|
|
687
|
+
name: List[str]
|
|
688
|
+
params: List[RoutineParam]
|
|
689
|
+
body: ScriptBlock
|
|
690
|
+
replace: bool = False
|
|
691
|
+
if_not_exists: bool = False
|
|
692
|
+
options_sql: Optional[str] = None
|
|
693
|
+
|
|
694
|
+
@property
|
|
695
|
+
def full_name(self) -> str:
|
|
696
|
+
return ".".join(self.name)
|
|
697
|
+
|
|
698
|
+
|
|
699
|
+
@dataclass(repr=False)
|
|
700
|
+
class CreateFunction(Node):
|
|
701
|
+
name: List[str]
|
|
702
|
+
params: List[RoutineParam] = field(default_factory=list)
|
|
703
|
+
returns: Optional[TypeNode] = None
|
|
704
|
+
returns_table: List[StructFieldType] = field(default_factory=list)
|
|
705
|
+
language: Optional[str] = None
|
|
706
|
+
body_expr: Optional[Expr] = None # SQL UDF: AS (expr)
|
|
707
|
+
body_query: Optional["Query"] = None # TVF: AS (SELECT ...)
|
|
708
|
+
body_string: Optional[str] = None # JS UDF: AS "..."
|
|
709
|
+
replace: bool = False
|
|
710
|
+
temp: bool = False
|
|
711
|
+
if_not_exists: bool = False
|
|
712
|
+
table_function: bool = False
|
|
713
|
+
aggregate: bool = False
|
|
714
|
+
deterministic: Optional[bool] = None
|
|
715
|
+
options_sql: Optional[str] = None
|
|
716
|
+
|
|
717
|
+
@property
|
|
718
|
+
def full_name(self) -> str:
|
|
719
|
+
return ".".join(self.name)
|
|
720
|
+
|
|
721
|
+
|
|
722
|
+
Statement = Union[
|
|
723
|
+
Query, CreateTableAsSelect, InsertStmt, UpdateStmt, DeleteStmt, MergeStmt,
|
|
724
|
+
DeclareStmt, SetStmt, ScriptBlock, IfStmt, LoopStmt, WhileStmt, RepeatStmt,
|
|
725
|
+
ForInStmt, BreakContinueStmt, CallStmt, ReturnStmt, RaiseStmt,
|
|
726
|
+
ExecuteImmediate, AssertStmt, TransactionStmt, TruncateStmt, DropStmt,
|
|
727
|
+
CreateProcedure, CreateFunction,
|
|
728
|
+
]
|