From fd70a7c8c8a88085bc868c6974f0bdf067b41bea Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 18 Aug 2026 20:37:17 +0000 Subject: [PATCH] Support the MySQL SHOW statement variants MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement the mysql_unsupported_show statement coverage group (MySQL 26.7 ยง15.7.7): its error goldens turn into Restore() goldens and the group is renamed to mysql_show with expanded coverage, following the mysql_admin precedent. Grammar, written from the reference manual since these statements postdate the goyacc grammar (parser/parse_show.go): - SHOW BINARY LOGS, joining the existing SHOW BINARY LOG STATUS branch - SHOW BINLOG EVENTS and SHOW RELAYLOG EVENTS with the shared [IN 'log'] [FROM pos] [LIMIT [offset,] count] [FOR CHANNEL 'ch'] tail (parseShowLogEventsTail); the LIMIT clause reuses SelectStmtLimit and the existing ShowStmt.Limit field - SHOW REPLICAS - SHOW ENGINE engine_name STATUS | MUTEX; the engine name is an identifier or string literal - SHOW CREATE EVENT/FUNCTION/TRIGGER/LIBRARY (qualified names allowed) and SHOW CREATE MASKING POLICY; FUNCTION uses the Procedure field like SHOW CREATE PROCEDURE, MASKING POLICY stores its name in DBName like SHOW CREATE PLACEMENT POLICY - SHOW FUNCTION CODE and SHOW PROCEDURE CODE, branching off the existing FUNCTION/PROCEDURE STATUS targets - SHOW LIBRARY STATUS with ShowLikeOrWhereOpt - SHOW PARSE_TREE, whose argument MySQL limits to a select statement (reuses finishSelectFamily, including the WITH form) The removed SHOW MASTER LOGS spelling stays unsupported, matching MySQL 8.4+, and SHOW ENGINE ... LOGS stays unsupported; both are recorded as error goldens. AST: fifteen new ShowStmtType values with Restore cases and SEMCommand strings, and new backwards-compatible ShowStmt fields Engine, LogName, Position, ChannelName, and ParseTreeStmt (visited by Accept). Keyword tables: CODE, LIBRARY, MUTEX, PARSE_TREE, and RELAYLOG become unreserved keywords, matching their MySQL 26.7 classification; TestKeywordsLength counts updated accordingly. testdata/errors.json is unaffected. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01BZ64iRBArJZJ4XAtwLM9X6 --- ast/dml.go | 106 +++++++++++++ ast/sem.go | 56 +++++++ parser/keyword_classes.go | 5 + parser/keywords.go | 5 + parser/keywords_test.go | 4 +- parser/misc.go | 5 + parser/parse_show.go | 145 +++++++++++++++++- parser/testdata/parser/mysql_show/input.sql | 79 ++++++++++ parser/testdata/parser/mysql_show/output.sql | 79 ++++++++++ .../parser/mysql_unsupported_show/input.sql | 27 ---- .../parser/mysql_unsupported_show/output.sql | 27 ---- parser/token_kinds.go | 5 + 12 files changed, 484 insertions(+), 59 deletions(-) create mode 100644 parser/testdata/parser/mysql_show/input.sql create mode 100644 parser/testdata/parser/mysql_show/output.sql delete mode 100644 parser/testdata/parser/mysql_unsupported_show/input.sql delete mode 100644 parser/testdata/parser/mysql_unsupported_show/output.sql diff --git a/ast/dml.go b/ast/dml.go index e7c596b..d46a3ca 100644 --- a/ast/dml.go +++ b/ast/dml.go @@ -3174,6 +3174,21 @@ const ( ShowDistributions ShowDistributionJobs ShowAffinity + ShowBinaryLogs + ShowBinlogEvents + ShowRelaylogEvents + ShowReplicas + ShowEngineStatus + ShowEngineMutex + ShowCreateEvent + ShowCreateFunction + ShowCreateTrigger + ShowCreateLibrary + ShowCreateMaskingPolicy + ShowFunctionCode + ShowProcedureCode + ShowLibraryStatus + ShowParseTree // showTpCount is the count of all kinds of `SHOW` statements. showTpCount ) @@ -3230,6 +3245,14 @@ type ShowStmt struct { ImportJobRaw bool // Used for `SHOW RAW IMPORT JOB(S)` syntax DistributionJobID *int64 // Used for `SHOW DISTRIBUTION JOB ` syntax + + Engine string // Used for `SHOW ENGINE STATUS|MUTEX` syntax + + LogName string // Used for `SHOW BINLOG|RELAYLOG EVENTS IN ''` syntax + Position *int64 // Used for `SHOW BINLOG|RELAYLOG EVENTS ... FROM ` syntax + ChannelName string // Used for `SHOW BINLOG|RELAYLOG EVENTS ... FOR CHANNEL ''` syntax + + ParseTreeStmt StmtNode // Used for `SHOW PARSE_TREE ` syntax } // Restore implements Node interface. @@ -3272,6 +3295,57 @@ func (n *ShowStmt) Restore(ctx *format.RestoreCtx) error { switch n.Tp { case ShowBinlogStatus: ctx.WriteKeyWord("BINARY LOG STATUS") + case ShowBinaryLogs: + ctx.WriteKeyWord("BINARY LOGS") + case ShowBinlogEvents, ShowRelaylogEvents: + if n.Tp == ShowBinlogEvents { + ctx.WriteKeyWord("BINLOG EVENTS") + } else { + ctx.WriteKeyWord("RELAYLOG EVENTS") + } + if n.LogName != "" { + ctx.WriteKeyWord(" IN ") + ctx.WriteString(n.LogName) + } + if n.Position != nil { + ctx.WriteKeyWord(" FROM ") + ctx.WritePlainf("%d", *n.Position) + } + if n.Limit != nil { + ctx.WritePlain(" ") + if err := n.Limit.Restore(ctx); err != nil { + return annotate(err, "An error occurred while restore ShowStmt.Limit") + } + } + if n.ChannelName != "" { + ctx.WriteKeyWord(" FOR CHANNEL ") + ctx.WriteString(n.ChannelName) + } + case ShowReplicas: + ctx.WriteKeyWord("REPLICAS") + case ShowEngineStatus: + ctx.WriteKeyWord("ENGINE ") + ctx.WriteName(n.Engine) + ctx.WriteKeyWord(" STATUS") + case ShowEngineMutex: + ctx.WriteKeyWord("ENGINE ") + ctx.WriteName(n.Engine) + ctx.WriteKeyWord(" MUTEX") + case ShowFunctionCode: + ctx.WriteKeyWord("FUNCTION CODE ") + if err := n.Procedure.Restore(ctx); err != nil { + return annotate(err, "An error occurred while restore ShowStmt.Procedure") + } + case ShowProcedureCode: + ctx.WriteKeyWord("PROCEDURE CODE ") + if err := n.Procedure.Restore(ctx); err != nil { + return annotate(err, "An error occurred while restore ShowStmt.Procedure") + } + case ShowParseTree: + ctx.WriteKeyWord("PARSE_TREE ") + if err := n.ParseTreeStmt.Restore(ctx); err != nil { + return annotate(err, "An error occurred while restore ShowStmt.ParseTreeStmt") + } case ShowCreateTable: ctx.WriteKeyWord("CREATE TABLE ") if err := n.Table.Restore(ctx); err != nil { @@ -3309,6 +3383,29 @@ func (n *ShowStmt) Restore(ctx *format.RestoreCtx) error { if err := n.User.Restore(ctx); err != nil { return annotate(err, "An error occurred while restore ShowStmt.User") } + case ShowCreateEvent: + ctx.WriteKeyWord("CREATE EVENT ") + if err := n.Table.Restore(ctx); err != nil { + return annotate(err, "An error occurred while restore ShowStmt.Table") + } + case ShowCreateFunction: + ctx.WriteKeyWord("CREATE FUNCTION ") + if err := n.Procedure.Restore(ctx); err != nil { + return annotate(err, "An error occurred while restore ShowStmt.Procedure") + } + case ShowCreateTrigger: + ctx.WriteKeyWord("CREATE TRIGGER ") + if err := n.Table.Restore(ctx); err != nil { + return annotate(err, "An error occurred while restore ShowStmt.Table") + } + case ShowCreateLibrary: + ctx.WriteKeyWord("CREATE LIBRARY ") + if err := n.Table.Restore(ctx); err != nil { + return annotate(err, "An error occurred while restore ShowStmt.Table") + } + case ShowCreateMaskingPolicy: + ctx.WriteKeyWord("CREATE MASKING POLICY ") + ctx.WriteName(n.DBName) case ShowMaskingPolicies: ctx.WriteKeyWord("MASKING POLICIES FOR ") if err := n.Table.Restore(ctx); err != nil { @@ -3539,6 +3636,8 @@ func (n *ShowStmt) Restore(ctx *format.RestoreCtx) error { ctx.WriteKeyWord("PROCEDURE STATUS") case ShowFunctionStatus: ctx.WriteKeyWord("FUNCTION STATUS") + case ShowLibraryStatus: + ctx.WriteKeyWord("LIBRARY STATUS") case ShowEvents: ctx.WriteKeyWord("EVENTS") restoreShowDatabaseNameOpt() @@ -3651,6 +3750,13 @@ func (n *ShowStmt) Accept(v Visitor) (Node, bool) { } n.Limit = node.(*Limit) } + if n.ParseTreeStmt != nil { + node, ok := n.ParseTreeStmt.Accept(v) + if !ok { + return n, false + } + n.ParseTreeStmt = node.(StmtNode) + } return v.Leave(n) } diff --git a/ast/sem.go b/ast/sem.go index e63589c..c7e8103 100644 --- a/ast/sem.go +++ b/ast/sem.go @@ -256,6 +256,34 @@ const ( ShowDistributionJobsCommand = "SHOW DISTRIBUTION JOB" // ShowAffinityCommand represents SHOW AFFINITY statement ShowAffinityCommand = "SHOW AFFINITY" + // ShowBinaryLogsCommand represents SHOW BINARY LOGS statement + ShowBinaryLogsCommand = "SHOW BINARY LOGS" + // ShowBinlogEventsCommand represents SHOW BINLOG EVENTS statement + ShowBinlogEventsCommand = "SHOW BINLOG EVENTS" + // ShowRelaylogEventsCommand represents SHOW RELAYLOG EVENTS statement + ShowRelaylogEventsCommand = "SHOW RELAYLOG EVENTS" + // ShowReplicasCommand represents SHOW REPLICAS statement + ShowReplicasCommand = "SHOW REPLICAS" + // ShowEngineCommand represents SHOW ENGINE statement + ShowEngineCommand = "SHOW ENGINE" + // ShowCreateEventCommand represents SHOW CREATE EVENT statement + ShowCreateEventCommand = "SHOW CREATE EVENT" + // ShowCreateFunctionCommand represents SHOW CREATE FUNCTION statement + ShowCreateFunctionCommand = "SHOW CREATE FUNCTION" + // ShowCreateTriggerCommand represents SHOW CREATE TRIGGER statement + ShowCreateTriggerCommand = "SHOW CREATE TRIGGER" + // ShowCreateLibraryCommand represents SHOW CREATE LIBRARY statement + ShowCreateLibraryCommand = "SHOW CREATE LIBRARY" + // ShowCreateMaskingPolicyCommand represents SHOW CREATE MASKING POLICY statement + ShowCreateMaskingPolicyCommand = "SHOW CREATE MASKING POLICY" + // ShowFunctionCodeCommand represents SHOW FUNCTION CODE statement + ShowFunctionCodeCommand = "SHOW FUNCTION CODE" + // ShowProcedureCodeCommand represents SHOW PROCEDURE CODE statement + ShowProcedureCodeCommand = "SHOW PROCEDURE CODE" + // ShowLibraryStatusCommand represents SHOW LIBRARY STATUS statement + ShowLibraryStatusCommand = "SHOW LIBRARY STATUS" + // ShowParseTreeCommand represents SHOW PARSE_TREE statement + ShowParseTreeCommand = "SHOW PARSE_TREE" ) // Admin Commands @@ -872,6 +900,34 @@ func (n *ShowStmt) SEMCommand() string { return ShowDistributionJobsCommand case ShowAffinity: return ShowAffinityCommand + case ShowBinaryLogs: + return ShowBinaryLogsCommand + case ShowBinlogEvents: + return ShowBinlogEventsCommand + case ShowRelaylogEvents: + return ShowRelaylogEventsCommand + case ShowReplicas: + return ShowReplicasCommand + case ShowEngineStatus, ShowEngineMutex: + return ShowEngineCommand + case ShowCreateEvent: + return ShowCreateEventCommand + case ShowCreateFunction: + return ShowCreateFunctionCommand + case ShowCreateTrigger: + return ShowCreateTriggerCommand + case ShowCreateLibrary: + return ShowCreateLibraryCommand + case ShowCreateMaskingPolicy: + return ShowCreateMaskingPolicyCommand + case ShowFunctionCode: + return ShowFunctionCodeCommand + case ShowProcedureCode: + return ShowProcedureCodeCommand + case ShowLibraryStatus: + return ShowLibraryStatusCommand + case ShowParseTree: + return ShowParseTreeCommand default: return UnknownCommand } diff --git a/parser/keyword_classes.go b/parser/keyword_classes.go index 3bc6438..d6ffd7b 100644 --- a/parser/keyword_classes.go +++ b/parser/keyword_classes.go @@ -430,6 +430,11 @@ var unReservedKeywordNames = []string{ "UPGRADE", "USE_FRM", "VCPU", + "CODE", + "LIBRARY", + "MUTEX", + "PARSE_TREE", + "RELAYLOG", } // notKeywordTokenNames lists the NotKeywordToken production alternatives of parser.y. diff --git a/parser/keywords.go b/parser/keywords.go index 11f8a60..b07f399 100644 --- a/parser/keywords.go +++ b/parser/keywords.go @@ -325,6 +325,7 @@ var Keywords = []KeywordsType{ {"CLUSTER", false, "unreserved"}, {"CLUSTERED", false, "unreserved"}, {"COALESCE", false, "unreserved"}, + {"CODE", false, "unreserved"}, {"COLLATION", false, "unreserved"}, {"COLUMNAR", false, "unreserved"}, {"COLUMNS", false, "unreserved"}, @@ -447,6 +448,7 @@ var Keywords = []KeywordsType{ {"LEAVES", false, "unreserved"}, {"LESS", false, "unreserved"}, {"LEVEL", false, "unreserved"}, + {"LIBRARY", false, "unreserved"}, {"LIST", false, "unreserved"}, {"LOAD_STATS", false, "unreserved"}, {"LOCAL", false, "unreserved"}, @@ -474,6 +476,7 @@ var Keywords = []KeywordsType{ {"MODE", false, "unreserved"}, {"MODIFY", false, "unreserved"}, {"MONTH", false, "unreserved"}, + {"MUTEX", false, "unreserved"}, {"NAMES", false, "unreserved"}, {"NATIONAL", false, "unreserved"}, {"NCHAR", false, "unreserved"}, @@ -508,6 +511,7 @@ var Keywords = []KeywordsType{ {"PAGE_COMPRESSION_LEVEL", false, "unreserved"}, {"PARALLEL", false, "unreserved"}, {"PARSER", false, "unreserved"}, + {"PARSE_TREE", false, "unreserved"}, {"PARTIAL", false, "unreserved"}, {"PARTITIONING", false, "unreserved"}, {"PARTITIONS", false, "unreserved"}, @@ -543,6 +547,7 @@ var Keywords = []KeywordsType{ {"RECOVER", false, "unreserved"}, {"REDUNDANT", false, "unreserved"}, {"REFRESH", false, "unreserved"}, + {"RELAYLOG", false, "unreserved"}, {"RELOAD", false, "unreserved"}, {"REMOVE", false, "unreserved"}, {"REORGANIZE", false, "unreserved"}, diff --git a/parser/keywords_test.go b/parser/keywords_test.go index 7c4b1ed..4bb3652 100644 --- a/parser/keywords_test.go +++ b/parser/keywords_test.go @@ -43,8 +43,8 @@ func TestKeywords(t *testing.T) { } func TestKeywordsLength(t *testing.T) { - if !reflect.DeepEqual(707, len(parser.Keywords)) { - t.Fatalf("got %v, want %v", len(parser.Keywords), 707) + if !reflect.DeepEqual(712, len(parser.Keywords)) { + t.Fatalf("got %v, want %v", len(parser.Keywords), 712) } reservedNr := 0 diff --git a/parser/misc.go b/parser/misc.go index 421b6c6..de90833 100644 --- a/parser/misc.go +++ b/parser/misc.go @@ -259,6 +259,7 @@ var tokenMap = map[string]int{ "CLUSTERED": clustered, "CMSKETCH": cmSketch, "COALESCE": coalesce, + "CODE": code, "COLLATE": collate, "COLLATION": collation, "COLUMN_FORMAT": columnFormat, @@ -531,6 +532,7 @@ var tokenMap = map[string]int{ "LEFT": left, "LESS": less, "LEVEL": level, + "LIBRARY": library, "LIKE": like, "LIMIT": limit, "LITE": lite, @@ -584,6 +586,7 @@ var tokenMap = map[string]int{ "MODIFY": modify, "MONITOR": monitor, "MONTH": month, + "MUTEX": mutex, "NAMES": names, "NATIONAL": national, "NATURAL": natural, @@ -640,6 +643,7 @@ var tokenMap = map[string]int{ "PAGE_COMPRESSION_LEVEL": pageCompressionLevel, "PARALLEL": parallel, "PARSER": parser, + "PARSE_TREE": parseTree, "PARTIAL": partial, "PARTITION": partition, "PARTITIONING": partitioning, @@ -700,6 +704,7 @@ var tokenMap = map[string]int{ "REGEXP": regexpKwd, "REGION": region, "REGIONS": regions, + "RELAYLOG": relaylog, "RELEASE": release, "RELOAD": reload, "REMOVE": remove, diff --git a/parser/parse_show.go b/parser/parse_show.go index 15668dd..5c91f94 100644 --- a/parser/parse_show.go +++ b/parser/parse_show.go @@ -169,13 +169,72 @@ func (r *rdParser) parseShowStmt() ast.StmtNode { Tp: ast.ShowMasterStatus, } case binaryType: - // "SHOW" "BINARY" "LOG" "STATUS" + // "SHOW" "BINARY" "LOG" "STATUS" | "SHOW" "BINARY" "LOGS" r.advance() + if r.accept(logs) { + return &ast.ShowStmt{ + Tp: ast.ShowBinaryLogs, + } + } r.expect(log) r.expect(status) return &ast.ShowStmt{ Tp: ast.ShowBinlogStatus, } + case binlog: + // "SHOW" "BINLOG" "EVENTS" ShowLogEventsTail + r.advance() + r.expect(events) + return r.parseShowLogEventsTail(ast.ShowBinlogEvents) + case relaylog: + // "SHOW" "RELAYLOG" "EVENTS" ShowLogEventsTail + r.advance() + r.expect(events) + return r.parseShowLogEventsTail(ast.ShowRelaylogEvents) + case replicas: + // "SHOW" "REPLICAS" + r.advance() + return &ast.ShowStmt{ + Tp: ast.ShowReplicas, + } + case engine: + // "SHOW" "ENGINE" (Identifier | stringLit) ("STATUS" | "MUTEX"); + // the statement postdates the goyacc grammar, so the shape follows + // the MySQL 26.7 reference manual. + r.advance() + stmt := &ast.ShowStmt{} + if r.tok() == stringLit { + stmt.Engine = r.cur().lit + r.advance() + } else { + stmt.Engine = r.parseIdentifier() + } + switch r.tok() { + case status: + r.advance() + stmt.Tp = ast.ShowEngineStatus + case mutex: + r.advance() + stmt.Tp = ast.ShowEngineMutex + default: + r.syntaxError() + } + return stmt + case parseTree: + // "SHOW" "PARSE_TREE" select statement; the statement postdates + // the goyacc grammar, and MySQL 26.7 limits its argument to a + // select statement. + r.advance() + stmt := &ast.ShowStmt{Tp: ast.ShowParseTree} + switch r.tok() { + case selectKwd, tableKwd, values, int('('): + stmt.ParseTreeStmt = r.finishSelectFamily(nil) + case with: + stmt.ParseTreeStmt = r.finishSelectFamily(r.parseWithClause()) + default: + r.syntaxError() + } + return stmt case replica, slave: // "SHOW" Replica "STATUS" r.advance() @@ -391,11 +450,72 @@ func (r *rdParser) parseShowCreate() ast.StmtNode { Tp: ast.ShowCreateProcedure, Procedure: r.parseTableName(), } + case function: + // "SHOW" "CREATE" "FUNCTION" TableName + r.advance() + return &ast.ShowStmt{ + Tp: ast.ShowCreateFunction, + Procedure: r.parseTableName(), + } + case event: + // "SHOW" "CREATE" "EVENT" TableName + r.advance() + return &ast.ShowStmt{ + Tp: ast.ShowCreateEvent, + Table: r.parseTableName(), + } + case trigger: + // "SHOW" "CREATE" "TRIGGER" TableName + r.advance() + return &ast.ShowStmt{ + Tp: ast.ShowCreateTrigger, + Table: r.parseTableName(), + } + case library: + // "SHOW" "CREATE" "LIBRARY" TableName + r.advance() + return &ast.ShowStmt{ + Tp: ast.ShowCreateLibrary, + Table: r.parseTableName(), + } + case masking: + // "SHOW" "CREATE" "MASKING" "POLICY" PolicyName + r.advance() + r.expect(policy) + return &ast.ShowStmt{ + Tp: ast.ShowCreateMaskingPolicy, + DBName: r.parseIdentifier(), + } } r.syntaxError() return nil } +// parseShowLogEventsTail implements the shared tail of "SHOW" "BINLOG" +// "EVENTS" and "SHOW" "RELAYLOG" "EVENTS"; the statements postdate the +// goyacc grammar, so the shape follows the MySQL 26.7 reference manual: +// +// ["IN" stringLit] ["FROM" Int64Num] [SelectStmtLimit] +// ["FOR" "CHANNEL" stringLit] +func (r *rdParser) parseShowLogEventsTail(tp ast.ShowStmtType) ast.StmtNode { + stmt := &ast.ShowStmt{Tp: tp} + if r.accept(in) { + stmt.LogName = r.expect(stringLit).lit + } + if r.accept(from) { + v := r.parseInt64Num() + stmt.Position = &v + } + if r.tok() == limit { + stmt.Limit = r.parseSelectStmtLimit() + } + if r.accept(forKwd) { + r.expect(channel) + stmt.ChannelName = r.expect(stringLit).lit + } + return stmt +} + // parseShowTable distinguishes the "SHOW" "TABLE" TableName ... targets // from ShowTargetFilterable's "TABLE" "STATUS" (where STATUS could also // be a table name; the target forms are tried first and rewound like the @@ -712,19 +832,38 @@ func (r *rdParser) parseShowTargetFilterable() ast.StmtNode { Tp: ast.ShowBindingCacheStatus, }) case procedure: - // "PROCEDURE" "STATUS" + // "PROCEDURE" "STATUS" | "PROCEDURE" "CODE" TableName r.advance() + if r.accept(code) { + return &ast.ShowStmt{ + Tp: ast.ShowProcedureCode, + Procedure: r.parseTableName(), + } + } r.expect(status) return r.applyShowLikeOrWhereOpt(&ast.ShowStmt{ Tp: ast.ShowProcedureStatus, }) case function: - // "FUNCTION" "STATUS" + // "FUNCTION" "STATUS" | "FUNCTION" "CODE" TableName r.advance() + if r.accept(code) { + return &ast.ShowStmt{ + Tp: ast.ShowFunctionCode, + Procedure: r.parseTableName(), + } + } r.expect(status) return r.applyShowLikeOrWhereOpt(&ast.ShowStmt{ Tp: ast.ShowFunctionStatus, }) + case library: + // "LIBRARY" "STATUS" + r.advance() + r.expect(status) + return r.applyShowLikeOrWhereOpt(&ast.ShowStmt{ + Tp: ast.ShowLibraryStatus, + }) case events: // "EVENTS" ShowDatabaseNameOpt r.advance() diff --git a/parser/testdata/parser/mysql_show/input.sql b/parser/testdata/parser/mysql_show/input.sql new file mode 100644 index 0000000..a0363f2 --- /dev/null +++ b/parser/testdata/parser/mysql_show/input.sql @@ -0,0 +1,79 @@ +SHOW BINARY LOGS +-- case +SHOW BINLOG EVENTS +-- case +SHOW BINLOG EVENTS IN 'binlog.000001' +-- case +SHOW BINLOG EVENTS IN 'binlog.000001' FROM 4 +-- case +SHOW BINLOG EVENTS IN 'binlog.000001' FROM 4 LIMIT 10 +-- case +SHOW BINLOG EVENTS IN 'binlog.000001' FROM 4 LIMIT 2, 10 +-- case +SHOW BINLOG EVENTS LIMIT 5 +-- case +SHOW BINLOG EVENTS FOR CHANNEL 'source_1' +-- case +SHOW BINLOG EVENTS IN 'binlog.000001' FROM 4 LIMIT 2, 10 FOR CHANNEL 'source_1' +-- case +SHOW RELAYLOG EVENTS +-- case +SHOW RELAYLOG EVENTS IN 'relay-bin.000002' +-- case +SHOW RELAYLOG EVENTS IN 'relay-bin.000002' FROM 4 LIMIT 1, 3 FOR CHANNEL 'group_replication_recovery' +-- case +SHOW REPLICAS +-- case +SHOW ENGINE INNODB STATUS +-- case +SHOW ENGINE INNODB MUTEX +-- case +SHOW ENGINE PERFORMANCE_SCHEMA STATUS +-- case +SHOW ENGINE 'InnoDB' STATUS +-- case +SHOW ENGINE INNODB LOGS +-- case +SHOW CREATE EVENT e +-- case +SHOW CREATE EVENT test.e +-- case +SHOW CREATE FUNCTION f +-- case +SHOW CREATE FUNCTION test.f +-- case +SHOW CREATE LIBRARY mylib +-- case +SHOW CREATE LIBRARY test.mylib +-- case +SHOW CREATE MASKING POLICY p +-- case +SHOW CREATE TRIGGER trg +-- case +SHOW CREATE TRIGGER test.trg +-- case +SHOW FUNCTION CODE f +-- case +SHOW FUNCTION CODE test.f +-- case +SHOW PROCEDURE CODE p +-- case +SHOW PROCEDURE CODE test.p +-- case +SHOW LIBRARY STATUS +-- case +SHOW LIBRARY STATUS LIKE 'lib%' +-- case +SHOW LIBRARY STATUS WHERE Db = 'test' +-- case +SHOW PARSE_TREE SELECT 1 +-- case +SHOW PARSE_TREE SELECT * FROM t WHERE a > 1 +-- case +SHOW PARSE_TREE (SELECT 1) +-- case +SHOW PARSE_TREE WITH cte AS (SELECT 1) SELECT * FROM cte +-- case +SHOW PARSE_TREE UPDATE t SET a = 1 +-- case +SHOW MASTER LOGS diff --git a/parser/testdata/parser/mysql_show/output.sql b/parser/testdata/parser/mysql_show/output.sql new file mode 100644 index 0000000..5b09963 --- /dev/null +++ b/parser/testdata/parser/mysql_show/output.sql @@ -0,0 +1,79 @@ +SHOW BINARY LOGS +-- case +SHOW BINLOG EVENTS +-- case +SHOW BINLOG EVENTS IN 'binlog.000001' +-- case +SHOW BINLOG EVENTS IN 'binlog.000001' FROM 4 +-- case +SHOW BINLOG EVENTS IN 'binlog.000001' FROM 4 LIMIT 10 +-- case +SHOW BINLOG EVENTS IN 'binlog.000001' FROM 4 LIMIT 2,10 +-- case +SHOW BINLOG EVENTS LIMIT 5 +-- case +SHOW BINLOG EVENTS FOR CHANNEL 'source_1' +-- case +SHOW BINLOG EVENTS IN 'binlog.000001' FROM 4 LIMIT 2,10 FOR CHANNEL 'source_1' +-- case +SHOW RELAYLOG EVENTS +-- case +SHOW RELAYLOG EVENTS IN 'relay-bin.000002' +-- case +SHOW RELAYLOG EVENTS IN 'relay-bin.000002' FROM 4 LIMIT 1,3 FOR CHANNEL 'group_replication_recovery' +-- case +SHOW REPLICAS +-- case +SHOW ENGINE `INNODB` STATUS +-- case +SHOW ENGINE `INNODB` MUTEX +-- case +SHOW ENGINE `PERFORMANCE_SCHEMA` STATUS +-- case +SHOW ENGINE `InnoDB` STATUS +-- case +-- error: line 1 column 23 near "LOGS" +-- case +SHOW CREATE EVENT `e` +-- case +SHOW CREATE EVENT `test`.`e` +-- case +SHOW CREATE FUNCTION `f` +-- case +SHOW CREATE FUNCTION `test`.`f` +-- case +SHOW CREATE LIBRARY `mylib` +-- case +SHOW CREATE LIBRARY `test`.`mylib` +-- case +SHOW CREATE MASKING POLICY `p` +-- case +SHOW CREATE TRIGGER `trg` +-- case +SHOW CREATE TRIGGER `test`.`trg` +-- case +SHOW FUNCTION CODE `f` +-- case +SHOW FUNCTION CODE `test`.`f` +-- case +SHOW PROCEDURE CODE `p` +-- case +SHOW PROCEDURE CODE `test`.`p` +-- case +SHOW LIBRARY STATUS +-- case +SHOW LIBRARY STATUS LIKE _UTF8MB4'lib%' +-- case +SHOW LIBRARY STATUS WHERE `Db`=_UTF8MB4'test' +-- case +SHOW PARSE_TREE SELECT 1 +-- case +SHOW PARSE_TREE SELECT * FROM `t` WHERE `a`>1 +-- case +SHOW PARSE_TREE (SELECT 1) +-- case +SHOW PARSE_TREE WITH `cte` AS (SELECT 1) SELECT * FROM `cte` +-- case +-- error: line 1 column 22 near "UPDATE t SET a = 1" +-- case +-- error: line 1 column 16 near "LOGS" diff --git a/parser/testdata/parser/mysql_unsupported_show/input.sql b/parser/testdata/parser/mysql_unsupported_show/input.sql deleted file mode 100644 index 8af11f6..0000000 --- a/parser/testdata/parser/mysql_unsupported_show/input.sql +++ /dev/null @@ -1,27 +0,0 @@ -SHOW BINARY LOGS --- case -SHOW BINLOG EVENTS IN 'binlog.000001' --- case -SHOW CREATE EVENT e --- case -SHOW CREATE FUNCTION f --- case -SHOW CREATE LIBRARY mylib --- case -SHOW CREATE MASKING POLICY p --- case -SHOW CREATE TRIGGER trg --- case -SHOW ENGINE INNODB STATUS --- case -SHOW FUNCTION CODE f --- case -SHOW LIBRARY STATUS --- case -SHOW PARSE_TREE SELECT 1 --- case -SHOW PROCEDURE CODE p --- case -SHOW RELAYLOG EVENTS --- case -SHOW REPLICAS diff --git a/parser/testdata/parser/mysql_unsupported_show/output.sql b/parser/testdata/parser/mysql_unsupported_show/output.sql deleted file mode 100644 index 2fc047f..0000000 --- a/parser/testdata/parser/mysql_unsupported_show/output.sql +++ /dev/null @@ -1,27 +0,0 @@ --- error: line 1 column 16 near "LOGS" --- case --- error: line 1 column 11 near "BINLOG EVENTS IN 'binlog.000001'" --- case --- error: line 1 column 17 near "EVENT e" --- case --- error: line 1 column 20 near "FUNCTION f" --- case --- error: line 1 column 19 near "LIBRARY mylib" --- case --- error: line 1 column 19 near "MASKING POLICY p" --- case --- error: line 1 column 19 near "TRIGGER trg" --- case --- error: line 1 column 11 near "ENGINE INNODB STATUS" --- case --- error: line 1 column 18 near "CODE f" --- case --- error: line 1 column 12 near "LIBRARY STATUS" --- case --- error: line 1 column 15 near "PARSE_TREE SELECT 1" --- case --- error: line 1 column 19 near "CODE p" --- case --- error: line 1 column 13 near "RELAYLOG EVENTS" --- case --- error: line 1 column 13 near "REPLICAS" diff --git a/parser/token_kinds.go b/parser/token_kinds.go index 0579d4a..a4bad8a 100644 --- a/parser/token_kinds.go +++ b/parser/token_kinds.go @@ -185,6 +185,7 @@ const ( clustered = 57650 cmSketch = 58158 coalesce = 57651 + code = 58275 collate = 57384 collation = 57652 column = 57385 @@ -475,6 +476,7 @@ const ( left = 57476 less = 57767 level = 57768 + library = 58276 like = 57477 limit = 57478 linear = 57479 @@ -553,6 +555,7 @@ const ( modify = 57793 monitor = 57794 month = 57795 + mutex = 58277 names = 57796 national = 57797 natural = 57498 @@ -622,6 +625,7 @@ const ( parallel = 58250 paramMarker = 58217 parser = 57828 + parseTree = 58278 partial = 57829 partition = 57516 partitioning = 57830 @@ -688,6 +692,7 @@ const ( regexpKwd = 57527 region = 58179 regions = 58180 + relaylog = 58279 release = 57528 reload = 57863 remove = 57864