Skip to content

Commit 3f2cb12

Browse files
committed
perf(database): normalize quoted SQL in character runs
1 parent 29dfba1 commit 3f2cb12

2 files changed

Lines changed: 10 additions & 2 deletions

File tree

storage/framework/core/database/src/query-parser.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,8 @@ export function normalizeQuery(sql: string): string {
138138
normalizedSql = normalizedSql.replace(/\b\d+\b/g, '?')
139139

140140
// Replace string literals with ?
141-
normalizedSql = normalizedSql.replace(/'([^']|'')*'/g, '?')
142-
normalizedSql = normalizedSql.replace(/"([^"]|"")*"/g, '?')
141+
normalizedSql = normalizedSql.replace(/'[^']*(?:''[^']*)*'/g, '?')
142+
normalizedSql = normalizedSql.replace(/"[^"]*(?:""[^"]*)*"/g, '?')
143143

144144
// Replace boolean and NULL literals in one pass.
145145
normalizedSql = normalizedSql.replace(/\b(?:true|false|null)\b/gi, '?')

storage/framework/core/database/tests/query-normalization.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@ import { normalizeQuery, parseQuery } from '../src/query-parser'
33

44
describe('query normalization', () => {
55
it.each([
6+
["SELECT 'it''s', \"a\"\"b\", '', \"\"", 'SELECT ?, ?, ?, ?'],
7+
["SELECT 'unterminated", "SELECT 'unterminated"],
8+
['SELECT "unterminated', 'SELECT "unterminated'],
9+
["SELECT 'a''b", "SELECT ?'b"],
10+
['SELECT "a""b', 'SELECT ?"b'],
11+
["SELECT 'a\"b', \"c'd\"", 'SELECT ?, ?'],
12+
["SELECT '漢\né', \"ü\n字\"", 'SELECT ?, ?'],
13+
[`SELECT '${'abcdefghijklmnop'.repeat(128)}', "${'q'.repeat(256)}"`, 'SELECT ?, ?'],
614
['SELECT true, FALSE, nUlL, TrUe, False, NULL', 'SELECT ?, ?, ?, ?, ?, ?'],
715
['SELECT truefalse, null_true, false9, 9null, is_true, nullish', 'SELECT truefalse, null_true, false9, 9null, is_true, nullish'],
816
['SELECT TRUE.false/null, (false), NULL::boolean', 'SELECT ?.?/?, (?), ?::boolean'],

0 commit comments

Comments
 (0)