@checkdigit/eslint-athena-plugin 1.0.0-PR.2-dcdf

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 (66) hide show
  1. package/LICENSE.txt +21 -0
  2. package/README.md +17 -0
  3. package/SECURITY.md +13 -0
  4. package/dist-mjs/athena/api-locator.mjs +66 -0
  5. package/dist-mjs/athena/api-matcher.mjs +206 -0
  6. package/dist-mjs/athena/athena.mjs +165 -0
  7. package/dist-mjs/athena/column.mjs +1 -0
  8. package/dist-mjs/athena/context.mjs +21 -0
  9. package/dist-mjs/athena/index.mjs +1 -0
  10. package/dist-mjs/athena/service-table.mjs +45 -0
  11. package/dist-mjs/athena/sql-file.mjs +123 -0
  12. package/dist-mjs/athena/types.mjs +1 -0
  13. package/dist-mjs/athena/validate.mjs +619 -0
  14. package/dist-mjs/athena/visitor.mjs +291 -0
  15. package/dist-mjs/get-documentation-url.mjs +9 -0
  16. package/dist-mjs/index.mjs +56 -0
  17. package/dist-mjs/openapi/deref-schema.mjs +20 -0
  18. package/dist-mjs/openapi/generate-schema.mjs +375 -0
  19. package/dist-mjs/openapi/service-schema-generator.mjs +176 -0
  20. package/dist-mjs/peggy/athena-peggy.mjs +20700 -0
  21. package/dist-mjs/service.mjs +9 -0
  22. package/dist-mjs/sql-parser.mjs +28 -0
  23. package/dist-types/athena/api-locator.d.ts +2 -0
  24. package/dist-types/athena/api-matcher.d.ts +14 -0
  25. package/dist-types/athena/athena.d.ts +5 -0
  26. package/dist-types/athena/column.d.ts +1 -0
  27. package/dist-types/athena/context.d.ts +21 -0
  28. package/dist-types/athena/index.d.ts +8 -0
  29. package/dist-types/athena/service-table.d.ts +8 -0
  30. package/dist-types/athena/sql-file.d.ts +5 -0
  31. package/dist-types/athena/types.d.ts +493 -0
  32. package/dist-types/athena/validate.d.ts +14 -0
  33. package/dist-types/athena/visitor.d.ts +75 -0
  34. package/dist-types/get-documentation-url.d.ts +1 -0
  35. package/dist-types/index.d.ts +5 -0
  36. package/dist-types/openapi/deref-schema.d.ts +1 -0
  37. package/dist-types/openapi/generate-schema.d.ts +33 -0
  38. package/dist-types/openapi/service-schema-generator.d.ts +5 -0
  39. package/dist-types/peggy/athena-peggy.d.ts +13 -0
  40. package/dist-types/service.d.ts +2 -0
  41. package/dist-types/sql-parser.d.ts +25 -0
  42. package/package.json +1 -0
  43. package/src/api/v1/swagger.yml +619 -0
  44. package/src/api/v2/swagger.yml +477 -0
  45. package/src/athena/api-locator.ts +78 -0
  46. package/src/athena/api-matcher.ts +323 -0
  47. package/src/athena/athena.ts +224 -0
  48. package/src/athena/column.ts +4 -0
  49. package/src/athena/context.ts +47 -0
  50. package/src/athena/index.ts +13 -0
  51. package/src/athena/service-table.ts +78 -0
  52. package/src/athena/sql-file.ts +161 -0
  53. package/src/athena/types.ts +568 -0
  54. package/src/athena/validate.ts +902 -0
  55. package/src/athena/visitor.ts +406 -0
  56. package/src/get-documentation-url.ts +7 -0
  57. package/src/index.ts +67 -0
  58. package/src/openapi/deref-schema.ts +20 -0
  59. package/src/openapi/generate-schema.ts +553 -0
  60. package/src/openapi/service-schema-generator.ts +241 -0
  61. package/src/peggy/athena-peggy.ts +22149 -0
  62. package/src/peggy/athena.peggy +2971 -0
  63. package/src/service.ts +11 -0
  64. package/src/services/eslintAthenaPlugin/v1/swagger.schema.deref.json +1931 -0
  65. package/src/services/eslintAthenaPlugin/v2/swagger.schema.deref.json +978 -0
  66. package/src/sql-parser.ts +53 -0
