feat(parser): support MySQL # line comments behind allowHashLineComments - #2508
Open
fudianchn wants to merge 1 commit into
Open
feat(parser): support MySQL # line comments behind allowHashLineComments#2508fudianchn wants to merge 1 commit into
fudianchn wants to merge 1 commit into
Conversation
The second step agreed in JSQLParser#2502: with Feature.allowHashLineComments (default off) a `#` runs to end of line as a comment, unconditional like MySQL itself (no blank needed, `42#24` is a comment too); with the flag off a lone `#` stays the binary operator introduced in JSQLParser#2507, so neither reading silently replaces the other. Mechanics: under the flag SimpleCharStream rewrites a token-start `#` in the buffer to a character no other lexical rule starts with, so the dedicated HASH_LINE_COMMENT production wins the match for every `#` form while identifier and JSON-operator lexing of the default mode stay untouched (rewriting the buffer keeps the matcher's backup / re-read arithmetic intact, and GetImage() restores the `#` in the token image). Unquoted identifiers (and @@variables) end at their first `#` via their token actions, which re-lex the remainder as the comment. Quoted forms ("#", `#`, "a#b") keep their `#` in both modes. Under the flag the statement semantics are MySQL's: `SELECT #temp FROM t` comments out the rest of the line and fails, quoted "#temp" still parses. Closes JSQLParser#2499, supersedes JSQLParser#2502. Signed-off-by: Fu Dian <fudianchn@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
AI disclosure: this change was prepared with AI coding agents, reviewed and revised line by line by me.
What
MySQL
#line comments behind a feature switch, the second step agreed in #2502 (fixes #2499):Why / Root cause
One lexeme, two dialects: PostgreSQL reads
#as the binary operator from #2507, MySQL as a line comment. The special-token-or-token identity is static per production, and longest match outranks any post-match rewrite (#wordlexes as an identifier before an operator or comment rule could act), so a static comment rule would silently drop one of the readings — the "no good solution" from the #2502 discussion.How
Three pieces, all inert while
Feature.allowHashLineCommentsis off (the default):SimpleCharStreamrewrites a token-start#in its buffer to a character no other lexical rule starts with. Rewriting the buffer (instead of synthesizing reads) keeps the matcher's backup / re-read arithmetic intact, andGetImage()restores the#, so the comment token carries the original text.HASH_LINE_COMMENTproduction claims that character, self-contained likeLINE_COMMENT, and emits the comment as a special token. Because nothing else starts with the character, it wins the match for every#form (# c,#c,#>,#-, ...).@@variablesend at their first#via their token actions, which back up and re-lex the remainder as the comment — real MySQL reads42#24as42plus comment too.Quoted forms (
'#',"a#b",`#`) keep their#in both modes. Under the flag the statement semantics are MySQL's:SELECT #temp FROM tcomments out the rest of the line and fails, quoted"#temp"still parses.Follow-up: with this landing there are now three lexer-level switches (square brackets, backslash,
#comments). The dialect presets sketched in the #2502 discussion would be a small standalone follow-up if you want them — a mapping from DatabaseType to the existing Feature set, no mechanism changes.Testing
CCJSqlParserUtilTest: 2 new tests (both states of the same SQL, MySQL statement semantics).SelectASTTest: 1 new test (the comment is a special token carrying the original# ...image). All verified failing under three mutants: stream rewrite removed, identifier truncation removed,#dropped from the identifier start set. Full suite green (4935 tests).Performance
gradle jmh,JSQLParserBenchmark.parseSQLStatementsonperformance.sql,version=latest, 10 forks × 10 iterations (100 samples) on a 32-core host, interleaved master/branch (one polluted run excluded, CI ± 0.15):dff722bΔ ≤ 1% with overlapping CIs in 2 of 3 windows; the residual is the three added per-token branches (token start, image, identifier action), each guarded to a null-check for parses that never opt in.