forked from rqlite/sql
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtoken.go
More file actions
617 lines (593 loc) · 12.2 KB
/
token.go
File metadata and controls
617 lines (593 loc) · 12.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
package sql
import (
"strconv"
)
var bareTokensMap = make(map[Token]struct{})
func init() {
for _, tok := range bareTokens {
bareTokensMap[tok] = struct{}{}
}
}
// Token is the set of lexical tokens of the Go programming language.
type Token int
// The list of tokens.
const (
// Special tokens
ILLEGAL Token = iota
EOF
COMMENT
SPACE
// literals
IDENT // IDENT
QIDENT // "IDENT"
STRING // 'string'
BLOB // ???
FLOAT // 123.45
INTEGER // 123
NULL // NULL
TRUE // true
FALSE // false
BIND //? or ?NNN or :VVV or @VVV or $VVV
// operators and delimiters
SEMI // ;
LP // (
RP // )
COMMA // ,
NE // !=
EQ // =
LE // <=
LT // <
GT // >
GE // >=
BITAND // &
BITOR // |
BITNOT // ~
LSHIFT // <<
RSHIFT // >>
PLUS // +
MINUS // -
STAR // *
SLASH // /
REM // %
CONCAT // ||
DOT // .
JSON_EXTRACT_JSON // ->
JSON_EXTRACT_SQL // ->>
// keywords
ABORT
ACTION
ADD
AFTER
ALL
ALTER
ALWAYS
ANALYZE
AND
AS
ASC
ATTACH
AUTOINCREMENT
BEFORE
BEGIN
BETWEEN
BY
CASCADE
CASE
CAST
CHECK
COLLATE
COLUMN
COMMIT
CONFLICT
CONSTRAINT
CREATE
CROSS
CURRENT
CURRENT_DATE
CURRENT_TIME
CURRENT_TIMESTAMP
DATABASE
DEFAULT
DEFERRABLE
DEFERRED
DELETE
DESC
DETACH
DISTINCT
DO
DROP
EACH
ELSE
END
ESCAPE
EXCEPT
EXCLUDE
EXCLUSIVE
EXISTS
EXPLAIN
FAIL
FILTER
FIRST
FOLLOWING
FOR
FOREIGN
FROM
FULL
GENERATED
GLOB
GROUP
GROUPS
HAVING
IF
IGNORE
IMMEDIATE
IN
INDEX
INDEXED
INITIALLY
INNER
INSERT
INSTEAD
INTERSECT
INTO
IS
ISNULL
JOIN
KEY
LAST
LEFT
LIKE
LIMIT
MATCH
MATERIALIZED
NATURAL
NO
NOT
NOTHING
NOTNULL
NULLS
OF
OFFSET
ON
OR
ORDER
OTHERS
OUTER
OVER
PARTITION
PLAN
PRAGMA
PRECEDING
PRIMARY
QUERY
RAISE
RANGE
RECURSIVE
REFERENCES
REGEXP
REINDEX
RELEASE
RENAME
REPLACE
RESTRICT
RETURNING
RIGHT
ROLLBACK
ROW
ROWS
SAVEPOINT
SELECT
SET
TABLE
TEMP
TEMPORARY
THEN
TIES
TO
TRANSACTION
TRIGGER
UNBOUNDED
UNION
UNIQUE
UPDATE
USING
VACUUM
VALUES
VIEW
VIRTUAL
WHEN
WHERE
WINDOW
WITH
WITHOUT
// sepcial keywords not in https://sqlite.org/lang_keywords.html
STRICT
ROWID
STORED
)
var tokens = [...]string{
// Special tokens
ILLEGAL: "ILLEGAL",
EOF: "EOF",
COMMENT: "COMMENT",
SPACE: "SPACE",
// literals
IDENT: "IDENT", // IDENT
QIDENT: "QIDENT", // "IDENT"
STRING: "STRING", // 'string'
BLOB: "BLOB", // ???
FLOAT: "FLOAT", // 123.45
INTEGER: "INTEGER", // 123
NULL: "NULL", // NULL
TRUE: "TRUE", // true
FALSE: "FALSE", // false
BIND: "BIND", //? or ?NNN or :VVV or @VVV or $VVV
// operators and delimiters
SEMI: ";", // ;
LP: "(", // (
RP: ")", // )
COMMA: ",", // ,
NE: "!=", // !=
EQ: "=", // =
LE: "<=", // <=
LT: "<", // <
GT: ">", // >
GE: ">=", // >=
BITAND: "&", // &
BITOR: "|", // |
BITNOT: "~", // ~
LSHIFT: "<<", // <<
RSHIFT: ">>", // >>
PLUS: "+", // +
MINUS: "-", // -
STAR: "*", // *
SLASH: "/", // /
REM: "%", // %
CONCAT: "||", // ||
DOT: ".", // .
JSON_EXTRACT_JSON: "->", // ->
JSON_EXTRACT_SQL: "->>", // ->>
// keywords
ABORT: "ABORT",
ACTION: "ACTION",
ADD: "ADD",
AFTER: "AFTER",
ALL: "ALL",
ALTER: "ALTER",
ALWAYS: "ALWAYS",
ANALYZE: "ANALYZE",
AND: "AND",
AS: "AS",
ASC: "ASC",
ATTACH: "ATTACH",
AUTOINCREMENT: "AUTOINCREMENT",
BEFORE: "BEFORE",
BEGIN: "BEGIN",
BETWEEN: "BETWEEN",
BY: "BY",
CASCADE: "CASCADE",
CASE: "CASE",
CAST: "CAST",
CHECK: "CHECK",
COLLATE: "COLLATE",
COLUMN: "COLUMN",
COMMIT: "COMMIT",
CONFLICT: "CONFLICT",
CONSTRAINT: "CONSTRAINT",
CREATE: "CREATE",
CROSS: "CROSS",
CURRENT: "CURRENT",
CURRENT_DATE: "CURRENT_DATE",
CURRENT_TIME: "CURRENT_TIME",
CURRENT_TIMESTAMP: "CURRENT_TIMESTAMP",
DATABASE: "DATABASE",
DEFAULT: "DEFAULT",
DEFERRABLE: "DEFERRABLE",
DEFERRED: "DEFERRED",
DELETE: "DELETE",
DESC: "DESC",
DETACH: "DETACH",
DISTINCT: "DISTINCT",
DO: "DO",
DROP: "DROP",
EACH: "EACH",
ELSE: "ELSE",
END: "END",
ESCAPE: "ESCAPE",
EXCEPT: "EXCEPT",
EXCLUDE: "EXCLUDE",
EXCLUSIVE: "EXCLUSIVE",
EXISTS: "EXISTS",
EXPLAIN: "EXPLAIN",
FAIL: "FAIL",
FILTER: "FILTER",
FIRST: "FIRST",
FOLLOWING: "FOLLOWING",
FOR: "FOR",
FOREIGN: "FOREIGN",
FROM: "FROM",
FULL: "FULL",
GENERATED: "GENERATED",
GLOB: "GLOB",
GROUP: "GROUP",
GROUPS: "GROUPS",
HAVING: "HAVING",
IF: "IF",
IGNORE: "IGNORE",
IMMEDIATE: "IMMEDIATE",
IN: "IN",
INDEX: "INDEX",
INDEXED: "INDEXED",
INITIALLY: "INITIALLY",
INNER: "INNER",
INSERT: "INSERT",
INSTEAD: "INSTEAD",
INTERSECT: "INTERSECT",
INTO: "INTO",
IS: "IS",
ISNULL: "ISNULL",
JOIN: "JOIN",
KEY: "KEY",
LAST: "LAST",
LEFT: "LEFT",
LIKE: "LIKE",
LIMIT: "LIMIT",
MATCH: "MATCH",
MATERIALIZED: "MATERIALIZED",
NATURAL: "NATURAL",
NO: "NO",
NOT: "NOT",
NOTHING: "NOTHING",
NOTNULL: "NOTNULL",
NULLS: "NULLS",
OF: "OF",
OFFSET: "OFFSET",
ON: "ON",
OR: "OR",
ORDER: "ORDER",
OTHERS: "OTHERS",
OUTER: "OUTER",
OVER: "OVER",
PARTITION: "PARTITION",
PLAN: "PLAN",
PRAGMA: "PRAGMA",
PRECEDING: "PRECEDING",
PRIMARY: "PRIMARY",
QUERY: "QUERY",
RAISE: "RAISE",
RANGE: "RANGE",
RECURSIVE: "RECURSIVE",
REFERENCES: "REFERENCES",
REGEXP: "REGEXP",
REINDEX: "REINDEX",
RELEASE: "RELEASE",
RENAME: "RENAME",
REPLACE: "REPLACE",
RESTRICT: "RESTRICT",
RETURNING: "RETURNING",
RIGHT: "RIGHT",
ROLLBACK: "ROLLBACK",
ROW: "ROW",
ROWS: "ROWS",
SAVEPOINT: "SAVEPOINT",
SELECT: "SELECT",
SET: "SET",
TABLE: "TABLE",
TEMP: "TEMP",
TEMPORARY: "TEMPORARY",
THEN: "THEN",
TIES: "TIES",
TO: "TO",
TRANSACTION: "TRANSACTION",
TRIGGER: "TRIGGER",
UNBOUNDED: "UNBOUNDED",
UNION: "UNION",
UNIQUE: "UNIQUE",
UPDATE: "UPDATE",
USING: "USING",
VACUUM: "VACUUM",
VALUES: "VALUES",
VIEW: "VIEW",
VIRTUAL: "VIRTUAL",
WHEN: "WHEN",
WHERE: "WHERE",
WINDOW: "WINDOW",
WITH: "WITH",
WITHOUT: "WITHOUT",
// sepcial keywords not in https://sqlite.org/lang_keywords.html
STRICT: "STRICT",
ROWID: "ROWID",
STORED: "STORED",
}
// A list of keywords that can be used as unquoted identifiers.
var bareTokens = [...]Token{
ABORT, ACTION, AFTER, ALWAYS, ANALYZE, ASC, ATTACH, BEFORE, BEGIN, BY,
CASCADE, CAST, COLUMN, CONFLICT, CROSS, CURRENT, CURRENT_DATE,
CURRENT_TIME, CURRENT_TIMESTAMP, DATABASE, DEFERRED, DESC, DETACH, DO,
EACH, END, EXCLUDE, EXCLUSIVE, EXPLAIN, FAIL, FILTER, FIRST, FOLLOWING,
FOR, GENERATED, GLOB, GROUPS, IF, IGNORE, IMMEDIATE, INDEXED, INITIALLY,
INNER, INSTEAD, KEY, LAST, LEFT, LIKE, MATCH, NATURAL, NO, NULLS, OF,
OFFSET, OTHERS, OUTER, OVER, PARTITION, PLAN, PRAGMA, PRECEDING, QUERY,
RAISE, RANGE, RECURSIVE, REGEXP, REINDEX, RELEASE, RENAME, REPLACE,
RESTRICT, ROLLBACK, ROW, ROWS, SAVEPOINT, TEMP, TEMPORARY, TIES, TRIGGER,
UNBOUNDED, VACUUM, VIEW, VIRTUAL, WINDOW, WITH, WITHOUT, STRICT, ROWID, STORED,
}
func (tok Token) String() string {
s := ""
if 0 <= tok && tok < Token(len(tokens)) {
s = tokens[tok]
}
if s == "" {
s = "token(" + strconv.Itoa(int(tok)) + ")"
}
return s
}
// isBareToken returns true if keyword token can be used as an identifier.
func isBareToken(tok Token) bool {
_, ok := bareTokensMap[tok]
return ok
}
func isIdentToken(tok Token) bool {
return tok == IDENT || tok == QIDENT || tok == STRING || isBareToken(tok)
}
// isExprIdentToken returns true if tok can be used as an identifier in an expression.
// It includes IDENT, QIDENT, and certain keywords.
func isExprIdentToken(tok Token) bool {
switch tok {
// List keywords that can be used as identifiers in expressions for pragma
case ON, FULL, DELETE:
return true
// Add any other non-reserved keywords here
default:
return isIdentToken(tok)
}
}
func assert(condition bool) {
if !condition {
panic("assert failed")
}
}
type OpType int
const (
OP_ILLEGAL OpType = iota
OP_OR
OP_AND
OP_NOT
OP_ISNULL
OP_NOTNULL
OP_IN
OP_NOT_IN
OP_MATCH
OP_NOT_MATCH
OP_LIKE
OP_NOT_LIKE
OP_REGEXP
OP_NOT_REGEXP
OP_GLOB
OP_NOT_GLOB
OP_BETWEEN
OP_NOT_BETWEEN
OP_IS_DISTINCT_FROM
OP_IS_NOT_DISTINCT_FROM
OP_EQ
OP_NE
OP_IS
OP_IS_NOT
OP_LT
OP_LE
OP_GT
OP_GE
OP_ESCAPE
OP_BITAND
OP_BITOR
OP_LSHIFT
OP_RSHIFT
OP_PLUS
OP_MINUS
OP_MULTIPLY
OP_DIVIDE
OP_MODULO
OP_CONCAT
OP_JSON_EXTRACT_JSON
OP_JSON_EXTRACT_SQL
OP_COLLATE
OP_BITNOT
)
func (op OpType) Precedence() int {
switch {
case op < OP_OR || op > OP_BITNOT:
return 0
case op == OP_OR:
return 1
case op == OP_AND:
return 2
case op <= OP_IS_NOT:
return 3
case op <= OP_GE:
return 4
case op <= OP_ESCAPE:
return 5
case op <= OP_RSHIFT:
return 6
case op <= OP_MINUS:
return 7
case op <= OP_MODULO:
return 8
case op <= OP_JSON_EXTRACT_SQL:
return 9
case op <= OP_COLLATE:
return 10
default:
return 11
}
}
func precedenceByStartBinaryOp(tok Token) int {
switch tok {
case PLUS:
return OP_PLUS.Precedence()
case MINUS:
return OP_MINUS.Precedence()
case STAR:
return OP_MULTIPLY.Precedence()
case SLASH:
return OP_DIVIDE.Precedence()
case REM:
return OP_MODULO.Precedence()
case CONCAT:
return OP_CONCAT.Precedence()
case BETWEEN:
return OP_BETWEEN.Precedence()
case LSHIFT:
return OP_LSHIFT.Precedence()
case RSHIFT:
return OP_RSHIFT.Precedence()
case BITAND:
return OP_BITAND.Precedence()
case BITOR:
return OP_BITOR.Precedence()
case LT:
return OP_LT.Precedence()
case LE:
return OP_LE.Precedence()
case GT:
return OP_GT.Precedence()
case GE:
return OP_GE.Precedence()
case EQ:
return OP_EQ.Precedence()
case NE:
return OP_NE.Precedence()
case JSON_EXTRACT_JSON:
return OP_JSON_EXTRACT_JSON.Precedence()
case JSON_EXTRACT_SQL:
return OP_JSON_EXTRACT_SQL.Precedence()
case IN:
return OP_IN.Precedence()
case LIKE:
return OP_LIKE.Precedence()
case GLOB:
return OP_GLOB.Precedence()
case MATCH:
return OP_MATCH.Precedence()
case REGEXP:
return OP_REGEXP.Precedence()
case AND:
return OP_AND.Precedence()
case OR:
return OP_OR.Precedence()
case ISNULL:
return OP_ISNULL.Precedence()
case NOTNULL:
return OP_NOTNULL.Precedence()
case ESCAPE:
return OP_ESCAPE.Precedence()
case COLLATE:
return OP_COLLATE.Precedence()
case IS:
return OP_IS.Precedence()
case NOT:
return OP_NOTNULL.Precedence()
default:
return 0
}
}