@@ -0,0 +1,2971 @@
1
+ {{
2
+ /* c8 ignore start */
3
+ /* eslint-disable */
4
+ // @ts-nocheck
5
+ }}
6
+ {
7
+ const reservedMap = {
8
+ 'ALTER': true,
9
+ 'ALL': true,
10
+ 'ADD': true,
11
+ 'AND': true,
12
+ 'AS': true,
13
+ 'ASC': true,
14
+
15
+ 'BETWEEN': true,
16
+ 'BY': true,
17
+
18
+ 'CALL': true,
19
+ 'CASE': true,
20
+ 'CREATE': true,
21
+ 'CROSS': true,
22
+ 'CONTAINS': true,
23
+ 'CURRENT_DATE': true,
24
+ 'CURRENT_TIME': true,
25
+ 'CURRENT_TIMESTAMP': true,
26
+ 'CURRENT_USER': true,
27
+
28
+ 'DELETE': true,
29
+ 'DESC': true,
30
+ 'DISTINCT': true,
31
+ 'DROP': true,
32
+
33
+ 'ELSE': true,
34
+ 'END': true,
35
+ 'EXISTS': true,
36
+ 'EXPLAIN': true,
37
+
38
+ 'FALSE': true,
39
+ 'FROM': true,
40
+ 'FULL': true,
41
+
42
+ 'GROUP': true,
43
+
44
+ 'HAVING': true,
45
+
46
+ 'IN': true,
47
+ 'INNER': true,
48
+ 'INSERT': true,
49
+ 'INTO': true,
50
+ 'IS': true,
51
+
52
+ 'JOIN': true,
53
+ 'JSON': true,
54
+
55
+ // 'KEY': true,
56
+
57
+ 'LEFT': true,
58
+ 'LIKE': true,
59
+ 'LIMIT': true,
60
+ 'LOW_PRIORITY': true, // for lock table
61
+
62
+ 'NOT': true,
63
+ 'NULL': true,
64
+
65
+ 'ON': true,
66
+ 'OR': true,
67
+ 'ORDER': true,
68
+ 'OUTER': true,
69
+
70
+ 'RECURSIVE': true,
71
+ 'RENAME': true,
72
+ // 'REPLACE': true,
73
+ 'READ': true, // for lock table
74
+ 'RIGHT': true,
75
+
76
+ 'SELECT': true,
77
+ 'SESSION_USER': true,
78
+ 'SET': true,
79
+ 'SHOW': true,
80
+ 'SYSTEM_USER': true,
81
+
82
+ 'TABLE': true,
83
+ 'THEN': true,
84
+ 'TRUE': true,
85
+ 'TRUNCATE': true,
86
+
87
+ 'UNION': true,
88
+ 'UPDATE': true,
89
+ 'USING': true,
90
+ 'UNNEST': true,
91
+
92
+ 'VALUES': true,
93
+
94
+ 'WITH': true,
95
+ 'WHEN': true,
96
+ 'WHERE': true,
97
+ 'WRITE': true, // for lock table
98
+
99
+ 'GLOBAL': true,
100
+ 'SESSION': true,
101
+ 'LOCAL': true,
102
+ 'PERSIST': true,
103
+ 'PERSIST_ONLY': true,
104
+ };
105
+
106
+ function getLocationObject() {
107
+ return options.includeLocations ? {loc: location()} : {}
108
+ }
109
+
110
+ function createUnaryExpr(op, e) {
111
+ return {
112
+ type: 'unary_expr',
113
+ operator: op,
114
+ expr: e
115
+ };
116
+ }
117
+
118
+ function createBinaryExpr(op, left, right) {
119
+ return {
120
+ type: 'binary_expr',
121
+ operator: op,
122
+ left: left,
123
+ right: right
124
+ };
125
+ }
126
+
127
+ function isBigInt(numberStr) {
128
+ const previousMaxSafe = BigInt(Number.MAX_SAFE_INTEGER)
129
+ const num = BigInt(numberStr)
130
+ if (num < previousMaxSafe) return false
131
+ return true
132
+ }
133
+
134
+ function createList(head, tail, po = 3) {
135
+ const result = [head];
136
+ for (let i = 0; i < tail.length; i++) {
137
+ delete tail[i][po].tableList
138
+ delete tail[i][po].columnList
139
+ result.push(tail[i][po]);
140
+ }
141
+ return result;
142
+ }
143
+
144
+ function createBinaryExprChain(head, tail) {
145
+ let result = head;
146
+ for (let i = 0; i < tail.length; i++) {
147
+ result = createBinaryExpr(tail[i][1], result, tail[i][3]);
148
+ }
149
+ return result;
150
+ }
151
+
152
+ function queryTableAlias(tableName) {
153
+ const alias = tableAlias[tableName]
154
+ if (alias) return alias
155
+ if (tableName) return tableName
156
+ return null
157
+ }
158
+
159
+ function columnListTableAlias(columnList) {
160
+ const newColumnsList = new Set()
161
+ const symbolChar = '::'
162
+ for(let column of columnList.keys()) {
163
+ const columnInfo = column.split(symbolChar)
164
+ if (!columnInfo) {
165
+ newColumnsList.add(column)
166
+ break
167
+ }
168
+ if (columnInfo && columnInfo[1]) columnInfo[1] = queryTableAlias(columnInfo[1])
169
+ newColumnsList.add(columnInfo.join(symbolChar))
170
+ }
171
+ return Array.from(newColumnsList)
172
+ }
173
+
174
+ function refreshColumnList(columnList) {
175
+ const columns = columnListTableAlias(columnList)
176
+ columnList.clear()
177
+ columns.forEach(col => columnList.add(col))
178
+ }
179
+
180
+ const cmpPrefixMap = {
181
+ '+': true,
182
+ '-': true,
183
+ '*': true,
184
+ '/': true,
185
+ '>': true,
186
+ '<': true,
187
+ '!': true,
188
+ '=': true,
189
+
190
+ //between
191
+ 'B': true,
192
+ 'b': true,
193
+ //for is or in
194
+ 'I': true,
195
+ 'i': true,
196
+ //for like
197
+ 'L': true,
198
+ 'l': true,
199
+ //for not
200
+ 'N': true,
201
+ 'n': true
202
+ };
203
+
204
+ // used for dependency analysis
205
+ let varList = [];
206
+
207
+ const tableList = new Set();
208
+ const columnList = new Set();
209
+ const tableAlias = {};
210
+ }
211
+
212
+ start
213
+ = __ n:(multiple_stmt) {
214
+ return n
215
+ }
216
+
217
+ cmd_stmt
218
+ = drop_stmt
219
+ / create_stmt
220
+ / truncate_stmt
221
+ / rename_stmt
222
+ / call_stmt
223
+ / use_stmt
224
+ / alter_stmt
225
+ / set_stmt
226
+ / lock_stmt
227
+ / unlock_stmt
228
+
229
+ create_stmt
230
+ = create_table_stmt
231
+ / create_db_stmt
232
+
233
+ alter_stmt
234
+ = alter_table_stmt
235
+
236
+ crud_stmt
237
+ = union_stmt
238
+ / update_stmt
239
+ / replace_insert_stmt
240
+ / insert_no_columns_stmt
241
+ / delete_stmt
242
+ / cmd_stmt
243
+ / proc_stmts
244
+
245
+ multiple_stmt
246
+ = head:crud_stmt tail:(__ SEMICOLON __ crud_stmt)* {
247
+ const headAst = head && head.ast || head
248
+ const cur = tail && tail.length && tail[0].length >= 4 ? [headAst] : headAst;
249
+ for (let i = 0; i < tail.length; i++) {
250
+ if(!tail[i][3] || tail[i][3].length === 0) continue;
251
+ cur.push(tail[i][3] && tail[i][3].ast || tail[i][3]);
252
+ }
253
+ return {
254
+ tableList: Array.from(tableList),
255
+ columnList: columnListTableAlias(columnList),
256
+ ast: cur
257
+ }
258
+ }
259
+ set_op
260
+ = KW_UNION __ s:(KW_ALL / KW_DISTINCT)? {
261
+ return s ? `union ${s.toLowerCase()}` : 'union'
262
+ }
263
+
264
+ union_stmt
265
+ = head:select_stmt tail:(__ set_op __ select_stmt)* __ ob: order_by_clause? __ l:limit_clause? {
266
+ tail.forEach(item => item.slice(1, 1))
267
+ let cur = head
268
+ for (let i = 0; i < tail.length; i++) {
269
+ cur._next = tail[i][3]
270
+ cur.set_op = tail[i][1]
271
+ cur = cur._next
272
+ }
273
+ if(ob) head._orderby = ob
274
+ if(l) head._limit = l
275
+ return {
276
+ tableList: Array.from(tableList),
277
+ columnList: columnListTableAlias(columnList),
278
+ ast: head
279
+ }
280
+ }
281
+
282
+ create_db_definition
283
+ = head:create_option_character_set tail:(__ create_option_character_set)* {
284
+ return createList(head, tail, 1)
285
+ }
286
+
287
+ if_not_exists_stmt
288
+ = 'IF'i __ KW_NOT __ KW_EXISTS {
289
+ return 'IF NOT EXISTS'
290
+ }
291
+
292
+ create_db_stmt
293
+ = a:KW_CREATE __
294
+ k:(KW_DATABASE / KW_SCHEMA) __
295
+ ife:if_not_exists_stmt? __
296
+ t:proc_func_name __
297
+ c:create_db_definition? {
298
+ const keyword = k.toLowerCase()
299
+ return {
300
+ tableList: Array.from(tableList),
301
+ columnList: columnListTableAlias(columnList),
302
+ ast: {
303
+ type: a[0].toLowerCase(),
304
+ keyword,
305
+ if_not_exists:ife,
306
+ [keyword]: { db: t.schema, schema: t.name },
307
+ create_definitions: c,
308
+ }
309
+ }
310
+ }
311
+
312
+ create_table_stmt
313
+ = a:KW_CREATE __
314
+ tp:KW_TEMPORARY? __
315
+ KW_TABLE __
316
+ ife:if_not_exists_stmt? __
317
+ t:table_ref_list __
318
+ c:create_table_definition __
319
+ to:table_options? __
320
+ ir: (KW_IGNORE / KW_REPLACE)? __
321
+ as: KW_AS? __
322
+ qe: union_stmt? {
323
+ if(t) t.forEach(tt => tableList.add(`create::${tt.db}::${tt.table}`));
324
+ return {
325
+ tableList: Array.from(tableList),
326
+ columnList: columnListTableAlias(columnList),
327
+ ast: {
328
+ type: a[0].toLowerCase(),
329
+ keyword: 'table',
330
+ temporary: tp && tp[0].toLowerCase(),
331
+ if_not_exists:ife,
332
+ table: t,
333
+ ignore_replace: ir && ir[0].toLowerCase(),
334
+ as: as && as[0].toLowerCase(),
335
+ query_expr: qe && qe.ast,
336
+ create_definitions: c,
337
+ table_options: to
338
+ }
339
+ }
340
+ }
341
+ / a:KW_CREATE __
342
+ tp:KW_TEMPORARY? __
343
+ KW_TABLE __
344
+ ife:if_not_exists_stmt? __
345
+ t:table_ref_list __
346
+ lt:create_like_table {
347
+ if(t) t.forEach(tt => tableList.add(`create::${tt.db}::${tt.table}`));
348
+ return {
349
+ tableList: Array.from(tableList),
350
+ columnList: columnListTableAlias(columnList),
351
+ ast: {
352
+ type: a[0].toLowerCase(),
353
+ keyword: 'table',
354
+ temporary: tp && tp[0].toLowerCase(),
355
+ if_not_exists:ife,
356
+ table: t,
357
+ like: lt
358
+ }
359
+ }
360
+ }
361
+
362
+ create_like_table_simple
363
+ = KW_LIKE __ t: table_ref_list {
364
+ return {
365
+ type: 'like',
366
+ table: t
367
+ }
368
+ }
369
+ create_like_table
370
+ = create_like_table_simple
371
+ / LPAREN __ e:create_like_table __ RPAREN {
372
+ e.parentheses = true;
373
+ return e;
374
+ }
375
+
376
+ create_table_definition
377
+ = LPAREN __ head:create_definition tail:(__ COMMA __ create_definition)* __ RPAREN {
378
+ return createList(head, tail);
379
+ }
380
+
381
+ create_definition
382
+ = create_column_definition
383
+ / create_index_definition
384
+ / create_fulltext_spatial_index_definition
385
+ / create_constraint_definition
386
+
387
+ column_definition_opt
388
+ = n:(literal_not_null / literal_null) {
389
+ if (n && !n.value) n.value = 'null'
390
+ return { nullable: n }
391
+ }
392
+ / d:default_expr {
393
+ return { default_val: d }
394
+ }
395
+ / a:('AUTO_INCREMENT'i) {
396
+ return { auto_increment: a.toLowerCase() }
397
+ }
398
+ / 'UNIQUE'i __ k:('KEY'i)? {
399
+ const sql = ['unique']
400
+ if (k) sql.push(k)
401
+ return { unique: sql.join(' ').toLowerCase('') }
402
+ }
403
+ / p:('PRIMARY'i)? __ 'KEY'i {
404
+ const sql = []
405
+ if (p) sql.push('primary')
406
+ sql.push('key')
407
+ return { primary_key: sql.join(' ').toLowerCase('') }
408
+ }
409
+ / co:keyword_comment {
410
+ return { comment: co }
411
+ }
412
+ / ca:collate_expr {
413
+ return { collate: ca }
414
+ }
415
+ / cf:column_format {
416
+ return { column_format: cf }
417
+ }
418
+ / s:storage {
419
+ return { storage: s }
420
+ }
421
+ / re:reference_definition {
422
+ return { reference_definition: re }
423
+ }
424
+
425
+ column_definition_opt_list
426
+ = head:column_definition_opt __ tail:(__ column_definition_opt)* {
427
+ let opt = head
428
+ for (let i = 0; i < tail.length; i++) {
429
+ opt = { ...opt, ...tail[i][1] }
430
+ }
431
+ return opt
432
+ }
433
+
434
+ create_column_definition
435
+ = c:column_ref __
436
+ d:data_type __
437
+ cdo:column_definition_opt_list? {
438
+ columnList.add(`create::${c.table}::${c.column}`)
439
+ return {
440
+ column: c,
441
+ definition: d,
442
+ resource: 'column',
443
+ ...(cdo || {})
444
+ }
445
+ }
446
+
447
+ collate_expr
448
+ = KW_COLLATE __ ca:ident_name __ s:KW_ASSIGIN_EQUAL __ t:ident {
449
+ return {
450
+ type: 'collate',
451
+ keyword: 'collate',
452
+ collate: {
453
+ name: ca,
454
+ symbol: s,
455
+ value: t
456
+ }
457
+ }
458
+ }
459
+ / KW_COLLATE __ s:KW_ASSIGIN_EQUAL? __ ca:ident {
460
+ return {
461
+ type: 'collate',
462
+ keyword: 'collate',
463
+ collate: {
464
+ name: ca,
465
+ symbol: s,
466
+ }
467
+ }
468
+ }
469
+
470
+ column_format
471
+ = k:'COLUMN_FORMAT'i __ f:('FIXED'i / 'DYNAMIC'i / 'DEFAULT'i) {
472
+ return {
473
+ type: 'column_format',
474
+ value: f.toLowerCase()
475
+ }
476
+ }
477
+ storage
478
+ = k:'STORAGE'i __ s:('DISK'i / 'MEMORY'i) {
479
+ return {
480
+ type: 'storage',
481
+ value: s.toLowerCase()
482
+ }
483
+ }
484
+ default_expr
485
+ = KW_DEFAULT __ ce:expr {
486
+ return {
487
+ type: 'default',
488
+ value: ce
489
+ }
490
+ }
491
+ drop_index_opt
492
+ = head:(ALTER_ALGORITHM / ALTER_LOCK) tail:(__ (ALTER_ALGORITHM / ALTER_LOCK))* {
493
+ return createList(head, tail, 1)
494
+ }
495
+ drop_stmt
496
+ = a:KW_DROP __
497
+ r:KW_TABLE __
498
+ t:table_ref_list {
499
+ if(t) t.forEach(tt => tableList.add(`${a}::${tt.db}::${tt.table}`));
500
+ return {
501
+ tableList: Array.from(tableList),
502
+ columnList: columnListTableAlias(columnList),
503
+ ast: {
504
+ type: a.toLowerCase(),
505
+ keyword: r.toLowerCase(),
506
+ name: t
507
+ }
508
+ };
509
+ }
510
+ / a:KW_DROP __
511
+ r:KW_INDEX __
512
+ i:column_ref __
513
+ KW_ON __
514
+ t:table_name __
515
+ op:drop_index_opt? __ {
516
+ return {
517
+ tableList: Array.from(tableList),
518
+ columnList: columnListTableAlias(columnList),
519
+ ast: {
520
+ type: a.toLowerCase(),
521
+ keyword: r.toLowerCase(),
522
+ name: i,
523
+ table: t,
524
+ options: op
525
+ }
526
+ };
527
+ }
528
+
529
+ truncate_stmt
530
+ = a:KW_TRUNCATE __
531
+ kw:KW_TABLE? __
532
+ t:table_ref_list {
533
+ if(t) t.forEach(tt => tableList.add(`${a}::${tt.db}::${tt.table}`));
534
+ return {
535
+ tableList: Array.from(tableList),
536
+ columnList: columnListTableAlias(columnList),
537
+ ast: {
538
+ type: a.toLowerCase(),
539
+ keyword: kw && kw.toLowerCase() || 'table',
540
+ name: t
541
+ }
542
+ };
543
+ }
544
+
545
+ use_stmt
546
+ = KW_USE __
547
+ d:ident {
548
+ tableList.add(`use::${d}::null`);
549
+ return {
550
+ tableList: Array.from(tableList),
551
+ columnList: columnListTableAlias(columnList),
552
+ ast: {
553
+ type: 'use',
554
+ db: d
555
+ }
556
+ };
557
+ }
558
+
559
+ alter_table_stmt
560
+ = KW_ALTER __
561
+ KW_TABLE __
562
+ t:table_ref_list __
563
+ e:alter_action_list {
564
+ if (t && t.length > 0) t.forEach(table => tableList.add(`alter::${table.db}::${table.table}`));
565
+ return {
566
+ tableList: Array.from(tableList),
567
+ columnList: columnListTableAlias(columnList),
568
+ ast: {
569
+ type: 'alter',
570
+ table: t,
571
+ expr: e
572
+ }
573
+ };
574
+ }
575
+
576
+ alter_action_list
577
+ = head:alter_action tail:(__ COMMA __ alter_action)* {
578
+ return createList(head, tail);
579
+ }
580
+
581
+ alter_action
582
+ = ALTER_ADD_COLUMN
583
+ / ALTER_DROP_COLUMN
584
+ / ALTER_ADD_INDEX_OR_KEY
585
+ / ALTER_ADD_FULLETXT_SPARITAL_INDEX
586
+ / ALTER_RENAME_TABLE
587
+ / ALTER_ALGORITHM
588
+ / ALTER_LOCK
589
+
590
+ ALTER_ADD_COLUMN
591
+ = KW_ADD __
592
+ kc:KW_COLUMN? __
593
+ cd:create_column_definition {
594
+ return {
595
+ action: 'add',
596
+ ...cd,
597
+ keyword: kc,
598
+ resource: 'column',
599
+ type: 'alter',
600
+ }
601
+ }
602
+
603
+ ALTER_DROP_COLUMN
604
+ = KW_DROP __
605
+ kc:KW_COLUMN? __
606
+ c:column_ref {
607
+ return {
608
+ action: 'drop',
609
+ column: c,
610
+ keyword: kc,
611
+ resource: 'column',
612
+ type: 'alter',
613
+ }
614
+ }
615
+
616
+ ALTER_ADD_INDEX_OR_KEY
617
+ = KW_ADD __
618
+ id:create_index_definition
619
+ {
620
+ return {
621
+ action: 'add',
622
+ type: 'alter',
623
+ ...id,
624
+ }
625
+ }
626
+
627
+ ALTER_RENAME_TABLE
628
+ = KW_RENAME __
629
+ kw:(KW_TO / KW_AS)? __
630
+ tn:ident {
631
+ return {
632
+ action: 'rename',
633
+ type: 'alter',
634
+ resource: 'table',
635
+ keyword: kw && kw[0].toLowerCase(),
636
+ table: tn
637
+ }
638
+ }
639
+
640
+ ALTER_ALGORITHM
641
+ = "ALGORITHM"i __ s:KW_ASSIGIN_EQUAL? __ val:("DEFAULT"i / "INSTANT"i / "INPLACE"i / "COPY"i) {
642
+ return {
643
+ type: 'alter',
644
+ keyword: 'algorithm',
645
+ resource: 'algorithm',
646
+ symbol: s,
647
+ algorithm: val
648
+ }
649
+ }
650
+
651
+ ALTER_LOCK
652
+ = "LOCK"i __ s:KW_ASSIGIN_EQUAL? __ val:("DEFAULT"i / "NONE"i / "SHARED"i / "EXCLUSIVE"i) {
653
+ return {
654
+ type: 'alter',
655
+ keyword: 'lock',
656
+ resource: 'lock',
657
+ symbol: s,
658
+ lock: val
659
+ }
660
+ }
661
+
662
+ create_index_definition
663
+ = kc:(KW_INDEX / KW_KEY) __
664
+ c:column? __
665
+ t:index_type? __
666
+ de:cte_column_definition __
667
+ id:index_options? __
668
+ {
669
+ return {
670
+ index: c,
671
+ definition: de,
672
+ keyword: kc.toLowerCase(),
673
+ index_type: t,
674
+ resource: 'index',
675
+ index_options: id,
676
+ }
677
+ }
678
+
679
+ create_fulltext_spatial_index_definition
680
+ = p: (KW_FULLTEXT / KW_SPATIAL) __
681
+ kc:(KW_INDEX / KW_KEY)? __
682
+ c:column? __
683
+ de: cte_column_definition __
684
+ id: index_options? __
685
+ {
686
+ return {
687
+ index: c,
688
+ definition: de,
689
+ keyword: kc && `${p.toLowerCase()} ${kc.toLowerCase()}` || p.toLowerCase(),
690
+ index_options: id,
691
+ resource: 'index',
692
+ }
693
+ }
694
+
695
+ create_constraint_definition
696
+ = create_constraint_primary
697
+ / create_constraint_unique
698
+ / create_constraint_foreign
699
+
700
+ constraint_name
701
+ = kc:KW_CONSTRAINT __
702
+ c:ident? {
703
+ return {
704
+ keyword: kc.toLowerCase(),
705
+ constraint: c
706
+ }
707
+ }
708
+ create_constraint_primary
709
+ = kc:constraint_name? __
710
+ p:('PRIMARY KEY'i) __
711
+ t:index_type? __
712
+ de:cte_column_definition __
713
+ id:index_options? {
714
+ return {
715
+ constraint: kc && kc.constraint,
716
+ definition: de,
717
+ constraint_type: p.toLowerCase(),
718
+ keyword: kc && kc.keyword,
719
+ index_type: t,
720
+ resource: 'constraint',
721
+ index_options: id,
722
+ }
723
+ }
724
+
725
+ create_constraint_unique
726
+ = kc:constraint_name? __
727
+ u:KW_UNIQUE __
728
+ p:(KW_INDEX / KW_KEY)? __
729
+ i:column? __
730
+ t:index_type? __
731
+ de:cte_column_definition __
732
+ id:index_options? {
733
+ return {
734
+ constraint: kc && kc.constraint,
735
+ definition: de,
736
+ constraint_type: p && `${u.toLowerCase()} ${p.toLowerCase()}` || u.toLowerCase(),
737
+ keyword: kc && kc.keyword,
738
+ index_type: t,
739
+ index: i,
740
+ resource: 'constraint',
741
+ index_options: id
742
+ }
743
+ }
744
+
745
+ create_constraint_foreign
746
+ = kc:constraint_name? __
747
+ p:('FOREIGN KEY'i) __
748
+ i:column? __
749
+ de:cte_column_definition __
750
+ id:reference_definition? {
751
+ return {
752
+ constraint: kc && kc.constraint,
753
+ definition: de,
754
+ constraint_type: p,
755
+ keyword: kc && kc.keyword,
756
+ index: i,
757
+ resource: 'constraint',
758
+ reference_definition: id
759
+ }
760
+ }
761
+
762
+ reference_definition
763
+ = kc:KW_REFERENCES __
764
+ t:table_ref_list __
765
+ de:cte_column_definition __
766
+ m:('MATCH FULL'i / 'MATCH PARTIAL'i / 'MATCH SIMPLE'i)? __
767
+ od:on_reference? __
768
+ ou:on_reference? {
769
+ return {
770
+ definition: de,
771
+ table: t,
772
+ keyword: kc.toLowerCase(),
773
+ match: m && m.toLowerCase(),
774
+ on_action: [od, ou].filter(v => v)
775
+ }
776
+ }
777
+ / oa:on_reference {
778
+ return {
779
+ on_action: [oa]
780
+ }
781
+ }
782
+
783
+ on_reference
784
+ = KW_ON __ kw:(KW_DELETE / KW_UPDATE) __ ro:reference_option {
785
+ // => { type: 'on delete' | 'on update'; value: reference_option; }
786
+ return {
787
+ type: `on ${kw[0].toLowerCase()}`,
788
+ value: ro
789
+ }
790
+ }
791
+
792
+ reference_option
793
+ = kw:KW_CURRENT_TIMESTAMP __ LPAREN __ l:expr_list? __ RPAREN {
794
+ return {
795
+ type: 'function',
796
+ name: { name: [{ type: 'origin', value: kw }]},
797
+ args: l
798
+ }
799
+ }
800
+ / kc:('RESTRICT'i / 'CASCADE'i / 'SET NULL'i / 'NO ACTION'i / 'SET DEFAULT'i / KW_CURRENT_TIMESTAMP) {
801
+ return {
802
+ type: 'origin',
803
+ value: kc.toLowerCase()
804
+ }
805
+ }
806
+
807
+ table_options
808
+ = head:table_option tail:(__ COMMA? __ table_option)* {
809
+ return createList(head, tail)
810
+ }
811
+
812
+ create_option_character_set_kw
813
+ = 'CHARACTER'i __ 'SET'i {
814
+ return 'CHARACTER SET'
815
+ }
816
+ create_option_character_set
817
+ = kw:KW_DEFAULT? __ t:(create_option_character_set_kw / 'CHARSET'i / 'COLLATE'i) __ s:(KW_ASSIGIN_EQUAL)? __ v:ident_without_kw_type {
818
+ return {
819
+ keyword: kw && `${kw[0].toLowerCase()} ${t.toLowerCase()}` || t.toLowerCase(),
820
+ symbol: s,
821
+ value: v
822
+ }
823
+ }
824
+
825
+ table_option
826
+ = kw:('AUTO_INCREMENT'i / 'AVG_ROW_LENGTH'i / 'KEY_BLOCK_SIZE'i / 'MAX_ROWS'i / 'MIN_ROWS'i / 'STATS_SAMPLE_PAGES'i) __ s:(KW_ASSIGIN_EQUAL)? __ v:literal_numeric {
827
+ return {
828
+ keyword: kw.toLowerCase(),
829
+ symbol: s,
830
+ value: v.value
831
+ }
832
+ }
833
+ / create_option_character_set
834
+ / kw:(KW_COMMENT / 'CONNECTION'i) __ s:(KW_ASSIGIN_EQUAL)? __ c:literal_string {
835
+ return {
836
+ keyword: kw.toLowerCase(),
837
+ symbol: s,
838
+ value: `'${c.value}'`
839
+ }
840
+ }
841
+ / kw:'COMPRESSION'i __ s:(KW_ASSIGIN_EQUAL)? __ v:("'"('ZLIB'i / 'LZ4'i / 'NONE'i)"'") {
842
+ return {
843
+ keyword: kw.toLowerCase(),
844
+ symbol: s,
845
+ value: v.join('').toUpperCase()
846
+ }
847
+ }
848
+ / kw:'ENGINE'i __ s:(KW_ASSIGIN_EQUAL)? __ c:ident_name {
849
+ return {
850
+ keyword: kw.toLowerCase(),
851
+ symbol: s,
852
+ value: c.toUpperCase()
853
+ }
854
+ }
855
+
856
+
857
+ ALTER_ADD_FULLETXT_SPARITAL_INDEX
858
+ = KW_ADD __
859
+ fsid:create_fulltext_spatial_index_definition
860
+ {
861
+ return {
862
+ action: 'add',
863
+ type: 'alter',
864
+ ...fsid,
865
+ }
866
+ }
867
+
868
+ rename_stmt
869
+ = KW_RENAME __
870
+ KW_TABLE __
871
+ t:table_to_list {
872
+ t.forEach(tg => tg.forEach(dt => dt.table && tableList.add(`rename::${dt.db}::${dt.table}`)))
873
+ return {
874
+ tableList: Array.from(tableList),
875
+ columnList: columnListTableAlias(columnList),
876
+ ast: {
877
+ type: 'rename',
878
+ table: t
879
+ }
880
+ };
881
+ }
882
+
883
+ set_stmt
884
+ = KW_SET __
885
+ kw: (KW_GLOBAL / KW_SESSION / KW_LOCAL / KW_PERSIST / KW_PERSIST_ONLY)? __
886
+ a: assign_stmt_list {
887
+ a.keyword = kw
888
+ return {
889
+ tableList: Array.from(tableList),
890
+ columnList: columnListTableAlias(columnList),
891
+ ast: {
892
+ type: 'set',
893
+ keyword: kw,
894
+ expr: a
895
+ }
896
+ }
897
+ }
898
+
899
+ unlock_stmt
900
+ = KW_UNLOCK __ KW_TABLES {
901
+ return {
902
+ tableList: Array.from(tableList),
903
+ columnList: columnListTableAlias(columnList),
904
+ ast: {
905
+ type: 'unlock',
906
+ keyword: 'tables'
907
+ }
908
+ }
909
+ }
910
+
911
+ lock_type
912
+ = "READ"i __ s:("LOCAL"i)? {
913
+ return {
914
+ type: 'read',
915
+ suffix: s && 'local'
916
+ }
917
+ }
918
+ / p:("LOW_PRIORITY"i)? __ "WRITE"i {
919
+ return {
920
+ type: 'write',
921
+ prefix: p && 'low_priority'
922
+ }
923
+ }
924
+
925
+ lock_table
926
+ = t:table_base __ lt:lock_type {
927
+ tableList.add(`lock::${t.db}::${t.table}`)
928
+ return {
929
+ table: t,
930
+ lock_type: lt
931
+ }
932
+ }
933
+
934
+ lock_table_list
935
+ = head:lock_table tail:(__ COMMA __ lock_table)* {
936
+ return createList(head, tail);
937
+ }
938
+
939
+ lock_stmt
940
+ = KW_LOCK __ KW_TABLES __ ltl:lock_table_list {
941
+ return {
942
+ tableList: Array.from(tableList),
943
+ columnList: columnListTableAlias(columnList),
944
+ ast: {
945
+ type: 'lock',
946
+ keyword: 'tables',
947
+ tables: ltl
948
+ }
949
+ }
950
+ }
951
+
952
+ call_stmt
953
+ = KW_CALL __
954
+ e: proc_func_call {
955
+ return {
956
+ tableList: Array.from(tableList),
957
+ columnList: columnListTableAlias(columnList),
958
+ ast: {
959
+ type: 'call',
960
+ expr: e
961
+ },
962
+ ...getLocationObject(),
963
+ }
964
+ }
965
+
966
+ select_stmt
967
+ = select_stmt_nake
968
+ / s:('(' __ select_stmt __ ')') {
969
+ return {
970
+ ...s[2],
971
+ parentheses_symbol: true,
972
+ }
973
+ }
974
+
975
+ with_clause
976
+ = KW_WITH __ head:cte_definition tail:(__ COMMA __ cte_definition)* {
977
+ return createList(head, tail);
978
+ }
979
+ / __ KW_WITH __ KW_RECURSIVE __ cte:cte_definition {
980
+ cte.recursive = true;
981
+ return [cte]
982
+ }
983
+
984
+ cte_definition
985
+ = name:(literal_string / ident_name) __ columns:cte_column_definition? __ KW_AS __ LPAREN __ stmt:union_stmt __ RPAREN {
986
+ if (typeof name === 'string') name = { type: 'default', value: name }
987
+ return { name, stmt, columns };
988
+ }
989
+
990
+ cte_column_definition
991
+ = LPAREN __ l:column_ref_list __ RPAREN {
992
+ return l
993
+ }
994
+
995
+ select_stmt_nake
996
+ = __ cte:with_clause? __ KW_SELECT ___
997
+ opts:option_clause? __
998
+ d:KW_DISTINCT? __
999
+ c:column_clause __
1000
+ f:from_clause? __
1001
+ w:where_clause? __
1002
+ g:group_by_clause? __
1003
+ h:having_clause? __
1004
+ o:order_by_clause? __
1005
+ l:limit_clause? {
1006
+ if(f) {
1007
+ const tables = Array.isArray(f) ? f : f.expr
1008
+ tables.forEach(info => info.table && tableList.add(`select::${info.db}::${info.table}`))
1009
+ }
1010
+ return {
1011
+ with: cte,
1012
+ type: 'select',
1013
+ options: opts,
1014
+ distinct: d,
1015
+ columns: c,
1016
+ from: f,
1017
+ where: w,
1018
+ groupby: g,
1019
+ having: h,
1020
+ orderby: o,
1021
+ limit: l,
1022
+ loc: location()
1023
+ };
1024
+ }
1025
+
1026
+ // MySQL extensions to standard SQL
1027
+ option_clause
1028
+ = head:query_option tail:(__ query_option)* {
1029
+ const opts = [head];
1030
+ for (let i = 0, l = tail.length; i < l; ++i) {
1031
+ opts.push(tail[i][1]);
1032
+ }
1033
+ return opts;
1034
+ }
1035
+
1036
+ query_option
1037
+ = option:(
1038
+ OPT_SQL_CALC_FOUND_ROWS
1039
+ / (OPT_SQL_CACHE / OPT_SQL_NO_CACHE)
1040
+ / OPT_SQL_BIG_RESULT
1041
+ / OPT_SQL_SMALL_RESULT
1042
+ / OPT_SQL_BUFFER_RESULT
1043
+ ) { return option; }
1044
+
1045
+ column_clause
1046
+ = head: (KW_ALL / (STAR !ident_start) / STAR) tail:(__ COMMA __ column_list_item)* {
1047
+ columnList.add('select::null::(.*)')
1048
+ const item = {
1049
+ expr: {
1050
+ type: 'column_ref',
1051
+ table: null,
1052
+ column: '*'
1053
+ },
1054
+ as: null
1055
+ }
1056
+ if (tail && tail.length > 0) return createList(item, tail)
1057
+ return [item]
1058
+ }
1059
+ / head:column_list_item tail:(__ COMMA __ column_list_item)* {
1060
+ return createList(head, tail);
1061
+ }
1062
+
1063
+ array_index
1064
+ = LBRAKE __ n:(literal_numeric / literal_string) __ RBRAKE s:(__ "." __ ident)? {
1065
+ let property
1066
+ if (s) property = { type: 'default', value: s[3] }
1067
+ return {
1068
+ brackets: true,
1069
+ index: n,
1070
+ property,
1071
+ }
1072
+ }
1073
+ array_index_list
1074
+ = head:array_index tail:(__ array_index)* {
1075
+ return createList(head, tail, 1)
1076
+ }
1077
+
1078
+ expr_item
1079
+ = e:binary_column_expr __ a:array_index_list? {
1080
+ if (a) e.array_index = a
1081
+ return e
1082
+ }
1083
+
1084
+ column_list_item
1085
+ = tbl:(ident __ DOT)? __ STAR {
1086
+ const table = tbl && tbl[0] || null
1087
+ columnList.add(`select::${table}::(.*)`);
1088
+ return {
1089
+ expr: {
1090
+ type: 'column_ref',
1091
+ table: table,
1092
+ column: '*'
1093
+ },
1094
+ as: null
1095
+ };
1096
+ }
1097
+ / e:expr_item __ alias:alias_clause? {
1098
+ return { type: 'expr', expr: e, as: alias };
1099
+ }
1100
+
1101
+ value_alias_clause
1102
+ = KW_AS? __ i:(a:alias_ident !(__ LPAREN) { return a; } / func_call) { return i; }
1103
+
1104
+ alias_clause
1105
+ = KW_AS __ i:(a:alias_ident !(__ LPAREN) { return a; } / func_call) { return i; }
1106
+ / KW_AS? __ i:ident { return i; }
1107
+
1108
+ with_offset
1109
+ = KW_WITH __ KW_OFFSET __ alias:alias_clause? {
1110
+ return {
1111
+ keyword: 'with offset as',
1112
+ as: alias
1113
+ }
1114
+ }
1115
+
1116
+ from_unnest_item
1117
+ = 'UNNEST'i __ LPAREN __ a:expr? __ RPAREN __ alias:(func_call / alias_clause)? __ wf:with_offset? {
1118
+ return {
1119
+ type: 'unnest',
1120
+ expr: a,
1121
+ parentheses: true,
1122
+ as: alias,
1123
+ with_offset: wf,
1124
+ }
1125
+ }
1126
+
1127
+ from_clause
1128
+ = KW_FROM __ l:table_ref_list { return l; }
1129
+
1130
+ table_to_list
1131
+ = head:table_to_item tail:(__ COMMA __ table_to_item)* {
1132
+ return createList(head, tail);
1133
+ }
1134
+
1135
+ table_to_item
1136
+ = head:table_name __ KW_TO __ tail: (table_name) {
1137
+ return [head, tail]
1138
+ }
1139
+
1140
+ index_type
1141
+ = KW_USING __
1142
+ t:("BTREE"i / "HASH"i) {
1143
+ return {
1144
+ keyword: 'using',
1145
+ type: t.toLowerCase(),
1146
+ }
1147
+ }
1148
+
1149
+ index_options
1150
+ = head:index_option tail:(__ index_option)* {
1151
+ const result = [head];
1152
+ for (let i = 0; i < tail.length; i++) {
1153
+ result.push(tail[i][1]);
1154
+ }
1155
+ return result;
1156
+ }
1157
+
1158
+ index_option
1159
+ = k:KW_KEY_BLOCK_SIZE __ e:(KW_ASSIGIN_EQUAL)? __ kbs:literal_numeric {
1160
+ return {
1161
+ type: k.toLowerCase(),
1162
+ symbol: e,
1163
+ expr: kbs
1164
+ };
1165
+ }
1166
+ / index_type
1167
+ / "WITH"i __ "PARSER"i __ pn:ident_name {
1168
+ return {
1169
+ type: 'with parser',
1170
+ expr: pn
1171
+ }
1172
+ }
1173
+ / k:("VISIBLE"i / "INVISIBLE"i) {
1174
+ return {
1175
+ type: k.toLowerCase(),
1176
+ expr: k.toLowerCase()
1177
+ }
1178
+ }
1179
+ / keyword_comment
1180
+
1181
+ table_ref_list
1182
+ = head:table_base __ tail:table_ref* {
1183
+ tail.unshift(head);
1184
+ tail.forEach(tableInfo => {
1185
+ const { table, as } = tableInfo
1186
+ tableAlias[table] = table
1187
+ if (as) tableAlias[as] = table
1188
+ refreshColumnList(columnList)
1189
+ })
1190
+ return tail;
1191
+ }
1192
+
1193
+ table_ref
1194
+ = __ COMMA __ t:table_base { return t; }
1195
+ / __ t:table_join { return t; }
1196
+
1197
+
1198
+ table_join
1199
+ = op:join_op __ t:table_base __ KW_USING __ LPAREN __ head:ident_name tail:(__ COMMA __ ident_name)* __ RPAREN {
1200
+ t.join = op;
1201
+ t.using = createList(head, tail);
1202
+ return t;
1203
+ }
1204
+ / op:join_op __ t:table_base __ expr:on_clause? {
1205
+ t.join = op;
1206
+ t.on = expr;
1207
+ return t;
1208
+ }
1209
+ / op:(join_op / set_op) __ LPAREN __ stmt:(union_stmt / table_ref_list) __ RPAREN __ alias:alias_clause? __ expr:on_clause? {
1210
+ stmt.parentheses = true;
1211
+ return {
1212
+ expr: stmt,
1213
+ as: alias,
1214
+ join: op,
1215
+ on: expr
1216
+ };
1217
+ }
1218
+
1219
+ //NOTE that, the table assigned to `var` shouldn't write in `table_join`
1220
+ table_base
1221
+ = from_unnest_item
1222
+ / KW_DUAL {
1223
+ return {
1224
+ type: 'dual'
1225
+ };
1226
+ }
1227
+ / stmt:value_clause __ alias:value_alias_clause? {
1228
+ return {
1229
+ expr: { type: 'values', values: stmt },
1230
+ as: alias
1231
+ };
1232
+ }
1233
+ / LPAREN __ stmt:value_clause __ RPAREN __ alias:value_alias_clause? {
1234
+ return {
1235
+ expr: { type: 'values', values: stmt, parentheses: true },
1236
+ as: alias
1237
+ };
1238
+ }
1239
+ / t:table_name __ alias:alias_clause? {
1240
+ if (t.type === 'var') {
1241
+ t.as = alias;
1242
+ return { ...t, ...getLocationObject() };
1243
+ } else {
1244
+ return {
1245
+ db: t.db,
1246
+ table: t.table,
1247
+ as: alias,
1248
+ ...getLocationObject(),
1249
+ };
1250
+ }
1251
+ }
1252
+ / LPAREN __ stmt:union_stmt __ RPAREN __ alias:alias_clause? {
1253
+ stmt.parentheses = true;
1254
+ return {
1255
+ expr: stmt,
1256
+ as: alias
1257
+ };
1258
+ }
1259
+ / LPAREN __ stmt:table_ref_list __ RPAREN __ alias:alias_clause? {
1260
+ stmt = { type: 'tables', expr: stmt, parentheses: true }
1261
+ return {
1262
+ expr: stmt,
1263
+ as: alias
1264
+ };
1265
+ }
1266
+
1267
+ join_op
1268
+ = KW_LEFT __ KW_OUTER? __ KW_JOIN { return 'LEFT JOIN'; }
1269
+ / KW_RIGHT __ KW_OUTER? __ KW_JOIN { return 'RIGHT JOIN'; }
1270
+ / KW_FULL __ KW_OUTER? __ KW_JOIN { return 'FULL JOIN'; }
1271
+ / (KW_INNER __)? KW_JOIN { return 'INNER JOIN'; }
1272
+ / KW_CROSS __ KW_JOIN { return 'CROSS JOIN'; }
1273
+
1274
+ table_name
1275
+ = dt:ident tail:(__ DOT __ ident)? {
1276
+ const obj = { db: null, table: dt };
1277
+ if (tail !== null) {
1278
+ obj.db = dt;
1279
+ obj.table = tail[3];
1280
+ }
1281
+ return obj;
1282
+ }
1283
+ / v:var_decl {
1284
+ v.db = null;
1285
+ v.table = v.name;
1286
+ return v;
1287
+ }
1288
+
1289
+ or_and_expr
1290
+ = head:expr tail:(__ (KW_AND / KW_OR) __ expr)* {
1291
+ const len = tail.length
1292
+ let result = head
1293
+ for (let i = 0; i < len; ++i) {
1294
+ result = createBinaryExpr(tail[i][1], result, tail[i][3])
1295
+ }
1296
+ return result
1297
+ }
1298
+
1299
+ on_clause
1300
+ = KW_ON __ e:or_and_expr { return e; }
1301
+
1302
+ where_clause
1303
+ = KW_WHERE __ e:or_and_where_expr { return e; }
1304
+
1305
+ group_by_clause
1306
+ = KW_GROUP __ KW_BY __ e:expr_list {
1307
+ return {
1308
+ columns: e.value
1309
+ }
1310
+ }
1311
+
1312
+ column_ref_list
1313
+ = head:column_ref tail:(__ COMMA __ column_ref)* {
1314
+ return createList(head, tail);
1315
+ }
1316
+
1317
+ having_clause
1318
+ = KW_HAVING __ e:or_and_where_expr { return e; }
1319
+
1320
+ as_window_specification
1321
+ = ident_name
1322
+ / LPAREN __ ws:window_specification? __ RPAREN {
1323
+ return {
1324
+ window_specification: ws || {},
1325
+ parentheses: true
1326
+ }
1327
+ }
1328
+
1329
+ window_specification
1330
+ = bc:partition_by_clause? __
1331
+ l:order_by_clause? __
1332
+ w:window_frame_clause? {
1333
+ return {
1334
+ name: null,
1335
+ partitionby: bc,
1336
+ orderby: l,
1337
+ window_frame_clause: w
1338
+ }
1339
+ }
1340
+
1341
+ window_specification_frameless
1342
+ = bc:partition_by_clause? __
1343
+ l:order_by_clause? {
1344
+ return {
1345
+ name: null,
1346
+ partitionby: bc,
1347
+ orderby: l,
1348
+ window_frame_clause: null
1349
+ }
1350
+ }
1351
+
1352
+ window_frame_clause
1353
+ = kw:KW_ROWS __ s:(window_frame_following / window_frame_preceding) {
1354
+ return {
1355
+ type: 'rows',
1356
+ expr: s
1357
+ }
1358
+ }
1359
+ / KW_ROWS __ op:KW_BETWEEN __ p:window_frame_preceding __ KW_AND __ f:(window_frame_following / window_frame_preceding) {
1360
+ const left = {
1361
+ type: 'origin',
1362
+ value: 'rows',
1363
+ }
1364
+ const right = {
1365
+ type: 'expr_list',
1366
+ value: [p, f]
1367
+ }
1368
+ return createBinaryExpr(op, left, right)
1369
+ }
1370
+
1371
+ window_frame_following
1372
+ = s:window_frame_value __ 'FOLLOWING'i {
1373
+ // => string
1374
+ s.value += ' FOLLOWING'
1375
+ return s
1376
+ }
1377
+ / window_frame_current_row
1378
+
1379
+ window_frame_preceding
1380
+ = s:window_frame_value __ 'PRECEDING'i {
1381
+ // => string
1382
+ s.value += ' PRECEDING'
1383
+ return s
1384
+ }
1385
+ / window_frame_current_row
1386
+
1387
+ window_frame_current_row
1388
+ = 'CURRENT'i __ 'ROW'i {
1389
+ return { type: 'origin', value: 'current row' }
1390
+ }
1391
+
1392
+ window_frame_value
1393
+ = s:'UNBOUNDED'i {
1394
+ // => literal_string
1395
+ return { type: 'origin', value: s.toUpperCase() }
1396
+ }
1397
+ / literal_numeric
1398
+
1399
+ order_by_clause
1400
+ = KW_ORDER __ KW_BY __ l:order_by_list { return l; }
1401
+
1402
+ partition_by_clause
1403
+ = KW_PARTITION __ KW_BY __ bc:column_clause { return bc; }
1404
+
1405
+ order_by_list
1406
+ = head:order_by_element tail:(__ COMMA __ order_by_element)* {
1407
+ return createList(head, tail);
1408
+ }
1409
+
1410
+ order_by_element
1411
+ = e:expr __ d:(KW_DESC / KW_ASC)? {
1412
+ const obj = { expr: e, type: d };
1413
+ return obj;
1414
+ }
1415
+
1416
+ number_or_param
1417
+ = literal_numeric
1418
+ / param
1419
+
1420
+ limit_clause
1421
+ = KW_LIMIT __ i1:(number_or_param) __ tail:((COMMA / KW_OFFSET) __ number_or_param)? {
1422
+ const res = [i1];
1423
+ if (tail) res.push(tail[2]);
1424
+ return {
1425
+ seperator: tail && tail[0] && tail[0].toLowerCase() || '',
1426
+ value: res
1427
+ };
1428
+ }
1429
+
1430
+ update_stmt
1431
+ = KW_UPDATE __
1432
+ t:table_ref_list __
1433
+ KW_SET __
1434
+ l:set_list __
1435
+ w:where_clause? {
1436
+ const dbObj = {}
1437
+ if (t) t.forEach(tableInfo => {
1438
+ const { db, as, table, join } = tableInfo
1439
+ const action = join ? 'select' : 'update'
1440
+ if (db) dbObj[table] = db
1441
+ if (table) tableList.add(`${action}::${db}::${table}`)
1442
+ });
1443
+ if(l) {
1444
+ l.forEach(col => {
1445
+ if (col.table) {
1446
+ const table = queryTableAlias(col.table)
1447
+ tableList.add(`update::${dbObj[table] || null}::${table}`)
1448
+ }
1449
+ columnList.add(`update::${col.table}::${col.column}`)
1450
+ });
1451
+ }
1452
+ return {
1453
+ tableList: Array.from(tableList),
1454
+ columnList: columnListTableAlias(columnList),
1455
+ ast: {
1456
+ type: 'update',
1457
+ table: t,
1458
+ set: l,
1459
+ where: w
1460
+ }
1461
+ };
1462
+ }
1463
+
1464
+ delete_stmt
1465
+ = KW_DELETE __
1466
+ t: table_ref_list? __
1467
+ f:from_clause __
1468
+ w:where_clause? {
1469
+ if(f) f.forEach(tableInfo => {
1470
+ const { db, as, table, join } = tableInfo
1471
+ const action = join ? 'select' : 'delete'
1472
+ if (table) tableList.add(`${action}::${db}::${table}`)
1473
+ if (!join) columnList.add(`delete::${table}::(.*)`);
1474
+ });
1475
+ if (t === null && f.length === 1) {
1476
+ const tableInfo = f[0]
1477
+ t = [{
1478
+ db: tableInfo.db,
1479
+ table: tableInfo.table,
1480
+ as: tableInfo.as,
1481
+ addition: true
1482
+ }]
1483
+ }
1484
+ return {
1485
+ tableList: Array.from(tableList),
1486
+ columnList: columnListTableAlias(columnList),
1487
+ ast: {
1488
+ type: 'delete',
1489
+ table: t,
1490
+ from: f,
1491
+ where: w
1492
+ }
1493
+ };
1494
+ }
1495
+ set_list
1496
+ = head:set_item tail:(__ COMMA __ set_item)* {
1497
+ return createList(head, tail);
1498
+ }
1499
+
1500
+ /**
1501
+ * here only use `additive_expr` to support 'col1 = col1+2'
1502
+ * if you want to use lower operator, please use '()' like below
1503
+ * 'col1 = (col2 > 3)'
1504
+ */
1505
+ set_item
1506
+ = tbl:(ident __ DOT)? __ c:column_without_kw __ '=' __ v:additive_expr {
1507
+ return { column: c, value: v, table: tbl && tbl[0] };
1508
+ }
1509
+ / tbl:(ident __ DOT)? __ c:column_without_kw __ '=' __ KW_VALUES __ LPAREN __ v:column_ref __ RPAREN {
1510
+ return { column: c, value: v, table: tbl && tbl[0], keyword: 'values' };
1511
+ }
1512
+
1513
+ insert_value_clause
1514
+ = value_clause
1515
+ / select_stmt_nake
1516
+
1517
+ insert_partition
1518
+ = KW_PARTITION __ LPAREN __ head:ident_name tail:(__ COMMA __ ident_name)* __ RPAREN {
1519
+ return createList(head, tail)
1520
+ }
1521
+ / KW_PARTITION __ v: value_item {
1522
+ return v
1523
+ }
1524
+
1525
+ replace_insert_stmt
1526
+ = ri:replace_insert __
1527
+ kw:KW_INTO __
1528
+ ta:KW_TABLE? __
1529
+ t:table_name
1530
+ p:insert_partition? __ LPAREN __ c:column_list __ RPAREN __
1531
+ v:insert_value_clause {
1532
+ if (t) {
1533
+ tableList.add(`insert::${t.db}::${t.table}`)
1534
+ t.as = null
1535
+ }
1536
+ if (c) {
1537
+ let table = t && t.table || null
1538
+ if(Array.isArray(v)) {
1539
+ v.forEach((row, idx) => {
1540
+ if(row.value.length != c.length) {
1541
+ throw new Error(`Error: column count doesn't match value count at row ${idx+1}`)
1542
+ }
1543
+ })
1544
+ }
1545
+ c.forEach(c => columnList.add(`insert::${table}::${c}`));
1546
+ }
1547
+ const tableKey = ta ? ` ${ta.toLowerCase()}` : ''
1548
+ return {
1549
+ tableList: Array.from(tableList),
1550
+ columnList: columnListTableAlias(columnList),
1551
+ ast: {
1552
+ type: ri,
1553
+ prefix: `${kw.toLowerCase()}${tableKey}`,
1554
+ table: [t],
1555
+ columns: c,
1556
+ values: v,
1557
+ partition: p,
1558
+ }
1559
+ };
1560
+ }
1561
+
1562
+ insert_no_columns_stmt
1563
+ = ri:replace_insert __
1564
+ kw:(KW_INTO / KW_OVERWRITE) __
1565
+ ta:KW_TABLE? __
1566
+ t:table_name __
1567
+ p:insert_partition? __
1568
+ v:insert_value_clause {
1569
+ if (t) {
1570
+ tableList.add(`insert::${t.db}::${t.table}`)
1571
+ columnList.add(`insert::${t.table}::(.*)`);
1572
+ t.as = null
1573
+ }
1574
+ const tableKey = ta ? ` ${ta.toLowerCase()}` : ''
1575
+ return {
1576
+ tableList: Array.from(tableList),
1577
+ columnList: columnListTableAlias(columnList),
1578
+ ast: {
1579
+ type: ri,
1580
+ prefix: `${kw.toLowerCase()}${tableKey}`,
1581
+ table: [t],
1582
+ columns: null,
1583
+ values: v,
1584
+ partition: p,
1585
+ }
1586
+ };
1587
+ }
1588
+
1589
+ replace_insert
1590
+ = KW_INSERT { return 'insert'; }
1591
+ / KW_REPLACE { return 'replace'; }
1592
+
1593
+ value_clause
1594
+ = KW_VALUES __ l:value_list { return l; }
1595
+
1596
+ value_list
1597
+ = head:value_item tail:(__ COMMA __ value_item)* {
1598
+ return createList(head, tail);
1599
+ }
1600
+
1601
+ value_item
1602
+ = LPAREN __ l:expr_list __ RPAREN {
1603
+ return l;
1604
+ }
1605
+ / func_call
1606
+
1607
+ expr_list
1608
+ = head:expr tail:(__ COMMA __ expr)* {
1609
+ const el = { type: 'expr_list' };
1610
+ el.value = createList(head, tail);
1611
+ return el;
1612
+ }
1613
+
1614
+ interval_expr
1615
+ = KW_INTERVAL __
1616
+ e:expr __
1617
+ u: interval_unit {
1618
+ return {
1619
+ type: 'interval',
1620
+ expr: e,
1621
+ unit: u.toLowerCase(),
1622
+ }
1623
+ }
1624
+
1625
+ case_expr
1626
+ = KW_CASE __
1627
+ condition_list:case_when_then_list __
1628
+ otherwise:case_else? __
1629
+ KW_END __ KW_CASE? {
1630
+ if (otherwise) condition_list.push(otherwise);
1631
+ return {
1632
+ type: 'case',
1633
+ expr: null,
1634
+ args: condition_list
1635
+ };
1636
+ }
1637
+ / KW_CASE __
1638
+ expr:expr __
1639
+ condition_list:case_when_then_list __
1640
+ otherwise:case_else? __
1641
+ KW_END __ KW_CASE? {
1642
+ if (otherwise) condition_list.push(otherwise);
1643
+ return {
1644
+ type: 'case',
1645
+ expr: expr,
1646
+ args: condition_list
1647
+ };
1648
+ }
1649
+
1650
+ case_when_then_list
1651
+ = head:case_when_then __ tail:(__ case_when_then)* {
1652
+ return createList(head, tail, 1)
1653
+ }
1654
+
1655
+ case_when_then
1656
+ = KW_WHEN __ condition:or_and_where_expr __ KW_THEN __ result:expr {
1657
+ return {
1658
+ type: 'when',
1659
+ cond: condition,
1660
+ result: result
1661
+ };
1662
+ }
1663
+
1664
+ case_else = KW_ELSE __ result:expr {
1665
+ return { type: 'else', result: result };
1666
+ }
1667
+
1668
+ /**
1669
+ * Borrowed from PL/SQL ,the priority of below list IS ORDER BY DESC
1670
+ * ---------------------------------------------------------------------------------------------------
1671
+ * | +, - | identity, negation |
1672
+ * | *, / | multiplication, division |
1673
+ * | +, - | addition, subtraction, concatenation |
1674
+ * | =, <, >, <=, >=, <>, !=, IS, LIKE, BETWEEN, IN | comparion |
1675
+ * | !, NOT | logical negation |
1676
+ * | AND | conjunction |
1677
+ * | OR | inclusion |
1678
+ * ---------------------------------------------------------------------------------------------------
1679
+ */
1680
+
1681
+ _expr
1682
+ = or_expr
1683
+ / unary_expr
1684
+
1685
+ expr
1686
+ = _expr / union_stmt
1687
+
1688
+ unary_expr
1689
+ = op: additive_operator tail: (__ primary)+ {
1690
+ return createUnaryExpr(op, tail[0][1]);
1691
+ }
1692
+
1693
+ binary_column_expr
1694
+ = head:expr tail:(__ (KW_AND / KW_OR / LOGIC_OPERATOR) __ expr)* {
1695
+ const ast = head.ast
1696
+ if (ast && ast.type === 'select') {
1697
+ if (!(head.parentheses_symbol || head.parentheses || head.ast.parentheses || head.ast.parentheses_symbol) || ast.columns.length !== 1 || ast.columns[0].expr.column === '*') throw new Error('invalid column clause with select statement')
1698
+ }
1699
+ if (!tail || tail.length === 0) return head
1700
+ const len = tail.length
1701
+ let result = tail[len - 1][3]
1702
+ for (let i = len - 1; i >= 0; i--) {
1703
+ const left = i === 0 ? head : tail[i - 1][3]
1704
+ result = createBinaryExpr(tail[i][1], left, result)
1705
+ }
1706
+ return result
1707
+ }
1708
+
1709
+ or_and_where_expr
1710
+ = head:expr tail:(__ (KW_AND / KW_OR / COMMA) __ expr)* {
1711
+ const len = tail.length
1712
+ let result = head;
1713
+ let seperator = ''
1714
+ for (let i = 0; i < len; ++i) {
1715
+ if (tail[i][1] === ',') {
1716
+ seperator = ','
1717
+ if (!Array.isArray(result)) result = [result]
1718
+ result.push(tail[i][3])
1719
+ } else {
1720
+ result = createBinaryExpr(tail[i][1], result, tail[i][3]);
1721
+ }
1722
+ }
1723
+ if (seperator === ',') {
1724
+ const el = { type: 'expr_list' }
1725
+ el.value = result
1726
+ return el
1727
+ }
1728
+ return result
1729
+ }
1730
+
1731
+ or_expr
1732
+ = head:and_expr tail:(___ KW_OR __ and_expr)* {
1733
+ return createBinaryExprChain(head, tail);
1734
+ }
1735
+
1736
+ and_expr
1737
+ = head:not_expr tail:(___ KW_AND __ not_expr)* {
1738
+ return createBinaryExprChain(head, tail);
1739
+ }
1740
+
1741
+ //here we should use `NOT` instead of `comparision_expr` to support chain-expr
1742
+ not_expr
1743
+ = comparison_expr
1744
+ / exists_expr
1745
+ / (KW_NOT / "!" !"=") __ expr:not_expr {
1746
+ return createUnaryExpr('NOT', expr);
1747
+ }
1748
+
1749
+ comparison_expr
1750
+ = left:additive_expr __ rh:comparison_op_right? {
1751
+ if (rh === null) return left;
1752
+ else if (rh.type === 'arithmetic') return createBinaryExprChain(left, rh.tail);
1753
+ else return createBinaryExpr(rh.op, left, rh.right);
1754
+ }
1755
+ / literal_string
1756
+ / column_ref
1757
+
1758
+ exists_expr
1759
+ = op:exists_op __ LPAREN __ stmt:union_stmt __ RPAREN {
1760
+ stmt.parentheses = true;
1761
+ return createUnaryExpr(op, stmt);
1762
+ }
1763
+
1764
+ exists_op
1765
+ = nk:(KW_NOT __ KW_EXISTS) { return nk[0] + ' ' + nk[2]; }
1766
+ / KW_EXISTS
1767
+
1768
+ comparison_op_right
1769
+ = arithmetic_op_right
1770
+ / in_op_right
1771
+ / between_op_right
1772
+ / is_op_right
1773
+ / like_op_right
1774
+ / rlike_op_right
1775
+
1776
+ arithmetic_op_right
1777
+ = l:(__ arithmetic_comparison_operator __ additive_expr)+ {
1778
+ return { type: 'arithmetic', tail: l };
1779
+ }
1780
+
1781
+ arithmetic_comparison_operator
1782
+ = ">=" / ">" / "<=" / "<>" / "<" / "==" / "=" / "!="
1783
+
1784
+ is_op_right
1785
+ = KW_IS __ right:additive_expr {
1786
+ return { op: 'IS', right: right };
1787
+ }
1788
+ / (KW_IS __ KW_NOT) __ right:additive_expr {
1789
+ return { op: 'IS NOT', right: right };
1790
+ }
1791
+
1792
+ between_op_right
1793
+ = op:between_or_not_between_op __ begin:additive_expr __ KW_AND __ end:additive_expr {
1794
+ return {
1795
+ op: op,
1796
+ right: {
1797
+ type: 'expr_list',
1798
+ value: [begin, end]
1799
+ }
1800
+ };
1801
+ }
1802
+
1803
+ between_or_not_between_op
1804
+ = nk:(KW_NOT __ KW_BETWEEN) { return nk[0] + ' ' + nk[2]; }
1805
+ / KW_BETWEEN
1806
+
1807
+ like_op
1808
+ = nk:(KW_NOT __ KW_LIKE) { return nk[0] + ' ' + nk[2]; }
1809
+ / KW_LIKE
1810
+
1811
+ rlike_op
1812
+ = nk:(KW_NOT __ KW_RLIKE) { return nk[0] + ' ' + nk[2]; }
1813
+ / KW_RLIKE
1814
+
1815
+ in_op
1816
+ = nk:(KW_NOT __ KW_IN) { return nk[0] + ' ' + nk[2]; }
1817
+ / KW_IN
1818
+
1819
+ like_op_right
1820
+ = op:like_op __ right:(literal / comparison_expr) {
1821
+ return { op: op, right: right };
1822
+ }
1823
+
1824
+ rlike_op_right
1825
+ = op:rlike_op __ right:(literal / comparison_expr) {
1826
+ return { op: op, right: right };
1827
+ }
1828
+
1829
+ in_op_right
1830
+ = op:in_op __ LPAREN __ l:expr_list __ RPAREN {
1831
+ return { op: op, right: l };
1832
+ }
1833
+ / op:in_op __ e:(var_decl / literal_string / func_call) {
1834
+ return { op: op, right: e };
1835
+ }
1836
+
1837
+ additive_expr
1838
+ = head:multiplicative_expr
1839
+ tail:(__ additive_operator __ multiplicative_expr)* {
1840
+ if (tail && tail.length && head.type === 'column_ref' && head.column === '*') throw new Error(JSON.stringify({
1841
+ message: 'args could not be star column in additive expr',
1842
+ ...getLocationObject(),
1843
+ }))
1844
+ return createBinaryExprChain(head, tail);
1845
+ }
1846
+
1847
+ additive_operator
1848
+ = "+" / "-"
1849
+
1850
+ multiplicative_expr
1851
+ = head:unary_expr_or_primary
1852
+ tail:(__ (multiplicative_operator / LOGIC_OPERATOR) __ unary_expr_or_primary)* {
1853
+ return createBinaryExprChain(head, tail)
1854
+ }
1855
+
1856
+ multiplicative_operator
1857
+ = "*" / "/" / "%"
1858
+
1859
+ primary
1860
+ = cast_expr
1861
+ / literal
1862
+ / aggr_func
1863
+ / f:func_call __ a:array_index_list {
1864
+ // => column_ref
1865
+ f.array_index = a
1866
+ return f
1867
+ }
1868
+ / func_call
1869
+ / case_expr
1870
+ / interval_expr
1871
+ / c:column_ref __ a:array_index_list {
1872
+ // => column_ref
1873
+ c.array_index = a
1874
+ return c
1875
+ }
1876
+ / column_ref
1877
+ / param
1878
+ / LPAREN __ list:or_and_where_expr __ RPAREN {
1879
+ list.parentheses = true;
1880
+ return list;
1881
+ }
1882
+ / var_decl
1883
+
1884
+ unary_expr_or_primary
1885
+ = jsonb_expr
1886
+ / op:(unary_operator) tail:(__ unary_expr_or_primary) {
1887
+ // => unary_expr
1888
+ return createUnaryExpr(op, tail[1])
1889
+ }
1890
+
1891
+ unary_operator
1892
+ = '!' / '-' / '+' / '~'
1893
+
1894
+ jsonb_expr
1895
+ = head:primary __ tail: (__ ('?|' / '?&' / '?' / '#-' / '#>>' / '#>' / SINGLE_ARROW / '@>' / '<@') __ primary)* {
1896
+ // => primary | binary_expr
1897
+ if (!tail || tail.length === 0) return head
1898
+ return createBinaryExprChain(head, tail)
1899
+ }
1900
+
1901
+ column_ref
1902
+ = schema:ident tbl:(__ DOT __ ident) col:(__ DOT __ column) ce:(__ collate_expr)? {
1903
+ columnList.add(`select::${schema}.${tbl[3]}::${col[3].value}`);
1904
+ return {
1905
+ type: 'column_ref',
1906
+ schema: schema,
1907
+ table: tbl[3],
1908
+ column: col[3],
1909
+ collate: ce && ce[1],
1910
+ ...getLocationObject(),
1911
+ };
1912
+ }
1913
+ / tbl:ident __ DOT __ col:column ce:(__ collate_expr)? {
1914
+ columnList.add(`select::${tbl}::${col}`);
1915
+ return {
1916
+ type: 'column_ref',
1917
+ table: tbl,
1918
+ column: col,
1919
+ collate: ce && ce[1],
1920
+ ...getLocationObject(),
1921
+ };
1922
+ }
1923
+ / col:column ce:(__ collate_expr)? {
1924
+ columnList.add(`select::null::${col}`);
1925
+ return {
1926
+ type: 'column_ref',
1927
+ table: null,
1928
+ column: col,
1929
+ collate: ce && ce[1],
1930
+ ...getLocationObject(),
1931
+ };
1932
+ }
1933
+
1934
+ column_list
1935
+ = head:column tail:(__ COMMA __ column)* {
1936
+ return createList(head, tail);
1937
+ }
1938
+
1939
+ ident_without_kw_type
1940
+ = n:ident_name {
1941
+ return { type: 'default', value: n }
1942
+ }
1943
+ / quoted_ident_type
1944
+
1945
+ ident_type
1946
+ = name:ident_name !{ return reservedMap[name.toUpperCase()] === true; } {
1947
+ return { type: 'default', value: name }
1948
+ }
1949
+ / quoted_ident_type
1950
+
1951
+ ident
1952
+ = name:ident_name !{ return reservedMap[name.toUpperCase()] === true; } {
1953
+ return name;
1954
+ }
1955
+ / name:quoted_ident {
1956
+ return name;
1957
+ }
1958
+
1959
+ alias_ident
1960
+ = name:ident_name !{
1961
+ if (reservedMap[name.toUpperCase()] === true) throw new Error("Error: "+ JSON.stringify(name)+" is a reserved word, can not as alias clause");
1962
+ return false
1963
+ } {
1964
+ return name;
1965
+ }
1966
+ / name:quoted_ident {
1967
+ return name;
1968
+ }
1969
+
1970
+ quoted_ident_type
1971
+ = double_quoted_ident / single_quoted_ident / backticks_quoted_ident
1972
+
1973
+ quoted_ident
1974
+ = v:(double_quoted_ident / single_quoted_ident / backticks_quoted_ident) {
1975
+ return v.value
1976
+ }
1977
+
1978
+ double_quoted_ident
1979
+ = '"' chars:[^"]+ '"' {
1980
+ return {
1981
+ type: 'double_quote_string',
1982
+ value: chars.join('')
1983
+ }
1984
+ }
1985
+
1986
+ single_quoted_ident
1987
+ = "'" chars:[^']+ "'" {
1988
+ return {
1989
+ type: 'single_quote_string',
1990
+ value: chars.join('')
1991
+ }
1992
+ }
1993
+
1994
+ backticks_quoted_ident
1995
+ = "`" chars:[^`]+ "`" {
1996
+ return {
1997
+ type: 'backticks_quote_string',
1998
+ value: chars.join('')
1999
+ }
2000
+ }
2001
+
2002
+ column_without_kw
2003
+ = name:column_name {
2004
+ return name;
2005
+ }
2006
+ / quoted_ident
2007
+
2008
+ column
2009
+ = name:column_name !{ return reservedMap[name.toUpperCase()] === true; } { return name; }
2010
+ / quoted_ident
2011
+
2012
+ column_name
2013
+ = start:ident_part parts:column_part* { return start + parts.join(''); }
2014
+
2015
+ ident_name
2016
+ = start:ident_start parts:ident_part* { return start + parts.join(''); }
2017
+
2018
+ ident_start = [A-Za-z_]
2019
+
2020
+ ident_part = [A-Za-z0-9_]
2021
+
2022
+ // to support column name like `cf1:name` in hbase
2023
+ column_part = [A-Za-z0-9_:]
2024
+
2025
+ param
2026
+ = l:(':' ident_name) {
2027
+ return { type: 'param', value: l[1] };
2028
+ }
2029
+
2030
+ aggr_func
2031
+ = aggr_fun_count
2032
+ / aggr_fun_smma
2033
+ / aggr_array_agg
2034
+
2035
+ aggr_fun_smma
2036
+ = name:KW_SUM_MAX_MIN_AVG __ LPAREN __ e:additive_expr __ RPAREN __ bc:over_partition? {
2037
+ return {
2038
+ type: 'aggr_func',
2039
+ name: name,
2040
+ args: {
2041
+ expr: e
2042
+ },
2043
+ over: bc,
2044
+ ...getLocationObject(),
2045
+ };
2046
+ }
2047
+
2048
+ KW_SUM_MAX_MIN_AVG
2049
+ = KW_SUM / KW_MAX / KW_MIN / KW_AVG
2050
+
2051
+ on_update_current_timestamp
2052
+ = KW_ON __ KW_UPDATE __ kw:KW_CURRENT_TIMESTAMP __ LPAREN __ l:expr_list? __ RPAREN{
2053
+ return {
2054
+ type: 'on update',
2055
+ keyword: kw,
2056
+ parentheses: true,
2057
+ expr: l
2058
+ }
2059
+ }
2060
+ / KW_ON __ KW_UPDATE __ kw:KW_CURRENT_TIMESTAMP {
2061
+ return {
2062
+ type: 'on update',
2063
+ keyword: kw,
2064
+ }
2065
+ }
2066
+
2067
+ over_partition
2068
+ = 'OVER'i __ aws:as_window_specification {
2069
+ return {
2070
+ type: 'window',
2071
+ as_window_specification: aws,
2072
+ }
2073
+ }
2074
+ / 'OVER'i __ LPAREN __ bc:partition_by_clause? __ l:order_by_clause? __ RPAREN {
2075
+ return {
2076
+ partitionby: bc,
2077
+ orderby: l
2078
+ }
2079
+ }
2080
+ / on_update_current_timestamp
2081
+
2082
+ aggr_fun_count
2083
+ = name:KW_COUNT __ LPAREN __ arg:count_arg __ RPAREN __ bc:over_partition? {
2084
+ return {
2085
+ type: 'aggr_func',
2086
+ name: name,
2087
+ args: arg,
2088
+ over: bc
2089
+ };
2090
+ }
2091
+ concat_separator
2092
+ = kw:(COMMA / OPERATOR_CONCATENATION) __ s:literal_string {
2093
+ // => { symbol: ',' | '||'; delimiter: literal_string; }
2094
+ return {
2095
+ symbol: kw,
2096
+ delimiter: s
2097
+ }
2098
+ }
2099
+
2100
+ distinct_args
2101
+ = d:KW_DISTINCT? __ LPAREN __ c:expr __ RPAREN __ tail:(__ (KW_AND / KW_OR / OPERATOR_CONCATENATION) __ expr)* __ or:order_by_clause? {
2102
+ const len = tail.length
2103
+ let result = c
2104
+ result.parentheses = true
2105
+ for (let i = 0; i < len; ++i) {
2106
+ result = createBinaryExpr(tail[i][1], result, tail[i][3])
2107
+ }
2108
+ return {
2109
+ distinct: d,
2110
+ expr: result,
2111
+ orderby: or,
2112
+ };
2113
+ }
2114
+ / d:KW_DISTINCT? __ c:or_and_expr __ tail:(__ (COMMA / OPERATOR_CONCATENATION) __ expr)* __ or:order_by_clause? {
2115
+ const len = tail.length
2116
+ let result = c
2117
+ for (let i = 0; i < len; ++i) {
2118
+ result = createBinaryExpr(tail[i][1], result, tail[i][3])
2119
+ }
2120
+ return { distinct: d, expr: result, orderby: or };
2121
+ }
2122
+
2123
+ count_arg
2124
+ = e:star_expr { return { expr: e }; }
2125
+ / distinct_args
2126
+
2127
+ aggr_array_agg
2128
+ = pre:(ident __ DOT)? __ name:(KW_ARRAY_AGG) __ LPAREN __ arg:distinct_args __ RPAREN {
2129
+ // => { type: 'aggr_func'; args:count_arg; name: 'ARRAY_AGG' | 'STRING_AGG'; }
2130
+ return {
2131
+ type: 'aggr_func',
2132
+ name: pre ? `${pre[0]}.${name}` : name,
2133
+ args: arg,
2134
+ };
2135
+ }
2136
+
2137
+ star_expr
2138
+ = "*" { return { type: 'star', value: '*' }; }
2139
+
2140
+ arrow_func
2141
+ = v:ident_without_kw_type __ s:SINGLE_ARROW __ e:expr {
2142
+ return createBinaryExpr(s, v, e)
2143
+ }
2144
+
2145
+ filter_func
2146
+ = 'filter'i __ LPAREN __ ar:expr __ COMMA __ af:arrow_func __ RPAREN {
2147
+ return {
2148
+ type: 'function',
2149
+ name: { name: [{ type: 'origin', value: 'filter' }] },
2150
+ args: { type: 'expr_list', value: [ar, af] },
2151
+ ...getLocationObject(),
2152
+ };
2153
+ }
2154
+
2155
+ trim_position
2156
+ = 'BOTH'i / 'LEADING'i / 'TRAILING'i
2157
+
2158
+ trim_rem
2159
+ = p:trim_position? __ rm:expr? __ k:KW_FROM {
2160
+ let value = []
2161
+ if (p) value.push({type: 'origin', value: p })
2162
+ if (rm) value.push(rm)
2163
+ value.push({type: 'origin', value: 'from' })
2164
+ return {
2165
+ type: 'expr_list',
2166
+ value,
2167
+ }
2168
+ }
2169
+
2170
+ trim_func_clause
2171
+ = 'trim'i __ LPAREN __ tr:trim_rem? __ s:expr_item __ RPAREN {
2172
+ let args = tr || { type: 'expr_list', value: [] }
2173
+ args.value.push(s)
2174
+ return {
2175
+ type: 'function',
2176
+ name: { name: [{ type: 'origin', value: 'trim' }] },
2177
+ args,
2178
+ };
2179
+ }
2180
+
2181
+ func_call
2182
+ = name:scalar_func __ LPAREN __ l:expr_list? __ RPAREN __ bc:over_partition? {
2183
+ return {
2184
+ type: 'function',
2185
+ name: { name: [{ type: 'origin', value: name }] },
2186
+ args: l ? l: { type: 'expr_list', value: [] },
2187
+ over: bc,
2188
+ ...getLocationObject(),
2189
+ };
2190
+ }
2191
+ / extract_func / filter_func / trim_func_clause
2192
+ / f:scalar_time_func __ up:on_update_current_timestamp? {
2193
+ return {
2194
+ type: 'function',
2195
+ name: { name: [{ type: 'origin', value: f }] },
2196
+ over: up,
2197
+ ...getLocationObject(),
2198
+ }
2199
+ }
2200
+ / name:(KW_DATE / KW_TIME / KW_TIMESTAMP / 'AT TIME ZONE'i) __ l:or_and_where_expr? __ bc:over_partition? {
2201
+ if (l && l.type !== 'expr_list') l = { type: 'expr_list', value: [l] }
2202
+ return {
2203
+ type: 'function',
2204
+ name: { name: [{ type: 'default', value: name }] },
2205
+ args: l ? l: { type: 'expr_list', value: [] },
2206
+ over: bc,
2207
+ args_parentheses: false,
2208
+ ...getLocationObject(),
2209
+ };
2210
+ }
2211
+ / name:proc_func_name __ LPAREN __ l:or_and_where_expr? __ RPAREN __ bc:over_partition? {
2212
+ if (l && l.type !== 'expr_list') l = { type: 'expr_list', value: [l] }
2213
+ return {
2214
+ type: 'function',
2215
+ name: name,
2216
+ args: l ? l: { type: 'expr_list', value: [] },
2217
+ over: bc,
2218
+ ...getLocationObject(),
2219
+ };
2220
+ }
2221
+ extract_filed
2222
+ = f:('CENTURY'i / 'DAY'i / 'DATE'i / 'DECADE'i / 'DOW'i / 'DOY'i / 'EPOCH'i / 'HOUR'i / 'ISODOW'i / 'ISOYEAR'i / 'MICROSECONDS'i / 'MILLENNIUM'i / 'MILLISECONDS'i / 'MINUTE'i / 'MONTH'i / 'QUARTER'i / 'SECOND'i / 'TIMEZONE'i / 'TIMEZONE_HOUR'i / 'TIMEZONE_MINUTE'i / 'WEEK'i / 'YEAR'i) {
2223
+ // => 'string'
2224
+ return f
2225
+ }
2226
+ extract_func
2227
+ = kw:KW_EXTRACT __ LPAREN __ f:extract_filed __ KW_FROM __ t:(KW_TIMESTAMP / KW_INTERVAL / KW_TIME / KW_DATE)? __ s:expr __ RPAREN {
2228
+ // => { type: 'extract'; args: { field: extract_filed; cast_type: 'TIMESTAMP' | 'INTERVAL' | 'TIME'; source: expr; }}
2229
+ return {
2230
+ type: kw.toLowerCase(),
2231
+ args: {
2232
+ field: f,
2233
+ cast_type: t,
2234
+ source: s,
2235
+ },
2236
+ ...getLocationObject(),
2237
+ }
2238
+ }
2239
+ / kw:KW_EXTRACT __ LPAREN __ f:extract_filed __ KW_FROM __ s:expr __ RPAREN {
2240
+ // => { type: 'extract'; args: { field: extract_filed; source: expr; }}
2241
+ return {
2242
+ type: kw.toLowerCase(),
2243
+ args: {
2244
+ field: f,
2245
+ source: s,
2246
+ },
2247
+ ...getLocationObject(),
2248
+ }
2249
+ }
2250
+ scalar_time_func
2251
+ = KW_CURRENT_DATE
2252
+ / KW_CURRENT_TIME
2253
+ / KW_CURRENT_TIMESTAMP
2254
+ scalar_func
2255
+ = scalar_time_func
2256
+ / KW_CURRENT_USER
2257
+ / KW_USER
2258
+ / KW_SESSION_USER
2259
+ / KW_SYSTEM_USER
2260
+
2261
+ cast_expr
2262
+ = c:(KW_CAST/KW_TRY_CAST) __ LPAREN __ e:expr __ KW_AS __ t:data_type __ RPAREN {
2263
+ return {
2264
+ type: 'cast',
2265
+ keyword: c.toLowerCase(),
2266
+ expr: e,
2267
+ symbol: 'as',
2268
+ target: [t]
2269
+ };
2270
+ }
2271
+ / c:KW_CAST __ LPAREN __ e:expr __ KW_AS __ KW_DECIMAL __ LPAREN __ precision:int __ RPAREN __ RPAREN {
2272
+ return {
2273
+ type: 'cast',
2274
+ keyword: c.toLowerCase(),
2275
+ expr: e,
2276
+ symbol: 'as',
2277
+ target: [{
2278
+ dataType: 'DECIMAL(' + precision + ')'
2279
+ }]
2280
+ };
2281
+ }
2282
+ / c:KW_CAST __ LPAREN __ e:expr __ KW_AS __ KW_DECIMAL __ LPAREN __ precision:int __ COMMA __ scale:int __ RPAREN __ RPAREN {
2283
+ return {
2284
+ type: 'cast',
2285
+ keyword: c.toLowerCase(),
2286
+ expr: e,
2287
+ symbol: 'as',
2288
+ target: [{
2289
+ dataType: 'DECIMAL(' + precision + ', ' + scale + ')'
2290
+ }]
2291
+ };
2292
+ }
2293
+ / c:KW_CAST __ LPAREN __ e:expr __ KW_AS __ s:signedness __ t:KW_INTEGER? __ RPAREN { /* MySQL cast to un-/signed integer */
2294
+ return {
2295
+ type: 'cast',
2296
+ keyword: c.toLowerCase(),
2297
+ expr: e,
2298
+ symbol: 'as',
2299
+ target: [{
2300
+ dataType: s + (t ? ' ' + t: '')
2301
+ }]
2302
+ };
2303
+ }
2304
+
2305
+ signedness
2306
+ = KW_SIGNED
2307
+ / KW_UNSIGNED
2308
+
2309
+ literal
2310
+ = literal_string
2311
+ / literal_numeric
2312
+ / literal_bool
2313
+ / literal_null
2314
+ / literal_datetime
2315
+ / literal_array
2316
+
2317
+ literal_array
2318
+ = s:KW_ARRAY __ LBRAKE __ c:expr_list? __ RBRAKE {
2319
+ return {
2320
+ expr_list: c || { type: 'origin', value: '' },
2321
+ type: 'array',
2322
+ keyword: 'array',
2323
+ brackets: true
2324
+ }
2325
+ }
2326
+
2327
+ literal_list
2328
+ = head:literal tail:(__ COMMA __ literal)* {
2329
+ return createList(head, tail);
2330
+ }
2331
+
2332
+ literal_null
2333
+ = KW_NULL {
2334
+ return { type: 'null', value: null };
2335
+ }
2336
+
2337
+ literal_not_null
2338
+ = KW_NOT_NULL {
2339
+ return {
2340
+ type: 'not null',
2341
+ value: 'not null',
2342
+ }
2343
+ }
2344
+
2345
+ literal_bool
2346
+ = KW_TRUE {
2347
+ return { type: 'bool', value: true };
2348
+ }
2349
+ / KW_FALSE {
2350
+ return { type: 'bool', value: false };
2351
+ }
2352
+
2353
+ literal_string
2354
+ = r:'u&'i ca:("'" single_char* "'") {
2355
+ return {
2356
+ type: 'unicode_string',
2357
+ value: ca[1].join('')
2358
+ };
2359
+ }
2360
+ / ca:("'" single_char* "'") {
2361
+ return {
2362
+ type: 'single_quote_string',
2363
+ value: ca[1].join('')
2364
+ };
2365
+ }
2366
+ / ca:("\"" single_quote_char* "\"") __ !(DOT / LPAREN) {
2367
+ return {
2368
+ type: 'double_quote_string',
2369
+ value: ca[1].join('')
2370
+ };
2371
+ }
2372
+
2373
+ literal_datetime
2374
+ = type:(KW_TIME / KW_DATE / KW_TIMESTAMP / KW_DATETIME) __ ca:("'" single_char* "'") {
2375
+ return {
2376
+ type: type.toLowerCase(),
2377
+ value: ca[1].join('')
2378
+ };
2379
+ }
2380
+ / type:(KW_TIME / KW_DATE / KW_TIMESTAMP / KW_DATETIME) __ ca:("\"" single_quote_char* "\"") {
2381
+ return {
2382
+ type: type.toLowerCase(),
2383
+ value: ca[1].join('')
2384
+ };
2385
+ }
2386
+
2387
+ single_quote_char
2388
+ = [^"\\\0-\x1F\x7f]
2389
+ / escape_char
2390
+
2391
+ single_char
2392
+ = [^'\\]
2393
+ / escape_char
2394
+
2395
+ escape_char
2396
+ = "\\'" { return "\\'"; }
2397
+ / '\\"' { return '\\"'; }
2398
+ / "\\\\" { return "\\\\"; }
2399
+ / "\\/" { return "\\/"; }
2400
+ / "\\b" { return "\b"; }
2401
+ / "\\f" { return "\f"; }
2402
+ / "\\n" { return "\n"; }
2403
+ / "\\r" { return "\r"; }
2404
+ / "\\t" { return "\t"; }
2405
+ / "\\u" h1:hexDigit h2:hexDigit h3:hexDigit h4:hexDigit {
2406
+ return String.fromCharCode(parseInt("0x" + h1 + h2 + h3 + h4));
2407
+ }
2408
+ / "\\" { return "\\"; }
2409
+ / "''" { return "''" }
2410
+ / '""' { return '""' }
2411
+ / '``' { return '``' }
2412
+
2413
+ line_terminator
2414
+ = [\n\r]
2415
+
2416
+ literal_numeric
2417
+ = n:number {
2418
+ if (n && n.type === 'bigint') return n
2419
+ return { type: 'number', value: n };
2420
+ }
2421
+
2422
+ number
2423
+ = int_:int frac:frac exp:exp {
2424
+ const numStr = int_ + frac + exp
2425
+ return {
2426
+ type: 'bigint',
2427
+ value: numStr
2428
+ }
2429
+ }
2430
+ / int_:int frac:frac {
2431
+ const numStr = int_ + frac
2432
+ if (isBigInt(int_)) return {
2433
+ type: 'bigint',
2434
+ value: numStr
2435
+ }
2436
+ return parseFloat(numStr);
2437
+ }
2438
+ / int_:int exp:exp {
2439
+ const numStr = int_ + exp
2440
+ return {
2441
+ type: 'bigint',
2442
+ value: numStr
2443
+ }
2444
+ }
2445
+ / int_:int {
2446
+ if (isBigInt(int_)) return {
2447
+ type: 'bigint',
2448
+ value: int_
2449
+ }
2450
+ return parseFloat(int_);
2451
+ }
2452
+
2453
+ int
2454
+ = digits
2455
+ / digit:digit
2456
+ / op:("-" / "+" ) digits:digits { return op + digits; }
2457
+ / op:("-" / "+" ) digit:digit { return op + digit; }
2458
+
2459
+ frac
2460
+ = "." digits:digits { return "." + digits; }
2461
+
2462
+ exp
2463
+ = e:e digits:digits { return e + digits; }
2464
+
2465
+ digits
2466
+ = digits:digit+ { return digits.join(""); }
2467
+
2468
+ digit = [0-9]
2469
+
2470
+ hexDigit
2471
+ = [0-9a-fA-F]
2472
+
2473
+ e
2474
+ = e:[eE] sign:[+-]? { return e + (sign !== null ? sign: ''); }
2475
+
2476
+
2477
+ KW_NULL = "NULL"i !ident_start
2478
+ KW_DEFAULT = "DEFAULT"i !ident_start
2479
+ KW_NOT_NULL = "NOT NULL"i !ident_start
2480
+ KW_TRUE = "TRUE"i !ident_start
2481
+ KW_TO = "TO"i !ident_start
2482
+ KW_FALSE = "FALSE"i !ident_start
2483
+
2484
+ KW_SHOW = "SHOW"i !ident_start
2485
+ KW_DROP = "DROP"i !ident_start { return 'DROP'; }
2486
+ KW_USE = "USE"i !ident_start
2487
+ KW_ALTER = "ALTER"i !ident_start
2488
+ KW_SELECT = "SELECT"i !ident_start
2489
+ KW_UPDATE = "UPDATE"i !ident_start
2490
+ KW_CREATE = "CREATE"i !ident_start
2491
+ KW_TEMPORARY = "TEMPORARY"i !ident_start
2492
+ KW_DELETE = "DELETE"i !ident_start
2493
+ KW_INSERT = "INSERT"i !ident_start
2494
+ KW_RECURSIVE= "RECURSIVE"i !ident_start
2495
+ KW_REPLACE = "REPLACE"i !ident_start
2496
+ KW_RENAME = "RENAME"i !ident_start
2497
+ KW_IGNORE = "IGNORE"i !ident_start
2498
+ KW_EXPLAIN = "EXPLAIN"i !ident_start
2499
+ KW_PARTITION = "PARTITION"i !ident_start { return 'PARTITION' }
2500
+
2501
+ KW_INTO = "INTO"i !ident_start { return 'INTO'; }
2502
+ KW_OVERWRITE = "OVERWRITE"i !ident_start { return 'OVERWRITE'; }
2503
+ KW_FROM = "FROM"i !ident_start
2504
+ KW_SET = "SET"i !ident_start { return 'SET' }
2505
+ KW_UNLOCK = "UNLOCK"i !ident_start
2506
+ KW_LOCK = "LOCK"i !ident_start
2507
+
2508
+ KW_AS = "AS"i !ident_start
2509
+ KW_TABLE = "TABLE"i !ident_start { return 'TABLE'; }
2510
+ KW_TABLES = "TABLES"i !ident_start { return 'TABLES'; }
2511
+ KW_DATABASE = "DATABASE"i !ident_start { return 'DATABASE'; }
2512
+ KW_SCHEMA = "SCHEMA"i !ident_start { return 'SCHEMA'; }
2513
+ KW_COLLATE = "COLLATE"i !ident_start { return 'COLLATE'; }
2514
+
2515
+ KW_ON = "ON"i !ident_start
2516
+ KW_LEFT = "LEFT"i !ident_start
2517
+ KW_RIGHT = "RIGHT"i !ident_start
2518
+ KW_FULL = "FULL"i !ident_start
2519
+ KW_CROSS = "CROSS"i !ident_start
2520
+ KW_INNER = "INNER"i !ident_start
2521
+ KW_JOIN = "JOIN"i !ident_start
2522
+ KW_OUTER = "OUTER"i !ident_start
2523
+ KW_OVER = "OVER"i !ident_start
2524
+ KW_UNION = "UNION"i !ident_start
2525
+ KW_VALUES = "VALUES"i !ident_start
2526
+ KW_USING = "USING"i !ident_start
2527
+
2528
+ KW_WHERE = "WHERE"i !ident_start
2529
+ KW_WITH = "WITH"i !ident_start
2530
+
2531
+ KW_GROUP = "GROUP"i !ident_start
2532
+ KW_BY = "BY"i !ident_start
2533
+ KW_ORDER = "ORDER"i !ident_start
2534
+ KW_HAVING = "HAVING"i !ident_start
2535
+
2536
+ KW_LIMIT = "LIMIT"i !ident_start
2537
+ KW_OFFSET = "OFFSET"i !ident_start { return 'OFFSET'; }
2538
+
2539
+ KW_ASC = "ASC"i !ident_start { return 'ASC'; }
2540
+ KW_DESC = "DESC"i !ident_start { return 'DESC'; }
2541
+
2542
+ KW_ALL = "ALL"i !ident_start { return 'ALL'; }
2543
+ KW_DISTINCT = "DISTINCT"i !ident_start { return 'DISTINCT';}
2544
+
2545
+ KW_BETWEEN = "BETWEEN"i !ident_start { return 'BETWEEN'; }
2546
+ KW_IN = "IN"i !ident_start { return 'IN'; }
2547
+ KW_IS = "IS"i !ident_start { return 'IS'; }
2548
+ KW_LIKE = "LIKE"i !ident_start { return 'LIKE'; }
2549
+ KW_RLIKE = "RLIKE"i !ident_start { return 'RLIKE'; }
2550
+ KW_EXISTS = "EXISTS"i !ident_start { return 'EXISTS'; }
2551
+
2552
+ KW_NOT = "NOT"i !ident_start { return 'NOT'; }
2553
+ KW_AND = "AND"i !ident_start { return 'AND'; }
2554
+ KW_OR = "OR"i !ident_start { return 'OR'; }
2555
+
2556
+ KW_COUNT = "COUNT"i !ident_start { return 'COUNT'; }
2557
+ KW_MAX = "MAX"i !ident_start { return 'MAX'; }
2558
+ KW_MIN = "MIN"i !ident_start { return 'MIN'; }
2559
+ KW_SUM = "SUM"i !ident_start { return 'SUM'; }
2560
+ KW_AVG = "AVG"i !ident_start { return 'AVG'; }
2561
+
2562
+ KW_EXTRACT = "EXTRACT"i !ident_start { return 'EXTRACT'; }
2563
+ KW_CALL = "CALL"i !ident_start { return 'CALL'; }
2564
+
2565
+ KW_CASE = "CASE"i !ident_start
2566
+ KW_WHEN = "WHEN"i !ident_start
2567
+ KW_THEN = "THEN"i !ident_start
2568
+ KW_ELSE = "ELSE"i !ident_start
2569
+ KW_END = "END"i !ident_start
2570
+
2571
+ KW_CAST = "CAST"i !ident_start { return 'CAST' }
2572
+ KW_TRY_CAST = "TRY_CAST"i !ident_start { return 'TRY_CAST' }
2573
+
2574
+ KW_ARRAY = "ARRAY"i !ident_start { return 'ARRAY'; }
2575
+ KW_ARRAY_AGG = "ARRAY_AGG"i !ident_start { return 'ARRAY_AGG'; }
2576
+ KW_CHAR = "CHAR"i !ident_start { return 'CHAR'; }
2577
+ KW_VARCHAR = "VARCHAR"i !ident_start { return 'VARCHAR';}
2578
+ KW_NUMERIC = "NUMERIC"i !ident_start { return 'NUMERIC'; }
2579
+ KW_DECIMAL = "DECIMAL"i !ident_start { return 'DECIMAL'; }
2580
+ KW_SIGNED = "SIGNED"i !ident_start { return 'SIGNED'; }
2581
+ KW_STRING = "STRING"i !ident_start { return 'STRING'; }
2582
+ KW_UNSIGNED = "UNSIGNED"i !ident_start { return 'UNSIGNED'; }
2583
+ KW_INT = "INT"i !ident_start { return 'INT'; }
2584
+ KW_ZEROFILL = "ZEROFILL"i !ident_start { return 'ZEROFILL'; }
2585
+ KW_INTEGER = "INTEGER"i !ident_start { return 'INTEGER'; }
2586
+ KW_JSON = "JSON"i !ident_start { return 'JSON'; }
2587
+ KW_BOOLEAN = "BOOLEAN"i !ident_start { return 'BOOLEAN'; }
2588
+ KW_MAP = "MAP"i !ident_start { return 'MAP'; }
2589
+ KW_SMALLINT = "SMALLINT"i !ident_start { return 'SMALLINT'; }
2590
+ KW_TINYINT = "TINYINT"i !ident_start { return 'TINYINT'; }
2591
+ KW_TINYTEXT = "TINYTEXT"i !ident_start { return 'TINYTEXT'; }
2592
+ KW_TEXT = "TEXT"i !ident_start { return 'TEXT'; }
2593
+ KW_MEDIUMTEXT = "MEDIUMTEXT"i !ident_start { return 'MEDIUMTEXT'; }
2594
+ KW_LONGTEXT = "LONGTEXT"i !ident_start { return 'LONGTEXT'; }
2595
+ KW_BIGINT = "BIGINT"i !ident_start { return 'BIGINT'; }
2596
+ KW_FLOAT = "FLOAT"i !ident_start { return 'FLOAT'; }
2597
+ KW_REAL = "REAL"i !ident_start { return 'REAL'; }
2598
+ KW_DOUBLE = "DOUBLE"i !ident_start { return 'DOUBLE'; }
2599
+ KW_DATE = "DATE"i !ident_start { return 'DATE'; }
2600
+ KW_DATETIME = "DATETIME"i !ident_start { return 'DATETIME'; }
2601
+ KW_ROWS = "ROWS"i !ident_start { return 'ROWS'; }
2602
+ KW_TIME = "TIME"i !ident_start { return 'TIME'; }
2603
+ KW_TIMESTAMP= "TIMESTAMP"i!ident_start { return 'TIMESTAMP'; }
2604
+ KW_TRUNCATE = "TRUNCATE"i !ident_start { return 'TRUNCATE'; }
2605
+ KW_USER = "USER"i !ident_start { return 'USER'; }
2606
+
2607
+ KW_CURRENT_DATE = "CURRENT_DATE"i !ident_start { return 'CURRENT_DATE'; }
2608
+ KW_ADD_DATE = "ADDDATE"i !ident_start { return 'ADDDATE'; }
2609
+ KW_INTERVAL = "INTERVAL"i !ident_start { return 'INTERVAL'; }
2610
+ KW_UNIT_YEAR = "YEAR"i !ident_start { return 'YEAR'; }
2611
+ KW_UNIT_MONTH = "MONTH"i !ident_start { return 'MONTH'; }
2612
+ KW_UNIT_DAY = "DAY"i !ident_start { return 'DAY'; }
2613
+ KW_UNIT_HOUR = "HOUR"i !ident_start { return 'HOUR'; }
2614
+ KW_UNIT_MINUTE = "MINUTE"i !ident_start { return 'MINUTE'; }
2615
+ KW_UNIT_SECOND = "SECOND"i !ident_start { return 'SECOND'; }
2616
+ KW_CURRENT_TIME = "CURRENT_TIME"i !ident_start { return 'CURRENT_TIME'; }
2617
+ KW_CURRENT_TIMESTAMP= "CURRENT_TIMESTAMP"i !ident_start { return 'CURRENT_TIMESTAMP'; }
2618
+ KW_CURRENT_USER = "CURRENT_USER"i !ident_start { return 'CURRENT_USER'; }
2619
+ KW_SESSION_USER = "SESSION_USER"i !ident_start { return 'SESSION_USER'; }
2620
+ KW_SYSTEM_USER = "SYSTEM_USER"i !ident_start { return 'SYSTEM_USER'; }
2621
+
2622
+ KW_GLOBAL = "GLOBAL"i !ident_start { return 'GLOBAL'; }
2623
+ KW_SESSION = "SESSION"i !ident_start { return 'SESSION'; }
2624
+ KW_LOCAL = "LOCAL"i !ident_start { return 'LOCAL'; }
2625
+ KW_PERSIST = "PERSIST"i !ident_start { return 'PERSIST'; }
2626
+ KW_PERSIST_ONLY = "PERSIST_ONLY"i !ident_start { return 'PERSIST_ONLY'; }
2627
+
2628
+ KW_VAR__PRE_AT = '@'
2629
+ KW_VAR__PRE_AT_AT = '@@'
2630
+ KW_VAR_PRE_DOLLAR = '$'
2631
+ KW_VAR_PRE
2632
+ = KW_VAR__PRE_AT_AT / KW_VAR__PRE_AT / KW_VAR_PRE_DOLLAR
2633
+ KW_RETURN = 'return'i
2634
+ KW_ASSIGN = ':='
2635
+ KW_ASSIGIN_EQUAL = '='
2636
+
2637
+ KW_DUAL = "DUAL"i
2638
+
2639
+ // MySQL Alter
2640
+ KW_ADD = "ADD"i !ident_start { return 'ADD'; }
2641
+ KW_COLUMN = "COLUMN"i !ident_start { return 'COLUMN'; }
2642
+ KW_INDEX = "INDEX"i !ident_start { return 'INDEX'; }
2643
+ KW_KEY = "KEY"i !ident_start { return 'KEY'; }
2644
+ KW_FULLTEXT = "FULLTEXT"i !ident_start { return 'FULLTEXT'; }
2645
+ KW_SPATIAL = "SPATIAL"i !ident_start { return 'SPATIAL'; }
2646
+ KW_UNIQUE = "UNIQUE"i !ident_start { return 'UNIQUE'; }
2647
+ KW_KEY_BLOCK_SIZE = "KEY_BLOCK_SIZE"i !ident_start { return 'KEY_BLOCK_SIZE'; }
2648
+ KW_COMMENT = "COMMENT"i !ident_start { return 'COMMENT'; }
2649
+ KW_CONSTRAINT = "CONSTRAINT"i !ident_start { return 'CONSTRAINT'; }
2650
+ KW_REFERENCES = "REFERENCES"i !ident_start { return 'REFERENCES'; }
2651
+
2652
+
2653
+
2654
+ // MySQL extensions to SQL
2655
+ OPT_SQL_CALC_FOUND_ROWS = "SQL_CALC_FOUND_ROWS"i
2656
+ OPT_SQL_CACHE = "SQL_CACHE"i
2657
+ OPT_SQL_NO_CACHE = "SQL_NO_CACHE"i
2658
+ OPT_SQL_SMALL_RESULT = "SQL_SMALL_RESULT"i
2659
+ OPT_SQL_BIG_RESULT = "SQL_BIG_RESULT"i
2660
+ OPT_SQL_BUFFER_RESULT = "SQL_BUFFER_RESULT"i
2661
+
2662
+ //special character
2663
+ DOT = '.'
2664
+ COMMA = ','
2665
+ STAR = '*'
2666
+ LPAREN = '('
2667
+ RPAREN = ')'
2668
+ LANGLE_BRACKET = '<'
2669
+ RANGLE_BRACKET = '>'
2670
+ LBRAKE = '['
2671
+ RBRAKE = ']'
2672
+
2673
+ SEMICOLON = ';'
2674
+ SINGLE_ARROW = '->'
2675
+ OPERATOR_CONCATENATION = '||'
2676
+ OPERATOR_AND = '&&'
2677
+ LOGIC_OPERATOR = OPERATOR_CONCATENATION / OPERATOR_AND
2678
+
2679
+ // separator
2680
+ __
2681
+ = (whitespace / comment)*
2682
+
2683
+ ___
2684
+ = (whitespace / comment)+
2685
+
2686
+ comment
2687
+ = block_comment
2688
+ / line_comment
2689
+ / pound_sign_comment
2690
+
2691
+ block_comment
2692
+ = "/*" (!"*/" char)* "*/"
2693
+
2694
+ line_comment
2695
+ = "--" (!EOL char)*
2696
+
2697
+ pound_sign_comment
2698
+ = "#" (!EOL char)*
2699
+
2700
+ keyword_comment
2701
+ = k:KW_COMMENT __ s:KW_ASSIGIN_EQUAL? __ c:literal_string {
2702
+ return {
2703
+ type: k.toLowerCase(),
2704
+ keyword: k.toLowerCase(),
2705
+ symbol: s,
2706
+ value: c,
2707
+ }
2708
+ }
2709
+
2710
+ char = .
2711
+
2712
+ interval_unit
2713
+ = KW_UNIT_YEAR
2714
+ / KW_UNIT_MONTH
2715
+ / KW_UNIT_DAY
2716
+ / KW_UNIT_HOUR
2717
+ / KW_UNIT_MINUTE
2718
+ / KW_UNIT_SECOND
2719
+
2720
+ whitespace =
2721
+ [ \t\n\r]
2722
+
2723
+ EOL
2724
+ = EOF
2725
+ / [\n\r]+
2726
+
2727
+ EOF = !.
2728
+
2729
+ //begin procedure extension
2730
+ proc_stmts
2731
+ = proc_stmt*
2732
+
2733
+ proc_stmt
2734
+ = &{ varList = []; return true; } __ s:(assign_stmt / return_stmt) {
2735
+ return { stmt: s, vars: varList };
2736
+ }
2737
+
2738
+ assign_stmt_list
2739
+ = head:assign_stmt tail:(__ COMMA __ assign_stmt)* {
2740
+ return createList(head, tail);
2741
+ }
2742
+
2743
+ assign_stmt
2744
+ = va:(var_decl / without_prefix_var_decl) __ s: (KW_ASSIGN / KW_ASSIGIN_EQUAL) __ e:proc_expr {
2745
+ return {
2746
+ type: 'assign',
2747
+ left: va,
2748
+ symbol: s,
2749
+ right: e
2750
+ };
2751
+ }
2752
+
2753
+
2754
+ return_stmt
2755
+ = KW_RETURN __ e:proc_expr {
2756
+ return { type: 'return', expr: e };
2757
+ }
2758
+
2759
+ proc_expr
2760
+ = select_stmt
2761
+ / proc_join
2762
+ / proc_additive_expr
2763
+ / proc_array
2764
+
2765
+ proc_additive_expr
2766
+ = head:proc_multiplicative_expr
2767
+ tail:(__ additive_operator __ proc_multiplicative_expr)* {
2768
+ return createBinaryExprChain(head, tail);
2769
+ }
2770
+
2771
+ proc_multiplicative_expr
2772
+ = head:proc_primary
2773
+ tail:(__ multiplicative_operator __ proc_primary)* {
2774
+ return createBinaryExprChain(head, tail);
2775
+ }
2776
+
2777
+ proc_join
2778
+ = lt:var_decl __ op:join_op __ rt:var_decl __ expr:on_clause {
2779
+ return {
2780
+ type: 'join',
2781
+ ltable: lt,
2782
+ rtable: rt,
2783
+ op: op,
2784
+ on: expr
2785
+ };
2786
+ }
2787
+
2788
+ proc_primary
2789
+ = literal
2790
+ / var_decl
2791
+ / proc_func_call
2792
+ / param
2793
+ / LPAREN __ e:proc_additive_expr __ RPAREN {
2794
+ e.parentheses = true;
2795
+ return e;
2796
+ }
2797
+
2798
+ proc_func_name
2799
+ = dt:ident_without_kw_type tail:(__ DOT __ ident_without_kw_type)? {
2800
+ const result = { name: [dt] }
2801
+ if (tail !== null) {
2802
+ result.schema = dt
2803
+ result.name = [tail[3]]
2804
+ }
2805
+ return result
2806
+ }
2807
+
2808
+ proc_func_call
2809
+ = name:proc_func_name __ LPAREN __ l:proc_primary_list? __ RPAREN {
2810
+ //compatible with original func_call
2811
+ return {
2812
+ type: 'function',
2813
+ name: name,
2814
+ args: {
2815
+ type: 'expr_list',
2816
+ value: l
2817
+ },
2818
+ ...getLocationObject(),
2819
+ };
2820
+ }
2821
+ / name:proc_func_name {
2822
+ return {
2823
+ type: 'function',
2824
+ name: name,
2825
+ args: null,
2826
+ ...getLocationObject(),
2827
+ };
2828
+ }
2829
+
2830
+ proc_primary_list
2831
+ = head:proc_primary tail:(__ COMMA __ proc_primary)* {
2832
+ return createList(head, tail);
2833
+ }
2834
+
2835
+ proc_array =
2836
+ LBRAKE __ l:proc_primary_list __ RBRAKE {
2837
+ return { type: 'array', value: l };
2838
+ }
2839
+
2840
+ var_decl
2841
+ = p: KW_VAR_PRE d: without_prefix_var_decl {
2842
+ //push for analysis
2843
+ return {
2844
+ type: 'var',
2845
+ ...d,
2846
+ prefix: p
2847
+ };
2848
+ }
2849
+
2850
+ without_prefix_var_decl
2851
+ = name:ident_name m:mem_chain {
2852
+ //push for analysis
2853
+ varList.push(name);
2854
+ return {
2855
+ type: 'var',
2856
+ name: name,
2857
+ members: m,
2858
+ prefix: null,
2859
+ };
2860
+ }
2861
+ / n:literal_numeric {
2862
+ return {
2863
+ type: 'var',
2864
+ name: n.value,
2865
+ members: [],
2866
+ quoted: null,
2867
+ prefix: null,
2868
+ }
2869
+ }
2870
+
2871
+ mem_chain
2872
+ = l:('.' ident_name)* {
2873
+ const s = [];
2874
+ for (let i = 0; i < l.length; i++) {
2875
+ s.push(l[i][1]);
2876
+ }
2877
+ return s;
2878
+ }
2879
+
2880
+ data_type
2881
+ = data_type_item
2882
+ / array_type
2883
+ / map_type
2884
+
2885
+ data_type_item
2886
+ = character_string_type
2887
+ / numeric_type
2888
+ / datetime_type
2889
+ / json_type
2890
+ / boolean_type
2891
+ / map_type
2892
+ / text_type
2893
+
2894
+ data_type_list
2895
+ = head:data_type_item tail:(__ COMMA __ data_type_item)* {
2896
+ return createList(head, tail);
2897
+ }
2898
+
2899
+ array_type
2900
+ = t:KW_ARRAY __ LPAREN __ a:data_type_list __ RPAREN {
2901
+ return {
2902
+ dataType: t,
2903
+ parentheses: true,
2904
+ expr: {
2905
+ type: 'expr_list',
2906
+ value: a.map(d => ({ type: 'datatype', ...d }))
2907
+ },
2908
+ }
2909
+ }
2910
+ / t:KW_ARRAY __ LANGLE_BRACKET __ a:data_type_list __ RANGLE_BRACKET {
2911
+ return {
2912
+ dataType: t,
2913
+ angle_brackets: true,
2914
+ expr: {
2915
+ type: 'expr_list',
2916
+ value: a.map(d => ({ type: 'datatype', ...d }))
2917
+ },
2918
+ }
2919
+ }
2920
+
2921
+ map_type
2922
+ = t:KW_MAP __ LPAREN __ a:data_type_list __ RPAREN {
2923
+ return {
2924
+ dataType: t,
2925
+ parentheses: true,
2926
+ expr: {
2927
+ type: 'expr_list',
2928
+ value: a.map(d => ({ type: 'datatype', ...d }))
2929
+ },
2930
+ }
2931
+ }
2932
+ / t:KW_MAP __ LANGLE_BRACKET __ a:data_type_list __ RANGLE_BRACKET {
2933
+ return {
2934
+ dataType: t,
2935
+ angle_brackets: true,
2936
+ expr: {
2937
+ type: 'expr_list',
2938
+ value: a.map(d => ({ type: 'datatype', ...d }))
2939
+ },
2940
+ }
2941
+ }
2942
+
2943
+ character_string_type
2944
+ = t:(KW_CHAR / KW_VARCHAR) __ LPAREN __ l:[0-9]+ __ RPAREN {
2945
+ return { dataType: t, length: parseInt(l.join(''), 10), parentheses: true };
2946
+ }
2947
+ / t:(KW_CHAR / KW_VARCHAR / KW_STRING) { return { dataType: t }; }
2948
+
2949
+ numeric_type_suffix
2950
+ = un: KW_UNSIGNED? __ ze: KW_ZEROFILL? {
2951
+ const result = []
2952
+ if (un) result.push(un)
2953
+ if (ze) result.push(ze)
2954
+ return result
2955
+ }
2956
+ numeric_type
2957
+ = t:(KW_NUMERIC / KW_DECIMAL / KW_INT / KW_INTEGER / KW_SMALLINT / KW_TINYINT / KW_BIGINT / KW_FLOAT / KW_DOUBLE / KW_REAL) __ LPAREN __ l:[0-9]+ __ r:(COMMA __ [0-9]+)? __ RPAREN __ s:numeric_type_suffix? { return { dataType: t, length: parseInt(l.join(''), 10), scale: r && parseInt(r[2].join(''), 10), parentheses: true, suffix: s }; }
2958
+ / t:(KW_NUMERIC / KW_DECIMAL / KW_INT / KW_INTEGER / KW_SMALLINT / KW_TINYINT / KW_BIGINT / KW_FLOAT / KW_DOUBLE / KW_REAL)l:[0-9]+ __ s:numeric_type_suffix? { return { dataType: t, length: parseInt(l.join(''), 10), suffix: s }; }
2959
+ / t:(KW_NUMERIC / KW_DECIMAL / KW_INT / KW_INTEGER / KW_SMALLINT / KW_TINYINT / KW_BIGINT / KW_FLOAT / KW_DOUBLE / KW_REAL) __ s:numeric_type_suffix? __{ return { dataType: t, suffix: s }; }
2960
+ datetime_type
2961
+ = t:(KW_DATE / KW_DATETIME / KW_TIME / KW_TIMESTAMP) __ LPAREN __ l:[0-9]+ __ RPAREN { return { dataType: t, length: parseInt(l.join(''), 10), parentheses: true }; }
2962
+ / t:(KW_DATE / KW_DATETIME / KW_TIME / KW_TIMESTAMP) { return { dataType: t }; }
2963
+
2964
+ json_type
2965
+ = t:KW_JSON { return { dataType: t }; }
2966
+
2967
+ boolean_type
2968
+ = t:KW_BOOLEAN { return { dataType: t }; }
2969
+
2970
+ text_type
2971
+ = t:(KW_TINYTEXT / KW_TEXT / KW_MEDIUMTEXT / KW_LONGTEXT) { return { dataType: t }}