Skip to content

Commit 2dcced1

Browse files
authored
#211 Fix trigger query parsing (#213)
1 parent 87421fa commit 2dcced1

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

src/sqlite/queryParser.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export function extractStatements(query: string): Statement[] {
55

66
let statement: Statement|undefined;
77
let isStmt = false;
8+
let isInternalBlock = false;
89
let isString = false;
910
let isComment = false;
1011
let isCommand = false;
@@ -18,6 +19,7 @@ export function extractStatements(query: string): Statement[] {
1819
let char = line[charIndex];
1920
let prevChar = charIndex>0? line[charIndex-1] : undefined;
2021
let nextChar = charIndex<line.length-1? line[charIndex+1] : undefined;
22+
let lastWord = (n: number) => line.substring(charIndex-n+1, charIndex+1)
2123

2224
if (isStmt) {
2325
if (statement) statement.sql += char;
@@ -28,7 +30,13 @@ export function extractStatements(query: string): Statement[] {
2830
} else if (!isString && char === '/' && nextChar === '*') {
2931
isComment = true;
3032
commentChar = '/';
31-
} else if (!isString && !isComment && char === ';') {
33+
} else if (!isString && !isComment && lastWord(5).toLowerCase() === "begin") {
34+
isInternalBlock = true;
35+
} else if (!isString && !isComment && lastWord(3).toLowerCase() === "end") {
36+
isInternalBlock = false;
37+
} else if (!isString && !isComment && isInternalBlock && lastWord(11).toLowerCase() === "transaction") {
38+
isInternalBlock = false;
39+
} else if (!isString && !isComment && !isInternalBlock && char === ';') {
3240
isStmt = false;
3341
if (statement) {
3442
statement.position.end = [lineIndex, charIndex];

tests/unit/sqlite/queryParser.test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,5 +110,33 @@ describe("QueryParser Tests", function () {
110110
expect(actual.map(s => s.sql)).toEqual(expected);
111111
});
112112

113+
test("should parse query with TRIGGER and SELECT (issue #210)", function() {
114+
let query = `CREATE TRIGGER newWidgetSale BEFORE UPDATE ON widgetSale
115+
BEGIN
116+
SELECT RAISE(ROLLBACK, 'cannot update table "widget sale"') FROM widgetSale WHERE id = NEW.id and reconciled = 1;
117+
END
118+
;`
119+
120+
let actual = queryParser.extractStatements(query);
121+
let expected = [query];
122+
123+
expect(actual.map(s => s.sql)).toEqual(expected);
124+
});
125+
126+
test("should parse query with transaction", function() {
127+
let query = `BEGIN TRANSACTION; -- start
128+
SELECT RAISE(ROLLBACK, 'cannot update table "widget sale"') FROM widgetSale WHERE id = NEW.id and reconciled = 1;
129+
END TRANSACTION;`
130+
131+
let actual = queryParser.extractStatements(query);
132+
let expected = [
133+
"BEGIN TRANSACTION;",
134+
"SELECT RAISE(ROLLBACK, 'cannot update table \"widget sale\"') FROM widgetSale WHERE id = NEW.id and reconciled = 1;",
135+
"END TRANSACTION;"
136+
];
137+
138+
expect(actual.map(s => s.sql)).toEqual(expected);
139+
});
140+
113141

114142
});

0 commit comments

Comments
 (0)