@checkdigit/eslint-plugin 7.17.1 → 7.18.0-PR.143-8290

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 (80) hide show
  1. package/dist-mjs/athena/api-locator.mjs +30 -0
  2. package/dist-mjs/athena/api-matcher.mjs +108 -0
  3. package/dist-mjs/athena/athena.mjs +331 -0
  4. package/dist-mjs/athena/column.mjs +1 -0
  5. package/dist-mjs/athena/context.mjs +21 -0
  6. package/dist-mjs/athena/index.mjs +1 -0
  7. package/dist-mjs/athena/service-table.mjs +32 -0
  8. package/dist-mjs/athena/types.mjs +1 -0
  9. package/dist-mjs/athena/visitor.mjs +258 -0
  10. package/dist-mjs/index.mjs +8 -4
  11. package/dist-mjs/no-status-code-assert.mjs +1 -1
  12. package/dist-mjs/openapi/deref-schema.mjs +14 -0
  13. package/dist-mjs/openapi/generate-schema.mjs +273 -0
  14. package/dist-mjs/openapi/service-schema-generator.mjs +147 -0
  15. package/dist-mjs/peggy/athena-peggy.mjs +20629 -0
  16. package/dist-types/athena/api-locator.d.ts +2 -0
  17. package/dist-types/athena/api-matcher.d.ts +14 -0
  18. package/dist-types/athena/athena.d.ts +6 -0
  19. package/dist-types/athena/column.d.ts +1 -0
  20. package/dist-types/athena/context.d.ts +21 -0
  21. package/dist-types/athena/index.d.ts +8 -0
  22. package/dist-types/athena/service-table.d.ts +8 -0
  23. package/dist-types/athena/types.d.ts +474 -0
  24. package/dist-types/athena/visitor.d.ts +63 -0
  25. package/dist-types/no-status-code-assert.d.ts +1 -1
  26. package/dist-types/openapi/deref-schema.d.ts +1 -0
  27. package/dist-types/openapi/generate-schema.d.ts +33 -0
  28. package/dist-types/openapi/service-schema-generator.d.ts +5 -0
  29. package/dist-types/peggy/athena-peggy.d.ts +13 -0
  30. package/package.json +1 -96
  31. package/src/athena/ATHENA.md +387 -0
  32. package/src/athena/PLAN.md +355 -0
  33. package/src/athena/api-locator.ts +39 -0
  34. package/src/athena/api-matcher.ts +169 -0
  35. package/src/athena/athena.ts +491 -0
  36. package/src/athena/column.ts +2 -0
  37. package/src/athena/context.ts +47 -0
  38. package/src/athena/index.ts +11 -0
  39. package/src/athena/service-table.ts +55 -0
  40. package/src/athena/types.ts +526 -0
  41. package/src/athena/visitor.ts +365 -0
  42. package/src/index.ts +4 -0
  43. package/src/no-side-effects.ts +1 -1
  44. package/src/no-status-code-assert.ts +2 -2
  45. package/src/openapi/deref-schema.ts +14 -0
  46. package/src/openapi/generate-schema.ts +422 -0
  47. package/src/openapi/service-schema-generator.ts +189 -0
  48. package/src/peggy/athena-chat.peggy +608 -0
  49. package/src/peggy/athena-peggy.ts +22078 -0
  50. package/src/peggy/athena.peggy +2967 -0
  51. package/src/require-service-call-response-declaration.ts +2 -2
  52. package/src/services/interchange/v1/swagger.schema.deref.json +849 -0
  53. package/src/services/interchange/v1/swagger.schema.json +473 -0
  54. package/src/services/interchange/v1/swagger.yml +414 -0
  55. package/src/services/ledger/v1/swagger.schema.deref.json +6694 -0
  56. package/src/services/ledger/v1/swagger.schema.json +1820 -0
  57. package/src/services/ledger/v1/swagger.yml +1094 -0
  58. package/src/services/link/v1/swagger.schema.deref.json +648 -0
  59. package/src/services/link/v1/swagger.schema.json +444 -0
  60. package/src/services/link/v1/swagger.yml +343 -0
  61. package/src/services/message/v1/swagger.schema.deref.json +22049 -0
  62. package/src/services/message/v1/swagger.schema.json +3470 -0
  63. package/src/services/message/v1/swagger.yml +2798 -0
  64. package/src/services/message/v2/swagger.schema.deref.json +72221 -0
  65. package/src/services/message/v2/swagger.schema.json +3558 -0
  66. package/src/services/message/v2/swagger.yml +3009 -0
  67. package/src/services/paymentCard/v1/swagger.schema.deref.json +4346 -0
  68. package/src/services/paymentCard/v1/swagger.schema.json +2181 -0
  69. package/src/services/paymentCard/v1/swagger.yml +1161 -0
  70. package/src/services/paymentCard/v2/swagger.schema.deref.json +4336 -0
  71. package/src/services/paymentCard/v2/swagger.schema.json +2155 -0
  72. package/src/services/paymentCard/v2/swagger.yml +1149 -0
  73. package/src/services/person/v1/swagger.schema.deref.json +6786 -0
  74. package/src/services/person/v1/swagger.schema.json +1445 -0
  75. package/src/services/person/v1/swagger.yml +1157 -0
  76. package/src/services/teampayApproval/v1/swagger.schema.deref.json +9898 -0
  77. package/src/services/teampayCardManagement/v1/swagger.schema.deref.json +6187 -0
  78. package/src/services/teampayClientManagement/v1/swagger.schema.deref.json +4914 -0
  79. package/src/services/teampayClientManagement/v1/swagger.schema.json +1964 -0
  80. package/src/services/teampayClientManagement/v1/swagger.yml +1376 -0
@@ -0,0 +1,2967 @@
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:(func_call / alias_ident) { return i; }
1103
+
1104
+ alias_clause
1105
+ = KW_AS __ i:(func_call / alias_ident) { 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;
1243
+ } else {
1244
+ return {
1245
+ db: t.db,
1246
+ table: t.table,
1247
+ as: alias
1248
+ };
1249
+ }
1250
+ }
1251
+ / LPAREN __ stmt:union_stmt __ RPAREN __ alias:alias_clause? {
1252
+ stmt.parentheses = true;
1253
+ return {
1254
+ expr: stmt,
1255
+ as: alias
1256
+ };
1257
+ }
1258
+ / LPAREN __ stmt:table_ref_list __ RPAREN __ alias:alias_clause? {
1259
+ stmt = { type: 'tables', expr: stmt, parentheses: true }
1260
+ return {
1261
+ expr: stmt,
1262
+ as: alias
1263
+ };
1264
+ }
1265
+
1266
+ join_op
1267
+ = KW_LEFT __ KW_OUTER? __ KW_JOIN { return 'LEFT JOIN'; }
1268
+ / KW_RIGHT __ KW_OUTER? __ KW_JOIN { return 'RIGHT JOIN'; }
1269
+ / KW_FULL __ KW_OUTER? __ KW_JOIN { return 'FULL JOIN'; }
1270
+ / (KW_INNER __)? KW_JOIN { return 'INNER JOIN'; }
1271
+ / KW_CROSS __ KW_JOIN { return 'CROSS JOIN'; }
1272
+
1273
+ table_name
1274
+ = dt:ident tail:(__ DOT __ ident)? {
1275
+ const obj = { db: null, table: dt };
1276
+ if (tail !== null) {
1277
+ obj.db = dt;
1278
+ obj.table = tail[3];
1279
+ }
1280
+ return obj;
1281
+ }
1282
+ / v:var_decl {
1283
+ v.db = null;
1284
+ v.table = v.name;
1285
+ return v;
1286
+ }
1287
+
1288
+ or_and_expr
1289
+ = head:expr tail:(__ (KW_AND / KW_OR) __ expr)* {
1290
+ const len = tail.length
1291
+ let result = head
1292
+ for (let i = 0; i < len; ++i) {
1293
+ result = createBinaryExpr(tail[i][1], result, tail[i][3])
1294
+ }
1295
+ return result
1296
+ }
1297
+
1298
+ on_clause
1299
+ = KW_ON __ e:or_and_where_expr { return e; }
1300
+
1301
+ where_clause
1302
+ = KW_WHERE __ e:or_and_where_expr { return e; }
1303
+
1304
+ group_by_clause
1305
+ = KW_GROUP __ KW_BY __ e:expr_list {
1306
+ return {
1307
+ columns: e.value
1308
+ }
1309
+ }
1310
+
1311
+ column_ref_list
1312
+ = head:column_ref tail:(__ COMMA __ column_ref)* {
1313
+ return createList(head, tail);
1314
+ }
1315
+
1316
+ having_clause
1317
+ = KW_HAVING __ e:or_and_where_expr { return e; }
1318
+
1319
+ as_window_specification
1320
+ = ident_name
1321
+ / LPAREN __ ws:window_specification? __ RPAREN {
1322
+ return {
1323
+ window_specification: ws || {},
1324
+ parentheses: true
1325
+ }
1326
+ }
1327
+
1328
+ window_specification
1329
+ = bc:partition_by_clause? __
1330
+ l:order_by_clause? __
1331
+ w:window_frame_clause? {
1332
+ return {
1333
+ name: null,
1334
+ partitionby: bc,
1335
+ orderby: l,
1336
+ window_frame_clause: w
1337
+ }
1338
+ }
1339
+
1340
+ window_specification_frameless
1341
+ = bc:partition_by_clause? __
1342
+ l:order_by_clause? {
1343
+ return {
1344
+ name: null,
1345
+ partitionby: bc,
1346
+ orderby: l,
1347
+ window_frame_clause: null
1348
+ }
1349
+ }
1350
+
1351
+ window_frame_clause
1352
+ = kw:KW_ROWS __ s:(window_frame_following / window_frame_preceding) {
1353
+ return {
1354
+ type: 'rows',
1355
+ expr: s
1356
+ }
1357
+ }
1358
+ / KW_ROWS __ op:KW_BETWEEN __ p:window_frame_preceding __ KW_AND __ f:(window_frame_following / window_frame_preceding) {
1359
+ const left = {
1360
+ type: 'origin',
1361
+ value: 'rows',
1362
+ }
1363
+ const right = {
1364
+ type: 'expr_list',
1365
+ value: [p, f]
1366
+ }
1367
+ return createBinaryExpr(op, left, right)
1368
+ }
1369
+
1370
+ window_frame_following
1371
+ = s:window_frame_value __ 'FOLLOWING'i {
1372
+ // => string
1373
+ s.value += ' FOLLOWING'
1374
+ return s
1375
+ }
1376
+ / window_frame_current_row
1377
+
1378
+ window_frame_preceding
1379
+ = s:window_frame_value __ 'PRECEDING'i {
1380
+ // => string
1381
+ s.value += ' PRECEDING'
1382
+ return s
1383
+ }
1384
+ / window_frame_current_row
1385
+
1386
+ window_frame_current_row
1387
+ = 'CURRENT'i __ 'ROW'i {
1388
+ return { type: 'origin', value: 'current row' }
1389
+ }
1390
+
1391
+ window_frame_value
1392
+ = s:'UNBOUNDED'i {
1393
+ // => literal_string
1394
+ return { type: 'origin', value: s.toUpperCase() }
1395
+ }
1396
+ / literal_numeric
1397
+
1398
+ order_by_clause
1399
+ = KW_ORDER __ KW_BY __ l:order_by_list { return l; }
1400
+
1401
+ partition_by_clause
1402
+ = KW_PARTITION __ KW_BY __ bc:column_clause { return bc; }
1403
+
1404
+ order_by_list
1405
+ = head:order_by_element tail:(__ COMMA __ order_by_element)* {
1406
+ return createList(head, tail);
1407
+ }
1408
+
1409
+ order_by_element
1410
+ = e:expr __ d:(KW_DESC / KW_ASC)? {
1411
+ const obj = { expr: e, type: d };
1412
+ return obj;
1413
+ }
1414
+
1415
+ number_or_param
1416
+ = literal_numeric
1417
+ / param
1418
+
1419
+ limit_clause
1420
+ = KW_LIMIT __ i1:(number_or_param) __ tail:((COMMA / KW_OFFSET) __ number_or_param)? {
1421
+ const res = [i1];
1422
+ if (tail) res.push(tail[2]);
1423
+ return {
1424
+ seperator: tail && tail[0] && tail[0].toLowerCase() || '',
1425
+ value: res
1426
+ };
1427
+ }
1428
+
1429
+ update_stmt
1430
+ = KW_UPDATE __
1431
+ t:table_ref_list __
1432
+ KW_SET __
1433
+ l:set_list __
1434
+ w:where_clause? {
1435
+ const dbObj = {}
1436
+ if (t) t.forEach(tableInfo => {
1437
+ const { db, as, table, join } = tableInfo
1438
+ const action = join ? 'select' : 'update'
1439
+ if (db) dbObj[table] = db
1440
+ if (table) tableList.add(`${action}::${db}::${table}`)
1441
+ });
1442
+ if(l) {
1443
+ l.forEach(col => {
1444
+ if (col.table) {
1445
+ const table = queryTableAlias(col.table)
1446
+ tableList.add(`update::${dbObj[table] || null}::${table}`)
1447
+ }
1448
+ columnList.add(`update::${col.table}::${col.column}`)
1449
+ });
1450
+ }
1451
+ return {
1452
+ tableList: Array.from(tableList),
1453
+ columnList: columnListTableAlias(columnList),
1454
+ ast: {
1455
+ type: 'update',
1456
+ table: t,
1457
+ set: l,
1458
+ where: w
1459
+ }
1460
+ };
1461
+ }
1462
+
1463
+ delete_stmt
1464
+ = KW_DELETE __
1465
+ t: table_ref_list? __
1466
+ f:from_clause __
1467
+ w:where_clause? {
1468
+ if(f) f.forEach(tableInfo => {
1469
+ const { db, as, table, join } = tableInfo
1470
+ const action = join ? 'select' : 'delete'
1471
+ if (table) tableList.add(`${action}::${db}::${table}`)
1472
+ if (!join) columnList.add(`delete::${table}::(.*)`);
1473
+ });
1474
+ if (t === null && f.length === 1) {
1475
+ const tableInfo = f[0]
1476
+ t = [{
1477
+ db: tableInfo.db,
1478
+ table: tableInfo.table,
1479
+ as: tableInfo.as,
1480
+ addition: true
1481
+ }]
1482
+ }
1483
+ return {
1484
+ tableList: Array.from(tableList),
1485
+ columnList: columnListTableAlias(columnList),
1486
+ ast: {
1487
+ type: 'delete',
1488
+ table: t,
1489
+ from: f,
1490
+ where: w
1491
+ }
1492
+ };
1493
+ }
1494
+ set_list
1495
+ = head:set_item tail:(__ COMMA __ set_item)* {
1496
+ return createList(head, tail);
1497
+ }
1498
+
1499
+ /**
1500
+ * here only use `additive_expr` to support 'col1 = col1+2'
1501
+ * if you want to use lower operator, please use '()' like below
1502
+ * 'col1 = (col2 > 3)'
1503
+ */
1504
+ set_item
1505
+ = tbl:(ident __ DOT)? __ c:column_without_kw __ '=' __ v:additive_expr {
1506
+ return { column: c, value: v, table: tbl && tbl[0] };
1507
+ }
1508
+ / tbl:(ident __ DOT)? __ c:column_without_kw __ '=' __ KW_VALUES __ LPAREN __ v:column_ref __ RPAREN {
1509
+ return { column: c, value: v, table: tbl && tbl[0], keyword: 'values' };
1510
+ }
1511
+
1512
+ insert_value_clause
1513
+ = value_clause
1514
+ / select_stmt_nake
1515
+
1516
+ insert_partition
1517
+ = KW_PARTITION __ LPAREN __ head:ident_name tail:(__ COMMA __ ident_name)* __ RPAREN {
1518
+ return createList(head, tail)
1519
+ }
1520
+ / KW_PARTITION __ v: value_item {
1521
+ return v
1522
+ }
1523
+
1524
+ replace_insert_stmt
1525
+ = ri:replace_insert __
1526
+ kw:KW_INTO __
1527
+ ta:KW_TABLE? __
1528
+ t:table_name
1529
+ p:insert_partition? __ LPAREN __ c:column_list __ RPAREN __
1530
+ v:insert_value_clause {
1531
+ if (t) {
1532
+ tableList.add(`insert::${t.db}::${t.table}`)
1533
+ t.as = null
1534
+ }
1535
+ if (c) {
1536
+ let table = t && t.table || null
1537
+ if(Array.isArray(v)) {
1538
+ v.forEach((row, idx) => {
1539
+ if(row.value.length != c.length) {
1540
+ throw new Error(`Error: column count doesn't match value count at row ${idx+1}`)
1541
+ }
1542
+ })
1543
+ }
1544
+ c.forEach(c => columnList.add(`insert::${table}::${c}`));
1545
+ }
1546
+ const tableKey = ta ? ` ${ta.toLowerCase()}` : ''
1547
+ return {
1548
+ tableList: Array.from(tableList),
1549
+ columnList: columnListTableAlias(columnList),
1550
+ ast: {
1551
+ type: ri,
1552
+ prefix: `${kw.toLowerCase()}${tableKey}`,
1553
+ table: [t],
1554
+ columns: c,
1555
+ values: v,
1556
+ partition: p,
1557
+ }
1558
+ };
1559
+ }
1560
+
1561
+ insert_no_columns_stmt
1562
+ = ri:replace_insert __
1563
+ kw:(KW_INTO / KW_OVERWRITE) __
1564
+ ta:KW_TABLE? __
1565
+ t:table_name __
1566
+ p:insert_partition? __
1567
+ v:insert_value_clause {
1568
+ if (t) {
1569
+ tableList.add(`insert::${t.db}::${t.table}`)
1570
+ columnList.add(`insert::${t.table}::(.*)`);
1571
+ t.as = null
1572
+ }
1573
+ const tableKey = ta ? ` ${ta.toLowerCase()}` : ''
1574
+ return {
1575
+ tableList: Array.from(tableList),
1576
+ columnList: columnListTableAlias(columnList),
1577
+ ast: {
1578
+ type: ri,
1579
+ prefix: `${kw.toLowerCase()}${tableKey}`,
1580
+ table: [t],
1581
+ columns: null,
1582
+ values: v,
1583
+ partition: p,
1584
+ }
1585
+ };
1586
+ }
1587
+
1588
+ replace_insert
1589
+ = KW_INSERT { return 'insert'; }
1590
+ / KW_REPLACE { return 'replace'; }
1591
+
1592
+ value_clause
1593
+ = KW_VALUES __ l:value_list { return l; }
1594
+
1595
+ value_list
1596
+ = head:value_item tail:(__ COMMA __ value_item)* {
1597
+ return createList(head, tail);
1598
+ }
1599
+
1600
+ value_item
1601
+ = LPAREN __ l:expr_list __ RPAREN {
1602
+ return l;
1603
+ }
1604
+ / func_call
1605
+
1606
+ expr_list
1607
+ = head:expr tail:(__ COMMA __ expr)* {
1608
+ const el = { type: 'expr_list' };
1609
+ el.value = createList(head, tail);
1610
+ return el;
1611
+ }
1612
+
1613
+ interval_expr
1614
+ = KW_INTERVAL __
1615
+ e:expr __
1616
+ u: interval_unit {
1617
+ return {
1618
+ type: 'interval',
1619
+ expr: e,
1620
+ unit: u.toLowerCase(),
1621
+ }
1622
+ }
1623
+
1624
+ case_expr
1625
+ = KW_CASE __
1626
+ condition_list:case_when_then_list __
1627
+ otherwise:case_else? __
1628
+ KW_END __ KW_CASE? {
1629
+ if (otherwise) condition_list.push(otherwise);
1630
+ return {
1631
+ type: 'case',
1632
+ expr: null,
1633
+ args: condition_list
1634
+ };
1635
+ }
1636
+ / KW_CASE __
1637
+ expr:expr __
1638
+ condition_list:case_when_then_list __
1639
+ otherwise:case_else? __
1640
+ KW_END __ KW_CASE? {
1641
+ if (otherwise) condition_list.push(otherwise);
1642
+ return {
1643
+ type: 'case',
1644
+ expr: expr,
1645
+ args: condition_list
1646
+ };
1647
+ }
1648
+
1649
+ case_when_then_list
1650
+ = head:case_when_then __ tail:(__ case_when_then)* {
1651
+ return createList(head, tail, 1)
1652
+ }
1653
+
1654
+ case_when_then
1655
+ = KW_WHEN __ condition:or_and_where_expr __ KW_THEN __ result:expr {
1656
+ return {
1657
+ type: 'when',
1658
+ cond: condition,
1659
+ result: result
1660
+ };
1661
+ }
1662
+
1663
+ case_else = KW_ELSE __ result:expr {
1664
+ return { type: 'else', result: result };
1665
+ }
1666
+
1667
+ /**
1668
+ * Borrowed from PL/SQL ,the priority of below list IS ORDER BY DESC
1669
+ * ---------------------------------------------------------------------------------------------------
1670
+ * | +, - | identity, negation |
1671
+ * | *, / | multiplication, division |
1672
+ * | +, - | addition, subtraction, concatenation |
1673
+ * | =, <, >, <=, >=, <>, !=, IS, LIKE, BETWEEN, IN | comparion |
1674
+ * | !, NOT | logical negation |
1675
+ * | AND | conjunction |
1676
+ * | OR | inclusion |
1677
+ * ---------------------------------------------------------------------------------------------------
1678
+ */
1679
+
1680
+ _expr
1681
+ = or_expr
1682
+ / unary_expr
1683
+
1684
+ expr
1685
+ = _expr / union_stmt
1686
+
1687
+ unary_expr
1688
+ = op: additive_operator tail: (__ primary)+ {
1689
+ return createUnaryExpr(op, tail[0][1]);
1690
+ }
1691
+
1692
+ binary_column_expr
1693
+ = head:expr tail:(__ (KW_AND / KW_OR / LOGIC_OPERATOR) __ expr)* {
1694
+ const ast = head.ast
1695
+ if (ast && ast.type === 'select') {
1696
+ 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')
1697
+ }
1698
+ if (!tail || tail.length === 0) return head
1699
+ const len = tail.length
1700
+ let result = tail[len - 1][3]
1701
+ for (let i = len - 1; i >= 0; i--) {
1702
+ const left = i === 0 ? head : tail[i - 1][3]
1703
+ result = createBinaryExpr(tail[i][1], left, result)
1704
+ }
1705
+ return result
1706
+ }
1707
+
1708
+ or_and_where_expr
1709
+ = head:expr tail:(__ (KW_AND / KW_OR / COMMA) __ expr)* {
1710
+ const len = tail.length
1711
+ let result = head;
1712
+ let seperator = ''
1713
+ for (let i = 0; i < len; ++i) {
1714
+ if (tail[i][1] === ',') {
1715
+ seperator = ','
1716
+ if (!Array.isArray(result)) result = [result]
1717
+ result.push(tail[i][3])
1718
+ } else {
1719
+ result = createBinaryExpr(tail[i][1], result, tail[i][3]);
1720
+ }
1721
+ }
1722
+ if (seperator === ',') {
1723
+ const el = { type: 'expr_list' }
1724
+ el.value = result
1725
+ return el
1726
+ }
1727
+ return result
1728
+ }
1729
+
1730
+ or_expr
1731
+ = head:and_expr tail:(___ KW_OR __ and_expr)* {
1732
+ return createBinaryExprChain(head, tail);
1733
+ }
1734
+
1735
+ and_expr
1736
+ = head:not_expr tail:(___ KW_AND __ not_expr)* {
1737
+ return createBinaryExprChain(head, tail);
1738
+ }
1739
+
1740
+ //here we should use `NOT` instead of `comparision_expr` to support chain-expr
1741
+ not_expr
1742
+ = comparison_expr
1743
+ / exists_expr
1744
+ / (KW_NOT / "!" !"=") __ expr:not_expr {
1745
+ return createUnaryExpr('NOT', expr);
1746
+ }
1747
+
1748
+ comparison_expr
1749
+ = left:additive_expr __ rh:comparison_op_right? {
1750
+ if (rh === null) return left;
1751
+ else if (rh.type === 'arithmetic') return createBinaryExprChain(left, rh.tail);
1752
+ else return createBinaryExpr(rh.op, left, rh.right);
1753
+ }
1754
+ / literal_string
1755
+ / column_ref
1756
+
1757
+ exists_expr
1758
+ = op:exists_op __ LPAREN __ stmt:union_stmt __ RPAREN {
1759
+ stmt.parentheses = true;
1760
+ return createUnaryExpr(op, stmt);
1761
+ }
1762
+
1763
+ exists_op
1764
+ = nk:(KW_NOT __ KW_EXISTS) { return nk[0] + ' ' + nk[2]; }
1765
+ / KW_EXISTS
1766
+
1767
+ comparison_op_right
1768
+ = arithmetic_op_right
1769
+ / in_op_right
1770
+ / between_op_right
1771
+ / is_op_right
1772
+ / like_op_right
1773
+ / rlike_op_right
1774
+
1775
+ arithmetic_op_right
1776
+ = l:(__ arithmetic_comparison_operator __ additive_expr)+ {
1777
+ return { type: 'arithmetic', tail: l };
1778
+ }
1779
+
1780
+ arithmetic_comparison_operator
1781
+ = ">=" / ">" / "<=" / "<>" / "<" / "==" / "=" / "!="
1782
+
1783
+ is_op_right
1784
+ = KW_IS __ right:additive_expr {
1785
+ return { op: 'IS', right: right };
1786
+ }
1787
+ / (KW_IS __ KW_NOT) __ right:additive_expr {
1788
+ return { op: 'IS NOT', right: right };
1789
+ }
1790
+
1791
+ between_op_right
1792
+ = op:between_or_not_between_op __ begin:additive_expr __ KW_AND __ end:additive_expr {
1793
+ return {
1794
+ op: op,
1795
+ right: {
1796
+ type: 'expr_list',
1797
+ value: [begin, end]
1798
+ }
1799
+ };
1800
+ }
1801
+
1802
+ between_or_not_between_op
1803
+ = nk:(KW_NOT __ KW_BETWEEN) { return nk[0] + ' ' + nk[2]; }
1804
+ / KW_BETWEEN
1805
+
1806
+ like_op
1807
+ = nk:(KW_NOT __ KW_LIKE) { return nk[0] + ' ' + nk[2]; }
1808
+ / KW_LIKE
1809
+
1810
+ rlike_op
1811
+ = nk:(KW_NOT __ KW_RLIKE) { return nk[0] + ' ' + nk[2]; }
1812
+ / KW_RLIKE
1813
+
1814
+ in_op
1815
+ = nk:(KW_NOT __ KW_IN) { return nk[0] + ' ' + nk[2]; }
1816
+ / KW_IN
1817
+
1818
+ like_op_right
1819
+ = op:like_op __ right:(literal / comparison_expr) {
1820
+ return { op: op, right: right };
1821
+ }
1822
+
1823
+ rlike_op_right
1824
+ = op:rlike_op __ right:(literal / comparison_expr) {
1825
+ return { op: op, right: right };
1826
+ }
1827
+
1828
+ in_op_right
1829
+ = op:in_op __ LPAREN __ l:expr_list __ RPAREN {
1830
+ return { op: op, right: l };
1831
+ }
1832
+ / op:in_op __ e:(var_decl / literal_string / func_call) {
1833
+ return { op: op, right: e };
1834
+ }
1835
+
1836
+ additive_expr
1837
+ = head:multiplicative_expr
1838
+ tail:(__ additive_operator __ multiplicative_expr)* {
1839
+ if (tail && tail.length && head.type === 'column_ref' && head.column === '*') throw new Error(JSON.stringify({
1840
+ message: 'args could not be star column in additive expr',
1841
+ ...getLocationObject(),
1842
+ }))
1843
+ return createBinaryExprChain(head, tail);
1844
+ }
1845
+
1846
+ additive_operator
1847
+ = "+" / "-"
1848
+
1849
+ multiplicative_expr
1850
+ = head:unary_expr_or_primary
1851
+ tail:(__ (multiplicative_operator / LOGIC_OPERATOR) __ unary_expr_or_primary)* {
1852
+ return createBinaryExprChain(head, tail)
1853
+ }
1854
+
1855
+ multiplicative_operator
1856
+ = "*" / "/" / "%"
1857
+
1858
+ primary
1859
+ = cast_expr
1860
+ / literal
1861
+ / aggr_func
1862
+ / f:func_call __ a:array_index_list {
1863
+ // => column_ref
1864
+ f.array_index = a
1865
+ return f
1866
+ }
1867
+ / func_call
1868
+ / case_expr
1869
+ / interval_expr
1870
+ / c:column_ref __ a:array_index_list {
1871
+ // => column_ref
1872
+ c.array_index = a
1873
+ return c
1874
+ }
1875
+ / column_ref
1876
+ / param
1877
+ / LPAREN __ list:or_and_where_expr __ RPAREN {
1878
+ list.parentheses = true;
1879
+ return list;
1880
+ }
1881
+ / var_decl
1882
+
1883
+ unary_expr_or_primary
1884
+ = jsonb_expr
1885
+ / op:(unary_operator) tail:(__ unary_expr_or_primary) {
1886
+ // => unary_expr
1887
+ return createUnaryExpr(op, tail[1])
1888
+ }
1889
+
1890
+ unary_operator
1891
+ = '!' / '-' / '+' / '~'
1892
+
1893
+ jsonb_expr
1894
+ = head:primary __ tail: (__ ('?|' / '?&' / '?' / '#-' / '#>>' / '#>' / SINGLE_ARROW / '@>' / '<@') __ primary)* {
1895
+ // => primary | binary_expr
1896
+ if (!tail || tail.length === 0) return head
1897
+ return createBinaryExprChain(head, tail)
1898
+ }
1899
+
1900
+ column_ref
1901
+ = schema:ident tbl:(__ DOT __ ident) col:(__ DOT __ column) ce:(__ collate_expr)? {
1902
+ columnList.add(`select::${schema}.${tbl[3]}::${col[3].value}`);
1903
+ return {
1904
+ type: 'column_ref',
1905
+ schema: schema,
1906
+ table: tbl[3],
1907
+ column: col[3],
1908
+ collate: ce && ce[1],
1909
+ };
1910
+ }
1911
+ / tbl:ident __ DOT __ col:column ce:(__ collate_expr)? {
1912
+ columnList.add(`select::${tbl}::${col}`);
1913
+ return {
1914
+ type: 'column_ref',
1915
+ table: tbl,
1916
+ column: col,
1917
+ collate: ce && ce[1],
1918
+ };
1919
+ }
1920
+ / col:column ce:(__ collate_expr)? {
1921
+ columnList.add(`select::null::${col}`);
1922
+ return {
1923
+ type: 'column_ref',
1924
+ table: null,
1925
+ column: col,
1926
+ collate: ce && ce[1],
1927
+ };
1928
+ }
1929
+
1930
+ column_list
1931
+ = head:column tail:(__ COMMA __ column)* {
1932
+ return createList(head, tail);
1933
+ }
1934
+
1935
+ ident_without_kw_type
1936
+ = n:ident_name {
1937
+ return { type: 'default', value: n }
1938
+ }
1939
+ / quoted_ident_type
1940
+
1941
+ ident_type
1942
+ = name:ident_name !{ return reservedMap[name.toUpperCase()] === true; } {
1943
+ return { type: 'default', value: name }
1944
+ }
1945
+ / quoted_ident_type
1946
+
1947
+ ident
1948
+ = name:ident_name !{ return reservedMap[name.toUpperCase()] === true; } {
1949
+ return name;
1950
+ }
1951
+ / name:quoted_ident {
1952
+ return name;
1953
+ }
1954
+
1955
+ alias_ident
1956
+ = name:ident_name !{
1957
+ if (reservedMap[name.toUpperCase()] === true) throw new Error("Error: "+ JSON.stringify(name)+" is a reserved word, can not as alias clause");
1958
+ return false
1959
+ } {
1960
+ return name;
1961
+ }
1962
+ / name:quoted_ident {
1963
+ return name;
1964
+ }
1965
+
1966
+ quoted_ident_type
1967
+ = double_quoted_ident / single_quoted_ident / backticks_quoted_ident
1968
+
1969
+ quoted_ident
1970
+ = v:(double_quoted_ident / single_quoted_ident / backticks_quoted_ident) {
1971
+ return v.value
1972
+ }
1973
+
1974
+ double_quoted_ident
1975
+ = '"' chars:[^"]+ '"' {
1976
+ return {
1977
+ type: 'double_quote_string',
1978
+ value: chars.join('')
1979
+ }
1980
+ }
1981
+
1982
+ single_quoted_ident
1983
+ = "'" chars:[^']+ "'" {
1984
+ return {
1985
+ type: 'single_quote_string',
1986
+ value: chars.join('')
1987
+ }
1988
+ }
1989
+
1990
+ backticks_quoted_ident
1991
+ = "`" chars:[^`]+ "`" {
1992
+ return {
1993
+ type: 'backticks_quote_string',
1994
+ value: chars.join('')
1995
+ }
1996
+ }
1997
+
1998
+ column_without_kw
1999
+ = name:column_name {
2000
+ return name;
2001
+ }
2002
+ / quoted_ident
2003
+
2004
+ column
2005
+ = name:column_name !{ return reservedMap[name.toUpperCase()] === true; } { return name; }
2006
+ / quoted_ident
2007
+
2008
+ column_name
2009
+ = start:ident_part parts:column_part* { return start + parts.join(''); }
2010
+
2011
+ ident_name
2012
+ = start:ident_start parts:ident_part* { return start + parts.join(''); }
2013
+
2014
+ ident_start = [A-Za-z_]
2015
+
2016
+ ident_part = [A-Za-z0-9_]
2017
+
2018
+ // to support column name like `cf1:name` in hbase
2019
+ column_part = [A-Za-z0-9_:]
2020
+
2021
+ param
2022
+ = l:(':' ident_name) {
2023
+ return { type: 'param', value: l[1] };
2024
+ }
2025
+
2026
+ aggr_func
2027
+ = aggr_fun_count
2028
+ / aggr_fun_smma
2029
+ / aggr_array_agg
2030
+
2031
+ aggr_fun_smma
2032
+ = name:KW_SUM_MAX_MIN_AVG __ LPAREN __ e:additive_expr __ RPAREN __ bc:over_partition? {
2033
+ return {
2034
+ type: 'aggr_func',
2035
+ name: name,
2036
+ args: {
2037
+ expr: e
2038
+ },
2039
+ over: bc,
2040
+ ...getLocationObject(),
2041
+ };
2042
+ }
2043
+
2044
+ KW_SUM_MAX_MIN_AVG
2045
+ = KW_SUM / KW_MAX / KW_MIN / KW_AVG
2046
+
2047
+ on_update_current_timestamp
2048
+ = KW_ON __ KW_UPDATE __ kw:KW_CURRENT_TIMESTAMP __ LPAREN __ l:expr_list? __ RPAREN{
2049
+ return {
2050
+ type: 'on update',
2051
+ keyword: kw,
2052
+ parentheses: true,
2053
+ expr: l
2054
+ }
2055
+ }
2056
+ / KW_ON __ KW_UPDATE __ kw:KW_CURRENT_TIMESTAMP {
2057
+ return {
2058
+ type: 'on update',
2059
+ keyword: kw,
2060
+ }
2061
+ }
2062
+
2063
+ over_partition
2064
+ = 'OVER'i __ aws:as_window_specification {
2065
+ return {
2066
+ type: 'window',
2067
+ as_window_specification: aws,
2068
+ }
2069
+ }
2070
+ / 'OVER'i __ LPAREN __ bc:partition_by_clause? __ l:order_by_clause? __ RPAREN {
2071
+ return {
2072
+ partitionby: bc,
2073
+ orderby: l
2074
+ }
2075
+ }
2076
+ / on_update_current_timestamp
2077
+
2078
+ aggr_fun_count
2079
+ = name:KW_COUNT __ LPAREN __ arg:count_arg __ RPAREN __ bc:over_partition? {
2080
+ return {
2081
+ type: 'aggr_func',
2082
+ name: name,
2083
+ args: arg,
2084
+ over: bc
2085
+ };
2086
+ }
2087
+ concat_separator
2088
+ = kw:(COMMA / OPERATOR_CONCATENATION) __ s:literal_string {
2089
+ // => { symbol: ',' | '||'; delimiter: literal_string; }
2090
+ return {
2091
+ symbol: kw,
2092
+ delimiter: s
2093
+ }
2094
+ }
2095
+
2096
+ distinct_args
2097
+ = d:KW_DISTINCT? __ LPAREN __ c:expr __ RPAREN __ tail:(__ (KW_AND / KW_OR / OPERATOR_CONCATENATION) __ expr)* __ or:order_by_clause? {
2098
+ const len = tail.length
2099
+ let result = c
2100
+ result.parentheses = true
2101
+ for (let i = 0; i < len; ++i) {
2102
+ result = createBinaryExpr(tail[i][1], result, tail[i][3])
2103
+ }
2104
+ return {
2105
+ distinct: d,
2106
+ expr: result,
2107
+ orderby: or,
2108
+ };
2109
+ }
2110
+ / d:KW_DISTINCT? __ c:(column_ref / or_and_expr) __ tail:(__ (COMMA / OPERATOR_CONCATENATION) __ expr)* __ or:order_by_clause? {
2111
+ const len = tail.length
2112
+ let result = c
2113
+ for (let i = 0; i < len; ++i) {
2114
+ result = createBinaryExpr(tail[i][1], result, tail[i][3])
2115
+ }
2116
+ return { distinct: d, expr: result, orderby: or };
2117
+ }
2118
+
2119
+ count_arg
2120
+ = e:star_expr { return { expr: e }; }
2121
+ / distinct_args
2122
+
2123
+ aggr_array_agg
2124
+ = pre:(ident __ DOT)? __ name:(KW_ARRAY_AGG) __ LPAREN __ arg:distinct_args __ RPAREN {
2125
+ // => { type: 'aggr_func'; args:count_arg; name: 'ARRAY_AGG' | 'STRING_AGG'; }
2126
+ return {
2127
+ type: 'aggr_func',
2128
+ name: pre ? `${pre[0]}.${name}` : name,
2129
+ args: arg,
2130
+ };
2131
+ }
2132
+
2133
+ star_expr
2134
+ = "*" { return { type: 'star', value: '*' }; }
2135
+
2136
+ arrow_func
2137
+ = v:ident_without_kw_type __ s:SINGLE_ARROW __ e:expr {
2138
+ return createBinaryExpr(s, v, e)
2139
+ }
2140
+
2141
+ filter_func
2142
+ = 'filter'i __ LPAREN __ ar:expr __ COMMA __ af:arrow_func __ RPAREN {
2143
+ return {
2144
+ type: 'function',
2145
+ name: { name: [{ type: 'origin', value: 'filter' }] },
2146
+ args: { type: 'expr_list', value: [ar, af] },
2147
+ ...getLocationObject(),
2148
+ };
2149
+ }
2150
+
2151
+ trim_position
2152
+ = 'BOTH'i / 'LEADING'i / 'TRAILING'i
2153
+
2154
+ trim_rem
2155
+ = p:trim_position? __ rm:expr? __ k:KW_FROM {
2156
+ let value = []
2157
+ if (p) value.push({type: 'origin', value: p })
2158
+ if (rm) value.push(rm)
2159
+ value.push({type: 'origin', value: 'from' })
2160
+ return {
2161
+ type: 'expr_list',
2162
+ value,
2163
+ }
2164
+ }
2165
+
2166
+ trim_func_clause
2167
+ = 'trim'i __ LPAREN __ tr:trim_rem? __ s:expr_item __ RPAREN {
2168
+ let args = tr || { type: 'expr_list', value: [] }
2169
+ args.value.push(s)
2170
+ return {
2171
+ type: 'function',
2172
+ name: { name: [{ type: 'origin', value: 'trim' }] },
2173
+ args,
2174
+ };
2175
+ }
2176
+
2177
+ func_call
2178
+ = name:scalar_func __ LPAREN __ l:expr_list? __ RPAREN __ bc:over_partition? {
2179
+ return {
2180
+ type: 'function',
2181
+ name: { name: [{ type: 'origin', value: name }] },
2182
+ args: l ? l: { type: 'expr_list', value: [] },
2183
+ over: bc,
2184
+ ...getLocationObject(),
2185
+ };
2186
+ }
2187
+ / extract_func / filter_func / trim_func_clause
2188
+ / f:scalar_time_func __ up:on_update_current_timestamp? {
2189
+ return {
2190
+ type: 'function',
2191
+ name: { name: [{ type: 'origin', value: f }] },
2192
+ over: up,
2193
+ ...getLocationObject(),
2194
+ }
2195
+ }
2196
+ / name:(KW_DATE / KW_TIME / KW_TIMESTAMP / 'AT TIME ZONE'i) __ l:or_and_where_expr? __ bc:over_partition? {
2197
+ if (l && l.type !== 'expr_list') l = { type: 'expr_list', value: [l] }
2198
+ return {
2199
+ type: 'function',
2200
+ name: { name: [{ type: 'default', value: name }] },
2201
+ args: l ? l: { type: 'expr_list', value: [] },
2202
+ over: bc,
2203
+ args_parentheses: false,
2204
+ ...getLocationObject(),
2205
+ };
2206
+ }
2207
+ / name:proc_func_name __ LPAREN __ l:or_and_where_expr? __ RPAREN __ bc:over_partition? {
2208
+ if (l && l.type !== 'expr_list') l = { type: 'expr_list', value: [l] }
2209
+ return {
2210
+ type: 'function',
2211
+ name: name,
2212
+ args: l ? l: { type: 'expr_list', value: [] },
2213
+ over: bc,
2214
+ ...getLocationObject(),
2215
+ };
2216
+ }
2217
+ extract_filed
2218
+ = 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) {
2219
+ // => 'string'
2220
+ return f
2221
+ }
2222
+ extract_func
2223
+ = kw:KW_EXTRACT __ LPAREN __ f:extract_filed __ KW_FROM __ t:(KW_TIMESTAMP / KW_INTERVAL / KW_TIME / KW_DATE)? __ s:expr __ RPAREN {
2224
+ // => { type: 'extract'; args: { field: extract_filed; cast_type: 'TIMESTAMP' | 'INTERVAL' | 'TIME'; source: expr; }}
2225
+ return {
2226
+ type: kw.toLowerCase(),
2227
+ args: {
2228
+ field: f,
2229
+ cast_type: t,
2230
+ source: s,
2231
+ },
2232
+ ...getLocationObject(),
2233
+ }
2234
+ }
2235
+ / kw:KW_EXTRACT __ LPAREN __ f:extract_filed __ KW_FROM __ s:expr __ RPAREN {
2236
+ // => { type: 'extract'; args: { field: extract_filed; source: expr; }}
2237
+ return {
2238
+ type: kw.toLowerCase(),
2239
+ args: {
2240
+ field: f,
2241
+ source: s,
2242
+ },
2243
+ ...getLocationObject(),
2244
+ }
2245
+ }
2246
+ scalar_time_func
2247
+ = KW_CURRENT_DATE
2248
+ / KW_CURRENT_TIME
2249
+ / KW_CURRENT_TIMESTAMP
2250
+ scalar_func
2251
+ = scalar_time_func
2252
+ / KW_CURRENT_USER
2253
+ / KW_USER
2254
+ / KW_SESSION_USER
2255
+ / KW_SYSTEM_USER
2256
+
2257
+ cast_expr
2258
+ = c:(KW_CAST/KW_TRY_CAST) __ LPAREN __ e:expr __ KW_AS __ t:data_type __ RPAREN {
2259
+ return {
2260
+ type: 'cast',
2261
+ keyword: c.toLowerCase(),
2262
+ expr: e,
2263
+ symbol: 'as',
2264
+ target: [t]
2265
+ };
2266
+ }
2267
+ / c:KW_CAST __ LPAREN __ e:expr __ KW_AS __ KW_DECIMAL __ LPAREN __ precision:int __ RPAREN __ RPAREN {
2268
+ return {
2269
+ type: 'cast',
2270
+ keyword: c.toLowerCase(),
2271
+ expr: e,
2272
+ symbol: 'as',
2273
+ target: [{
2274
+ dataType: 'DECIMAL(' + precision + ')'
2275
+ }]
2276
+ };
2277
+ }
2278
+ / c:KW_CAST __ LPAREN __ e:expr __ KW_AS __ KW_DECIMAL __ LPAREN __ precision:int __ COMMA __ scale:int __ RPAREN __ RPAREN {
2279
+ return {
2280
+ type: 'cast',
2281
+ keyword: c.toLowerCase(),
2282
+ expr: e,
2283
+ symbol: 'as',
2284
+ target: [{
2285
+ dataType: 'DECIMAL(' + precision + ', ' + scale + ')'
2286
+ }]
2287
+ };
2288
+ }
2289
+ / c:KW_CAST __ LPAREN __ e:expr __ KW_AS __ s:signedness __ t:KW_INTEGER? __ RPAREN { /* MySQL cast to un-/signed integer */
2290
+ return {
2291
+ type: 'cast',
2292
+ keyword: c.toLowerCase(),
2293
+ expr: e,
2294
+ symbol: 'as',
2295
+ target: [{
2296
+ dataType: s + (t ? ' ' + t: '')
2297
+ }]
2298
+ };
2299
+ }
2300
+
2301
+ signedness
2302
+ = KW_SIGNED
2303
+ / KW_UNSIGNED
2304
+
2305
+ literal
2306
+ = literal_string
2307
+ / literal_numeric
2308
+ / literal_bool
2309
+ / literal_null
2310
+ / literal_datetime
2311
+ / literal_array
2312
+
2313
+ literal_array
2314
+ = s:KW_ARRAY __ LBRAKE __ c:expr_list? __ RBRAKE {
2315
+ return {
2316
+ expr_list: c || { type: 'origin', value: '' },
2317
+ type: 'array',
2318
+ keyword: 'array',
2319
+ brackets: true
2320
+ }
2321
+ }
2322
+
2323
+ literal_list
2324
+ = head:literal tail:(__ COMMA __ literal)* {
2325
+ return createList(head, tail);
2326
+ }
2327
+
2328
+ literal_null
2329
+ = KW_NULL {
2330
+ return { type: 'null', value: null };
2331
+ }
2332
+
2333
+ literal_not_null
2334
+ = KW_NOT_NULL {
2335
+ return {
2336
+ type: 'not null',
2337
+ value: 'not null',
2338
+ }
2339
+ }
2340
+
2341
+ literal_bool
2342
+ = KW_TRUE {
2343
+ return { type: 'bool', value: true };
2344
+ }
2345
+ / KW_FALSE {
2346
+ return { type: 'bool', value: false };
2347
+ }
2348
+
2349
+ literal_string
2350
+ = r:'u&'i ca:("'" single_char* "'") {
2351
+ return {
2352
+ type: 'unicode_string',
2353
+ value: ca[1].join('')
2354
+ };
2355
+ }
2356
+ / ca:("'" single_char* "'") {
2357
+ return {
2358
+ type: 'single_quote_string',
2359
+ value: ca[1].join('')
2360
+ };
2361
+ }
2362
+ / ca:("\"" single_quote_char* "\"") __ !(DOT / LPAREN) {
2363
+ return {
2364
+ type: 'double_quote_string',
2365
+ value: ca[1].join('')
2366
+ };
2367
+ }
2368
+
2369
+ literal_datetime
2370
+ = type:(KW_TIME / KW_DATE / KW_TIMESTAMP / KW_DATETIME) __ ca:("'" single_char* "'") {
2371
+ return {
2372
+ type: type.toLowerCase(),
2373
+ value: ca[1].join('')
2374
+ };
2375
+ }
2376
+ / type:(KW_TIME / KW_DATE / KW_TIMESTAMP / KW_DATETIME) __ ca:("\"" single_quote_char* "\"") {
2377
+ return {
2378
+ type: type.toLowerCase(),
2379
+ value: ca[1].join('')
2380
+ };
2381
+ }
2382
+
2383
+ single_quote_char
2384
+ = [^"\\\0-\x1F\x7f]
2385
+ / escape_char
2386
+
2387
+ single_char
2388
+ = [^'\\]
2389
+ / escape_char
2390
+
2391
+ escape_char
2392
+ = "\\'" { return "\\'"; }
2393
+ / '\\"' { return '\\"'; }
2394
+ / "\\\\" { return "\\\\"; }
2395
+ / "\\/" { return "\\/"; }
2396
+ / "\\b" { return "\b"; }
2397
+ / "\\f" { return "\f"; }
2398
+ / "\\n" { return "\n"; }
2399
+ / "\\r" { return "\r"; }
2400
+ / "\\t" { return "\t"; }
2401
+ / "\\u" h1:hexDigit h2:hexDigit h3:hexDigit h4:hexDigit {
2402
+ return String.fromCharCode(parseInt("0x" + h1 + h2 + h3 + h4));
2403
+ }
2404
+ / "\\" { return "\\"; }
2405
+ / "''" { return "''" }
2406
+ / '""' { return '""' }
2407
+ / '``' { return '``' }
2408
+
2409
+ line_terminator
2410
+ = [\n\r]
2411
+
2412
+ literal_numeric
2413
+ = n:number {
2414
+ if (n && n.type === 'bigint') return n
2415
+ return { type: 'number', value: n };
2416
+ }
2417
+
2418
+ number
2419
+ = int_:int frac:frac exp:exp {
2420
+ const numStr = int_ + frac + exp
2421
+ return {
2422
+ type: 'bigint',
2423
+ value: numStr
2424
+ }
2425
+ }
2426
+ / int_:int frac:frac {
2427
+ const numStr = int_ + frac
2428
+ if (isBigInt(int_)) return {
2429
+ type: 'bigint',
2430
+ value: numStr
2431
+ }
2432
+ return parseFloat(numStr);
2433
+ }
2434
+ / int_:int exp:exp {
2435
+ const numStr = int_ + exp
2436
+ return {
2437
+ type: 'bigint',
2438
+ value: numStr
2439
+ }
2440
+ }
2441
+ / int_:int {
2442
+ if (isBigInt(int_)) return {
2443
+ type: 'bigint',
2444
+ value: int_
2445
+ }
2446
+ return parseFloat(int_);
2447
+ }
2448
+
2449
+ int
2450
+ = digits
2451
+ / digit:digit
2452
+ / op:("-" / "+" ) digits:digits { return op + digits; }
2453
+ / op:("-" / "+" ) digit:digit { return op + digit; }
2454
+
2455
+ frac
2456
+ = "." digits:digits { return "." + digits; }
2457
+
2458
+ exp
2459
+ = e:e digits:digits { return e + digits; }
2460
+
2461
+ digits
2462
+ = digits:digit+ { return digits.join(""); }
2463
+
2464
+ digit = [0-9]
2465
+
2466
+ hexDigit
2467
+ = [0-9a-fA-F]
2468
+
2469
+ e
2470
+ = e:[eE] sign:[+-]? { return e + (sign !== null ? sign: ''); }
2471
+
2472
+
2473
+ KW_NULL = "NULL"i !ident_start
2474
+ KW_DEFAULT = "DEFAULT"i !ident_start
2475
+ KW_NOT_NULL = "NOT NULL"i !ident_start
2476
+ KW_TRUE = "TRUE"i !ident_start
2477
+ KW_TO = "TO"i !ident_start
2478
+ KW_FALSE = "FALSE"i !ident_start
2479
+
2480
+ KW_SHOW = "SHOW"i !ident_start
2481
+ KW_DROP = "DROP"i !ident_start { return 'DROP'; }
2482
+ KW_USE = "USE"i !ident_start
2483
+ KW_ALTER = "ALTER"i !ident_start
2484
+ KW_SELECT = "SELECT"i !ident_start
2485
+ KW_UPDATE = "UPDATE"i !ident_start
2486
+ KW_CREATE = "CREATE"i !ident_start
2487
+ KW_TEMPORARY = "TEMPORARY"i !ident_start
2488
+ KW_DELETE = "DELETE"i !ident_start
2489
+ KW_INSERT = "INSERT"i !ident_start
2490
+ KW_RECURSIVE= "RECURSIVE"i !ident_start
2491
+ KW_REPLACE = "REPLACE"i !ident_start
2492
+ KW_RENAME = "RENAME"i !ident_start
2493
+ KW_IGNORE = "IGNORE"i !ident_start
2494
+ KW_EXPLAIN = "EXPLAIN"i !ident_start
2495
+ KW_PARTITION = "PARTITION"i !ident_start { return 'PARTITION' }
2496
+
2497
+ KW_INTO = "INTO"i !ident_start { return 'INTO'; }
2498
+ KW_OVERWRITE = "OVERWRITE"i !ident_start { return 'OVERWRITE'; }
2499
+ KW_FROM = "FROM"i !ident_start
2500
+ KW_SET = "SET"i !ident_start { return 'SET' }
2501
+ KW_UNLOCK = "UNLOCK"i !ident_start
2502
+ KW_LOCK = "LOCK"i !ident_start
2503
+
2504
+ KW_AS = "AS"i !ident_start
2505
+ KW_TABLE = "TABLE"i !ident_start { return 'TABLE'; }
2506
+ KW_TABLES = "TABLES"i !ident_start { return 'TABLES'; }
2507
+ KW_DATABASE = "DATABASE"i !ident_start { return 'DATABASE'; }
2508
+ KW_SCHEMA = "SCHEMA"i !ident_start { return 'SCHEMA'; }
2509
+ KW_COLLATE = "COLLATE"i !ident_start { return 'COLLATE'; }
2510
+
2511
+ KW_ON = "ON"i !ident_start
2512
+ KW_LEFT = "LEFT"i !ident_start
2513
+ KW_RIGHT = "RIGHT"i !ident_start
2514
+ KW_FULL = "FULL"i !ident_start
2515
+ KW_CROSS = "CROSS"i !ident_start
2516
+ KW_INNER = "INNER"i !ident_start
2517
+ KW_JOIN = "JOIN"i !ident_start
2518
+ KW_OUTER = "OUTER"i !ident_start
2519
+ KW_OVER = "OVER"i !ident_start
2520
+ KW_UNION = "UNION"i !ident_start
2521
+ KW_VALUES = "VALUES"i !ident_start
2522
+ KW_USING = "USING"i !ident_start
2523
+
2524
+ KW_WHERE = "WHERE"i !ident_start
2525
+ KW_WITH = "WITH"i !ident_start
2526
+
2527
+ KW_GROUP = "GROUP"i !ident_start
2528
+ KW_BY = "BY"i !ident_start
2529
+ KW_ORDER = "ORDER"i !ident_start
2530
+ KW_HAVING = "HAVING"i !ident_start
2531
+
2532
+ KW_LIMIT = "LIMIT"i !ident_start
2533
+ KW_OFFSET = "OFFSET"i !ident_start { return 'OFFSET'; }
2534
+
2535
+ KW_ASC = "ASC"i !ident_start { return 'ASC'; }
2536
+ KW_DESC = "DESC"i !ident_start { return 'DESC'; }
2537
+
2538
+ KW_ALL = "ALL"i !ident_start { return 'ALL'; }
2539
+ KW_DISTINCT = "DISTINCT"i !ident_start { return 'DISTINCT';}
2540
+
2541
+ KW_BETWEEN = "BETWEEN"i !ident_start { return 'BETWEEN'; }
2542
+ KW_IN = "IN"i !ident_start { return 'IN'; }
2543
+ KW_IS = "IS"i !ident_start { return 'IS'; }
2544
+ KW_LIKE = "LIKE"i !ident_start { return 'LIKE'; }
2545
+ KW_RLIKE = "RLIKE"i !ident_start { return 'RLIKE'; }
2546
+ KW_EXISTS = "EXISTS"i !ident_start { return 'EXISTS'; }
2547
+
2548
+ KW_NOT = "NOT"i !ident_start { return 'NOT'; }
2549
+ KW_AND = "AND"i !ident_start { return 'AND'; }
2550
+ KW_OR = "OR"i !ident_start { return 'OR'; }
2551
+
2552
+ KW_COUNT = "COUNT"i !ident_start { return 'COUNT'; }
2553
+ KW_MAX = "MAX"i !ident_start { return 'MAX'; }
2554
+ KW_MIN = "MIN"i !ident_start { return 'MIN'; }
2555
+ KW_SUM = "SUM"i !ident_start { return 'SUM'; }
2556
+ KW_AVG = "AVG"i !ident_start { return 'AVG'; }
2557
+
2558
+ KW_EXTRACT = "EXTRACT"i !ident_start { return 'EXTRACT'; }
2559
+ KW_CALL = "CALL"i !ident_start { return 'CALL'; }
2560
+
2561
+ KW_CASE = "CASE"i !ident_start
2562
+ KW_WHEN = "WHEN"i !ident_start
2563
+ KW_THEN = "THEN"i !ident_start
2564
+ KW_ELSE = "ELSE"i !ident_start
2565
+ KW_END = "END"i !ident_start
2566
+
2567
+ KW_CAST = "CAST"i !ident_start { return 'CAST' }
2568
+ KW_TRY_CAST = "TRY_CAST"i !ident_start { return 'TRY_CAST' }
2569
+
2570
+ KW_ARRAY = "ARRAY"i !ident_start { return 'ARRAY'; }
2571
+ KW_ARRAY_AGG = "ARRAY_AGG"i !ident_start { return 'ARRAY_AGG'; }
2572
+ KW_CHAR = "CHAR"i !ident_start { return 'CHAR'; }
2573
+ KW_VARCHAR = "VARCHAR"i !ident_start { return 'VARCHAR';}
2574
+ KW_NUMERIC = "NUMERIC"i !ident_start { return 'NUMERIC'; }
2575
+ KW_DECIMAL = "DECIMAL"i !ident_start { return 'DECIMAL'; }
2576
+ KW_SIGNED = "SIGNED"i !ident_start { return 'SIGNED'; }
2577
+ KW_STRING = "STRING"i !ident_start { return 'STRING'; }
2578
+ KW_UNSIGNED = "UNSIGNED"i !ident_start { return 'UNSIGNED'; }
2579
+ KW_INT = "INT"i !ident_start { return 'INT'; }
2580
+ KW_ZEROFILL = "ZEROFILL"i !ident_start { return 'ZEROFILL'; }
2581
+ KW_INTEGER = "INTEGER"i !ident_start { return 'INTEGER'; }
2582
+ KW_JSON = "JSON"i !ident_start { return 'JSON'; }
2583
+ KW_BOOLEAN = "BOOLEAN"i !ident_start { return 'BOOLEAN'; }
2584
+ KW_MAP = "MAP"i !ident_start { return 'MAP'; }
2585
+ KW_SMALLINT = "SMALLINT"i !ident_start { return 'SMALLINT'; }
2586
+ KW_TINYINT = "TINYINT"i !ident_start { return 'TINYINT'; }
2587
+ KW_TINYTEXT = "TINYTEXT"i !ident_start { return 'TINYTEXT'; }
2588
+ KW_TEXT = "TEXT"i !ident_start { return 'TEXT'; }
2589
+ KW_MEDIUMTEXT = "MEDIUMTEXT"i !ident_start { return 'MEDIUMTEXT'; }
2590
+ KW_LONGTEXT = "LONGTEXT"i !ident_start { return 'LONGTEXT'; }
2591
+ KW_BIGINT = "BIGINT"i !ident_start { return 'BIGINT'; }
2592
+ KW_FLOAT = "FLOAT"i !ident_start { return 'FLOAT'; }
2593
+ KW_REAL = "REAL"i !ident_start { return 'REAL'; }
2594
+ KW_DOUBLE = "DOUBLE"i !ident_start { return 'DOUBLE'; }
2595
+ KW_DATE = "DATE"i !ident_start { return 'DATE'; }
2596
+ KW_DATETIME = "DATETIME"i !ident_start { return 'DATETIME'; }
2597
+ KW_ROWS = "ROWS"i !ident_start { return 'ROWS'; }
2598
+ KW_TIME = "TIME"i !ident_start { return 'TIME'; }
2599
+ KW_TIMESTAMP= "TIMESTAMP"i!ident_start { return 'TIMESTAMP'; }
2600
+ KW_TRUNCATE = "TRUNCATE"i !ident_start { return 'TRUNCATE'; }
2601
+ KW_USER = "USER"i !ident_start { return 'USER'; }
2602
+
2603
+ KW_CURRENT_DATE = "CURRENT_DATE"i !ident_start { return 'CURRENT_DATE'; }
2604
+ KW_ADD_DATE = "ADDDATE"i !ident_start { return 'ADDDATE'; }
2605
+ KW_INTERVAL = "INTERVAL"i !ident_start { return 'INTERVAL'; }
2606
+ KW_UNIT_YEAR = "YEAR"i !ident_start { return 'YEAR'; }
2607
+ KW_UNIT_MONTH = "MONTH"i !ident_start { return 'MONTH'; }
2608
+ KW_UNIT_DAY = "DAY"i !ident_start { return 'DAY'; }
2609
+ KW_UNIT_HOUR = "HOUR"i !ident_start { return 'HOUR'; }
2610
+ KW_UNIT_MINUTE = "MINUTE"i !ident_start { return 'MINUTE'; }
2611
+ KW_UNIT_SECOND = "SECOND"i !ident_start { return 'SECOND'; }
2612
+ KW_CURRENT_TIME = "CURRENT_TIME"i !ident_start { return 'CURRENT_TIME'; }
2613
+ KW_CURRENT_TIMESTAMP= "CURRENT_TIMESTAMP"i !ident_start { return 'CURRENT_TIMESTAMP'; }
2614
+ KW_CURRENT_USER = "CURRENT_USER"i !ident_start { return 'CURRENT_USER'; }
2615
+ KW_SESSION_USER = "SESSION_USER"i !ident_start { return 'SESSION_USER'; }
2616
+ KW_SYSTEM_USER = "SYSTEM_USER"i !ident_start { return 'SYSTEM_USER'; }
2617
+
2618
+ KW_GLOBAL = "GLOBAL"i !ident_start { return 'GLOBAL'; }
2619
+ KW_SESSION = "SESSION"i !ident_start { return 'SESSION'; }
2620
+ KW_LOCAL = "LOCAL"i !ident_start { return 'LOCAL'; }
2621
+ KW_PERSIST = "PERSIST"i !ident_start { return 'PERSIST'; }
2622
+ KW_PERSIST_ONLY = "PERSIST_ONLY"i !ident_start { return 'PERSIST_ONLY'; }
2623
+
2624
+ KW_VAR__PRE_AT = '@'
2625
+ KW_VAR__PRE_AT_AT = '@@'
2626
+ KW_VAR_PRE_DOLLAR = '$'
2627
+ KW_VAR_PRE
2628
+ = KW_VAR__PRE_AT_AT / KW_VAR__PRE_AT / KW_VAR_PRE_DOLLAR
2629
+ KW_RETURN = 'return'i
2630
+ KW_ASSIGN = ':='
2631
+ KW_ASSIGIN_EQUAL = '='
2632
+
2633
+ KW_DUAL = "DUAL"i
2634
+
2635
+ // MySQL Alter
2636
+ KW_ADD = "ADD"i !ident_start { return 'ADD'; }
2637
+ KW_COLUMN = "COLUMN"i !ident_start { return 'COLUMN'; }
2638
+ KW_INDEX = "INDEX"i !ident_start { return 'INDEX'; }
2639
+ KW_KEY = "KEY"i !ident_start { return 'KEY'; }
2640
+ KW_FULLTEXT = "FULLTEXT"i !ident_start { return 'FULLTEXT'; }
2641
+ KW_SPATIAL = "SPATIAL"i !ident_start { return 'SPATIAL'; }
2642
+ KW_UNIQUE = "UNIQUE"i !ident_start { return 'UNIQUE'; }
2643
+ KW_KEY_BLOCK_SIZE = "KEY_BLOCK_SIZE"i !ident_start { return 'KEY_BLOCK_SIZE'; }
2644
+ KW_COMMENT = "COMMENT"i !ident_start { return 'COMMENT'; }
2645
+ KW_CONSTRAINT = "CONSTRAINT"i !ident_start { return 'CONSTRAINT'; }
2646
+ KW_REFERENCES = "REFERENCES"i !ident_start { return 'REFERENCES'; }
2647
+
2648
+
2649
+
2650
+ // MySQL extensions to SQL
2651
+ OPT_SQL_CALC_FOUND_ROWS = "SQL_CALC_FOUND_ROWS"i
2652
+ OPT_SQL_CACHE = "SQL_CACHE"i
2653
+ OPT_SQL_NO_CACHE = "SQL_NO_CACHE"i
2654
+ OPT_SQL_SMALL_RESULT = "SQL_SMALL_RESULT"i
2655
+ OPT_SQL_BIG_RESULT = "SQL_BIG_RESULT"i
2656
+ OPT_SQL_BUFFER_RESULT = "SQL_BUFFER_RESULT"i
2657
+
2658
+ //special character
2659
+ DOT = '.'
2660
+ COMMA = ','
2661
+ STAR = '*'
2662
+ LPAREN = '('
2663
+ RPAREN = ')'
2664
+ LANGLE_BRACKET = '<'
2665
+ RANGLE_BRACKET = '>'
2666
+ LBRAKE = '['
2667
+ RBRAKE = ']'
2668
+
2669
+ SEMICOLON = ';'
2670
+ SINGLE_ARROW = '->'
2671
+ OPERATOR_CONCATENATION = '||'
2672
+ OPERATOR_AND = '&&'
2673
+ LOGIC_OPERATOR = OPERATOR_CONCATENATION / OPERATOR_AND
2674
+
2675
+ // separator
2676
+ __
2677
+ = (whitespace / comment)*
2678
+
2679
+ ___
2680
+ = (whitespace / comment)+
2681
+
2682
+ comment
2683
+ = block_comment
2684
+ / line_comment
2685
+ / pound_sign_comment
2686
+
2687
+ block_comment
2688
+ = "/*" (!"*/" char)* "*/"
2689
+
2690
+ line_comment
2691
+ = "--" (!EOL char)*
2692
+
2693
+ pound_sign_comment
2694
+ = "#" (!EOL char)*
2695
+
2696
+ keyword_comment
2697
+ = k:KW_COMMENT __ s:KW_ASSIGIN_EQUAL? __ c:literal_string {
2698
+ return {
2699
+ type: k.toLowerCase(),
2700
+ keyword: k.toLowerCase(),
2701
+ symbol: s,
2702
+ value: c,
2703
+ }
2704
+ }
2705
+
2706
+ char = .
2707
+
2708
+ interval_unit
2709
+ = KW_UNIT_YEAR
2710
+ / KW_UNIT_MONTH
2711
+ / KW_UNIT_DAY
2712
+ / KW_UNIT_HOUR
2713
+ / KW_UNIT_MINUTE
2714
+ / KW_UNIT_SECOND
2715
+
2716
+ whitespace =
2717
+ [ \t\n\r]
2718
+
2719
+ EOL
2720
+ = EOF
2721
+ / [\n\r]+
2722
+
2723
+ EOF = !.
2724
+
2725
+ //begin procedure extension
2726
+ proc_stmts
2727
+ = proc_stmt*
2728
+
2729
+ proc_stmt
2730
+ = &{ varList = []; return true; } __ s:(assign_stmt / return_stmt) {
2731
+ return { stmt: s, vars: varList };
2732
+ }
2733
+
2734
+ assign_stmt_list
2735
+ = head:assign_stmt tail:(__ COMMA __ assign_stmt)* {
2736
+ return createList(head, tail);
2737
+ }
2738
+
2739
+ assign_stmt
2740
+ = va:(var_decl / without_prefix_var_decl) __ s: (KW_ASSIGN / KW_ASSIGIN_EQUAL) __ e:proc_expr {
2741
+ return {
2742
+ type: 'assign',
2743
+ left: va,
2744
+ symbol: s,
2745
+ right: e
2746
+ };
2747
+ }
2748
+
2749
+
2750
+ return_stmt
2751
+ = KW_RETURN __ e:proc_expr {
2752
+ return { type: 'return', expr: e };
2753
+ }
2754
+
2755
+ proc_expr
2756
+ = select_stmt
2757
+ / proc_join
2758
+ / proc_additive_expr
2759
+ / proc_array
2760
+
2761
+ proc_additive_expr
2762
+ = head:proc_multiplicative_expr
2763
+ tail:(__ additive_operator __ proc_multiplicative_expr)* {
2764
+ return createBinaryExprChain(head, tail);
2765
+ }
2766
+
2767
+ proc_multiplicative_expr
2768
+ = head:proc_primary
2769
+ tail:(__ multiplicative_operator __ proc_primary)* {
2770
+ return createBinaryExprChain(head, tail);
2771
+ }
2772
+
2773
+ proc_join
2774
+ = lt:var_decl __ op:join_op __ rt:var_decl __ expr:on_clause {
2775
+ return {
2776
+ type: 'join',
2777
+ ltable: lt,
2778
+ rtable: rt,
2779
+ op: op,
2780
+ on: expr
2781
+ };
2782
+ }
2783
+
2784
+ proc_primary
2785
+ = literal
2786
+ / var_decl
2787
+ / proc_func_call
2788
+ / param
2789
+ / LPAREN __ e:proc_additive_expr __ RPAREN {
2790
+ e.parentheses = true;
2791
+ return e;
2792
+ }
2793
+
2794
+ proc_func_name
2795
+ = dt:ident_without_kw_type tail:(__ DOT __ ident_without_kw_type)? {
2796
+ const result = { name: [dt] }
2797
+ if (tail !== null) {
2798
+ result.schema = dt
2799
+ result.name = [tail[3]]
2800
+ }
2801
+ return result
2802
+ }
2803
+
2804
+ proc_func_call
2805
+ = name:proc_func_name __ LPAREN __ l:proc_primary_list? __ RPAREN {
2806
+ //compatible with original func_call
2807
+ return {
2808
+ type: 'function',
2809
+ name: name,
2810
+ args: {
2811
+ type: 'expr_list',
2812
+ value: l
2813
+ },
2814
+ ...getLocationObject(),
2815
+ };
2816
+ }
2817
+ / name:proc_func_name {
2818
+ return {
2819
+ type: 'function',
2820
+ name: name,
2821
+ args: null,
2822
+ ...getLocationObject(),
2823
+ };
2824
+ }
2825
+
2826
+ proc_primary_list
2827
+ = head:proc_primary tail:(__ COMMA __ proc_primary)* {
2828
+ return createList(head, tail);
2829
+ }
2830
+
2831
+ proc_array =
2832
+ LBRAKE __ l:proc_primary_list __ RBRAKE {
2833
+ return { type: 'array', value: l };
2834
+ }
2835
+
2836
+ var_decl
2837
+ = p: KW_VAR_PRE d: without_prefix_var_decl {
2838
+ //push for analysis
2839
+ return {
2840
+ type: 'var',
2841
+ ...d,
2842
+ prefix: p
2843
+ };
2844
+ }
2845
+
2846
+ without_prefix_var_decl
2847
+ = name:ident_name m:mem_chain {
2848
+ //push for analysis
2849
+ varList.push(name);
2850
+ return {
2851
+ type: 'var',
2852
+ name: name,
2853
+ members: m,
2854
+ prefix: null,
2855
+ };
2856
+ }
2857
+ / n:literal_numeric {
2858
+ return {
2859
+ type: 'var',
2860
+ name: n.value,
2861
+ members: [],
2862
+ quoted: null,
2863
+ prefix: null,
2864
+ }
2865
+ }
2866
+
2867
+ mem_chain
2868
+ = l:('.' ident_name)* {
2869
+ const s = [];
2870
+ for (let i = 0; i < l.length; i++) {
2871
+ s.push(l[i][1]);
2872
+ }
2873
+ return s;
2874
+ }
2875
+
2876
+ data_type
2877
+ = data_type_item
2878
+ / array_type
2879
+ / map_type
2880
+
2881
+ data_type_item
2882
+ = character_string_type
2883
+ / numeric_type
2884
+ / datetime_type
2885
+ / json_type
2886
+ / boolean_type
2887
+ / map_type
2888
+ / text_type
2889
+
2890
+ data_type_list
2891
+ = head:data_type_item tail:(__ COMMA __ data_type_item)* {
2892
+ return createList(head, tail);
2893
+ }
2894
+
2895
+ array_type
2896
+ = t:KW_ARRAY __ LPAREN __ a:data_type_list __ RPAREN {
2897
+ return {
2898
+ dataType: t,
2899
+ parentheses: true,
2900
+ expr: {
2901
+ type: 'expr_list',
2902
+ value: a.map(d => ({ type: 'datatype', ...d }))
2903
+ },
2904
+ }
2905
+ }
2906
+ / t:KW_ARRAY __ LANGLE_BRACKET __ a:data_type_list __ RANGLE_BRACKET {
2907
+ return {
2908
+ dataType: t,
2909
+ angle_brackets: true,
2910
+ expr: {
2911
+ type: 'expr_list',
2912
+ value: a.map(d => ({ type: 'datatype', ...d }))
2913
+ },
2914
+ }
2915
+ }
2916
+
2917
+ map_type
2918
+ = t:KW_MAP __ LPAREN __ a:data_type_list __ RPAREN {
2919
+ return {
2920
+ dataType: t,
2921
+ parentheses: true,
2922
+ expr: {
2923
+ type: 'expr_list',
2924
+ value: a.map(d => ({ type: 'datatype', ...d }))
2925
+ },
2926
+ }
2927
+ }
2928
+ / t:KW_MAP __ LANGLE_BRACKET __ a:data_type_list __ RANGLE_BRACKET {
2929
+ return {
2930
+ dataType: t,
2931
+ angle_brackets: true,
2932
+ expr: {
2933
+ type: 'expr_list',
2934
+ value: a.map(d => ({ type: 'datatype', ...d }))
2935
+ },
2936
+ }
2937
+ }
2938
+
2939
+ character_string_type
2940
+ = t:(KW_CHAR / KW_VARCHAR) __ LPAREN __ l:[0-9]+ __ RPAREN {
2941
+ return { dataType: t, length: parseInt(l.join(''), 10), parentheses: true };
2942
+ }
2943
+ / t:(KW_CHAR / KW_VARCHAR / KW_STRING) { return { dataType: t }; }
2944
+
2945
+ numeric_type_suffix
2946
+ = un: KW_UNSIGNED? __ ze: KW_ZEROFILL? {
2947
+ const result = []
2948
+ if (un) result.push(un)
2949
+ if (ze) result.push(ze)
2950
+ return result
2951
+ }
2952
+ numeric_type
2953
+ = 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 }; }
2954
+ / 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 }; }
2955
+ / 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 }; }
2956
+ datetime_type
2957
+ = t:(KW_DATE / KW_DATETIME / KW_TIME / KW_TIMESTAMP) __ LPAREN __ l:[0-9]+ __ RPAREN { return { dataType: t, length: parseInt(l.join(''), 10), parentheses: true }; }
2958
+ / t:(KW_DATE / KW_DATETIME / KW_TIME / KW_TIMESTAMP) { return { dataType: t }; }
2959
+
2960
+ json_type
2961
+ = t:KW_JSON { return { dataType: t }; }
2962
+
2963
+ boolean_type
2964
+ = t:KW_BOOLEAN { return { dataType: t }; }
2965
+
2966
+ text_type
2967
+ = t:(KW_TINYTEXT / KW_TEXT / KW_MEDIUMTEXT / KW_LONGTEXT) { return { dataType: t }}