@checkdigit/eslint-plugin 7.18.0-PR.143-3aac → 7.18.0-PR.143-5adf
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-mjs/athena/athena.mjs +62 -15
- package/dist-mjs/peggy/athena-peggy.mjs +10 -6
- package/package.json +1 -1
- package/src/athena/athena.ts +66 -18
- package/src/peggy/athena-peggy.ts +5 -1
- package/src/peggy/athena.peggy +6 -2
- package/src/peggy/athena-chat.peggy +0 -608
|
@@ -1,608 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
// ===== Helpers =====
|
|
3
|
-
function node(type, props) { return Object.assign({ type }, props); }
|
|
4
|
-
function list(first, rest) { return [first, ...rest.map(r => r[3])]; }
|
|
5
|
-
function qname(first, rest) { return [first, ...rest.map(r => r[3])].join('.'); }
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
Start
|
|
9
|
-
= _ stmts:StatementList _ EOF { return stmts; }
|
|
10
|
-
|
|
11
|
-
EOF
|
|
12
|
-
= !.
|
|
13
|
-
|
|
14
|
-
StatementList
|
|
15
|
-
= head:Statement tail:(_ ";" _ Statement)* _ ";"? {
|
|
16
|
-
return [head, ...tail.map(t => t[3])];
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
Statement
|
|
20
|
-
= Query
|
|
21
|
-
/ DDL
|
|
22
|
-
/ ShowStmt
|
|
23
|
-
/ DescribeStmt
|
|
24
|
-
/ MsckRepair
|
|
25
|
-
/ UseStmt
|
|
26
|
-
|
|
27
|
-
// ======================
|
|
28
|
-
// DML (Trino-style)
|
|
29
|
-
// ======================
|
|
30
|
-
|
|
31
|
-
Query
|
|
32
|
-
= WithQuery / QueryTerm
|
|
33
|
-
|
|
34
|
-
WithQuery
|
|
35
|
-
= "WITH"i __ ctes:CTEList __ body:QueryTerm {
|
|
36
|
-
return node("WithQuery", { ctes, body });
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
CTEList
|
|
40
|
-
= first:CTE rest:(_ "," _ CTE)* { return list(first, rest); }
|
|
41
|
-
|
|
42
|
-
CTE
|
|
43
|
-
= name:Ident _ "AS"i _ "(" _ q:Query _ ")" {
|
|
44
|
-
return node("CTE", { name, query: q });
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
QueryTerm
|
|
48
|
-
= left:QueryPrimary rest:(_ SetOp _ QueryPrimary)+ {
|
|
49
|
-
return rest.reduce((acc, r) => node("SetOp", { op: r[1], left: acc, right: r[3] }), left);
|
|
50
|
-
}
|
|
51
|
-
/ QueryPrimary
|
|
52
|
-
|
|
53
|
-
SetOp
|
|
54
|
-
= "UNION ALL"i { return "UNION ALL"; }
|
|
55
|
-
/ "UNION"i { return "UNION"; }
|
|
56
|
-
/ "INTERSECT"i { return "INTERSECT"; }
|
|
57
|
-
/ "EXCEPT"i { return "EXCEPT"; }
|
|
58
|
-
|
|
59
|
-
QueryPrimary
|
|
60
|
-
= SelectStmt
|
|
61
|
-
/ "(" _ q:Query _ ")" { return q; }
|
|
62
|
-
|
|
63
|
-
SelectStmt
|
|
64
|
-
= "SELECT"i _ "DISTINCT"i _ sel:SelectList from:FromClause? where:WhereClause?
|
|
65
|
-
group:GroupByClause? having:HavingClause? window:WindowClause?
|
|
66
|
-
order:OrderByClause? limit:LimitClause?
|
|
67
|
-
{
|
|
68
|
-
return node("Select", {
|
|
69
|
-
distinct: true, select: sel,
|
|
70
|
-
from, where, groupBy: group ?? null, having: having ?? null,
|
|
71
|
-
window: window ?? null, orderBy: order ?? null, limit: limit ?? null
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
/ "SELECT"i _ sel:SelectList from:FromClause? where:WhereClause?
|
|
75
|
-
group:GroupByClause? having:HavingClause? window:WindowClause?
|
|
76
|
-
order:OrderByClause? limit:LimitClause?
|
|
77
|
-
{
|
|
78
|
-
return node("Select", {
|
|
79
|
-
distinct: false, select: sel,
|
|
80
|
-
from, where, groupBy: group ?? null, having: having ?? null,
|
|
81
|
-
window: window ?? null, orderBy: order ?? null, limit: limit ?? null
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
SelectList
|
|
86
|
-
= first:SelectItem rest:(_ "," _ SelectItem)* { return list(first, rest); }
|
|
87
|
-
|
|
88
|
-
SelectItem
|
|
89
|
-
= e:Expression _ "AS"i __ a:Ident { return node("SelectItem", { expr: e, alias: a }); }
|
|
90
|
-
/ e:Expression __ a:Ident { return node("SelectItem", { expr: e, alias: a }); }
|
|
91
|
-
/ e:Expression { return node("SelectItem", { expr: e }); }
|
|
92
|
-
/ "*" { return node("Star", {}); }
|
|
93
|
-
/ q:QualifiedStar { return node("QualifiedStar", { prefix: q }); }
|
|
94
|
-
|
|
95
|
-
QualifiedStar
|
|
96
|
-
= first:Ident rest:(_ "." _ Ident)+ _ "." _ "*" {
|
|
97
|
-
return [first, ...rest.map(r => r[3])];
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
FromClause
|
|
101
|
-
= _ "FROM"i _ src:Relation { return src; }
|
|
102
|
-
|
|
103
|
-
Relation
|
|
104
|
-
= JoinedRelation
|
|
105
|
-
/ TableOrSubquery
|
|
106
|
-
|
|
107
|
-
JoinedRelation
|
|
108
|
-
= left:TableOrSubquery rest:(_ JoinSpec _ TableOrSubquery)+ {
|
|
109
|
-
return rest.reduce((acc, r) => node("Join", {
|
|
110
|
-
kind: r[1].kind, lateral: r[1].lateral, criteria: r[1].criteria ?? null,
|
|
111
|
-
left: acc, right: r[3]
|
|
112
|
-
}), left);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
JoinSpec
|
|
116
|
-
= "JOIN"i _ on:JoinCriteria? { return { kind:"INNER", lateral:false, criteria:on ?? null }; }
|
|
117
|
-
/ "INNER JOIN"i _ on:JoinCriteria? { return { kind:"INNER", lateral:false, criteria:on ?? null }; }
|
|
118
|
-
/ "LEFT JOIN"i _ on:JoinCriteria? { return { kind:"LEFT", lateral:false, criteria:on ?? null }; }
|
|
119
|
-
/ "LEFT OUTER JOIN"i _ on:JoinCriteria? { return { kind:"LEFT", lateral:false, criteria:on ?? null }; }
|
|
120
|
-
/ "RIGHT JOIN"i _ on:JoinCriteria? { return { kind:"RIGHT", lateral:false, criteria:on ?? null }; }
|
|
121
|
-
/ "FULL JOIN"i _ on:JoinCriteria? { return { kind:"FULL", lateral:false, criteria:on ?? null }; }
|
|
122
|
-
/ "FULL OUTER JOIN"i _ on:JoinCriteria? { return { kind:"FULL", lateral:false, criteria:on ?? null }; }
|
|
123
|
-
/ "CROSS JOIN"i { return { kind:"CROSS", lateral:false, criteria:null }; }
|
|
124
|
-
/ "LATERAL VIEW JOIN"i _ on:JoinCriteria? { return { kind:"LATERAL VIEW", lateral:true, criteria:on ?? null }; }
|
|
125
|
-
|
|
126
|
-
JoinCriteria
|
|
127
|
-
= "ON"i _ e:Expression { return { type:"ON", expr:e }; }
|
|
128
|
-
/ "USING"i _ "(" _ cols:IdentList _ ")" { return { type:"USING", columns: cols }; }
|
|
129
|
-
|
|
130
|
-
TableOrSubquery
|
|
131
|
-
= "(" _ q:Query _ ")" __ a:Ident { return node("Subquery", { query:q, alias:a }); }
|
|
132
|
-
/ "(" _ q:Query _ ")" { return node("Subquery", { query:q }); }
|
|
133
|
-
/ t:TableName __ a:Ident { return node("Table", { name:t, alias:a }); }
|
|
134
|
-
/ t:TableName { return node("Table", { name:t }); }
|
|
135
|
-
/ "UNNEST"i _ "(" _ args:ExprList _ ")" __ a:Ident {
|
|
136
|
-
return node("Unnest", { args, alias:a });
|
|
137
|
-
}
|
|
138
|
-
/ "UNNEST"i _ "(" _ args:ExprList _ ")" {
|
|
139
|
-
return node("Unnest", { args });
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
TableName
|
|
143
|
-
= first:Ident rest:(_ "." _ Ident)* { return qname(first, rest); }
|
|
144
|
-
|
|
145
|
-
WhereClause
|
|
146
|
-
= _ "WHERE"i _ e:Expression { return e; }
|
|
147
|
-
|
|
148
|
-
GroupByClause
|
|
149
|
-
= _ "GROUP BY"i __ items:GroupByItemList { return items; }
|
|
150
|
-
|
|
151
|
-
GroupByItemList
|
|
152
|
-
= first:GroupByItem rest:(_ "," _ GroupByItem)* { return list(first, rest); }
|
|
153
|
-
|
|
154
|
-
GroupByItem
|
|
155
|
-
= "ROLLUP"i _ "(" _ l:ExprList _ ")" { return node("Rollup", { items:l }); }
|
|
156
|
-
/ "CUBE"i _ "(" _ l:ExprList _ ")" { return node("Cube", { items:l }); }
|
|
157
|
-
/ "GROUPING SETS"i _ "(" _ sets:GroupingSets _ ")" { return node("GroupingSets", { sets }); }
|
|
158
|
-
/ e:Expression { return e; }
|
|
159
|
-
|
|
160
|
-
GroupingSets
|
|
161
|
-
= first:GroupingSet rest:(_ "," _ GroupingSet)* { return list(first, rest); }
|
|
162
|
-
|
|
163
|
-
GroupingSet
|
|
164
|
-
= "(" _ ")" { return []; }
|
|
165
|
-
/ "(" _ l:ExprList _ ")" { return l; }
|
|
166
|
-
|
|
167
|
-
HavingClause
|
|
168
|
-
= _ "HAVING"i _ e:Expression { return e; }
|
|
169
|
-
|
|
170
|
-
WindowClause
|
|
171
|
-
= _ "WINDOW"i _ defs:WindowDefList { return defs; }
|
|
172
|
-
|
|
173
|
-
WindowDefList
|
|
174
|
-
= first:WindowDef rest:(_ "," _ WindowDef)* { return list(first, rest); }
|
|
175
|
-
|
|
176
|
-
WindowDef
|
|
177
|
-
= name:Ident _ "AS"i _ spec:WindowSpec { return node("WindowDef", { name, spec }); }
|
|
178
|
-
|
|
179
|
-
WindowSpec
|
|
180
|
-
= "(" _ p:PartitionBy? o:OrderByClause? f:FrameSpec? _ ")" {
|
|
181
|
-
return node("WindowSpec", { partitionBy: p ?? [], orderBy: o ?? null, frame: f ?? null });
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
PartitionBy
|
|
185
|
-
= "PARTITION BY"i __ l:ExprList { return l; }
|
|
186
|
-
|
|
187
|
-
FrameSpec
|
|
188
|
-
= "ROWS"i _ FrameExtent
|
|
189
|
-
/ "RANGE"i _ FrameExtent
|
|
190
|
-
|
|
191
|
-
FrameExtent
|
|
192
|
-
= "BETWEEN"i __ a:FrameBound __ "AND"i __ b:FrameBound { return { between:true, start:a, end:b }; }
|
|
193
|
-
/ b:FrameBound { return { between:false, end:b }; }
|
|
194
|
-
|
|
195
|
-
FrameBound
|
|
196
|
-
= "UNBOUNDED PRECEDING"i { return { type:"UNBOUNDED_PRECEDING" }; }
|
|
197
|
-
/ "UNBOUNDED FOLLOWING"i { return { type:"UNBOUNDED_FOLLOWING" }; }
|
|
198
|
-
/ n:Integer __ "PRECEDING"i { return { type:"PRECEDING", value:n }; }
|
|
199
|
-
/ n:Integer __ "FOLLOWING"i { return { type:"FOLLOWING", value:n }; }
|
|
200
|
-
/ "CURRENT ROW"i { return { type:"CURRENT_ROW" }; }
|
|
201
|
-
|
|
202
|
-
OrderByClause
|
|
203
|
-
= _ "ORDER BY"i __ first:SortItem rest:(_ "," _ SortItem)* { return list(first, rest); }
|
|
204
|
-
|
|
205
|
-
SortItem
|
|
206
|
-
= e:Expression _ dir:SortDir? _ nulls:NullsOrder? {
|
|
207
|
-
return node("SortItem", { expr:e, direction: dir ?? "ASC", nulls: nulls ?? null });
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
SortDir
|
|
211
|
-
= "ASC"i { return "ASC"; } / "DESC"i { return "DESC"; }
|
|
212
|
-
|
|
213
|
-
NullsOrder
|
|
214
|
-
= "NULLS FIRST"i { return "NULLS FIRST"; }
|
|
215
|
-
/ "NULLS LAST"i { return "NULLS LAST"; }
|
|
216
|
-
|
|
217
|
-
LimitClause
|
|
218
|
-
= _ "LIMIT"i __ n:Integer { return n; }
|
|
219
|
-
|
|
220
|
-
// ======================
|
|
221
|
-
// Expressions
|
|
222
|
-
// ======================
|
|
223
|
-
|
|
224
|
-
ExprList
|
|
225
|
-
= first:Expression rest:(_ "," _ Expression)* { return list(first, rest); }
|
|
226
|
-
|
|
227
|
-
Expression
|
|
228
|
-
= LogicalOr
|
|
229
|
-
|
|
230
|
-
LogicalOr
|
|
231
|
-
= left:LogicalAnd rest:(_ "OR"i _ LogicalAnd)* {
|
|
232
|
-
return rest.reduce((acc, r) => node("BinaryOp", { op:"OR", left:acc, right:r[3] }), left);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
LogicalAnd
|
|
236
|
-
= left:NotExpr rest:(_ "AND"i _ NotExpr)* {
|
|
237
|
-
return rest.reduce((acc, r) => node("BinaryOp", { op:"AND", left:acc, right:r[3] }), left);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
NotExpr
|
|
241
|
-
= "NOT"i __ e:NotExpr { return node("UnaryOp", { op:"NOT", expr:e }); }
|
|
242
|
-
/ Predicate
|
|
243
|
-
|
|
244
|
-
Predicate
|
|
245
|
-
= left:ValueExpr tail:PredicateTail? {
|
|
246
|
-
if (!tail) return left;
|
|
247
|
-
return node("Predicate", Object.assign({ left }, tail));
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
PredicateTail
|
|
251
|
-
= _ "IS NULL"i { return { kind:"IS NULL" }; }
|
|
252
|
-
/ _ "IS NOT NULL"i { return { kind:"IS NOT NULL" }; }
|
|
253
|
-
/ _ "IS TRUE"i { return { kind:"IS TRUE" }; }
|
|
254
|
-
/ _ "IS FALSE"i { return { kind:"IS FALSE" }; }
|
|
255
|
-
/ _ "IS NOT TRUE"i { return { kind:"IS NOT TRUE" }; }
|
|
256
|
-
/ _ "IS NOT FALSE"i { return { kind:"IS NOT FALSE" }; }
|
|
257
|
-
/ _ "IN"i _ "(" _ l:ExprList _ ")" { return { kind:"IN", list:l }; }
|
|
258
|
-
/ _ "NOT IN"i _ "(" _ l:ExprList _ ")" { return { kind:"NOT IN", list:l }; }
|
|
259
|
-
/ _ "BETWEEN"i __ a:ValueExpr __ "AND"i __ b:ValueExpr { return { kind:"BETWEEN", lower:a, upper:b }; }
|
|
260
|
-
/ _ "LIKE"i __ p:ValueExpr ( __ "ESCAPE"i __ e:ValueExpr )? {
|
|
261
|
-
return { kind:"LIKE", pattern:p, escape: e ?? null };
|
|
262
|
-
}
|
|
263
|
-
/ _ "REGEXP_LIKE"i _ "(" _ v:Expression _ "," _ r:Expression ( _ "," _ f:Expression )? _ ")" {
|
|
264
|
-
return { kind:"REGEXP_LIKE", args: [v, r].concat(f ? [f] : []) };
|
|
265
|
-
}
|
|
266
|
-
/ _ op:CmpOp _ r:ValueExpr { return { kind:"COMPARE", op, right:r }; }
|
|
267
|
-
|
|
268
|
-
CmpOp
|
|
269
|
-
= "=" / "<>" / "!=" / "<=" / ">=" / "<" / ">"
|
|
270
|
-
|
|
271
|
-
ValueExpr
|
|
272
|
-
= Additive
|
|
273
|
-
|
|
274
|
-
Additive
|
|
275
|
-
= left:Multiplicative rest:(_ ("+" / "-") _ Multiplicative)* {
|
|
276
|
-
return rest.reduce((acc, r) => node("BinaryOp", { op:r[1], left:acc, right:r[3] }), left);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
Multiplicative
|
|
280
|
-
= left:Unary rest:(_ ("*" / "/" / "%") _ Unary)* {
|
|
281
|
-
return rest.reduce((acc, r) => node("BinaryOp", { op:r[1], left:acc, right:r[3] }), left);
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
Unary
|
|
285
|
-
= "+" _ u:Unary { return node("UnaryOp", { op:"+", expr:u }); }
|
|
286
|
-
/ "-" _ u:Unary { return node("UnaryOp", { op:"-", expr:u }); }
|
|
287
|
-
/ Primary
|
|
288
|
-
|
|
289
|
-
Primary
|
|
290
|
-
= Literal
|
|
291
|
-
/ QualifiedName
|
|
292
|
-
/ FunctionCall
|
|
293
|
-
/ "CASE"i __ CaseExpr "END"i
|
|
294
|
-
/ "(" _ Expression _ ")"
|
|
295
|
-
/ ArrayLiteral
|
|
296
|
-
/ MapLiteral
|
|
297
|
-
/ StructLiteral
|
|
298
|
-
/ CastExpr
|
|
299
|
-
/ TryExpr
|
|
300
|
-
/ SubselectPrimary
|
|
301
|
-
|
|
302
|
-
SubselectPrimary
|
|
303
|
-
= "(" _ q:Query _ ")" { return node("SubqueryExpr", { query:q }); }
|
|
304
|
-
|
|
305
|
-
CaseExpr
|
|
306
|
-
= value:Expression? _ branches:WhenThen+ _ elsePart:ElsePart? {
|
|
307
|
-
return node("Case", { value: value ?? null, whens: branches, else: elsePart ?? null });
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
WhenThen
|
|
311
|
-
= "WHEN"i __ c:Expression __ "THEN"i __ v:Expression { return { when:c, then:v }; }
|
|
312
|
-
|
|
313
|
-
ElsePart
|
|
314
|
-
= "ELSE"i __ e:Expression { return e; }
|
|
315
|
-
|
|
316
|
-
FunctionCall
|
|
317
|
-
= name:QualifiedName _ "(" _ args:StarOrDistinctArgs? _ ")" filter:FilterClause? over:OverClause? {
|
|
318
|
-
return node("FunctionCall", { name, args: args ?? [], filter: filter ?? null, over: over ?? null });
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
StarOrDistinctArgs
|
|
322
|
-
= "*" { return [{ type:"StarArg" }]; }
|
|
323
|
-
/ "DISTINCT"i __ l:ExprList { return [{ type:"DistinctArgs", args:l }]; }
|
|
324
|
-
/ l:ExprList { return l; }
|
|
325
|
-
|
|
326
|
-
FilterClause
|
|
327
|
-
= _ "FILTER"i _ "(" _ "WHERE"i __ e:Expression _ ")" { return e; }
|
|
328
|
-
|
|
329
|
-
OverClause
|
|
330
|
-
= _ "OVER"i _ spec:WindowSpec { return spec; }
|
|
331
|
-
|
|
332
|
-
CastExpr
|
|
333
|
-
= "CAST"i _ "(" _ e:Expression _ "AS"i __ t:TypeSpec _ ")" {
|
|
334
|
-
return node("Cast", { expr:e, type:t });
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
TryExpr
|
|
338
|
-
= "TRY"i _ "(" _ e:Expression _ ")" { return node("Try", { expr:e }); }
|
|
339
|
-
|
|
340
|
-
// ======================
|
|
341
|
-
// Literals & Types
|
|
342
|
-
// ======================
|
|
343
|
-
|
|
344
|
-
Literal
|
|
345
|
-
= StringLiteral
|
|
346
|
-
/ NumericLiteral
|
|
347
|
-
/ "NULL"i { return node("Null", {}); }
|
|
348
|
-
/ "TRUE"i { return node("Boolean", { value:true }); }
|
|
349
|
-
/ "FALSE"i { return node("Boolean", { value:false }); }
|
|
350
|
-
/ "INTERVAL"i __ s:StringLiteral __ u:Ident { return node("Interval", { value:s.value, unit:u }); }
|
|
351
|
-
/ DateTimeLiteral
|
|
352
|
-
|
|
353
|
-
DateTimeLiteral
|
|
354
|
-
= "DATE"i __ s:StringLiteral { return node("Date", { value:s.value }); }
|
|
355
|
-
/ "TIME"i __ s:StringLiteral { return node("Time", { value:s.value }); }
|
|
356
|
-
/ "TIMESTAMP"i __ s:StringLiteral { return node("Timestamp", { value:s.value }); }
|
|
357
|
-
|
|
358
|
-
ArrayLiteral
|
|
359
|
-
= "ARRAY"i _ "[" _ l:ExprList? _ "]" { return node("Array", { elements: l ?? [] }); }
|
|
360
|
-
|
|
361
|
-
MapLiteral
|
|
362
|
-
= "MAP"i _ "(" _ pairs:KeyValueList _ ")" { return node("Map", { entries:pairs }); }
|
|
363
|
-
|
|
364
|
-
KeyValueList
|
|
365
|
-
= first:KeyValue rest:(_ "," _ KeyValue)* { return list(first, rest); }
|
|
366
|
-
|
|
367
|
-
KeyValue
|
|
368
|
-
= k:Expression _ "," _ v:Expression { return { key:k, value:v }; }
|
|
369
|
-
|
|
370
|
-
StructLiteral
|
|
371
|
-
= "ROW"i _ "(" _ l:ExprList _ ")" { return node("Row", { fields:l }); }
|
|
372
|
-
|
|
373
|
-
NumericLiteral
|
|
374
|
-
= n:Float { return node("Number", { value:parseFloat(n) }); }
|
|
375
|
-
/ n:Integer { return node("Number", { value:parseInt(n,10) }); }
|
|
376
|
-
|
|
377
|
-
StringLiteral
|
|
378
|
-
= "'" chars:("''" { return "'"; } / [^'])* "'" {
|
|
379
|
-
return node("String", { value: chars.join("") });
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
Integer
|
|
383
|
-
= digits:[0-9]+ { return digits.join(""); }
|
|
384
|
-
|
|
385
|
-
Float
|
|
386
|
-
= [0-9]+ "." [0-9]* ([eE] [+\-]? [0-9]+)? { return text(); }
|
|
387
|
-
/ "." [0-9]+ ([eE] [+\-]? [0-9]+)? { return text(); }
|
|
388
|
-
/ [0-9]+ [eE] [+\-]? [0-9]+ { return text(); }
|
|
389
|
-
|
|
390
|
-
TypeSpec
|
|
391
|
-
= SimpleType / ComplexType
|
|
392
|
-
|
|
393
|
-
SimpleType
|
|
394
|
-
= "BOOLEAN"i { return {name:"BOOLEAN"}; }
|
|
395
|
-
/ "TINYINT"i { return {name:"TINYINT"}; }
|
|
396
|
-
/ "SMALLINT"i { return {name:"SMALLINT"}; }
|
|
397
|
-
/ "INT"i { return {name:"INT"}; }
|
|
398
|
-
/ "INTEGER"i { return {name:"INTEGER"}; }
|
|
399
|
-
/ "BIGINT"i { return {name:"BIGINT"}; }
|
|
400
|
-
/ "REAL"i { return {name:"REAL"}; }
|
|
401
|
-
/ "FLOAT"i { return {name:"FLOAT"}; }
|
|
402
|
-
/ "DOUBLE"i { return {name:"DOUBLE"}; }
|
|
403
|
-
/ "DECIMAL"i _ "(" _ p:Integer _ "," _ s:Integer _ ")" { return {name:"DECIMAL", precision:+p, scale:+s}; }
|
|
404
|
-
/ "VARCHAR"i _ "(" _ n:Integer _ ")" { return {name:"VARCHAR", length:+n}; }
|
|
405
|
-
/ "VARCHAR"i { return {name:"VARCHAR"}; }
|
|
406
|
-
/ "CHAR"i _ "(" _ n:Integer _ ")" { return {name:"CHAR", length:+n}; }
|
|
407
|
-
/ "VARBINARY"i { return {name:"VARBINARY"}; }
|
|
408
|
-
/ "JSON"i { return {name:"JSON"}; }
|
|
409
|
-
/ "DATE"i { return {name:"DATE"}; }
|
|
410
|
-
/ "TIME"i { return {name:"TIME"}; }
|
|
411
|
-
/ "TIMESTAMP"i { return {name:"TIMESTAMP"}; }
|
|
412
|
-
|
|
413
|
-
ComplexType
|
|
414
|
-
= "ARRAY"i _ "(" _ t:TypeSpec _ ")" { return {name:"ARRAY", element:t}; }
|
|
415
|
-
/ "MAP"i _ "(" _ k:TypeSpec _ "," _ v:TypeSpec _ ")" { return {name:"MAP", key:k, value:v}; }
|
|
416
|
-
/ "ROW"i _ "(" _ fields:RowTypeFields _ ")" { return {name:"ROW", fields}; }
|
|
417
|
-
|
|
418
|
-
RowTypeFields
|
|
419
|
-
= first:RowTypeField rest:(_ "," _ RowTypeField)* { return list(first, rest); }
|
|
420
|
-
|
|
421
|
-
RowTypeField
|
|
422
|
-
= n:Ident _ t:TypeSpec { return { name:n, type:t }; }
|
|
423
|
-
|
|
424
|
-
// ======================
|
|
425
|
-
// Names & identifiers
|
|
426
|
-
// ======================
|
|
427
|
-
|
|
428
|
-
QualifiedName
|
|
429
|
-
= first:Ident rest:(_ "." _ Ident)* {
|
|
430
|
-
return node("Identifier", { name: qname(first, rest) });
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
IdentList
|
|
434
|
-
= first:Ident rest:(_ "," _ Ident)* { return list(first, rest); }
|
|
435
|
-
|
|
436
|
-
Ident
|
|
437
|
-
= DQuotedIdent
|
|
438
|
-
/ BacktickIdent
|
|
439
|
-
/ UnquotedIdent
|
|
440
|
-
|
|
441
|
-
// double-quoted; "" escapes "
|
|
442
|
-
DQuotedIdent
|
|
443
|
-
= '"' chars:('""' { return '"'; } / [^"])* '"' {
|
|
444
|
-
return chars.join("");
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
// backtick-quoted; `` escapes `
|
|
448
|
-
BacktickIdent
|
|
449
|
-
= '`' chars:('``' { return '`'; } / [^`])* '`' {
|
|
450
|
-
return chars.join("");
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
// unquoted: start letter/_ ; continue letter/digit/_
|
|
454
|
-
UnquotedIdent
|
|
455
|
-
= $([A-Za-z_][A-Za-z0-9_]*) { return text(); }
|
|
456
|
-
|
|
457
|
-
// ======================
|
|
458
|
-
// DDL (Hive-style in Athena)
|
|
459
|
-
// ======================
|
|
460
|
-
|
|
461
|
-
DDL
|
|
462
|
-
= CreateDatabase
|
|
463
|
-
/ DropDatabase
|
|
464
|
-
/ CreateTable
|
|
465
|
-
/ DropTable
|
|
466
|
-
/ CreateView
|
|
467
|
-
/ DropView
|
|
468
|
-
/ AlterTable
|
|
469
|
-
|
|
470
|
-
UseStmt
|
|
471
|
-
= "USE"i __ n:Ident { return node("Use", { database:n }); }
|
|
472
|
-
|
|
473
|
-
CreateDatabase
|
|
474
|
-
= "CREATE DATABASE"i _ ifn:IfNotExists? n:Ident props:DbProperties? {
|
|
475
|
-
return node("CreateDatabase", { name:n, ifNotExists: !!ifn, properties: props ?? {} });
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
IfNotExists
|
|
479
|
-
= "IF NOT EXISTS"i _
|
|
480
|
-
|
|
481
|
-
DbProperties
|
|
482
|
-
= _ "WITH DBPROPERTIES"i _ "(" _ pairs:TblProperties _ ")" { return pairs; }
|
|
483
|
-
|
|
484
|
-
DropDatabase
|
|
485
|
-
= "DROP DATABASE"i _ ife:IfExists? n:Ident (_ ("CASCADE"i / "RESTRICT"i))? {
|
|
486
|
-
return node("DropDatabase", { name:n, ifExists: !!ife });
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
IfExists
|
|
490
|
-
= "IF EXISTS"i _
|
|
491
|
-
|
|
492
|
-
CreateTable
|
|
493
|
-
= "CREATE"i __ ext:("EXTERNAL"i __)? "TABLE"i _ ifn:IfNotExists? name:TableName
|
|
494
|
-
_ "(" _ cols:ColumnDefs _ ")"
|
|
495
|
-
part:PartitionSpec? fmt:RowFormat? loc:LocationSpec? tblProps:TableProperties? asSelect:CreateTableAsSelect?
|
|
496
|
-
{
|
|
497
|
-
return node("CreateTable", {
|
|
498
|
-
external: !!ext, ifNotExists: !!ifn, name,
|
|
499
|
-
columns: cols, partitionedBy: part ?? null, rowFormat: fmt ?? null,
|
|
500
|
-
location: loc ?? null, tableProperties: tblProps ?? null,
|
|
501
|
-
asSelect: asSelect ?? null
|
|
502
|
-
});
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
CreateTableAsSelect
|
|
506
|
-
= _ "AS"i _ q:Query { return q; }
|
|
507
|
-
|
|
508
|
-
ColumnDefs
|
|
509
|
-
= first:ColumnDef rest:(_ "," _ ColumnDef)* { return list(first, rest); }
|
|
510
|
-
|
|
511
|
-
ColumnDef
|
|
512
|
-
= n:Ident _ t:TypeSpec c:ColumnComment? { return { name:n, type:t, comment: c ?? null }; }
|
|
513
|
-
|
|
514
|
-
ColumnComment
|
|
515
|
-
= _ "COMMENT"i __ s:StringLiteral { return s.value; }
|
|
516
|
-
|
|
517
|
-
PartitionSpec
|
|
518
|
-
= _ "PARTITIONED BY"i _ "(" _ cols:ColumnDefs _ ")" { return cols; }
|
|
519
|
-
|
|
520
|
-
RowFormat
|
|
521
|
-
= _ "ROW FORMAT SERDE"i __ s:QuotedString
|
|
522
|
-
_ "WITH SERDEPROPERTIES"i _ "(" _ p:TblProperties _ ")" {
|
|
523
|
-
return { serde: s, serdeProperties: p };
|
|
524
|
-
}
|
|
525
|
-
/ _ "ROW FORMAT DELIMITED"i ( (!("LOCATION"i) .) )* { return { delimited: true, raw: text() }; }
|
|
526
|
-
|
|
527
|
-
LocationSpec
|
|
528
|
-
= _ "LOCATION"i __ s:QuotedString { return s; }
|
|
529
|
-
|
|
530
|
-
TableProperties
|
|
531
|
-
= _ "TBLPROPERTIES"i _ "(" _ p:TblProperties _ ")" { return p; }
|
|
532
|
-
|
|
533
|
-
TblProperties
|
|
534
|
-
= first:TblProp rest:(_ "," _ TblProp)* { return Object.fromEntries([first, ...rest.map(r => r[3])]); }
|
|
535
|
-
|
|
536
|
-
TblProp
|
|
537
|
-
= k:QuotedString _ "=" _ v:QuotedString { return [k, v]; }
|
|
538
|
-
|
|
539
|
-
QuotedString
|
|
540
|
-
= s:StringLiteral { return s.value; }
|
|
541
|
-
|
|
542
|
-
DropTable
|
|
543
|
-
= "DROP TABLE"i _ ife:IfExists? n:TableName {
|
|
544
|
-
return node("DropTable", { name:n, ifExists: !!ife });
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
AlterTable
|
|
548
|
-
= "ALTER TABLE"i __ n:TableName __ a:AlterAction {
|
|
549
|
-
return node("AlterTable", { name:n, action:a });
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
AlterAction
|
|
553
|
-
= "ADD PARTITION"i _ "(" _ p:TblProperties _ ")" { return { type:"ADD PARTITION", spec:p }; }
|
|
554
|
-
/ "RENAME TO"i __ newName:TableName { return { type:"RENAME TO", name:newName }; }
|
|
555
|
-
/ "SET TBLPROPERTIES"i _ "(" _ t:TblProperties _ ")" { return { type:"SET TBLPROPERTIES", props:t }; }
|
|
556
|
-
|
|
557
|
-
CreateView
|
|
558
|
-
= "CREATE OR REPLACE VIEW"i __ n:TableName _ "AS"i _ q:Query {
|
|
559
|
-
return node("CreateView", { name:n, query:q, orReplace:true });
|
|
560
|
-
}
|
|
561
|
-
/ "CREATE VIEW"i __ n:TableName _ "AS"i _ q:Query {
|
|
562
|
-
return node("CreateView", { name:n, query:q, orReplace:false });
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
DropView
|
|
566
|
-
= "DROP VIEW"i _ ife:IfExists? n:TableName { return node("DropView", { name:n, ifExists: !!ife }); }
|
|
567
|
-
|
|
568
|
-
// ======================
|
|
569
|
-
// SHOW / DESCRIBE / MSCK
|
|
570
|
-
// ======================
|
|
571
|
-
|
|
572
|
-
ShowStmt
|
|
573
|
-
= "SHOW TABLES"i (_ "IN"i __ db:Ident)? {
|
|
574
|
-
return node("ShowTables", { database: db ?? null });
|
|
575
|
-
}
|
|
576
|
-
/ "SHOW DATABASES"i { return node("ShowDatabases", {}); }
|
|
577
|
-
/ "SHOW COLUMNS FROM"i __ t:TableName { return node("ShowColumns", { table:t }); }
|
|
578
|
-
/ "SHOW PARTITIONS"i __ t:TableName { return node("ShowPartitions", { table:t }); }
|
|
579
|
-
/ "SHOW VIEWS"i (_ "IN"i __ db2:Ident)? {
|
|
580
|
-
return node("ShowViews", { database: db2 ?? null });
|
|
581
|
-
}
|
|
582
|
-
/ "SHOW CREATE TABLE"i __ t2:TableName { return node("ShowCreateTable", { table:t2 }); }
|
|
583
|
-
/ "SHOW CREATE VIEW"i __ v:TableName { return node("ShowCreateView", { view:v }); }
|
|
584
|
-
|
|
585
|
-
DescribeStmt
|
|
586
|
-
= "DESCRIBE"i __ "VIEW"i __ v:TableName { return node("DescribeView", { target:v }); }
|
|
587
|
-
/ "DESCRIBE"i __ t:TableName { return node("Describe", { target:t }); }
|
|
588
|
-
|
|
589
|
-
MsckRepair
|
|
590
|
-
= "MSCK REPAIR TABLE"i __ t:TableName { return node("MsckRepair", { table:t }); }
|
|
591
|
-
|
|
592
|
-
// ======================
|
|
593
|
-
// Whitespace & Comments
|
|
594
|
-
// ======================
|
|
595
|
-
|
|
596
|
-
_ = (WS / Comment)*
|
|
597
|
-
__ = (WS / Comment)+
|
|
598
|
-
|
|
599
|
-
WS = [ \t\r\n\f\v\u00A0]
|
|
600
|
-
|
|
601
|
-
Comment
|
|
602
|
-
= LineComment / BlockComment
|
|
603
|
-
|
|
604
|
-
LineComment
|
|
605
|
-
= "--" [^\n\r]*
|
|
606
|
-
|
|
607
|
-
BlockComment
|
|
608
|
-
= "/*" (!"*/" .)* "*/"
|