Skip to content

Support the MySQL txn, replication, DML, and DDL statement coverage groups - #41

Merged
kyleconroy merged 4 commits into
mainfrom
claude/mysql-unsupported-operations-kudhpx
Aug 18, 2026
Merged

Support the MySQL txn, replication, DML, and DDL statement coverage groups#41
kyleconroy merged 4 commits into
mainfrom
claude/mysql-unsupported-operations-kudhpx

Conversation

@kyleconroy

Copy link
Copy Markdown
Contributor

Implements all four remaining mysql_unsupported_* statement coverage groups from #38, one commit per group, following the #39/#40 precedent: each group's error goldens turn into Restore() goldens and the group is renamed with expanded coverage. All grammar is written from the MySQL 26.7 reference manual in the style of parser.y, since these statements postdate the goyacc grammar.

mysql_unsupported_txn → mysql_txn (18 cases)

  • XA {START|BEGIN}/END/PREPARE/COMMIT/ROLLBACK/RECOVER with xid (gtrid [, bqual [, formatID]]), JOIN/RESUME, SUSPEND [FOR MIGRATE], ONE PHASE, and CONVERT XID; XA BEGIN canonicalizes to XA START (ast/xa.go, parser/parse_xa.go)
  • LOCK INSTANCE FOR BACKUP and UNLOCK INSTANCE join the LOCK/UNLOCK families in parse_misc.go

mysql_unsupported_replication → mysql_replication (31 cases)

  • PURGE BINARY LOGS {TO | BEFORE} and RESET BINARY LOGS AND GTIDS; the removed pre-8.4 spellings (PURGE MASTER LOGS, RESET MASTER, CHANGE MASTER TO, RESET/START/STOP SLAVE) are not parsed, matching the CHANGE MASTER TO precedent from Align keyword tables with MySQL 26.7 and support CHANGE REPLICATION SOURCE TO #36
  • CHANGE REPLICATION FILTER with all seven filter types — the _DB, _TABLE, _WILD_, and REPLICATE_REWRITE_DB pair value forms, empty () values, and FOR CHANNEL
  • RESET REPLICA [ALL], START REPLICA (thread types, UNTIL options including bare SQL_AFTER_MTS_GAPS, USER/PASSWORD/DEFAULT_AUTH/PLUGIN_DIR connection options, FOR CHANNEL), STOP REPLICA, and START/STOP GROUP_REPLICATION
  • parse_replication.go now owns the START, STOP, and PURGE statement heads and routes their non-replication alternatives back to parse_txn.go/parse_brie.go; StartReplicaStmt and StartGroupReplicationStmt implement SecureText to mask passwords like ChangeReplicationSourceStmt

mysql_unsupported_dml → mysql_dml (26 cases)

  • HANDLER OPEN [[AS] alias], HANDLER READ (indexed compare form with = <= >= < >, indexed and table-scan FIRST/NEXT/PREV/LAST forms, WHERE, LIMIT), and HANDLER CLOSE (parser/parse_handler.go)
  • IMPORT TABLE FROM and LOAD XML with all documented clauses, reusing the LOAD DATA helpers
  • SELECT ... INTO var_list and INTO DUMPFILE, filling in the SelectIntoVars/SelectIntoDumpfile enum values that existed unimplemented; the INTO clause also parses in the common position between the field list and FROM, restoring in the trailing position

mysql_unsupported_ddl → mysql_ddl (70 cases)

  • CREATE/ALTER/DROP EVENT with AT and EVERY ... STARTS/ENDS schedules, ON COMPLETION, ENABLE/DISABLE [ON REPLICA], COMMENT, RENAME TO, and DO bodies
  • CREATE/DROP TRIGGER with BEFORE/AFTER, INSERT/UPDATE/DELETE, FOR EACH ROW, and FOLLOWS/PRECEDES
  • Stored CREATE FUNCTION (parameter list, RETURNS type, characteristics, RETURN or compound bodies), ALTER FUNCTION/PROCEDURE, and DROP FUNCTION; RETURN joins ProcedureProcStmt, and CREATE FUNCTION dispatches between the stored and loadable forms on the parameter list
  • The DEFINER = user clause on views, events, triggers, procedures (new ProcedureInfo.Definer field), and functions, with the statement head peeking past the clause to dispatch
  • ALTER VIEW mirroring CreateViewStmt; CREATE/ALTER/DROP SERVER; CREATE/ALTER/DROP [UNDO] TABLESPACE and LOGFILE GROUP with a shared option catalogue; CREATE/DROP SPATIAL REFERENCE SYSTEM (CREATE SPATIAL now dispatches between the index and SRS forms); CREATE/ALTER/DROP LIBRARY
  • CREATE/ALTER JSON DUALITY VIEW with the JSON_DUALITY_OBJECT('key' : value, ...) select-list constructor as a new expression atom
  • The remaining ALTER INSTANCE forms (ROTATE {INNODB|BINLOG} MASTER KEY, RELOAD TLS FOR CHANNEL, RELOAD KEYRING, ENABLE/DISABLE INNODB REDO_LOG) and the USING (expr) spelling plus DROP for MASKING POLICY

