Skip to content

Fix lexing of qualified names like t.1 and order.id - #584

Draft
JanJakes wants to merge 5 commits into
trunkfrom
lexer-review-fixes
Draft

JanJakes wants to merge 5 commits into
trunkfrom
lexer-review-fixes

Conversation

@JanJakes

Copy link
Copy Markdown
Member

MySQL reads t.1, t.1st, and order.id as qualified names, but both of our lexers failed on them. They scanned .1 as a decimal number and emitted order as the ORDER keyword, so such queries didn't parse.

This change makes both lexers handle qualified names like MySQL's own lexer. It covers the new mysql-parser lexer and the mysql-on-sqlite lexer that the driver still uses:

  • Digits after a dot that follows a name are a name part, so t.1 and t.1e5 are qualified names.
  • A keyword right before a dot and a name is an identifier, so order.id works, while @@session.sql_mode keeps its meaning.
  • A dot after a quoted name or a space still starts a number, as in MySQL.

All cases were checked against MySQL 8.4, and one more query from the MySQL server test corpus now parses.

The PR also applies smaller notes from the review of the new lexer:

  • Removes comments that only repeated the code or described its history.
  • Writes the backslash pattern in token unescaping as a plain literal.
  • Keeps the unquoted identifier characters in one shared constant.

Follows up on #429.

State what the inline block is and why, instead of how it came to be.
It mirrors scan_lexeme(), so the pointer keeps the two copies in sync.
Each of these comments repeated the byte that the condition right above
it already checks. Comments that label less obvious skips stay.
The pattern matches a single literal backslash, so it can be written
directly instead of being built with preg_quote() on every call.
Both lexers repeated the ASCII characters allowed in an unquoted
identifier in read_identifier() and in the "@" variable name scan.
MySQL reads "t.1", "t.1st", and "order.id" as qualified names, but both
lexers failed on them: they scanned ".1" as a decimal number, and they
emitted "order" as the ORDER keyword.

Follow MySQL's MY_LEX_IDENT_SEP lexer state:

- A "." right after an unquoted identifier separates name parts, and
  digits after it start an identifier. After a quoted identifier or
  whitespace, ".1" stays a number.
- A word right before a "." and a name is an identifier, even when it is
  a reserved keyword. After "@@", it stays a keyword, so system variable
  scopes like "@@session.sql_mode" keep working.

The fix applies to the mysql-parser lexer and to the mysql-on-sqlite lexer
that the driver still uses. The MySQL server corpus query that covers this
case now parses in both, and driver tests run such queries end to end.

See: https://github.com/mysql/mysql-server/blob/mysql-8.4.10/sql/sql_lex.cc
@coderabbitai

coderabbitai Bot commented Oct 29, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

🤖 Lexer benchmark

Changes to lexer-related files were detected and triggered a benchmark:

Config Base (QPS) This PR (QPS) Speedup
no JIT 125,773 126,061 1.00×
tracing JIT 233,334 232,660 1.00×

Note: Hosted runners are noisy, and absolute numbers vary. Treat the results with caution and verify them locally.

To reproduce locally:

cd packages/mysql-on-sqlite && composer run bench-lexer

@JanJakes JanJakes changed the title Fix qualified name lexing and apply lexer review notes Fix lexing of qualified names like t.1 and order.id Oct 29, 2026

This branch has not been deployed

No deployments
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.

1 participant