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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants