@tachybase/database 0.23.8

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 (226) hide show
  1. package/.turbo/turbo-build.log +10 -0
  2. package/LICENSE +201 -0
  3. package/lib/collection-factory.d.ts +17 -0
  4. package/lib/collection-factory.js +52 -0
  5. package/lib/collection-group-manager.d.ts +26 -0
  6. package/lib/collection-group-manager.js +57 -0
  7. package/lib/collection-importer.d.ts +7 -0
  8. package/lib/collection-importer.js +74 -0
  9. package/lib/collection.d.ts +138 -0
  10. package/lib/collection.js +686 -0
  11. package/lib/database-utils/index.d.ts +9 -0
  12. package/lib/database-utils/index.js +71 -0
  13. package/lib/database-utils/traverseJSON.d.ts +10 -0
  14. package/lib/database-utils/traverseJSON.js +126 -0
  15. package/lib/database.d.ts +201 -0
  16. package/lib/database.js +765 -0
  17. package/lib/decorators/must-have-filter-decorator.d.ts +2 -0
  18. package/lib/decorators/must-have-filter-decorator.js +38 -0
  19. package/lib/decorators/target-collection-decorator.d.ts +2 -0
  20. package/lib/decorators/target-collection-decorator.js +47 -0
  21. package/lib/decorators/transaction-decorator.d.ts +1 -0
  22. package/lib/decorators/transaction-decorator.js +88 -0
  23. package/lib/eager-loading/eager-loading-tree.d.ts +31 -0
  24. package/lib/eager-loading/eager-loading-tree.js +439 -0
  25. package/lib/errors/identifier-error.d.ts +3 -0
  26. package/lib/errors/identifier-error.js +35 -0
  27. package/lib/errors/zero-column-table-error.d.ts +2 -0
  28. package/lib/errors/zero-column-table-error.js +31 -0
  29. package/lib/features/references-map.d.ts +18 -0
  30. package/lib/features/references-map.js +109 -0
  31. package/lib/features/referential-integrity-check.d.ts +8 -0
  32. package/lib/features/referential-integrity-check.js +83 -0
  33. package/lib/field-repository/array-field-repository.d.ts +28 -0
  34. package/lib/field-repository/array-field-repository.js +197 -0
  35. package/lib/fields/array-field.d.ts +11 -0
  36. package/lib/fields/array-field.js +57 -0
  37. package/lib/fields/belongs-to-field.d.ts +17 -0
  38. package/lib/fields/belongs-to-field.js +154 -0
  39. package/lib/fields/belongs-to-many-field.d.ts +20 -0
  40. package/lib/fields/belongs-to-many-field.js +187 -0
  41. package/lib/fields/boolean-field.d.ts +8 -0
  42. package/lib/fields/boolean-field.js +36 -0
  43. package/lib/fields/context-field.d.ts +14 -0
  44. package/lib/fields/context-field.js +70 -0
  45. package/lib/fields/date-field.d.ts +13 -0
  46. package/lib/fields/date-field.js +64 -0
  47. package/lib/fields/field.d.ts +43 -0
  48. package/lib/fields/field.js +156 -0
  49. package/lib/fields/has-inverse-field.d.ts +4 -0
  50. package/lib/fields/has-inverse-field.js +15 -0
  51. package/lib/fields/has-many-field.d.ts +68 -0
  52. package/lib/fields/has-many-field.js +156 -0
  53. package/lib/fields/has-one-field.d.ts +68 -0
  54. package/lib/fields/has-one-field.js +150 -0
  55. package/lib/fields/index.d.ts +46 -0
  56. package/lib/fields/index.js +65 -0
  57. package/lib/fields/json-field.d.ts +14 -0
  58. package/lib/fields/json-field.js +54 -0
  59. package/lib/fields/nanoid-field.d.ts +13 -0
  60. package/lib/fields/nanoid-field.js +58 -0
  61. package/lib/fields/number-field.d.ts +41 -0
  62. package/lib/fields/number-field.js +85 -0
  63. package/lib/fields/password-field.d.ts +21 -0
  64. package/lib/fields/password-field.js +95 -0
  65. package/lib/fields/radio-field.d.ts +16 -0
  66. package/lib/fields/radio-field.js +66 -0
  67. package/lib/fields/relation-field.d.ts +21 -0
  68. package/lib/fields/relation-field.js +79 -0
  69. package/lib/fields/set-field.d.ts +10 -0
  70. package/lib/fields/set-field.js +46 -0
  71. package/lib/fields/sort-field.d.ts +16 -0
  72. package/lib/fields/sort-field.js +187 -0
  73. package/lib/fields/string-field.d.ts +8 -0
  74. package/lib/fields/string-field.js +36 -0
  75. package/lib/fields/text-field.d.ts +8 -0
  76. package/lib/fields/text-field.js +36 -0
  77. package/lib/fields/time-field.d.ts +8 -0
  78. package/lib/fields/time-field.js +36 -0
  79. package/lib/fields/uid-field.d.ts +13 -0
  80. package/lib/fields/uid-field.js +63 -0
  81. package/lib/fields/uuid-field.d.ts +9 -0
  82. package/lib/fields/uuid-field.js +45 -0
  83. package/lib/fields/virtual-field.d.ts +8 -0
  84. package/lib/fields/virtual-field.js +36 -0
  85. package/lib/filter-match.d.ts +1 -0
  86. package/lib/filter-match.js +66 -0
  87. package/lib/filter-parser.d.ts +21 -0
  88. package/lib/filter-parser.js +230 -0
  89. package/lib/helpers.d.ts +3 -0
  90. package/lib/helpers.js +167 -0
  91. package/lib/index.d.ts +30 -0
  92. package/lib/index.js +114 -0
  93. package/lib/inherited-collection.d.ts +14 -0
  94. package/lib/inherited-collection.js +138 -0
  95. package/lib/inherited-map.d.ts +21 -0
  96. package/lib/inherited-map.js +113 -0
  97. package/lib/inherited-sync-runner.d.ts +4 -0
  98. package/lib/inherited-sync-runner.js +175 -0
  99. package/lib/listeners/adjacency-list.d.ts +2 -0
  100. package/lib/listeners/adjacency-list.js +42 -0
  101. package/lib/listeners/append-child-collection-name-after-repository-find.d.ts +6 -0
  102. package/lib/listeners/append-child-collection-name-after-repository-find.js +66 -0
  103. package/lib/listeners/index.d.ts +2 -0
  104. package/lib/listeners/index.js +33 -0
  105. package/lib/magic-attribute-model.d.ts +8 -0
  106. package/lib/magic-attribute-model.js +203 -0
  107. package/lib/migration.d.ts +35 -0
  108. package/lib/migration.js +103 -0
  109. package/lib/mock-database.d.ts +25 -0
  110. package/lib/mock-database.js +126 -0
  111. package/lib/model-hook.d.ts +12 -0
  112. package/lib/model-hook.js +92 -0
  113. package/lib/model.d.ts +23 -0
  114. package/lib/model.js +152 -0
  115. package/lib/operators/array.d.ts +2 -0
  116. package/lib/operators/array.js +158 -0
  117. package/lib/operators/association.d.ts +2 -0
  118. package/lib/operators/association.js +35 -0
  119. package/lib/operators/boolean.d.ts +2 -0
  120. package/lib/operators/boolean.js +38 -0
  121. package/lib/operators/child-collection.d.ts +2 -0
  122. package/lib/operators/child-collection.js +67 -0
  123. package/lib/operators/date.d.ts +2 -0
  124. package/lib/operators/date.js +140 -0
  125. package/lib/operators/empty.d.ts +5 -0
  126. package/lib/operators/empty.js +89 -0
  127. package/lib/operators/eq.d.ts +2 -0
  128. package/lib/operators/eq.js +35 -0
  129. package/lib/operators/index.d.ts +5 -0
  130. package/lib/operators/index.js +56 -0
  131. package/lib/operators/jsonb.d.ts +2 -0
  132. package/lib/operators/jsonb.js +50 -0
  133. package/lib/operators/ne.d.ts +2 -0
  134. package/lib/operators/ne.js +40 -0
  135. package/lib/operators/notIn.d.ts +2 -0
  136. package/lib/operators/notIn.js +33 -0
  137. package/lib/operators/string.d.ts +2 -0
  138. package/lib/operators/string.js +109 -0
  139. package/lib/operators/utils.d.ts +4 -0
  140. package/lib/operators/utils.js +40 -0
  141. package/lib/options-parser.d.ts +37 -0
  142. package/lib/options-parser.js +332 -0
  143. package/lib/playground.d.ts +1 -0
  144. package/lib/playground.js +43 -0
  145. package/lib/query-interface/mysql-query-interface.d.ts +35 -0
  146. package/lib/query-interface/mysql-query-interface.js +122 -0
  147. package/lib/query-interface/postgres-query-interface.d.ts +32 -0
  148. package/lib/query-interface/postgres-query-interface.js +189 -0
  149. package/lib/query-interface/query-interface-builder.d.ts +2 -0
  150. package/lib/query-interface/query-interface-builder.js +46 -0
  151. package/lib/query-interface/query-interface.d.ts +42 -0
  152. package/lib/query-interface/query-interface.js +46 -0
  153. package/lib/query-interface/sqlite-query-interface.d.ts +35 -0
  154. package/lib/query-interface/sqlite-query-interface.js +131 -0
  155. package/lib/relation-repository/belongs-to-many-repository.d.ts +21 -0
  156. package/lib/relation-repository/belongs-to-many-repository.js +280 -0
  157. package/lib/relation-repository/belongs-to-repository.d.ts +6 -0
  158. package/lib/relation-repository/belongs-to-repository.js +39 -0
  159. package/lib/relation-repository/hasmany-repository.d.ts +10 -0
  160. package/lib/relation-repository/hasmany-repository.js +182 -0
  161. package/lib/relation-repository/hasone-repository.d.ts +6 -0
  162. package/lib/relation-repository/hasone-repository.js +39 -0
  163. package/lib/relation-repository/multiple-relation-repository.d.ts +20 -0
  164. package/lib/relation-repository/multiple-relation-repository.js +229 -0
  165. package/lib/relation-repository/relation-repository.d.ts +29 -0
  166. package/lib/relation-repository/relation-repository.js +202 -0
  167. package/lib/relation-repository/single-relation-repository.d.ts +25 -0
  168. package/lib/relation-repository/single-relation-repository.js +162 -0
  169. package/lib/relation-repository/types.d.ts +7 -0
  170. package/lib/relation-repository/types.js +15 -0
  171. package/lib/repositories/tree-repository/adjacency-list-repository.d.ts +18 -0
  172. package/lib/repositories/tree-repository/adjacency-list-repository.js +183 -0
  173. package/lib/repositories/view-repository.d.ts +3 -0
  174. package/lib/repositories/view-repository.js +32 -0
  175. package/lib/repository.d.ts +206 -0
  176. package/lib/repository.js +597 -0
  177. package/lib/sql-collection/index.d.ts +2 -0
  178. package/lib/sql-collection/index.js +23 -0
  179. package/lib/sql-collection/query-generator.d.ts +10 -0
  180. package/lib/sql-collection/query-generator.js +70 -0
  181. package/lib/sql-collection/sql-collection.d.ts +7 -0
  182. package/lib/sql-collection/sql-collection.js +69 -0
  183. package/lib/sql-collection/sql-model.d.ts +16 -0
  184. package/lib/sql-collection/sql-model.js +168 -0
  185. package/lib/sql-parser/index.d.ts +10 -0
  186. package/lib/sql-parser/index.js +10699 -0
  187. package/lib/sql-parser/postgres.d.ts +10 -0
  188. package/lib/sql-parser/postgres.js +31506 -0
  189. package/lib/sql-parser/sql.pegjs +1297 -0
  190. package/lib/sync-runner.d.ts +30 -0
  191. package/lib/sync-runner.js +277 -0
  192. package/lib/types.d.ts +49 -0
  193. package/lib/types.js +15 -0
  194. package/lib/update-associations.d.ts +60 -0
  195. package/lib/update-associations.js +405 -0
  196. package/lib/update-guard.d.ts +28 -0
  197. package/lib/update-guard.js +202 -0
  198. package/lib/utils.d.ts +7 -0
  199. package/lib/utils.js +127 -0
  200. package/lib/value-parsers/array-value-parser.d.ts +8 -0
  201. package/lib/value-parsers/array-value-parser.js +58 -0
  202. package/lib/value-parsers/base-value-parser.d.ts +12 -0
  203. package/lib/value-parsers/base-value-parser.js +63 -0
  204. package/lib/value-parsers/boolean-value-parser.d.ts +4 -0
  205. package/lib/value-parsers/boolean-value-parser.js +52 -0
  206. package/lib/value-parsers/date-value-parser.d.ts +5 -0
  207. package/lib/value-parsers/date-value-parser.js +88 -0
  208. package/lib/value-parsers/index.d.ts +12 -0
  209. package/lib/value-parsers/index.js +78 -0
  210. package/lib/value-parsers/json-value-parser.d.ts +4 -0
  211. package/lib/value-parsers/json-value-parser.js +47 -0
  212. package/lib/value-parsers/number-value-parser.d.ts +4 -0
  213. package/lib/value-parsers/number-value-parser.js +58 -0
  214. package/lib/value-parsers/string-value-parser.d.ts +8 -0
  215. package/lib/value-parsers/string-value-parser.js +64 -0
  216. package/lib/value-parsers/to-many-value-parser.d.ts +13 -0
  217. package/lib/value-parsers/to-many-value-parser.js +108 -0
  218. package/lib/value-parsers/to-one-value-parser.d.ts +4 -0
  219. package/lib/value-parsers/to-one-value-parser.js +48 -0
  220. package/lib/view/field-type-map.d.ts +97 -0
  221. package/lib/view/field-type-map.js +90 -0
  222. package/lib/view/view-inference.d.ts +32 -0
  223. package/lib/view/view-inference.js +146 -0
  224. package/lib/view-collection.d.ts +6 -0
  225. package/lib/view-collection.js +45 -0
  226. package/package.json +38 -0
