Skip to content

Commit aa70c09

Browse files
committed
refactor: remove safeScanSync workaround, use scanSync directly
@libpg-query/parser@17.6.10 fixes the JSON escaping bug in build_scan_json() so the workaround is no longer needed.
1 parent e1ea118 commit aa70c09

3 files changed

Lines changed: 12 additions & 47 deletions

File tree

packages/parse/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
"round-trip"
4141
],
4242
"dependencies": {
43-
"@libpg-query/parser": "^17.6.3",
43+
"@libpg-query/parser": "^17.6.10",
4444
"@pgsql/types": "^17.6.2",
4545
"pgsql-deparser": "workspace:*"
4646
},

packages/parse/src/scanner.ts

Lines changed: 1 addition & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -6,53 +6,10 @@
66
* to identify SQL_COMMENT tokens with exact byte positions.
77
* Whitespace detection uses token gaps to find blank lines
88
* between statements/comments.
9-
*
10-
* Note: @libpg-query/parser has an upstream JSON serialization bug in
11-
* _wasm_scan where literal control characters in token text are not
12-
* escaped. We work around this by retrying with a patched JSON.parse
13-
* that escapes control characters before parsing.
149
*/
1510

1611
import { scanSync, type ScanToken } from '@libpg-query/parser';
1712

18-
/**
19-
* Escape unescaped control characters inside JSON string values.
20-
* The upstream _wasm_scan emits raw \n, \r, \t in token text fields,
21-
* which breaks JSON.parse. This replaces them with their escape sequences.
22-
*/
23-
function fixScanJson(raw: string): string {
24-
return raw.replace(
25-
/"(?:[^"\\]|\\.)*"/g,
26-
(match) =>
27-
match
28-
.replace(/\t/g, '\\t')
29-
.replace(/\n/g, '\\n')
30-
.replace(/\r/g, '\\r')
31-
);
32-
}
33-
34-
/**
35-
* Call scanSync with a workaround for the upstream JSON serialization bug.
36-
* First tries the normal path; if JSON.parse throws, retries with a
37-
* temporarily patched JSON.parse that escapes control characters.
38-
* This is synchronous so there are no concurrency concerns.
39-
*/
40-
function safeScanSync(sql: string): { tokens: ScanToken[] } {
41-
try {
42-
return scanSync(sql);
43-
} catch {
44-
// Retry with patched JSON.parse to handle unescaped control chars
45-
const origParse = JSON.parse;
46-
try {
47-
JSON.parse = ((text: string, reviver?: Parameters<typeof JSON.parse>[1]) =>
48-
origParse(fixScanJson(text), reviver)) as typeof JSON.parse;
49-
return scanSync(sql);
50-
} finally {
51-
JSON.parse = origParse;
52-
}
53-
}
54-
}
55-
5613
/** Token type for -- line comments from PostgreSQL's lexer */
5714
const SQL_COMMENT = 275;
5815

@@ -105,7 +62,7 @@ export function scanComments(sql: string): ScannedElement[] {
10562

10663
let tokens: ScanToken[];
10764
try {
108-
const scanResult = safeScanSync(sql);
65+
const scanResult = scanSync(sql);
10966
tokens = scanResult.tokens;
11067
} catch {
11168
return [];

pnpm-lock.yaml

Lines changed: 10 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)