Skip to content

Align keyword tables with MySQL 26.7 and support CHANGE REPLICATION SOURCE TO - #36

Merged
kyleconroy merged 3 commits into
mainfrom
claude/mysql-26-7-syntax-klszkw
Aug 18, 2026
Merged

Align keyword tables with MySQL 26.7 and support CHANGE REPLICATION SOURCE TO#36
kyleconroy merged 3 commits into
mainfrom
claude/mysql-26-7-syntax-klszkw

Conversation

@kyleconroy

Copy link
Copy Markdown
Contributor

Reviewing the MySQL 26.7.0 changelog (the first calendar-versioned release, 2026-07-28) surfaced two parser-relevant items; this PR implements both, plus the policy change that unblocks the second.

Keyword reservation (22d71fd)

MySQL 26.7 corrected information_schema.KEYWORDS (Bug #114874): the server has rejected CUBE, EXTERNAL, QUALIFY, and TABLESAMPLE as unquoted identifiers since 8.4, while MANUAL and PARALLEL are non-reserved. marino had only TABLESAMPLE; the rest lexed as plain identifiers.

  • CUBE, EXTERNAL, QUALIFY are now reserved: rejected as unquoted identifiers, still valid backquoted or after a qualifying dot (SELECT t.cube FROM t), matching MySQL.
  • MANUAL and PARALLEL join the unreserved keyword class and keep working in identifier position.

Breaking change: SQL that used cube, external, or qualify as unquoted identifiers no longer parses. That is the cost of matching MySQL 8.4+/26.7.

ast policy (adb7755)

CLAUDE.md previously declared the ast package frozen (a rewrite-era rule from PLAN.md, where it kept oracle and HEAD dumps comparable). It now permits backwards-compatible evolution: new node types and fields are allowed; existing nodes, fields, and semantics remain part of the contract with sqlc's MySQL engine.

CHANGE REPLICATION SOURCE TO (8385d39)

26.7 adds three Change Stream Applier options (APPLIER_VERSION, APPLIER_WORKER_COUNT, APPLIER_EVENT_MEMORY_LIMIT) to CHANGE REPLICATION SOURCE TO, which marino did not parse at all. New additive support:

  • ast.ChangeReplicationSourceStmt with a generic NAME = literal option list and FOR CHANNEL clause. Option names are uppercased but not validated against the server's option list, so the 26.7 applier options parse like the connection options and future additions need no parser change. Implements SensitiveStmtNode; SecureText() masks options whose name contains PASSWORD.
  • parser/parse_replication.go registers CHANGE as a statement leader. The production comment cites the MySQL 26.7 manual since the statement postdates the goyacc grammar. The removed CHANGE MASTER TO spelling stays a syntax error, matching MySQL 8.4+.
  • CHANNEL added as a non-reserved keyword (MySQL's classification).
  • Option values are limited to string/integer/decimal literals for now; keyword-valued options (e.g. ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS = OFF) and list-valued ones (IGNORE_SERVER_IDS = (...)) would need small extensions.

Testing

TestMySQLReservedWordCompat and TestChangeReplicationSource cover reservation semantics, the applier options, restore round-trips, negative cases, and password masking; TestSimple lists gained the six new words. TestKeywordConsistent keeps the four hand-maintained keyword tables in agreement, and TestKeywordsLength counts are updated (679→685 total, 233→236 reserved). Full go test ./... -count=1 -timeout 120s is green; TestRDErrorFidelity goldens unchanged.

🤖 Generated with Claude Code

https://claude.ai/code/session_019Jbktm7oVU7ysVz4MdS9D7


Generated by Claude Code

claude added 3 commits August 18, 2026 17:23
MySQL 26.7.0 corrected the classification of six keywords (MySQL Bug
#114874): CUBE, EXTERNAL, QUALIFY, and TABLESAMPLE are reserved words
(the server has rejected them as unquoted identifiers since 8.4), while
MANUAL and PARALLEL are non-reserved keywords.

marino previously treated all of them except TABLESAMPLE as plain
identifiers. Reserve CUBE, EXTERNAL, and QUALIFY - they remain usable
quoted or after a qualifying dot, matching MySQL - and register MANUAL
and PARALLEL as unreserved keywords, which keep working in identifier
position.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019Jbktm7oVU7ysVz4MdS9D7
The ast package is no longer frozen outright: new node types and new
fields are allowed. Existing nodes, fields, and their semantics remain
part of the contract with sqlc's MySQL engine and must not change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019Jbktm7oVU7ysVz4MdS9D7
Add ChangeReplicationSourceStmt, the first additive ast change under the
relaxed backwards-compatibility rule. The statement parses a generic
name = literal option list plus the FOR CHANNEL clause, so the MySQL
26.7 Change Stream Applier options (APPLIER_VERSION,
APPLIER_WORKER_COUNT, APPLIER_EVENT_MEMORY_LIMIT) parse like the
connection options; option names are not validated against the server's
list. SecureText masks PASSWORD-carrying options. CHANNEL joins the
keyword tables as a non-reserved keyword, matching MySQL. The removed
CHANGE MASTER TO spelling stays unsupported, matching MySQL 8.4+.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019Jbktm7oVU7ysVz4MdS9D7
@kyleconroy
kyleconroy merged commit 782dc15 into main Aug 18, 2026
1 check 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