@@ -0,0 +1,1297 @@
1
+ {
2
+ const reservedMap = {
3
+ 'ALL': true,
4
+ 'AND': true,
5
+ 'AS': true,
6
+ 'ASC': true,
7
+
8
+ 'BETWEEN': true,
9
+ 'BY': true,
10
+
11
+ 'CASE': true,
12
+ 'CREATE': true,
13
+ 'CONTAINS': true,
14
+ 'CURRENT_DATE': true,
15
+ 'CURRENT_TIME': true,
16
+ 'CURRENT_TIMESTAMP': true,
17
+ 'CURRENT_USER': true,
18
+
19
+ 'DELETE': true,
20
+ 'DESC': true,
21
+ 'DISTINCT': true,
22
+ 'DROP': true,
23
+
24
+ 'ELSE': true,
25
+ 'END': true,
26
+ 'EXISTS': true,
27
+ 'EXPLAIN': true,
28
+
29
+ 'FALSE': true,
30
+ 'FROM': true,
31
+ 'FULL': true,
32
+
33
+ 'GROUP': true,
34
+
35
+ 'HAVING': true,
36
+
37
+ 'IN': true,
38
+ 'INDEX': true,
39
+ 'INNER': true,
40
+ 'INSERT': true,
41
+ 'INTO': true,
42
+ 'IS': true,
43
+
44
+ 'JOIN': true,
45
+ 'JSON': true,
46
+
47
+ 'LEFT': true,
48
+ 'LIKE': true,
49
+ 'LIMIT': true,
50
+
51
+ 'NOT': true,
52
+ 'NULL': true,
53
+
54
+ 'ON': true,
55
+ 'OR': true,
56
+ 'ORDER': true,
57
+ 'OUTER': true,
58
+
59
+ 'RECURSIVE': true,
60
+ 'REPLACE': true,
61
+ 'RIGHT': true,
62
+
63
+ 'SELECT': true,
64
+ 'SESSION_USER': true,
65
+ 'SET': true,
66
+ 'SHOW': true,
67
+ 'STATUS': true, // reserved (MySQL)
68
+ 'SYSTEM_USER': true,
69
+
70
+ 'TABLE': true,
71
+ 'THEN': true,
72
+ 'TRUE': true,
73
+ 'TYPE': true, // reserved (MySQL)
74
+
75
+ 'UNION': true,
76
+ 'UPDATE': true,
77
+ 'USER': true,
78
+ 'USING': true,
79
+
80
+ 'VALUES': true,
81
+
82
+ 'WITH': true,
83
+ 'WHEN': true,
84
+ 'WHERE': true
85
+ };
86
+
87
+ function createUnaryExpr(op, e) {
88
+ return {
89
+ type: 'unary_expr',
90
+ operator: op,
91
+ expr: e
92
+ };
93
+ }
94
+
95
+ function createBinaryExpr(op, left, right) {
96
+ return {
97
+ type: 'binary_expr',
98
+ operator: op,
99
+ left: left,
100
+ right: right
101
+ };
102
+ }
103
+
104
+ function createList(head, tail) {
105
+ const result = [head];
106
+ for (let i = 0; i < tail.length; i++) {
107
+ result.push(tail[i][3]);
108
+ }
109
+ return result;
110
+ }
111
+
112
+ function createBinaryExprChain(head, tail) {
113
+ let result = head;
114
+ for (let i = 0; i < tail.length; i++) {
115
+ result = createBinaryExpr(tail[i][1], result, tail[i][3]);
116
+ }
117
+ return result;
118
+ }
119
+
120
+ const cmpPrefixMap = {
121
+ '+': true,
122
+ '-': true,
123
+ '*': true,
124
+ '/': true,
125
+ '>': true,
126
+ '<': true,
127
+ '!': true,
128
+ '=': true,
129
+
130
+ //between
131
+ 'B': true,
132
+ 'b': true,
133
+ //for is or in
134
+ 'I': true,
135
+ 'i': true,
136
+ //for like
137
+ 'L': true,
138
+ 'l': true,
139
+ //for not
140
+ 'N': true,
141
+ 'n': true
142
+ };
143
+
144
+ // used for dependency analysis
145
+ let varList = [];
146
+
147
+ const tableList = new Set();
148
+ const columnList = new Set();
149
+ }
150
+
151
+ start
152
+ = multiple_stmt
153
+ / crud_stmt
154
+
155
+ crud_stmt
156
+ = union_stmt
157
+ / update_stmt
158
+ / replace_insert_stmt
159
+ / insert_no_columns_stmt
160
+ / delete_stmt
161
+ / proc_stmts
162
+
163
+ multiple_stmt
164
+ = head:crud_stmt tail:(__ SEMICOLON __ crud_stmt)+ {
165
+ const cur = [head && head.ast || head];
166
+ for (let i = 0; i < tail.length; i++) {
167
+ if(!tail[i][3] || tail[i][3].length === 0) continue;
168
+ cur.push(tail[i][3] && tail[i][3].ast || tail[i][3]);
169
+ }
170
+ return {
171
+ tableList: Array.from(tableList),
172
+ columnList: Array.from(columnList),
173
+ ast: cur
174
+ }
175
+ }
176
+
177
+ union_stmt
178
+ = head:select_stmt tail:(__ KW_UNION __ select_stmt)* {
179
+ let cur = head;
180
+ for (let i = 0; i < tail.length; i++) {
181
+ cur._next = tail[i][3];
182
+ cur = cur._next
183
+ }
184
+ return {
185
+ tableList: Array.from(tableList),
186
+ columnList: Array.from(columnList),
187
+ ast: head
188
+ }
189
+ }
190
+
191
+ select_stmt
192
+ = select_stmt_nake
193
+ / s:('(' __ select_stmt __ ')') {
194
+ return s[2];
195
+ }
196
+
197
+ with_clause
198
+ = KW_WITH __ head:cte_definition tail:(__ COMMA __ cte_definition)* {
199
+ return createList(head, tail);
200
+ }
201
+ / __ KW_WITH __ KW_RECURSIVE __ cte:cte_definition {
202
+ cte.recursive = true;
203
+ return [cte]
204
+ }
205
+
206
+ cte_definition
207
+ = name:ident_name __ columns:cte_column_definition? __ KW_AS __ LPAREN __ stmt:union_stmt __ RPAREN {
208
+ return { name, stmt, columns };
209
+ }
210
+
211
+ cte_column_definition
212
+ = LPAREN __ head:column tail:(__ COMMA __ column)* __ RPAREN {
213
+ return createList(head, tail);
214
+ }
215
+
216
+ select_stmt_nake
217
+ = cte:with_clause? __ KW_SELECT __
218
+ opts:option_clause? __
219
+ d:KW_DISTINCT? __
220
+ c:column_clause __
221
+ f:from_clause? __
222
+ w:where_clause? __
223
+ g:group_by_clause? __
224
+ h:having_clause? __
225
+ o:order_by_clause? __
226
+ l:limit_clause? {
227
+ if(f) f.forEach(info => info.table && tableList.add(`select::${info.db}::${info.table}`));
228
+ return {
229
+ with: cte,
230
+ type: 'select',
231
+ options: opts,
232
+ distinct: d,
233
+ columns: c,
234
+ from: f,
235
+ where: w,
236
+ groupby: g,
237
+ having: h,
238
+ orderby: o,
239
+ limit: l
240
+ };
241
+ }
242
+
243
+ // MySQL extensions to standard SQL
244
+ option_clause
245
+ = head:query_option tail:(__ query_option)* {
246
+ const opts = [head];
247
+ for (let i = 0, l = tail.length; i < l; ++i) {
248
+ opts.push(tail[i][1]);
249
+ }
250
+ return opts;
251
+ }
252
+
253
+ query_option
254
+ = option:(
255
+ OPT_SQL_CALC_FOUND_ROWS
256
+ / (OPT_SQL_CACHE / OPT_SQL_NO_CACHE)
257
+ / OPT_SQL_BIG_RESULT
258
+ / OPT_SQL_SMALL_RESULT
259
+ / OPT_SQL_BUFFER_RESULT
260
+ ) { return option; }
261
+
262
+ column_clause
263
+ = (KW_ALL / (STAR !ident_start) / STAR) {
264
+ columnList.add('select::null::(.*)');
265
+ return '*';
266
+ }
267
+ / head:column_list_item tail:(__ COMMA __ column_list_item)* {
268
+ return createList(head, tail);
269
+ }
270
+
271
+ column_list_item
272
+ = tbl:ident __ DOT __ STAR {
273
+ columnList.add(`select::${tbl}::(.*)`);
274
+ return {
275
+ expr: {
276
+ type: 'column_ref',
277
+ table: tbl,
278
+ column: '*'
279
+ },
280
+ as: null
281
+ };
282
+ }
283
+ / e:expr __ alias:alias_clause? {
284
+ return { expr: e, as: alias };
285
+ }
286
+
287
+ alias_clause
288
+ = KW_AS __ i:alias_ident { return i; }
289
+ / KW_AS? __ i:ident { return i; }
290
+
291
+ from_clause
292
+ = KW_FROM __ l:table_ref_list { return l; }
293
+
294
+ table_ref_list
295
+ = head:table_base
296
+ tail:table_ref* {
297
+ tail.unshift(head);
298
+ return tail;
299
+ }
300
+
301
+ table_ref
302
+ = __ COMMA __ t:table_base { return t; }
303
+ / __ t:table_join { return t; }
304
+
305
+
306
+ table_join
307
+ = op:join_op __ t:table_base __ KW_USING __ LPAREN __ head:ident_name tail:(__ COMMA __ ident_name)* __ RPAREN {
308
+ t.join = op;
309
+ t.using = createList(head, tail);
310
+ return t;
311
+ }
312
+ / op:join_op __ t:table_base __ expr:on_clause? {
313
+ t.join = op;
314
+ t.on = expr;
315
+ return t;
316
+ }
317
+ / op:join_op __ LPAREN __ stmt:union_stmt __ RPAREN __ alias:alias_clause? __ expr:on_clause? {
318
+ stmt.parentheses = true;
319
+ return {
320
+ expr: stmt,
321
+ as: alias,
322
+ join: op,
323
+ on: expr
324
+ };
325
+ }
326
+
327
+ //NOTE that, the table assigned to `var` shouldn't write in `table_join`
328
+ table_base
329
+ = KW_DUAL {
330
+ return {
331
+ type: 'dual'
332
+ };
333
+ }
334
+ / t:table_name __ alias:alias_clause? {
335
+ if (t.type === 'var') {
336
+ t.as = alias;
337
+ return t;
338
+ } else {
339
+ return {
340
+ db: t.db,
341
+ table: t.table,
342
+ as: alias
343
+ };
344
+ }
345
+ }
346
+ / LPAREN __ stmt:union_stmt __ RPAREN __ alias:alias_clause? {
347
+ stmt.parentheses = true;
348
+ return {
349
+ expr: stmt,
350
+ as: alias
351
+ };
352
+ }
353
+
354
+ join_op
355
+ = KW_LEFT __ KW_OUTER? __ KW_JOIN { return 'LEFT JOIN'; }
356
+ / KW_RIGHT __ KW_OUTER? __ KW_JOIN { return 'RIGHT JOIN'; }
357
+ / KW_FULL __ KW_OUTER? __ KW_JOIN { return 'FULL JOIN'; }
358
+ / (KW_INNER __)? KW_JOIN { return 'INNER JOIN'; }
359
+
360
+ table_name
361
+ = dt:ident tail:(__ DOT __ ident)? {
362
+ const obj = { db: null, table: dt };
363
+ if (tail !== null) {
364
+ obj.db = dt;
365
+ obj.table = tail[3];
366
+ }
367
+ return obj;
368
+ }
369
+ / v:var_decl {
370
+ v.db = null;
371
+ v.table = v.name;
372
+ return v;
373
+ }
374
+
375
+ on_clause
376
+ = KW_ON __ e:expr { return e; }
377
+
378
+ where_clause
379
+ = KW_WHERE __ e:expr { return e; }
380
+
381
+ group_by_clause
382
+ = KW_GROUP __ KW_BY __ l:column_ref_list { return l; }
383
+
384
+ column_ref_list
385
+ = head:column_ref tail:(__ COMMA __ column_ref)* {
386
+ return createList(head, tail);
387
+ }
388
+
389
+ having_clause
390
+ = KW_HAVING __ e:expr { return e; }
391
+
392
+ order_by_clause
393
+ = KW_ORDER __ KW_BY __ l:order_by_list { return l; }
394
+
395
+ order_by_list
396
+ = head:order_by_element tail:(__ COMMA __ order_by_element)* {
397
+ return createList(head, tail);
398
+ }
399
+
400
+ order_by_element
401
+ = e:expr __ d:(KW_DESC / KW_ASC)? {
402
+ const obj = { expr: e, type: 'ASC' };
403
+ if (d === 'DESC') obj.type = 'DESC';
404
+ return obj;
405
+ }
406
+
407
+ number_or_param
408
+ = literal_numeric
409
+ / param
410
+
411
+ limit_clause
412
+ = KW_LIMIT __ i1:(number_or_param) __ tail:(COMMA __ number_or_param)? {
413
+ const res = [i1];
414
+ if (tail === null) res.unshift({ type: 'number', value: 0 });
415
+ else res.push(tail[2]);
416
+ return res;
417
+ }
418
+
419
+ update_stmt
420
+ = KW_UPDATE __
421
+ t:table_name __
422
+ KW_SET __
423
+ l:set_list __
424
+ w:where_clause? {
425
+ if(t.table) tableList.add(`update::${t.db}::${t.table}`);
426
+ if(l) l.forEach(col => columnList.add(`update::${t.table}::${col.column}`));
427
+ return {
428
+ tableList: Array.from(tableList),
429
+ columnList: Array.from(columnList),
430
+ ast: {
431
+ type: 'update',
432
+ db: t.db,
433
+ table: t.table,
434
+ set: l,
435
+ where: w
436
+ }
437
+ };
438
+ }
439
+
440
+ delete_stmt
441
+ = KW_DELETE __
442
+ t: table_ref_list? __
443
+ f:from_clause __
444
+ w:where_clause? {
445
+ if(f) f.forEach(info => {
446
+ info.table && tableList.add(`delete::${info.db}::${info.table}`);
447
+ columnList.add(`delete::${info.table}::(.*)`);
448
+ });
449
+ return {
450
+ tableList: Array.from(tableList),
451
+ columnList: Array.from(columnList),
452
+ ast: {
453
+ type: 'delete',
454
+ tables: t,
455
+ from: f,
456
+ where: w
457
+ }
458
+ };
459
+ }
460
+ set_list
461
+ = head:set_item tail:(__ COMMA __ set_item)* {
462
+ return createList(head, tail);
463
+ }
464
+
465
+ /**
466
+ * here only use `additive_expr` to support 'col1 = col1+2'
467
+ * if you want to use lower operator, please use '()' like below
468
+ * 'col1 = (col2 > 3)'
469
+ */
470
+ set_item
471
+ = tbl:(ident __ DOT)? __ c:column_name __ '=' __ v:additive_expr {
472
+ return { column: c, value: v, table: tbl && tbl[0] };
473
+ }
474
+
475
+ replace_insert_stmt
476
+ = ri:replace_insert __
477
+ KW_INTO __
478
+ t:table_name __ LPAREN __
479
+ c:column_list __ RPAREN __
480
+ v:value_clause {
481
+ if (t.table) tableList.add(`insert::${t.db}::${t.table}`);
482
+ if (c) c.forEach(c => columnList.add(`insert::${t.table}::${c}`));
483
+ return {
484
+ tableList: Array.from(tableList),
485
+ columnList: Array.from(columnList),
486
+ ast: {
487
+ type: ri,
488
+ db: t.db,
489
+ table: t.table,
490
+ columns: c,
491
+ values: v
492
+ }
493
+ };
494
+ }
495
+
496
+ insert_no_columns_stmt
497
+ = ri:replace_insert __
498
+ KW_INTO __
499
+ t:table_name __
500
+ v:value_clause {
501
+ if (t.table) tableList.add(`insert::${t.db}::${t.table}`);
502
+ columnList.add(`insert::${t.table}::(.*)`);
503
+ return {
504
+ tableList: Array.from(tableList),
505
+ columnList: Array.from(columnList),
506
+ ast: {
507
+ type: ri,
508
+ db: t.db,
509
+ table: t.table,
510
+ columns: null,
511
+ values: v
512
+ }
513
+ };
514
+ }
515
+
516
+ replace_insert
517
+ = KW_INSERT { return 'insert'; }
518
+ / KW_REPLACE { return 'replace'; }
519
+
520
+ value_clause
521
+ = KW_VALUES __ l:value_list { return l; }
522
+
523
+ value_list
524
+ = head:value_item tail:(__ COMMA __ value_item)* {
525
+ return createList(head, tail);
526
+ }
527
+
528
+ value_item
529
+ = LPAREN __ l:expr_list __ RPAREN {
530
+ return l;
531
+ }
532
+
533
+ expr_list
534
+ = head:expr tail:(__ COMMA __ expr)* {
535
+ const el = { type: 'expr_list' };
536
+ el.value = createList(head, tail);
537
+ return el;
538
+ }
539
+
540
+ interval_expr
541
+ = KW_INTERVAL __
542
+ n:number __
543
+ u: interval_unit {
544
+ return {
545
+ type: 'interval',
546
+ value: [n, u]
547
+ }
548
+ }
549
+
550
+ case_expr
551
+ = KW_CASE __
552
+ expr:expr? __
553
+ condition_list:case_when_then+ __
554
+ otherwise:case_else? __
555
+ KW_END __ KW_CASE? {
556
+ if (otherwise) condition_list.push(otherwise);
557
+ return {
558
+ type: 'case',
559
+ expr: expr || null,
560
+ args: condition_list
561
+ };
562
+ }
563
+
564
+ case_when_then
565
+ = KW_WHEN __ condition:expr __ KW_THEN __ result:expr __ {
566
+ return {
567
+ type: 'when',
568
+ cond: condition,
569
+ result: result
570
+ };
571
+ }
572
+
573
+ case_else = KW_ELSE __ result:expr {
574
+ return { type: 'else', result: result };
575
+ }
576
+
577
+ /**
578
+ * Borrowed from PL/SQL ,the priority of below list IS ORDER BY DESC
579
+ * ---------------------------------------------------------------------------------------------------
580
+ * | +, - | identity, negation |
581
+ * | *, / | multiplication, division |
582
+ * | +, - | addition, subtraction, concatenation |
583
+ * | =, <, >, <=, >=, <>, !=, IS, LIKE, BETWEEN, IN | comparion |
584
+ * | !, NOT | logical negation |
585
+ * | AND | conjunction |
586
+ * | OR | inclusion |
587
+ * ---------------------------------------------------------------------------------------------------
588
+ */
589
+
590
+ expr
591
+ = or_expr
592
+ / select_stmt
593
+
594
+ or_expr
595
+ = head:and_expr tail:(__ KW_OR __ and_expr)* {
596
+ return createBinaryExprChain(head, tail);
597
+ }
598
+
599
+ and_expr
600
+ = head:not_expr tail:(__ KW_AND __ not_expr)* {
601
+ return createBinaryExprChain(head, tail);
602
+ }
603
+
604
+ //here we should use `NOT` instead of `comparision_expr` to support chain-expr
605
+ not_expr
606
+ = comparison_expr
607
+ / exists_expr
608
+ / (KW_NOT / "!" !"=") __ expr:not_expr {
609
+ return createUnaryExpr('NOT', expr);
610
+ }
611
+
612
+ comparison_expr
613
+ = left:additive_expr __ rh:comparison_op_right? {
614
+ if (rh === null) return left;
615
+ else if (rh.type === 'arithmetic') return createBinaryExprChain(left, rh.tail);
616
+ else return createBinaryExpr(rh.op, left, rh.right);
617
+ }
618
+
619
+ exists_expr
620
+ = op:exists_op __ LPAREN __ stmt:union_stmt __ RPAREN {
621
+ stmt.parentheses = true;
622
+ return createUnaryExpr(op, stmt);
623
+ }
624
+
625
+ exists_op
626
+ = nk:(KW_NOT __ KW_EXISTS) { return nk[0] + ' ' + nk[2]; }
627
+ / KW_EXISTS
628
+
629
+ comparison_op_right
630
+ = arithmetic_op_right
631
+ / in_op_right
632
+ / between_op_right
633
+ / is_op_right
634
+ / like_op_right
635
+
636
+ arithmetic_op_right
637
+ = l:(__ arithmetic_comparison_operator __ additive_expr)+ {
638
+ return { type: 'arithmetic', tail: l };
639
+ }
640
+
641
+ arithmetic_comparison_operator
642
+ = ">=" / ">" / "<=" / "<>" / "<" / "=" / "!="
643
+
644
+ is_op_right
645
+ = KW_IS __ right:additive_expr {
646
+ return { op: 'IS', right: right };
647
+ }
648
+ / (KW_IS __ KW_NOT) __ right:additive_expr {
649
+ return { op: 'IS NOT', right: right };
650
+ }
651
+
652
+ between_op_right
653
+ = op:between_or_not_between_op __ begin:additive_expr __ KW_AND __ end:additive_expr {
654
+ return {
655
+ op: op,
656
+ right: {
657
+ type: 'expr_list',
658
+ value: [begin, end]
659
+ }
660
+ };
661
+ }
662
+
663
+ between_or_not_between_op
664
+ = nk:(KW_NOT __ KW_BETWEEN) { return nk[0] + ' ' + nk[2]; }
665
+ / KW_BETWEEN
666
+
667
+ like_op
668
+ = nk:(KW_NOT __ KW_LIKE) { return nk[0] + ' ' + nk[2]; }
669
+ / KW_LIKE
670
+
671
+ in_op
672
+ = nk:(KW_NOT __ KW_IN) { return nk[0] + ' ' + nk[2]; }
673
+ / KW_IN
674
+
675
+ like_op_right
676
+ = op:like_op __ right:comparison_expr {
677
+ return { op: op, right: right };
678
+ }
679
+
680
+ in_op_right
681
+ = op:in_op __ LPAREN __ l:expr_list __ RPAREN {
682
+ return { op: op, right: l };
683
+ }
684
+ / op:in_op __ e:var_decl {
685
+ return { op: op, right: e };
686
+ }
687
+
688
+ additive_expr
689
+ = head:multiplicative_expr
690
+ tail:(__ additive_operator __ multiplicative_expr)* {
691
+ return createBinaryExprChain(head, tail);
692
+ }
693
+
694
+ additive_operator
695
+ = "+" / "-"
696
+
697
+ multiplicative_expr
698
+ = head:primary
699
+ tail:(__ multiplicative_operator __ primary)* {
700
+ return createBinaryExprChain(head, tail)
701
+ }
702
+
703
+ multiplicative_operator
704
+ = "*" / "/" / "%"
705
+
706
+ primary
707
+ = literal
708
+ / cast_expr
709
+ / aggr_func
710
+ / func_call
711
+ / case_expr
712
+ / interval_expr
713
+ / column_ref
714
+ / param
715
+ / LPAREN __ e:expr __ RPAREN {
716
+ e.parentheses = true;
717
+ return e;
718
+ }
719
+ / LPAREN __ list:expr_list __ RPAREN {
720
+ list.parentheses = true;
721
+ return list;
722
+ }
723
+ / var_decl
724
+
725
+ column_ref
726
+ = tbl:ident __ DOT __ col:column {
727
+ columnList.add(`select::${tbl}::${col}`);
728
+ return {
729
+ type: 'column_ref',
730
+ table: tbl,
731
+ column: col
732
+ };
733
+ }
734
+ / col:column {
735
+ columnList.add(`select::null::${col}`);
736
+ return {
737
+ type: 'column_ref',
738
+ table: null,
739
+ column: col
740
+ };
741
+ }
742
+
743
+ column_list
744
+ = head:column tail:(__ COMMA __ column)* {
745
+ return createList(head, tail);
746
+ }
747
+
748
+ ident
749
+ = name:ident_name !{ return reservedMap[name.toUpperCase()] === true; } {
750
+ return name;
751
+ }
752
+ / name:quoted_ident {
753
+ return name;
754
+ }
755
+
756
+ alias_ident
757
+ = name:ident_name !{
758
+ if (reservedMap[name.toUpperCase()] === true) throw new Error("Error: "+ JSON.stringify(name)+" is a reserved word, can not as alias clause");
759
+ return false
760
+ } {
761
+ return name;
762
+ }
763
+ / name:quoted_ident {
764
+ return name;
765
+ }
766
+
767
+ quoted_ident
768
+ = double_quoted_ident
769
+ / single_quoted_ident
770
+ / backticks_quoted_ident
771
+
772
+ double_quoted_ident
773
+ = '"' chars:[^"]+ '"' { return chars.join(''); }
774
+
775
+ single_quoted_ident
776
+ = "'" chars:[^']+ "'" { return chars.join(''); }
777
+
778
+ backticks_quoted_ident
779
+ = "`" chars:[^`]+ "`" { return chars.join(''); }
780
+
781
+ column
782
+ = name:column_name !{ return reservedMap[name.toUpperCase()] === true; } { return name; }
783
+ / quoted_ident
784
+
785
+ column_name
786
+ = start:ident_start parts:column_part* { return start + parts.join(''); }
787
+
788
+ ident_name
789
+ = start:ident_start parts:ident_part* { return start + parts.join(''); }
790
+
791
+ ident_start = [A-Za-z_]
792
+
793
+ ident_part = [A-Za-z0-9_]
794
+
795
+ // to support column name like `cf1:name` in hbase
796
+ column_part = [A-Za-z0-9_:]
797
+
798
+ param
799
+ = l:(':' ident_name) {
800
+ return { type: 'param', value: l[1] };
801
+ }
802
+
803
+ aggr_func
804
+ = aggr_fun_count
805
+ / aggr_fun_smma
806
+
807
+ aggr_fun_smma
808
+ = name:KW_SUM_MAX_MIN_AVG __ LPAREN __ e:additive_expr __ RPAREN {
809
+ return {
810
+ type: 'aggr_func',
811
+ name: name,
812
+ args: {
813
+ expr: e
814
+ }
815
+ };
816
+ }
817
+
818
+ KW_SUM_MAX_MIN_AVG
819
+ = KW_SUM / KW_MAX / KW_MIN / KW_AVG
820
+
821
+ aggr_fun_count
822
+ = name:KW_COUNT __ LPAREN __ arg:count_arg __ RPAREN {
823
+ return {
824
+ type: 'aggr_func',
825
+ name: name,
826
+ args: arg
827
+ };
828
+ }
829
+
830
+ count_arg
831
+ = e:star_expr { return { expr: e }; }
832
+ / d:KW_DISTINCT? __ c:column_ref { return { distinct: d, expr: c }; }
833
+
834
+ star_expr
835
+ = "*" { return { type: 'star', value: '*' }; }
836
+
837
+ func_call
838
+ = name:ident __ LPAREN __ l:expr_list? __ RPAREN {
839
+ return {
840
+ type: 'function',
841
+ name: name,
842
+ args: l ? l: { type: 'expr_list', value: [] }
843
+ };
844
+ }
845
+ / name:scalar_func (__ LPAREN RPAREN __)? {
846
+ return {
847
+ type: 'function',
848
+ name: name,
849
+ args: { type: 'expr_list', value: [] }
850
+ };
851
+ }
852
+
853
+ scalar_func
854
+ = KW_CURRENT_DATE
855
+ / KW_CURRENT_TIME
856
+ / KW_CURRENT_TIMESTAMP
857
+ / KW_CURRENT_USER
858
+ / KW_USER
859
+ / KW_SESSION_USER
860
+ / KW_SYSTEM_USER
861
+
862
+ cast_expr
863
+ = KW_CAST __ LPAREN __ e:expr __ KW_AS __ t:data_type __ RPAREN {
864
+ return {
865
+ type: 'cast',
866
+ expr: e,
867
+ target: t
868
+ };
869
+ }
870
+ / KW_CAST __ LPAREN __ e:expr __ KW_AS __ KW_DECIMAL __ LPAREN __ precision:int __ RPAREN __ RPAREN {
871
+ return {
872
+ type: 'cast',
873
+ expr: e,
874
+ target: {
875
+ dataType: 'DECIMAL(' + precision + ')'
876
+ }
877
+ };
878
+ }
879
+ / KW_CAST __ LPAREN __ e:expr __ KW_AS __ KW_DECIMAL __ LPAREN __ precision:int __ COMMA __ scale:int __ RPAREN __ RPAREN {
880
+ return {
881
+ type: 'cast',
882
+ expr: e,
883
+ target: {
884
+ dataType: 'DECIMAL(' + precision + ', ' + scale + ')'
885
+ }
886
+ };
887
+ }
888
+ / KW_CAST __ LPAREN __ e:expr __ KW_AS __ s:signedness __ t:KW_INTEGER? __ RPAREN { /* MySQL cast to un-/signed integer */
889
+ return {
890
+ type: 'cast',
891
+ expr: e,
892
+ target: {
893
+ dataType: s + (t ? ' ' + t: '')
894
+ }
895
+ };
896
+ }
897
+
898
+ signedness
899
+ = KW_SIGNED
900
+ / KW_UNSIGNED
901
+
902
+ literal
903
+ = literal_string
904
+ / literal_numeric
905
+ / literal_bool
906
+ / literal_null
907
+ / literal_datetime
908
+
909
+ literal_list
910
+ = head:literal tail:(__ COMMA __ literal)* {
911
+ return createList(head, tail);
912
+ }
913
+
914
+ literal_null
915
+ = KW_NULL {
916
+ return { type: 'null', value: null };
917
+ }
918
+
919
+ literal_bool
920
+ = KW_TRUE {
921
+ return { type: 'bool', value: true };
922
+ }
923
+ / KW_FALSE {
924
+ return { type: 'bool', value: false };
925
+ }
926
+
927
+ literal_string
928
+ = ca:("'" single_char* "'") {
929
+ return {
930
+ type: 'string',
931
+ value: ca[1].join('')
932
+ };
933
+ }
934
+ / ca:("\"" single_quote_char* "\"") {
935
+ return {
936
+ type: 'string',
937
+ value: ca[1].join('')
938
+ };
939
+ }
940
+
941
+ literal_datetime
942
+ = type:(KW_TIME / KW_DATE / KW_TIMESTAMP) __ ca:("'" single_char* "'") {
943
+ return {
944
+ type: type.toLowerCase(),
945
+ value: ca[1].join('')
946
+ };
947
+ }
948
+
949
+ single_quote_char
950
+ = [^"\\\0-\x1F\x7f]
951
+ / escape_char
952
+
953
+ single_char
954
+ = [^'\\\0-\x1F\x7f]
955
+ / escape_char
956
+
957
+ escape_char
958
+ = "\\'" { return "'"; }
959
+ / '\\"' { return '"'; }
960
+ / "\\\\" { return "\\"; }
961
+ / "\\/" { return "/"; }
962
+ / "\\b" { return "\b"; }
963
+ / "\\f" { return "\f"; }
964
+ / "\\n" { return "\n"; }
965
+ / "\\r" { return "\r"; }
966
+ / "\\t" { return "\t"; }
967
+ / "\\u" h1:hexDigit h2:hexDigit h3:hexDigit h4:hexDigit {
968
+ return String.fromCharCode(parseInt("0x" + h1 + h2 + h3 + h4));
969
+ }
970
+
971
+ line_terminator
972
+ = [\n\r]
973
+
974
+ literal_numeric
975
+ = n:number {
976
+ return { type: 'number', value: n };
977
+ }
978
+
979
+ number
980
+ = int_:int frac:frac exp:exp __ { return parseFloat(int_ + frac + exp); }
981
+ / int_:int frac:frac __ { return parseFloat(int_ + frac); }
982
+ / int_:int exp:exp __ { return parseFloat(int_ + exp); }
983
+ / int_:int __ { return parseFloat(int_); }
984
+
985
+ int
986
+ = digit19:digit19 digits:digits { return digit19 + digits; }
987
+ / digit:digit
988
+ / op:("-" / "+" ) digit19:digit19 digits:digits { return "-" + digit19 + digits; }
989
+ / op:("-" / "+" ) digit:digit { return "-" + digit; }
990
+
991
+ frac
992
+ = "." digits:digits { return "." + digits; }
993
+
994
+ exp
995
+ = e:e digits:digits { return e + digits; }
996
+
997
+ digits
998
+ = digits:digit+ { return digits.join(""); }
999
+
1000
+ digit = [0-9]
1001
+ digit19 = [1-9]
1002
+
1003
+ hexDigit
1004
+ = [0-9a-fA-F]
1005
+
1006
+ e
1007
+ = e:[eE] sign:[+-]? { return e + (sign !== null ? sign: ''); }
1008
+
1009
+
1010
+ KW_NULL = "NULL"i !ident_start
1011
+ KW_TRUE = "TRUE"i !ident_start
1012
+ KW_FALSE = "FALSE"i !ident_start
1013
+
1014
+ KW_SHOW = "SHOW"i !ident_start
1015
+ KW_DROP = "DROP"i !ident_start
1016
+ KW_SELECT = "SELECT"i !ident_start
1017
+ KW_UPDATE = "UPDATE"i !ident_start
1018
+ KW_CREATE = "CREATE"i !ident_start
1019
+ KW_DELETE = "DELETE"i !ident_start
1020
+ KW_INSERT = "INSERT"i !ident_start
1021
+ KW_RECURSIVE= "RECURSIVE" !ident_start
1022
+ KW_REPLACE = "REPLACE"i !ident_start
1023
+ KW_EXPLAIN = "EXPLAIN"i !ident_start
1024
+
1025
+ KW_INTO = "INTO"i !ident_start
1026
+ KW_FROM = "FROM"i !ident_start
1027
+ KW_SET = "SET"i !ident_start
1028
+
1029
+ KW_AS = "AS"i !ident_start
1030
+ KW_TABLE = "TABLE"i !ident_start
1031
+
1032
+ KW_ON = "ON"i !ident_start
1033
+ KW_LEFT = "LEFT"i !ident_start
1034
+ KW_RIGHT = "RIGHT"i !ident_start
1035
+ KW_FULL = "FULL"i !ident_start
1036
+ KW_INNER = "INNER"i !ident_start
1037
+ KW_JOIN = "JOIN"i !ident_start
1038
+ KW_OUTER = "OUTER"i !ident_start
1039
+ KW_UNION = "UNION"i !ident_start
1040
+ KW_VALUES = "VALUES"i !ident_start
1041
+ KW_USING = "USING"i !ident_start
1042
+
1043
+ KW_WHERE = "WHERE"i !ident_start
1044
+ KW_WITH = "WITH"i !ident_start
1045
+
1046
+ KW_GROUP = "GROUP"i !ident_start
1047
+ KW_BY = "BY"i !ident_start
1048
+ KW_ORDER = "ORDER"i !ident_start
1049
+ KW_HAVING = "HAVING"i !ident_start
1050
+
1051
+ KW_LIMIT = "LIMIT"i !ident_start
1052
+
1053
+ KW_ASC = "ASC"i !ident_start { return 'ASC'; }
1054
+ KW_DESC = "DESC"i !ident_start { return 'DESC'; }
1055
+
1056
+ KW_ALL = "ALL"i !ident_start { return 'ALL'; }
1057
+ KW_DISTINCT = "DISTINCT"i !ident_start { return 'DISTINCT';}
1058
+
1059
+ KW_BETWEEN = "BETWEEN"i !ident_start { return 'BETWEEN'; }
1060
+ KW_IN = "IN"i !ident_start { return 'IN'; }
1061
+ KW_IS = "IS"i !ident_start { return 'IS'; }
1062
+ KW_LIKE = "LIKE"i !ident_start { return 'LIKE'; }
1063
+ KW_EXISTS = "EXISTS"i !ident_start { return 'EXISTS'; }
1064
+
1065
+ KW_NOT = "NOT"i !ident_start { return 'NOT'; }
1066
+ KW_AND = "AND"i !ident_start { return 'AND'; }
1067
+ KW_OR = "OR"i !ident_start { return 'OR'; }
1068
+
1069
+ KW_COUNT = "COUNT"i !ident_start { return 'COUNT'; }
1070
+ KW_MAX = "MAX"i !ident_start { return 'MAX'; }
1071
+ KW_MIN = "MIN"i !ident_start { return 'MIN'; }
1072
+ KW_SUM = "SUM"i !ident_start { return 'SUM'; }
1073
+ KW_AVG = "AVG"i !ident_start { return 'AVG'; }
1074
+
1075
+ KW_CASE = "CASE"i !ident_start
1076
+ KW_WHEN = "WHEN"i !ident_start
1077
+ KW_THEN = "THEN"i !ident_start
1078
+ KW_ELSE = "ELSE"i !ident_start
1079
+ KW_END = "END"i !ident_start
1080
+
1081
+ KW_CAST = "CAST"i !ident_start
1082
+
1083
+ KW_CHAR = "CHAR"i !ident_start { return 'CHAR'; }
1084
+ KW_VARCHAR = "VARCHAR"i !ident_start { return 'VARCHAR';}
1085
+ KW_NUMERIC = "NUMERIC"i !ident_start { return 'NUMERIC'; }
1086
+ KW_DECIMAL = "DECIMAL"i !ident_start { return 'DECIMAL'; }
1087
+ KW_SIGNED = "SIGNED"i !ident_start { return 'SIGNED'; }
1088
+ KW_UNSIGNED = "UNSIGNED"i !ident_start { return 'UNSIGNED'; }
1089
+ KW_INT = "INT"i !ident_start { return 'INT'; }
1090
+ KW_INTEGER = "INTEGER"i !ident_start { return 'INTEGER'; }
1091
+ KW_JSON = "JSON"i !ident_start { return 'JSON'; }
1092
+ KW_SMALLINT = "SMALLINT"i !ident_start { return 'SMALLINT'; }
1093
+ KW_DATE = "DATE"i !ident_start { return 'DATE'; }
1094
+ KW_TIME = "TIME"i !ident_start { return 'TIME'; }
1095
+ KW_TIMESTAMP= "TIMESTAMP"i!ident_start { return 'TIMESTAMP'; }
1096
+ KW_USER = "USER"i !ident_start { return 'USER'; }
1097
+
1098
+ KW_CURRENT_DATE = "CURRENT_DATE"i !ident_start { return 'CURRENT_DATE'; }
1099
+ KW_ADD_DATE = "ADDDATE"i !ident_start { return 'ADDDATE'; }
1100
+ KW_INTERVAL = "INTERVAL"i !ident_start { return 'INTERVAL'; }
1101
+ KW_UNIT_YEAR = "YEAR"i !ident_start { return 'YEAR'; }
1102
+ KW_UNIT_MONTH = "MONTH"i !ident_start { return 'MONTH'; }
1103
+ KW_UNIT_DAY = "DAY"i !ident_start { return 'DAY'; }
1104
+ KW_UNIT_HOUR = "HOUR"i !ident_start { return 'HOUR'; }
1105
+ KW_UNIT_MINUTE = "MINUTE"i !ident_start { return 'MINUTE'; }
1106
+ KW_UNIT_SECOND = "SECOND"i !ident_start { return 'SECOND'; }
1107
+ KW_CURRENT_TIME = "CURRENT_TIME"i !ident_start { return 'CURRENT_TIME'; }
1108
+ KW_CURRENT_TIMESTAMP= "CURRENT_TIMESTAMP"i !ident_start { return 'CURRENT_TIMESTAMP'; }
1109
+ KW_CURRENT_USER = "CURRENT_USER"i !ident_start { return 'CURRENT_USER'; }
1110
+ KW_SESSION_USER = "SESSION_USER"i !ident_start { return 'SESSION_USER'; }
1111
+ KW_SYSTEM_USER = "SYSTEM_USER"i !ident_start { return 'SYSTEM_USER'; }
1112
+
1113
+ KW_VAR_PRE = '$'
1114
+ KW_RETURN = 'return'i
1115
+ KW_ASSIGN = ':='
1116
+
1117
+ KW_DUAL = "DUAL"i
1118
+
1119
+ // MySQL extensions to SQL
1120
+ OPT_SQL_CALC_FOUND_ROWS = "SQL_CALC_FOUND_ROWS"i
1121
+ OPT_SQL_CACHE = "SQL_CACHE"i
1122
+ OPT_SQL_NO_CACHE = "SQL_NO_CACHE"i
1123
+ OPT_SQL_SMALL_RESULT = "SQL_SMALL_RESULT"i
1124
+ OPT_SQL_BIG_RESULT = "SQL_BIG_RESULT"i
1125
+ OPT_SQL_BUFFER_RESULT = "SQL_BUFFER_RESULT"i
1126
+
1127
+ //special character
1128
+ DOT = '.'
1129
+ COMMA = ','
1130
+ STAR = '*'
1131
+ LPAREN = '('
1132
+ RPAREN = ')'
1133
+
1134
+ LBRAKE = '['
1135
+ RBRAKE = ']'
1136
+
1137
+ SEMICOLON = ';'
1138
+
1139
+ // separator
1140
+ __
1141
+ = (whitespace / comment)*
1142
+
1143
+ comment
1144
+ = block_comment
1145
+ / line_comment
1146
+
1147
+ block_comment
1148
+ = "/*" (!"*/" char)* "*/"
1149
+
1150
+ line_comment
1151
+ = "--" (!EOL char)*
1152
+
1153
+ char = .
1154
+
1155
+ interval_unit
1156
+ = KW_UNIT_YEAR
1157
+ / KW_UNIT_MONTH
1158
+ / KW_UNIT_DAY
1159
+ / KW_UNIT_HOUR
1160
+ / KW_UNIT_MINUTE
1161
+ / KW_UNIT_SECOND
1162
+
1163
+ whitespace =
1164
+ [ \t\n\r]
1165
+
1166
+ EOL
1167
+ = EOF
1168
+ / [\n\r]+
1169
+
1170
+ EOF = !.
1171
+
1172
+ //begin procedure extension
1173
+ proc_stmts
1174
+ = proc_stmt*
1175
+
1176
+ proc_stmt
1177
+ = &{ varList = []; return true; } __ s:(assign_stmt / return_stmt) {
1178
+ return { stmt: s, vars: varList };
1179
+ }
1180
+
1181
+ assign_stmt
1182
+ = va:var_decl __ KW_ASSIGN __ e:proc_expr {
1183
+ return {
1184
+ type: 'assign',
1185
+ left: va,
1186
+ right: e
1187
+ };
1188
+ }
1189
+
1190
+ return_stmt
1191
+ = KW_RETURN __ e:proc_expr {
1192
+ return { type: 'return', expr: e };
1193
+ }
1194
+
1195
+ proc_expr
1196
+ = select_stmt
1197
+ / proc_join
1198
+ / proc_additive_expr
1199
+ / proc_array
1200
+
1201
+ proc_additive_expr
1202
+ = head:proc_multiplicative_expr
1203
+ tail:(__ additive_operator __ proc_multiplicative_expr)* {
1204
+ return createBinaryExprChain(head, tail);
1205
+ }
1206
+
1207
+ proc_multiplicative_expr
1208
+ = head:proc_primary
1209
+ tail:(__ multiplicative_operator __ proc_primary)* {
1210
+ return createBinaryExprChain(head, tail);
1211
+ }
1212
+
1213
+ proc_join
1214
+ = lt:var_decl __ op:join_op __ rt:var_decl __ expr:on_clause {
1215
+ return {
1216
+ type: 'join',
1217
+ ltable: lt,
1218
+ rtable: rt,
1219
+ op: op,
1220
+ on: expr
1221
+ };
1222
+ }
1223
+
1224
+ proc_primary
1225
+ = literal
1226
+ / var_decl
1227
+ / proc_func_call
1228
+ / param
1229
+ / LPAREN __ e:proc_additive_expr __ RPAREN {
1230
+ e.parentheses = true;
1231
+ return e;
1232
+ }
1233
+
1234
+ proc_func_call
1235
+ = name:ident __ LPAREN __ l:proc_primary_list __ RPAREN {
1236
+ //compatible with original func_call
1237
+ return {
1238
+ type: 'function',
1239
+ name: name,
1240
+ args: {
1241
+ type: 'expr_list',
1242
+ value: l
1243
+ }
1244
+ };
1245
+ }
1246
+
1247
+ proc_primary_list
1248
+ = head:proc_primary tail:(__ COMMA __ proc_primary)* {
1249
+ return createList(head, tail);
1250
+ }
1251
+
1252
+ proc_array =
1253
+ LBRAKE __ l:proc_primary_list __ RBRAKE {
1254
+ return { type: 'array', value: l };
1255
+ }
1256
+
1257
+ var_decl
1258
+ = KW_VAR_PRE name:ident_name m:mem_chain {
1259
+ //push for analysis
1260
+ varList.push(name);
1261
+ return {
1262
+ type: 'var',
1263
+ name: name,
1264
+ members: m
1265
+ };
1266
+ }
1267
+
1268
+ mem_chain
1269
+ = l:('.' ident_name)* {
1270
+ const s = [];
1271
+ for (let i = 0; i < l.length; i++) {
1272
+ s.push(l[i][1]);
1273
+ }
1274
+ return s;
1275
+ }
1276
+
1277
+ data_type
1278
+ = character_string_type
1279
+ / numeric_type
1280
+ / datetime_type
1281
+ / json_type
1282
+
1283
+ character_string_type
1284
+ = t:(KW_CHAR / KW_VARCHAR) __ LPAREN __ l:[0-9]+ __ RPAREN __ {
1285
+ return { dataType: t, length: parseInt(l.join(''), 10) };
1286
+ }
1287
+ / t:KW_CHAR { return { dataType: t }; }
1288
+ / t:KW_VARCHAR { return { dataType: t }; }
1289
+
1290
+ numeric_type
1291
+ = t:(KW_NUMERIC / KW_DECIMAL / KW_INT / KW_INTEGER / KW_SMALLINT) { return { dataType: t }; }
1292
+
1293
+ datetime_type
1294
+ = t:(KW_DATE / KW_TIME / KW_TIMESTAMP) { return { dataType: t }; }
1295
+
1296
+ json_type
1297
+ = t:KW_JSON { return { dataType: t }; }