From 576746df0c5be35e92b48a5664d1b47e00526384 Mon Sep 17 00:00:00 2001 From: Ngo Quoc Dat Date: Sun, 20 Sep 2026 22:16:56 +0700 Subject: [PATCH] fix(editor): keep reading the keyword behind an invisible character --- TablePro/Core/Utilities/SQL/QueryClassifier.swift | 2 +- .../SQL/InvisibleCharacterRemoverTests.swift | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/TablePro/Core/Utilities/SQL/QueryClassifier.swift b/TablePro/Core/Utilities/SQL/QueryClassifier.swift index 4bdef638f7..c296b8ac9c 100644 --- a/TablePro/Core/Utilities/SQL/QueryClassifier.swift +++ b/TablePro/Core/Utilities/SQL/QueryClassifier.swift @@ -192,7 +192,7 @@ enum QueryClassifier { /// The first keyword of a code projection, past any opening parentheses. static func leadingCodeKeyword(_ code: String) -> String { - let remaining = code.drop { $0.isWhitespace || $0 == "(" } + let remaining = code.drop { StatementBlank.isBlank($0) || $0 == "(" } return remaining.prefix { $0.isLetter || $0.isNumber || $0 == "_" }.uppercased() } } diff --git a/TableProTests/Core/Utilities/SQL/InvisibleCharacterRemoverTests.swift b/TableProTests/Core/Utilities/SQL/InvisibleCharacterRemoverTests.swift index 012e209c42..1a2696cb0d 100644 --- a/TableProTests/Core/Utilities/SQL/InvisibleCharacterRemoverTests.swift +++ b/TableProTests/Core/Utilities/SQL/InvisibleCharacterRemoverTests.swift @@ -68,8 +68,15 @@ struct InvisibleCharacterRemoverTests { @Test("A PostgreSQL dollar-quoted body is kept") func dollarQuotedBodyIsKept() { - let text = "SELECT\u{A0}$$a\u{A0}b$$" - #expect(clean(text, grammar: TestGrammar.postgres) == "SELECT $$a\u{A0}b$$") + let text = "SELECT $$a\u{A0}b$$" + #expect(clean(text, grammar: TestGrammar.postgres) == text) + } + + /// Measured on PostgreSQL 17: `SELECT$$a b$$` is a syntax error, because every byte over 0x7F continues an + /// identifier there and a `$` glued to one opens no literal. So the text is code, and its blanks are cleaned. + @Test("A dollar sign glued to a non-ASCII blank opens no literal") + func dollarQuoteBehindABlankIsCode() { + #expect(clean("SELECT\u{A0}$$a\u{A0}b$$", grammar: TestGrammar.postgres) == "SELECT $$a b$$") } @Test("A MySQL conditional comment runs, so it is cleaned like code")