From dfa352838861c60c1d011d4b073a105c8f9f183c Mon Sep 17 00:00:00 2001 From: Elijah Allen <56412012+eaallen@users.noreply.github.com> Date: Tue, 21 Jul 2026 16:49:47 -0600 Subject: [PATCH] fix: support SQL-standard doubled quotes in string literals MySQL/SQL allow escaping a quote inside a string by doubling it (e.g. 'O''Hare'). The lexer only recognized backslash escapes, so these literals were split into multiple STRING tokens and failed to parse. Update the STRING lexer rules to accept '' and "" inside quoted strings, matching https://dev.mysql.com/doc/refman/5.7/en/string-literals.html Co-authored-by: Cursor --- src/sqlParser.jison | 4 ++-- test/main.test.js | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/sqlParser.jison b/src/sqlParser.jison index 271c94a..8cc99ff 100644 --- a/src/sqlParser.jison +++ b/src/sqlParser.jison @@ -119,8 +119,8 @@ UNION return 'UNION' "}" return '}' ";" return ';' -['](\\.|[^'])*['] return 'STRING' -["](\\.|[^"])*["] return 'STRING' +['](['][']|\\.|[^'])*['] return 'STRING' +["](["]["]|\\.|[^"])*["] return 'STRING' [0][x][0-9a-fA-F]+ return 'HEX_NUMERIC' [-]?[0-9]+(\.[0-9]+)? return 'NUMERIC' [-]?[0-9]+(\.[0-9]+)?[eE][-][0-9]+(\.[0-9]+)? return 'EXPONENT_NUMERIC' diff --git a/test/main.test.js b/test/main.test.js index 4bf50b6..13d8893 100644 --- a/test/main.test.js +++ b/test/main.test.js @@ -468,4 +468,15 @@ describe('select grammar support', function () { SELECT one.name, group_concat(j.value, ', ') FROM one, json_each(one.stringArray) AS j GROUP BY one.id `) }) + + it('support SQL-standard doubled quotes inside string literals', function () { + const ast = testParser("select * from t where name = 'O''Hare'"); + assert.equal(ast.value.where.right.value, "'O''Hare'"); + + const astDouble = testParser('select * from t where name = "say ""hi"""'); + assert.equal(astDouble.value.where.right.value, '"say ""hi"""'); + + // empty string and backslash escapes should keep working + testParser("select * from t where a = '' and b = 'O\\'Hare'"); + }) });