Keyword tables

40 new tokens, classified to match MySQL 26.7: BEFORE, DETERMINISTIC, EACH, MODIFIES, READS, RETURN, and UNDO become reserved; 32 words become unreserved; JSON_DUALITY_OBJECT is a NotKeywordToken. Free-form words that are not MySQL keywords (REFERENCE, the SRS attribute, server option, size option, and replication filter/option names, ACTIVE/INACTIVE, KEYRING, REDO_LOG) are matched case-insensitively in identifier position, following the SIGNAL information-item precedent from #38. Before reserving anything I verified none of the newly reserved words appear as identifiers in the existing test corpus or testdata/errors.json, which is byte-for-byte unaffected.

Notes

  • Unlike ProcedureInfo, the new body-carrying nodes (events, triggers, functions) traverse their body statement in Accept, so most bodies round-trip without canonical spelling; the two BEGIN...END test cases still use canonical Restore spelling because ProcedureBlock.Accept deliberately does not traverse its inner statements (the Map MySQL 26.7 statement coverage and support SIGNAL, RESIGNAL, and GET DIAGNOSTICS #38 limitation)
  • FieldType.Restore (not CompactStr) restores function parameter and return types so unspecified display widths round-trip
  • ReplicationSourceOption.Value may now be nil (bare option names like SQL_AFTER_MTS_GAPS); all ast changes are additive
  • The lexer test for AT now expects the keyword token instead of a plain identifier

go test ./... -count=1 -timeout 120s passes on every commit, and regenerating all goldens with -update produces no drift outside the four renamed groups.

🤖 Generated with Claude Code

https://claude.ai/code/session_01FGwevXQRPY7iPxud2UyaJH


Generated by Claude Code

claude added 4 commits August 18, 2026 21:03
Implement the mysql_unsupported_txn statement coverage group (MySQL 26.7
§15.3.5 and §15.3.8): its error goldens turn into Restore() goldens and
the group is renamed to mysql_txn with expanded coverage, following the
mysql_admin precedent.

Grammar, written from the reference manual since these statements
postdate the goyacc grammar (parser/parse_xa.go):

- XA {START|BEGIN} xid [JOIN|RESUME], XA END xid [SUSPEND [FOR
  MIGRATE]], XA PREPARE xid, XA COMMIT xid [ONE PHASE], XA ROLLBACK xid,
  and XA RECOVER [CONVERT XID], with xid: gtrid [, bqual [, formatID]].
  The XA BEGIN spelling parses to XAOpStart, so Restore() canonicalizes
  it to XA START.
- LOCK INSTANCE FOR BACKUP and UNLOCK INSTANCE join the LOCK/UNLOCK
  statement families in parse_misc.go.

New AST nodes (ast/xa.go): XAStmt with the XID transaction identifier
node, LockInstanceStmt, and UnlockInstanceStmt, plus their SEMCommand
strings.

Keyword tables: MIGRATE, ONE, PHASE, SUSPEND, XA, and XID become
unreserved keywords, matching their MySQL 26.7 classification;
TestKeywordsLength counts updated accordingly. testdata/errors.json is
unaffected.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FGwevXQRPY7iPxud2UyaJH
Implement the mysql_unsupported_replication statement coverage group
(MySQL 26.7 §15.4): its error goldens turn into Restore() goldens and
the group is renamed to mysql_replication with expanded coverage,
following the mysql_admin precedent.

Grammar, written from the reference manual since these statements
postdate the goyacc grammar (parser/parse_replication.go, which now owns
the START, STOP, and PURGE statement heads and routes their
non-replication alternatives to parse_txn.go and parse_brie.go; the
RESET head stays with parse_mysql_admin.go and routes here):

- PURGE BINARY LOGS {TO 'log' | BEFORE datetime_expr} and RESET BINARY
  LOGS AND GTIDS; the removed pre-8.4 spellings (PURGE MASTER LOGS,
  RESET MASTER) are not parsed, matching the CHANGE MASTER TO precedent
- CHANGE REPLICATION FILTER with all seven filter types — the _DB, _TABLE,
  _WILD_, and REPLICATE_REWRITE_DB value forms, empty () values, and FOR
  CHANNEL; the filter names are matched case-insensitively in identifier
  position like the CHANGE REPLICATION SOURCE TO option names
- RESET REPLICA [ALL] [FOR CHANNEL], START REPLICA with thread types,
  UNTIL options (including bare SQL_AFTER_MTS_GAPS, which makes
  ReplicationSourceOption.Value optional), the USER/PASSWORD/
  DEFAULT_AUTH/PLUGIN_DIR connection options, and FOR CHANNEL; STOP
  REPLICA with thread types and FOR CHANNEL
- START GROUP_REPLICATION [USER=, PASSWORD=, DEFAULT_AUTH=] and STOP
  GROUP_REPLICATION

New AST nodes (ast/replication.go): PurgeBinaryLogsStmt,
ResetBinaryLogsAndGtidsStmt, ChangeReplicationFilterStmt (with
ReplicationFilter and ReplicationRewriteDB), ResetReplicaStmt,
StartReplicaStmt, StopReplicaStmt, StartGroupReplicationStmt, and
StopGroupReplicationStmt, plus their SEMCommand strings. StartReplicaStmt
and StartGroupReplicationStmt implement SecureText to mask passwords,
like ChangeReplicationSourceStmt.

Keyword tables: BEFORE becomes a reserved word and FILTER,
GROUP_REPLICATION, GTIDS, IO_THREAD, and SQL_THREAD unreserved, matching
their MySQL 26.7 classification; TestKeywordsLength counts updated
accordingly. testdata/errors.json is unaffected.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FGwevXQRPY7iPxud2UyaJH
…r statements

Implement the mysql_unsupported_dml statement coverage group (MySQL 26.7
§15.2): its error goldens turn into Restore() goldens and the group is
renamed to mysql_dml with expanded coverage, following the mysql_admin
precedent.

Grammar, written from the reference manual since these statements
postdate the goyacc grammar:

- HANDLER ... OPEN [[AS] alias], HANDLER ... READ with the indexed
  compare form (= <= >= < > with a value list), the indexed and
  table-scan direction forms (FIRST/NEXT/PREV/LAST), WHERE, and LIMIT,
  and HANDLER ... CLOSE (parser/parse_handler.go)
- IMPORT TABLE FROM sdi_file [, sdi_file] ... and LOAD XML with
  LOW_PRIORITY/CONCURRENT, LOCAL, REPLACE/IGNORE, CHARACTER SET, ROWS
  IDENTIFIED BY, IGNORE n {LINES|ROWS} (canonicalized to ROWS), the
  column/user-var list, and SET assignments, reusing the LOAD DATA
  helpers (parser/parse_dml.go)
- The SELECT ... INTO var_list and INTO DUMPFILE forms of
  SelectStmtIntoOption, filling in the SelectIntoVars and
  SelectIntoDumpfile enum values that existed unimplemented. The INTO
  clause also parses between the field list and FROM, restoring in the
  trailing position. Variable targets are user variables or stored
  program variable names; they carry no origin position because
  SelectStmt.Accept does not traverse SelectIntoOpt.

New AST nodes (ast/mysql_dml.go): HandlerOpenStmt, HandlerReadStmt,
HandlerCloseStmt, ImportTableStmt, and LoadXMLStmt, plus their
SEMCommand strings. SelectIntoOption gains a Vars field and its Restore
supports all three forms.

Keyword tables: CONCURRENT, DUMPFILE, PREV, and XML become unreserved
keywords, matching their MySQL 26.7 classification; TestKeywordsLength
counts updated accordingly. testdata/errors.json is unaffected.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FGwevXQRPY7iPxud2UyaJH
…storage objects

Implement the mysql_unsupported_ddl statement coverage group (MySQL 26.7
§15.1): its error goldens turn into Restore() goldens and the group is
renamed to mysql_ddl with expanded coverage, following the mysql_admin
precedent.

Grammar, written from the reference manual since these statements
postdate the goyacc grammar (parser/parse_mysql_ddl.go, with dispatch
from the CREATE/ALTER/DROP statement heads):

- CREATE/ALTER/DROP EVENT with the AT and EVERY ... STARTS/ENDS
  schedules, ON COMPLETION, ENABLE/DISABLE [ON REPLICA], COMMENT,
  RENAME TO, and DO bodies
- CREATE/DROP TRIGGER with BEFORE/AFTER, INSERT/UPDATE/DELETE, FOR EACH
  ROW, and FOLLOWS/PRECEDES
- CREATE FUNCTION for stored functions (parameter list, RETURNS type,
  characteristics, RETURN or compound bodies), ALTER FUNCTION, DROP
  FUNCTION, and ALTER PROCEDURE; RETURN joins ProcedureProcStmt; CREATE
  FUNCTION dispatches between the stored and loadable forms on the
  parameter list
- The DEFINER = user clause on CREATE/ALTER VIEW-family, EVENT, TRIGGER,
  PROCEDURE (new ProcedureInfo.Definer field), and FUNCTION, with the
  statement head peeking past the clause to dispatch
- ALTER VIEW, mirroring CreateViewStmt
- CREATE/ALTER/DROP SERVER with the OPTIONS list
- CREATE/ALTER/DROP [UNDO] TABLESPACE and CREATE/ALTER/DROP LOGFILE
  GROUP with a shared option catalogue (sizes, NODEGROUP, WAIT,
  ENCRYPTION, COMMENT, ENGINE, ENGINE_ATTRIBUTE)
- CREATE/DROP SPATIAL REFERENCE SYSTEM with the NAME/DEFINITION/
  ORGANIZATION/DESCRIPTION attributes; CREATE SPATIAL now dispatches
  between the index and SRS forms
- CREATE/ALTER/DROP LIBRARY and CREATE/ALTER JSON DUALITY VIEW with the
  JSON_DUALITY_OBJECT('key' : value, ...) select-list constructor as a
  new expression atom
- The remaining ALTER INSTANCE forms: ROTATE {INNODB|BINLOG} MASTER KEY,
  RELOAD TLS FOR CHANNEL, RELOAD KEYRING, and ENABLE/DISABLE INNODB
  REDO_LOG (new AlterInstanceStmt fields)
- The USING (expr) spelling of CREATE MASKING POLICY (new Using field)
  and DROP MASKING POLICY

Free-form words of these productions that are not keywords (REFERENCE,
the SRS attribute and server option names, the size option names,
ACTIVE/INACTIVE, KEYRING, REDO_LOG) are matched case-insensitively in
identifier position, following the SIGNAL information-item precedent.

New AST nodes (ast/mysql_ddl.go, plus DropMaskingPolicyStmt in ddl.go):
the statements above with EventSchedule, TriggerOrder,
RoutineCharacteristics, FunctionParam, ServerOption, TablespaceOption,
SRSAttribute, and JSONDualityObjectExpr, plus their SEMCommand strings.
Unlike ProcedureInfo, the new body-carrying nodes traverse their body
statement in Accept. FieldType.Restore (not CompactStr) restores
function parameter and return types so unspecified display widths
round-trip.

Keyword tables: DETERMINISTIC, EACH, MODIFIES, READS, RETURN, and UNDO
become reserved words, AT, COMPLETION, CONTAINS, DATAFILE, DUALITY,
ENDS, EVERY, FOLLOWS, INNODB, LOGFILE, OPTIONS, PRECEDES, ROTATE,
SERVER, STARTS, UNDOFILE, and WRAPPER unreserved, and
JSON_DUALITY_OBJECT a NotKeywordToken, matching their MySQL 26.7
classification; TestKeywordsLength counts updated accordingly and the
lexer test for AT now expects the keyword token. testdata/errors.json is
unaffected.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FGwevXQRPY7iPxud2UyaJH
@kyleconroy
kyleconroy merged commit 8a88a70 into main Aug 18, 2026
1 check passed
kyleconroy pushed a commit that referenced this pull request Aug 21, 2026
With every case now supported, the mysql_unsupported_* names no longer
describe their contents. Following the #39-#41 precedent of renaming an
implemented group, the seven groups whose mysql_* counterpart already
exists (txn, dml, ddl, admin, show, replication, compound) have their
cases appended to it, and the five without one (types, functions,
routines, account, utility) are renamed to mysql_<name>. No case or
golden changes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GBD2pnzaVgeXtHgWwUqxUg
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