Skip to content

Commit a550fbc

Browse files
committed
Merge branch 'sqlite-keywords'
Refs #92
2 parents c33d234 + fa8120c commit a550fbc

5 files changed

Lines changed: 176 additions & 168 deletions

File tree

src/keywords/sqlite.keywords.ts

Lines changed: 164 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -2,158 +2,170 @@
22
// https://www.sqlite.org/lang_keywords.html
33
//
44
// However, not all of them are fully reserved.
5-
// I've marked the ones that by my testing are reserved with (R).
6-
// This might or might not be fully accurate.
75
//
8-
// Some keywords are never reserved. I've removed these from the list:
9-
// - KEY
10-
// Some are reserved only in certain contexts. I've removed these from the list:
11-
// - COLUMN
6+
// The following map lists the contexts in which the keywords are reserved.
7+
// If the array is empty, then the keyword is reserved in all contexts.
128
//
13-
export const sqliteKeywords: Record<string, boolean> = {
14-
ABORT: true,
15-
ACTION: true,
16-
ADD: true, // (R)
17-
AFTER: true,
18-
ALL: true, // (R)
19-
ALTER: true, // (R)
20-
ALWAYS: true,
21-
ANALYZE: true,
22-
AND: true, // (R)
23-
AS: true, // (R)
24-
ASC: true,
25-
ATTACH: true,
26-
AUTOINCREMENT: true, // (R)
27-
BEFORE: true,
28-
BEGIN: true,
29-
BETWEEN: true,
30-
BY: true,
31-
CASCADE: true,
32-
CASE: true,
33-
CAST: true,
34-
CHECK: true,
35-
COLLATE: true,
36-
COMMIT: true,
37-
CONFLICT: true,
38-
CONSTRAINT: true,
39-
CREATE: true,
40-
CROSS: true,
41-
CURRENT: true,
42-
CURRENT_DATE: true,
43-
CURRENT_TIME: true,
44-
CURRENT_TIMESTAMP: true,
45-
DATABASE: true,
46-
DEFAULT: true,
47-
DEFERRABLE: true,
48-
DEFERRED: true,
49-
DELETE: true,
50-
DESC: true,
51-
DETACH: true,
52-
DISTINCT: true, // (R)
53-
DO: true,
54-
DROP: true, // (R)
55-
EACH: true,
56-
ELSE: true, // (R)
57-
END: true,
58-
ESCAPE: true, // (R)
59-
EXCEPT: true, // (R)
60-
EXCLUDE: true,
61-
EXCLUSIVE: true,
62-
EXISTS: true, // (R)
63-
EXPLAIN: true,
64-
FAIL: true,
65-
FILTER: true,
66-
FIRST: true,
67-
FOLLOWING: true,
68-
FOR: true,
69-
FOREIGN: true, // (R)
70-
FROM: true, // (R)
71-
FULL: true,
72-
GENERATED: true,
73-
GLOB: true,
74-
GROUP: true, // (R)
75-
GROUPS: true,
76-
HAVING: true, // (R)
77-
IF: true, // (R)
78-
IGNORE: true,
79-
IMMEDIATE: true,
80-
IN: true, // (R)
81-
INDEX: true, // (R)
82-
INDEXED: true,
83-
INITIALLY: true,
84-
INNER: true,
85-
INSERT: true, // (R)
86-
INSTEAD: true,
87-
INTERSECT: true, // (R)
88-
INTO: true, // (R)
89-
IS: true, // (R)
90-
ISNULL: true, // (R)
91-
JOIN: true, // (R)
92-
LAST: true,
93-
LEFT: true,
94-
LIKE: true,
95-
LIMIT: true, // (R)
96-
MATCH: true,
97-
MATERIALIZED: true,
98-
NATURAL: true,
99-
NO: true,
100-
NOT: true, // (R)
101-
NOTHING: true, // (R)
102-
NOTNULL: true, // (R)
103-
NULL: true, // (R)
104-
NULLS: true,
105-
OF: true,
106-
OFFSET: true,
107-
ON: true, // (R)
108-
OR: true, // (R)
109-
ORDER: true, // (R)
110-
OTHERS: true,
111-
OUTER: true,
112-
OVER: true,
113-
PARTITION: true,
114-
PLAN: true,
115-
PRAGMA: true,
116-
PRECEDING: true,
117-
PRIMARY: true, // (R)
118-
QUERY: true,
119-
RAISE: true,
120-
RANGE: true,
121-
RECURSIVE: true,
122-
REFERENCES: true, // (R)
123-
REGEXP: true,
124-
REINDEX: true,
125-
RELEASE: true,
126-
RENAME: true,
127-
REPLACE: true,
128-
RESTRICT: true,
129-
RETURNING: true, // (R)
130-
RIGHT: true,
131-
ROLLBACK: true,
132-
ROW: true,
133-
ROWS: true,
134-
SAVEPOINT: true,
135-
SELECT: true, // (R)
136-
SET: true, // (R)
137-
TABLE: true, // (R)
138-
TEMP: true,
139-
TEMPORARY: true,
140-
THEN: true, // (R)
141-
TIES: true,
142-
TO: true, // (R)
143-
TRANSACTION: true, // (R)
144-
TRIGGER: true,
145-
UNBOUNDED: true,
146-
UNION: true, // (R)
147-
UNIQUE: true, // (R)
148-
UPDATE: true, // (R)
149-
USING: true, // (R)
150-
VACUUM: true,
151-
VALUES: true, // (R)
152-
VIEW: true,
153-
VIRTUAL: true,
154-
WHEN: true, // (R)
155-
WHERE: true, // (R)
156-
WINDOW: true,
157-
WITH: true,
158-
WITHOUT: true,
9+
// The contexts are:
10+
// - "create-table": cannot be used in: CREATE TABLE <kw> (id INT)
11+
// - "col-alias": cannot be used as an alias in: SELECT 1 <kw>
12+
// - "col-as-alias": cannot be used as an alias in: SELECT 1 AS <kw>
13+
// - "tbl-alias": cannot be used as an alias in: SELECT col FROM tbl [AS] <kw>
14+
// - "col-name": cannot be used as a column name in: SELECT <kw> FROM tbl
15+
// - "parser-issue": for now we have problems with parsing when this keywords is not reserved.
16+
//
17+
export const keywordDefs: Record<string, string[]> = {
18+
ABORT: [],
19+
ACTION: [],
20+
ADD: ["create-table", "col-alias", "tbl-alias", "col-name"],
21+
AFTER: [],
22+
ALL: ["create-table", "col-alias", "tbl-alias", "col-name"],
23+
ALTER: ["create-table", "col-alias", "tbl-alias", "col-name"],
24+
ALWAYS: [],
25+
ANALYZE: [],
26+
AND: ["create-table", "col-alias", "tbl-alias", "col-name"],
27+
AS: ["create-table", "col-alias", "tbl-alias", "col-name"],
28+
ASC: [],
29+
ATTACH: [],
30+
AUTOINCREMENT: ["create-table", "col-alias", "tbl-alias", "col-name"],
31+
BEFORE: [],
32+
BEGIN: [],
33+
BETWEEN: ["col-alias", "tbl-alias", "col-name"],
34+
BY: [],
35+
CASCADE: [],
36+
CASE: ["col-alias", "tbl-alias", "col-name"],
37+
CAST: ["col-name"],
38+
CHECK: ["col-alias", "tbl-alias", "col-name"],
39+
COLLATE: ["col-alias", "tbl-alias", "col-name"],
40+
COLUMN: [],
41+
COMMIT: ["col-alias", "tbl-alias", "col-name"],
42+
CONFLICT: [],
43+
CONSTRAINT: ["col-alias", "tbl-alias", "col-name"],
44+
CREATE: ["col-alias", "tbl-alias", "col-name"],
45+
CROSS: ["col-alias"],
46+
CURRENT: [],
47+
CURRENT_DATE: [],
48+
CURRENT_TIME: [],
49+
CURRENT_TIMESTAMP: [],
50+
DATABASE: [],
51+
DEFAULT: ["col-alias", "tbl-alias", "col-name"],
52+
DEFERRABLE: ["col-alias", "tbl-alias", "col-name"],
53+
DEFERRED: [],
54+
DELETE: ["col-alias", "tbl-alias", "col-name"],
55+
DESC: [],
56+
DETACH: [],
57+
DISTINCT: ["create-table", "col-alias", "tbl-alias", "col-name"],
58+
DO: [],
59+
DROP: ["create-table", "col-alias", "tbl-alias", "col-name"],
60+
EACH: [],
61+
ELSE: ["create-table", "col-alias", "tbl-alias", "col-name"],
62+
END: [],
63+
ESCAPE: ["create-table", "col-alias", "tbl-alias", "col-name"],
64+
EXCEPT: ["create-table", "col-alias", "tbl-alias", "col-name"],
65+
EXCLUDE: [],
66+
EXCLUSIVE: [],
67+
EXISTS: ["create-table", "col-alias", "tbl-alias", "col-name"],
68+
EXPLAIN: [],
69+
FAIL: [],
70+
FILTER: [],
71+
FIRST: [],
72+
FOLLOWING: [],
73+
FOR: [],
74+
FOREIGN: ["create-table", "col-alias", "tbl-alias", "col-name"],
75+
FROM: ["create-table", "col-alias", "tbl-alias", "col-name"],
76+
FULL: ["col-alias"],
77+
GENERATED: [],
78+
GLOB: ["col-alias"],
79+
GROUP: ["create-table", "col-alias", "tbl-alias", "col-name"],
80+
GROUPS: ["parser-issue"], // Should be allowed as alias name, but currently causes parsing issues.
81+
HAVING: ["create-table", "col-alias", "tbl-alias", "col-name"],
82+
IF: ["create-table"],
83+
IGNORE: [],
84+
IMMEDIATE: [],
85+
IN: ["create-table", "col-alias", "tbl-alias", "col-name"],
86+
INDEX: ["create-table", "col-alias", "tbl-alias", "col-name"],
87+
INDEXED: ["col-alias"],
88+
INITIALLY: [],
89+
INNER: ["col-alias"],
90+
INSERT: ["create-table", "col-alias", "tbl-alias", "col-name"],
91+
INSTEAD: [],
92+
INTERSECT: ["create-table", "col-alias", "tbl-alias", "col-name"],
93+
INTO: ["create-table", "col-alias", "tbl-alias", "col-name"],
94+
IS: ["create-table", "col-alias", "tbl-alias", "col-name"],
95+
ISNULL: ["create-table", "tbl-alias", "col-as-alias", "col-name"],
96+
JOIN: ["create-table", "col-alias", "tbl-alias", "col-name"],
97+
KEY: [],
98+
LAST: [],
99+
LEFT: ["col-alias"],
100+
LIKE: ["col-alias"],
101+
LIMIT: ["create-table", "col-alias", "tbl-alias", "col-name"],
102+
MATCH: ["col-alias"],
103+
MATERIALIZED: [],
104+
NATURAL: ["col-alias"],
105+
NO: [],
106+
NOT: ["create-table", "col-alias", "tbl-alias", "col-name"],
107+
NOTHING: ["create-table", "col-alias", "tbl-alias", "col-name"],
108+
NOTNULL: ["create-table", "tbl-alias", "col-as-alias", "col-name"],
109+
NULL: ["create-table", "col-alias", "tbl-alias"],
110+
NULLS: [],
111+
OF: [],
112+
OFFSET: [],
113+
ON: ["create-table", "col-alias", "tbl-alias", "col-name"],
114+
OR: ["create-table", "col-alias", "tbl-alias", "col-name"],
115+
ORDER: ["create-table", "col-alias", "tbl-alias", "col-name"],
116+
OTHERS: [],
117+
OUTER: ["col-alias"],
118+
OVER: [],
119+
PARTITION: [],
120+
PLAN: [],
121+
PRAGMA: [],
122+
PRECEDING: [],
123+
PRIMARY: ["create-table", "col-alias", "tbl-alias", "col-name"],
124+
QUERY: [],
125+
RAISE: ["col-name"],
126+
RANGE: [],
127+
RECURSIVE: [],
128+
REFERENCES: ["create-table", "col-alias", "tbl-alias", "col-name"],
129+
REGEXP: ["col-alias"],
130+
REINDEX: [],
131+
RELEASE: [],
132+
RENAME: [],
133+
REPLACE: [],
134+
RESTRICT: [],
135+
RETURNING: ["create-table", "col-alias", "tbl-alias", "col-name"],
136+
RIGHT: ["col-alias"],
137+
ROLLBACK: [],
138+
ROW: [],
139+
ROWS: [],
140+
SAVEPOINT: [],
141+
SELECT: ["create-table", "col-alias", "tbl-alias", "col-name"],
142+
SET: ["create-table", "col-alias", "tbl-alias", "col-name"],
143+
TABLE: ["create-table", "col-alias", "tbl-alias", "col-name"],
144+
TEMP: [],
145+
TEMPORARY: [],
146+
THEN: ["create-table", "col-alias", "tbl-alias", "col-name"],
147+
TIES: [],
148+
TO: ["create-table", "col-alias", "tbl-alias", "col-name"],
149+
TRANSACTION: ["create-table", "col-alias", "tbl-alias", "col-name"],
150+
TRIGGER: [],
151+
UNBOUNDED: [],
152+
UNION: ["create-table", "col-alias", "tbl-alias", "col-name"],
153+
UNIQUE: ["create-table", "col-alias", "tbl-alias", "col-name"],
154+
UPDATE: ["create-table", "col-alias", "tbl-alias", "col-name"],
155+
USING: ["create-table", "col-alias", "tbl-alias", "col-name"],
156+
VACUUM: [],
157+
VALUES: ["create-table", "col-alias", "tbl-alias", "col-name"],
158+
VIEW: [],
159+
VIRTUAL: [],
160+
WHEN: ["create-table", "col-alias", "tbl-alias", "col-name"],
161+
WHERE: ["create-table", "col-alias", "tbl-alias", "col-name"],
162+
WINDOW: ["parser-issue"], // Should be allowed as alias name, but currently causes parsing issues.
163+
WITH: [],
164+
WITHOUT: [],
159165
};
166+
167+
export const sqliteKeywords: Record<string, boolean> = Object.fromEntries(
168+
Object.entries(keywordDefs)
169+
.filter(([, contexts]) => contexts.length > 0)
170+
.map(([k]) => [k, true])
171+
);

src/parser.pegjs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6617,7 +6617,14 @@ table_constraint
66176617
}
66186618

