Skip to content

feat(parser): support double quoted string literals behind allowDoubleQuotedStrings - #2513

Merged
manticore-projects merged 1 commit into
JSQLParser:masterfrom
fudianchn:double-quote-strings
Aug 26, 2026
Merged

feat(parser): support double quoted string literals behind allowDoubleQuotedStrings#2513
manticore-projects merged 1 commit into
JSQLParser:masterfrom
fudianchn:double-quote-strings

Conversation

@fudianchn

@fudianchn fudianchn commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

AI disclosure: this change was prepared with AI coding agents, reviewed and revised line by line by me.

What

Double quoted string literals behind a feature switch, item 1 of #2512:

CCJSqlParserUtil.parse("SELECT \"not an identifier\"", p -> p.withDoubleQuotedStrings(true))
// -> StringValue "not an identifier"; a Column when off

Why

One lexeme, two readings, inventoried across the dialects JSqlParser models and the popular engines, every row verified against the vendor docs:

"..." reads as dialects
string literal MySQL, MariaDB (default sql_mode; ANSI_QUOTES flips back), BigQuery, Databricks (Spark SQL), Hive (these three quote identifiers with backticks)
identifier ANSI SQL, PostgreSQL, Oracle, SQL Server (QUOTED_IDENTIFIER ON), H2, Exasol, Snowflake, Redshift, ClickHouse, DuckDB, Trino, Db2

SQLite is the documented exception: identifier by the standard, with its double-quoted-string "misfeature" fallback when nothing matches, which a parser should not replicate. Master always produced the identifier reading, so the string side silently got a Column where their dialect has a string value.

How

The S_QUOTED_IDENTIFIER token action rewrites the token kind to the string literal token when the feature is on, the same place the square bracket quotation machinery lives (#677 style, no grammar changes). StringValue strips double quotes and keeps them for round-trip through its existing quoteStr (the $$ path already worked this way); the public StringValue(String) constructor accordingly strips a double-quoted argument the way it always stripped single-quoted ones. Backticks and brackets are untouched (first-character guard).

The MYSQL and MARIADB presets carry the switch (default sql_mode reading; under ANSI_QUOTES MySQL flips back to identifiers, so preset users wanting that reading keep the explicit switch off).

Disclosed leniency: in table positions a "..." token follows the existing string-as-table branch (FROM 'file.csv'), the same leniency single quotes already have; MySQL itself errors there.

Testing

CCJSqlParserUtilTest: testDoubleQuotedStringsFeature (off = Column unchanged, on = StringValue with value and round-trip, empty string, doubled quotes, the string-as-table leniency), testDoubleQuotedStringsPreset (MYSQL/MARIADB on, SQLSERVER off). All verified failing with the token rewrite removed, with the StringValue branch removed, and with MYSQL missing the preset feature; full suite green.

Performance

gradle jmh, JSQLParserBenchmark.parseSQLStatements on performance.sql, version=latest, 10 forks × 10 iterations (100 samples) on a 32-core host, interleaved master/branch:

build run 1 run 2
master 94c4508 3.754 ± 0.023 3.795 ± 0.026
branch (this PR) 3.777 ± 0.024 3.805 ± 0.024

Same-window deltas are +0.6% and +0.3% with overlapping CIs, and the drift between the two master runs (3.754 -> 3.795) is larger than the master/branch delta: no regression. The residual is the one added getAsBoolean in the S_QUOTED_IDENTIFIER action, paid per quoted identifier token only.

Implements item 1 of #2512.

…eQuotedStrings

One lexeme, two readings: ANSI/Postgres/Oracle and SQL Server quote
identifiers with double quotes, while BigQuery, Spark/Databricks and
MySQL default sql_mode read them as string literals. The switch rewrites
the token kind in the S_QUOTED_IDENTIFIER action (the square bracket
machinery below), StringValue keeps the double quote on round-trip via
its quoteStr. MYSQL and MARIADB presets carry the switch. Implements
item 1 of JSQLParser#2512.
@manticore-projects

Copy link
Copy Markdown
Contributor

Great! Thank you for your time and effort!

@manticore-projects
manticore-projects merged commit c86cf6a into JSQLParser:master Aug 26, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants