Commit 98ef75d
sqlite: replace the ANTLR parser with meyer (#4535)
* sqlite: replace the ANTLR parser with meyer
meyer is a hand-written recursive descent parser for SQLite's dialect,
ported from src/parse.y and src/tokenize.c and checked against SQLite
itself. Moving to it deletes 1.2 MB of generated ANTLR code and the
antlr4-go dependency, and replaces a grammar that only approximated
SQLite with one that accepts what SQLite accepts.
parse.go calls meyer and slices statement extents out of the node spans;
convert.go maps meyer's tree onto sqlc's AST; reserved.go now defers to
meyer's keyword table, which the hand-maintained list was missing
MATERIALIZED and RETURNING from.
SQLite has no schema-qualified function call, so sqlc.arg() and its
siblings are not SQL meyer will parse. The parser folds "sqlc.name(" to
"sqlc_name(" over the token stream -- one byte for another, so every
offset still points into the original source, and string literals and
comments are untouched -- and the converter puts the schema back.
Behavior the old grammar got wrong and this corrects:
- "col TEXT NULL" was read as a column of type "TEXTNULL", so the column
generated as interface{} rather than a nullable string. This changes
one golden file.
- GROUP BY was dropped whenever the query also had a WHERE clause, from
an off-by-one over the ANTLR expression list. Now that GROUP BY reaches
the compiler, its column references are validated, which SQLite's
implicit rowid would have failed; the compiler now recognizes rowid,
_rowid_ and oid for SQLite.
- Comparison operators other than "=" were all recorded as "=", and IS,
ISNULL, NOTNULL and LIKE reached the AST as "=" too. They now carry
their own spelling, and lang.IsComparisonOperator learned the
keyword-spelled comparisons so they still type as bool.
- ORDER BY, DISTINCT, WITH RECURSIVE, ON CONFLICT, OVER and FILTER were
parsed and then discarded, so ast.Format dropped them from the SQL it
rebuilds. All are carried through now.
- Quoted identifiers other than "..." kept their quotes; float literals
became the integer 0.
One capability is lost: the pinned SQLite build meyer targets defines
neither SQLITE_ENABLE_UPDATE_DELETE_LIMIT nor SQLITE_UDL_CAPABLE_PARSER,
so UPDATE and DELETE no longer accept ORDER BY or LIMIT. No test covered
it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RkrYmzwTktB2CA5Bvqg6z5
* sqlite: drop parse_test.go
The end-to-end tests are the acceptance gate for the parser.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RkrYmzwTktB2CA5Bvqg6z5
* sqlite: drop catalog_test.go
The end-to-end tests cover the catalog the schema builds. Removing the
test leaves newTestCatalog with no callers, so it goes too.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RkrYmzwTktB2CA5Bvqg6z5
* sqlite: drop the analyzer test
The end-to-end tests exercise the analyzer against a real database.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RkrYmzwTktB2CA5Bvqg6z5
* sqlite: drop the sqlc.arg fold, now that preprocessing handles it
#4537 rewrites sqlc's syntax to native placeholders above the engines, and
SQLite is one of the preprocessed dialects, so sqlc.arg() and @name never
reach the parser. The fold this branch carried is dead.
One gap follows from the pass's rule that a statement whose sqlc syntax
did not validate is copied through for the engine to parse: that assumes
the engine can parse it. SQLite cannot, so an invalid sqlc.arg() surfaced
as `near "(": syntax error` and the preprocessor's own diagnostics were
never reported -- from parseCatalog, since a schema file and a query file
are often the same file. On a parse failure the compiler now reports the
sqlc syntax errors recorded for that file, if any, in place of the failure
they produced.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RkrYmzwTktB2CA5Bvqg6z5
* sqlite: update to meyer v0.1.1, restoring UPDATE/DELETE LIMIT
v0.1.1 adds parser.Options, whose UpdateDeleteLimit field compiles in the
grammar SQLITE_ENABLE_UPDATE_DELETE_LIMIT does. The option selects between
two forms of SQLite's own rules, so meyer cannot tell which one a caller
wants from the SQL alone; sqlc has always accepted ORDER BY and LIMIT on
UPDATE and DELETE, so it asks for them.
UpdateStmt and DeleteStmt grow OrderBy and Limit fields to match. sqlc's
AST has somewhere to put the LIMIT and nowhere to put the ORDER BY, which
is what the ANTLR converter did with them too.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RkrYmzwTktB2CA5Bvqg6z5
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 5ce31fc commit 98ef75d
25 files changed
Lines changed: 1087 additions & 40444 deletions
File tree
- internal
- compiler
- endtoend/testdata/case_named_params/sqlite/go
- engine/sqlite
- analyzer
- parser
- sql/lang
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | | - | |
9 | 8 | | |
10 | 9 | | |
11 | 10 | | |
| |||
22 | 21 | | |
23 | 22 | | |
24 | 23 | | |
| 24 | + | |
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
| |||
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
| 39 | + | |
39 | 40 | | |
40 | 41 | | |
41 | 42 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
83 | 83 | | |
84 | 84 | | |
85 | 85 | | |
| 86 | + | |
| 87 | + | |
86 | 88 | | |
87 | 89 | | |
88 | 90 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
48 | 48 | | |
49 | 49 | | |
50 | 50 | | |
51 | | - | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
52 | 57 | | |
53 | 58 | | |
54 | 59 | | |
| |||
111 | 116 | | |
112 | 117 | | |
113 | 118 | | |
114 | | - | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
115 | 122 | | |
116 | 123 | | |
117 | 124 | | |
| |||
162 | 169 | | |
163 | 170 | | |
164 | 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 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
| |||
69 | 70 | | |
70 | 71 | | |
71 | 72 | | |
72 | | - | |
| 73 | + | |
73 | 74 | | |
74 | 75 | | |
75 | 76 | | |
| |||
85 | 86 | | |
86 | 87 | | |
87 | 88 | | |
88 | | - | |
| 89 | + | |
89 | 90 | | |
90 | 91 | | |
91 | 92 | | |
| |||
101 | 102 | | |
102 | 103 | | |
103 | 104 | | |
104 | | - | |
| 105 | + | |
105 | 106 | | |
106 | 107 | | |
107 | 108 | | |
| |||
713 | 714 | | |
714 | 715 | | |
715 | 716 | | |
716 | | - | |
| 717 | + | |
717 | 718 | | |
718 | 719 | | |
719 | 720 | | |
720 | 721 | | |
| 722 | + | |
| 723 | + | |
| 724 | + | |
721 | 725 | | |
722 | 726 | | |
723 | 727 | | |
| 728 | + | |
| 729 | + | |
| 730 | + | |
| 731 | + | |
| 732 | + | |
| 733 | + | |
| 734 | + | |
| 735 | + | |
| 736 | + | |
| 737 | + | |
| 738 | + | |
| 739 | + | |
| 740 | + | |
| 741 | + | |
| 742 | + | |
| 743 | + | |
| 744 | + | |
| 745 | + | |
| 746 | + | |
724 | 747 | | |
725 | 748 | | |
726 | 749 | | |
| |||
Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
This file was deleted.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
15 | | - | |
16 | | - | |
17 | | - | |
18 | | - | |
0 commit comments