66196619
constraint_name
6620-
= kw:CONSTRAINT name:(__ ident)? {
6620+
= &mysql kw:CONSTRAINT name:(__ ident)? {
6621+
return loc({
6622+
type: "constraint_name",
6623+
constraintKw: kw,
6624+
name: read(name),
6625+
});
6626+
}
6627+
/ !mysql kw:CONSTRAINT name:(__ ident) {
66216628
return loc({
66226629
type: "constraint_name",
66236630
constraintKw: kw,

test/ddl/constraints_column.test.ts

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ describe("column constraints", () => {
276276
});
277277
});
278278

279-
dialect(["mysql", "mariadb", "sqlite"], () => {
279+
dialect(["mysql", "mariadb"], () => {
280280
it("supports CONSTRAINT keyword for keys and check()", () => {
281281
testColConstWc("CONSTRAINT PRIMARY KEY");
282282
testColConstWc("CONSTRAINT UNIQUE");
@@ -292,17 +292,6 @@ describe("column constraints", () => {
292292
});
293293
});
294294

295-
dialect(["sqlite"], () => {
296-
it("supports CONSTRAINT keyword for column constraints", () => {
297-
testColConstWc("CONSTRAINT NULL");
298-
testColConstWc("CONSTRAINT NOT NULL");
299-
testColConstWc("CONSTRAINT DEFAULT 10");
300-
testColConstWc("CONSTRAINT COLLATE utf8");
301-
testColConstWc("CONSTRAINT GENERATED ALWAYS AS (x + y)");
302-
testColConstWc("CONSTRAINT REFERENCES tbl2 (col)");
303-
});
304-
});
305-
306295
dialect(["sqlite", "postgresql"], () => {
307296
it("supports named column constraints", () => {
308297
testColConstWc("CONSTRAINT cname NULL");

test/ddl/constraints_table.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ describe("table constraints", () => {
226226
});
227227
});
228228

229-
dialect(["mysql", "mariadb", "sqlite"], () => {
229+
dialect(["mysql", "mariadb"], () => {
230230
it("supports CONSTRAINT keyword for table constraints", () => {
231231
testTblConstWc("CONSTRAINT PRIMARY KEY (id)");
232232
testTblConstWc("CONSTRAINT UNIQUE KEY (id)");

test/expr/row.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,12 @@ describe("ROW constructor", () => {
5050
});
5151
});
5252

53-
dialect(["sqlite", "mysql"], () => {
53+
dialect(["mysql"], () => {
5454
it("does not support ROW() constructor", () => {
5555
expect(() => parseExpr("ROW(1, 2, 3)")).toThrow();
5656
});
5757
});
58-
dialect(["bigquery", "mariadb"], () => {
58+
dialect(["bigquery", "mariadb", "sqlite"], () => {
5959
it("parses ROW() as a function", () => {
6060
expect(parseExpr("ROW(1, 2, 3)").type).toBe("func_call");
6161
});

0 commit comments

Comments
 (0)