Repository navigation
Conversation
CREATE USER and DEFINER read user@host with their own copies of the same rule. Neither accepted app@'%' or 'app'@localhost, because the lexer reads app@ and @localhost as single tokens. Without a dialect a double-quoted part also lost its quotes, so CREATE USER "app"@"%" rendered as app@%. Add one MySqlAccountName() production that splits those tokens, keep the quote character of double-quoted and backquoted parts apart from their value, and use it for CREATE USER and DEFINER. Signed-off-by: minleejae <mmj9808@gmail.com>
This was referenced Oct 14, 2026
This branch has not been deployed
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.
Purpose
Read MySQL account names (
user[@host]) with one grammar rule wherever they appear. Today,CREATE USERand the view, trigger and routineDEFINERclause each repeat the same rule, and both miss spellings that MySQL accepts:CREATE USER app@'%'andCREATE USER 'app'@localhostfail. The lexer readsapp@and@localhostas single tokens, and neither rule splits them.CREATE USER "app"@"%" IDENTIFIED BY 'x'renders asCREATE USER app@% IDENTIFIED BY 'x', which is not valid SQL. The double quotes are dropped.`app`), while a single-quoted part keeps only its text (app).The account statements and GRANT/REVOKE changes that follow build on this rule.
Current design (As-is)
MySqlUserAccount()(CREATE USER) andMySqlDefiner()both readMySqlAccountNamePart() [@ MySqlAccountNamePart()].MySqlAccountNamePart()turns an identifier intonew StringValue(name). That constructor strips double quotes, and the result is then marked unquoted.Target design (To-be)
MySqlAccountName(), that returns aUserAccountwith separate user and host parts. It accepts every spelling:',"or a backquote;app@localhost,app@'%'and'app'@localhost, which it splits into user and host.MySqlUserAccount()(CREATE USER) andMySqlDefiner()use it. Their models are unchanged:UserAccountandMySqlDefinerkeepgetUser()/getHost().getQuoteStr()and its text ingetValue(), the same way a single-quoted part already did.CREATE USER "app"@"%"now renders unchanged in every mode.DEFINER = CURRENT_USER[()]is unchanged.Compatibility: rendered SQL is unchanged, except for the double-quoted accounts that previously lost their quotes. In the AST:
appwith quote`, instead of the value`app`.app@localhostis now split into userappand hostlocalhost. Before, it was one user namedapp@localhostwithout a host.Validation
MySqlAccountNameTest, 25 cases. Ten spellings each go through CREATE USER (withDialect.MYSQLand without a dialect), view DEFINER and trigger DEFINER, with exacttoString()andStatementDeParseroutput and the user/host value and quote character. It also checks rejected forms (app@,@host,'app'@) and the unchangedDEFINER = CURRENT_USER().spotlessApply check: 10,377 tests, 10,352 passed, 25 skipped, zero failures/errors. The grammar choice conflict check passes.app2@'%','app3'@localhost,`app4`@`%`,"app5"@"%", …master. On two servers per database, the rendered SQL gives the same results as the original for all 205 MySQL and 327 PostgreSQL statements that render.Integration validation
Applied #2806–#2819 together on
master(bdf8ac31), with the stacked PRs on top of their bases (#2806 → #2807 → #2808, #2806 → #2809 → #2810 and #2811 → #2812).master. Between the branches, conflicts are limited to adjacent additions (README/index rows, usage sections, imports, visitor and feature lists, one enum line and one alias guard).spotlessApply check: 11,494 tests, 11,469 passed, 25 skipped, zero failures/errors. The grammar choice conflict check passes.master: 206) and 363 of 364 PostgreSQL statements (master: 328). Every MySQL 8.4 non-reserved word and PostgreSQL 18 unreserved or column-name keyword parses as a column and table name.