Repository navigation
Conversation
FLUSH, KILL and HANDLER failed in every dialect, RESET PERSIST alone reset a parameter named PERSIST and RESET PERSIST name failed. FlushStatement keeps the binlog modifier, the flush options in source order (FlushOption, with the channel of RELAY LOGS) or the FLUSH TABLES form with its tables and WITH READ LOCK or FOR EXPORT. KillStatement keeps CONNECTION or QUERY and the identifier expression. ResetStatement gains isPersist() and isIfExists(), and the variable name may have a component or DEFAULT prefix. HandlerStatement keeps OPEN with the table and its alias, READ with the index, key comparison and values or direction, WHERE and LIMIT, and CLOSE; as in MySQL, a READ takes no subquery. The forms parse with the MySQL dialect and without one; other dialects keep rejecting them. HANDLER becomes a non-reserved keyword, and TablesNamesFinder no longer throws for RESET. The new statements and CHECK, CHECKSUM, OPTIMIZE and REPAIR TABLE now start a statement, so unsupported statement capture no longer takes them. Signed-off-by: minleejae <mmj9808@gmail.com>
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
MySQL administration scripts flush, kill and reset, and some applications read tables through
HANDLER. Onmasterthese statements fail, for example:FLUSH,KILLandHANDLERfail in every dialect.RESET PERSISTalone parses as a reset of a parameter namedPERSIST,RESET PERSIST max_connectionsfails, andTablesNamesFinderthrowsUnsupportedOperationExceptionfor everyRESET.Syntax reference: MySQL 8.4 FLUSH, KILL, RESET PERSIST, HANDLER.
Current design (As-is)
FLUSHandKILLare non-reserved tokens that only Oracle'sALTER SYSTEM FLUSH …andALTER SYSTEM KILL SESSION …use. No statement starts with them.HANDLERis a contextual word of PostgreSQL'sCREATE FOREIGN DATA WRAPPER … [NO] HANDLERandCREATE ACCESS METHOD … HANDLER, and the routine body scanner recognizes MySQL'sDECLARE … HANDLERby it.ResetStatementmodels PostgreSQL'sRESET name,RESET ALLandRESET TIME ZONEas one name string, andTablesNamesFinder.visit(ResetStatement)throws.isStatementStartAhead()lacksCHECK,CHECKSUM,OPTIMIZEandREPAIR, so with unsupported statements enabledCHECK TABLE tbecomes anUnsupportedStatement.NO_WRITE_TO_BINLOG | LOCALisTableMaintenanceStatement.Modifier, whichOPTIMIZE/REPAIR TABLEand the MySQL partition operations share. Each parses it with its own copy of the same alternative.Target design (To-be)
FlushStatement(net.sf.jsqlparser.statement.admin):getModifier()is the sharedTableMaintenanceStatement.Modifier; the newBinlogModifier()production now parses it forFLUSH,OPTIMIZE/REPAIRand the partition operations.getOptions()keeps the flush options in source order. Each is aFlushOptionwithgetKind(), one of MySQL 8.4's options (BINARY_LOGS,ENGINE_LOGS,ERROR_LOGS,GENERAL_LOGS,LOGS,OPTIMIZER_COSTS,PRIVILEGES,RELAY_LOGS,SLOW_LOGS,STATUS,USER_RESOURCES), andgetChannel(), the string literal ofRELAY LOGS FOR CHANNEL 'name'.FLUSH {TABLE | TABLES} [tbl_name [, tbl_name] …] [WITH READ LOCK | FOR EXPORT]:isFlushTables()is derived from the empty option list, withgetTables(),isTablesKeyword()andgetTableLock()(WITH_READ_LOCK,FOR_EXPORT).TABLESform takes no flush option,FOR EXPORTrequires a table list, onlyRELAY LOGSnames a channel and the channel is a string literal.FLUSH HOSTS, which MySQL 8.4 removed, is rejected.KillStatement:getKind()isCONNECTION,QUERYor null when neither keyword is given, andgetProcesslistId()is anExpression: MySQL's grammar takesKILL [CONNECTION | QUERY] expr, soKILL @idandKILL CONNECTION 1 + 2parse. As there,CONNECTIONandQUERYare keywords directly afterKILL(KILL connection + 1kills connection 1), whileKILL CONNECTION_ID()calls the function.RESET PERSIST [[IF EXISTS] system_var_name]extendsResetStatementwithisPersist()andisIfExists().getName()is the variable as written, or null when none is named; as in MySQL'spersisted_variable_identit may carry a component orDEFAULTprefix (RESET PERSIST IF EXISTS validate_password.length,RESET PERSIST DEFAULT.x), while a three-part name is rejected.toString()andResetStatementDeParsershare the newappendTo(). ARESET PERSISTproduction is dispatched before the existingReset(), which is unchanged.HandlerStatement(net.sf.jsqlparser.statement.handler):getAction()isOPEN,READorCLOSE.getTable()is the table thatOPENopens, with the handler name as its alias, or the handler name thatREADandCLOSEtake. MySQL takes an unqualified name there, soHANDLER db1.t CLOSEis rejected.getHandlerName()returns the alias or the table name.READthrough an index hasgetIndexName()and eithergetKeyComparison()(=,<=,>=,<,>) withgetKeyValues(), a parenthesized list that may holdDEFAULTas MySQL's grammar allows, orgetDirection()(FIRST,NEXT,PREV,LAST). Without an index onlyFIRSTandNEXTread in storage order. A word followed by a direction is an index name, as in MySQL (HANDLER h READ first NEXT).getWhere()reusesWhereClause(), andgetLimit()reusesLimitWithOffset();LIMIT n OFFSET mkeeps itsOFFSETingetOffset().HANDLER … READwith subqueries disallowed and reports one as a syntax error, so a subquery in the key values, the condition orLIMITis rejected (HANDLER h READ FIRST WHERE a IN (SELECT b FROM s)).toString()and the deparser shareappendTo(builder, expressionRenderer), so the deparser renders the key values and the condition with itsExpressionDeParser.Dialect.MYSQLand without a dialect; the other dialects, MariaDB included, keep rejecting them. Without a dialect a bareRESET PERSISTkeeps resetting a parameter namedpersist, since PostgreSQL reads it that way; a variable name orIF EXISTSafterPERSISTselects the MySQL form.HANDLERbecomes a non-reserved keyword, likeCHECKSUM(feat: parse MySQL CHECKSUM TABLE and histogram update options #2883), and remains usable as a name. The foreign data wrapper, access method and routine body uses of the word read the new token.isStatementStartAhead()recognizes the new statements, so they end a preceding statement and are not captured as unsupported. It now also recognizesCHECK,CHECKSUM,OPTIMIZEandREPAIR TABLE, which were parsed alone but captured asUnsupportedStatements when unsupported statements were enabled.FLUSHcounts as a start only whenTABLE,TABLESor a flush option word follows, soFLUSH HOSTSor MariaDB'sFLUSH QUERY CACHEremainUnsupportedStatements when unsupported statements are enabled.HANDLERneeds a name and thenOPEN,READorCLOSE.StatementVisitordefaults,StatementVisitorAdapter(visits theKILLexpression and the key values and condition of aREAD),StatementDeParser.TablesNamesFinderreports the tables ofFLUSH TABLESand the table thatHANDLER … OPENopens, not the handler name ofREADandCLOSE, which may be an alias. It finds the tables of a subquery in theKILLexpression, which MySQL rejects only when it runs the statement, and returns no table instead of throwing for everyRESET.flush,kill,handlerandresetPersist, enabled inMySqlVersion. A PostgreSQLRESETkeepsreset.MODIFIES_SESSIONforFLUSH,KILLandHANDLER … OPEN/CLOSE, plusMODIFIES_TRANSACTIONwhenFLUSH TABLESlocks tables;READS_DATAandRETURNS_RESULT_SETforHANDLER … READ.Public signatures are retained. Behavior changes:
TablesNamesFinderno longer throws forRESET, and withDialect.MYSQLa bareRESET PERSISTnow hasisPersist()and a nullgetName()instead of the namePERSIST; its rendering is unchanged.Validation
MySqlFlushStatementTest53,MySqlHandlerStatementTest64,MySqlKillStatementTest26,MySqlServerAdminValidatorTest22, 30 inResetStatementTestand 1 inTableMaintenanceStatementTest;ASTNodeCoverageTestwalks seven of the statements.toString()and the deparser and parsed again, withDialect.MYSQLand without a dialect, plus the AST fields: modifier, option kinds and channel, tables and lock, kill kind and expression,RESET PERSISTname andIF EXISTS, handler action, table, alias and handler name, index, key comparison and values, direction,WHERE,LIMITandOFFSET.FLUSH HOSTS,FLUSH TABLES FOR EXPORT,FLUSH TABLES t WITH READ LOCK, PRIVILEGES,FLUSH RELAY LOGS FOR CHANNEL c1,KILL QUERY,RESET PERSIST IF EXISTS,RESET PERSIST a.b.c,HANDLER t OPEN h AS x,HANDLER db1.t CLOSE,HANDLER h READ PREV,HANDLER h READ i1 <> (1)andHANDLER h READ FIRST WHERE EXISTS (SELECT 1).RESET persistkeeps its PostgreSQL reading without a dialect and with the PostgreSQL and MariaDB dialects. Oracle'sALTER SYSTEM FLUSHandALTER SYSTEM KILL SESSION, PostgreSQL'sCREATE ACCESS METHOD … HANDLERand MySQL'sDECLARE CONTINUE HANDLERin routine bodies are unchanged, andflush,kill,handlerand the option words remain usable as names. MySQL 8.4 reservesKILL, butkillstays accepted as a name, as onmaster.FLUSH HOSTSstays unsupported), node spans, builders, table discovery, validation capabilities and statement features.master(12548b9da) 78 of the 80 statements fail;RESET PERSISTalone parses there as a reset of a parameter namedPERSIST.masterrejects 80. Some fail only when run, for example an unknown handler, table or thread id, a replica channel that does not exist,RESET PERSISTof a variable that is not persisted, orKILL (SELECT MAX(id) FROM t), whose subquery MySQL does not support yet. The server reports a syntax error for the other 67, and the parser rejects 66 of them, including a subquery anywhere in aHANDLER … READ,RESET PERSIST a.b.candFLUSH HOSTS. The exception isSELECT kill, query, connection FROM kill: MySQL 8.4 reservesKILL, but the parser keeps acceptingkillas a name, asmasterdoes. PostgreSQL 18.6 rejectsFLUSH,KILL,HANDLERandRESET PERSIST max_connections, andDialect.POSTGRESQLrejects them too;RESET persistkeeps its PostgreSQL reading.check: 12,993 tests, 0 failures, 25 skipped. Grammar ambiguity, formatting (Spotless ratchet againstupstream/master), Checkstyle, PMD, SpotBugs and JaCoCo pass.master(12548b9da) on a corpus of MySQL 8.4 and PostgreSQL 18 statements other than DDL/DCL, each accepted by the server, with the MySQL or PostgreSQL dialect and without a dialect:Dialect.MYSQLand without a dialect:HANDLER t OPEN AS h,HANDLER h READ FIRST WHERE a > 1 LIMIT 5,HANDLER h CLOSE,RESET PERSIST max_connections,FLUSH TABLES WITH READ LOCK,FLUSH TABLES t FOR EXPORT,FLUSH PRIVILEGES,FLUSH LOCAL BINARY LOGS,KILL QUERY 123andKILL CONNECTION 123. Each renders identically to the source.master(12548b9da) on the DDL/DCL survey corpora of MySQL 8.4 and PostgreSQL 18 statements, plus variants, scripts and the keyword sweeps: 0 regressed, 0 changed.AI assistance: prepared with Claude Code.