// Auto-generated by Perses AST.
// DO NOT MODIFY.
parser grammar MySqlParser;

options {
    tokenVocab=MySqlLexer;
}


root
    : sqlStatements? (MINUS MINUS)? EOF
    ;

sqlStatements
    : (sqlStatement (MINUS MINUS)? SEMI? | emptyStatement_)* (sqlStatement ((MINUS MINUS)? SEMI)? | emptyStatement_)
    ;

sqlStatement
    : ddlStatement
    | dmlStatement
    | transactionStatement
    | replicationStatement
    | preparedStatement
    | administrationStatement
    | utilityStatement
    ;

emptyStatement_
    : SEMI
    ;

ddlStatement
    : createDatabase
    | createEvent
    | createIndex
    | createLogfileGroup
    | createProcedure
    | createFunction
    | createServer
    | createTable
    | createTablespaceInnodb
    | createTablespaceNdb
    | createTrigger
    | createView
    | createRole
    | alterDatabase
    | alterEvent
    | alterFunction
    | alterInstance
    | alterLogfileGroup
    | alterProcedure
    | alterServer
    | alterTable
    | alterTablespace
    | alterView
    | dropDatabase
    | dropEvent
    | dropIndex
    | dropLogfileGroup
    | dropProcedure
    | dropFunction
    | dropServer
    | dropTable
    | dropTablespace
    | dropTrigger
    | dropView
    | dropRole
    | setRole
    | renameTable
    | truncateTable
    ;

dmlStatement
    : selectStatement
    | insertStatement
    | updateStatement
    | deleteStatement
    | replaceStatement
    | callStatement
    | loadDataStatement
    | loadXmlStatement
    | doStatement
    | handlerStatement
    | valuesStatement
    | withStatement
    | tableStatement
    ;

transactionStatement
    : startTransaction
    | beginWork
    | commitWork
    | rollbackWork
    | savepointStatement
    | rollbackStatement
    | releaseStatement
    | lockTables
    | unlockTables
    ;

replicationStatement
    : changeMaster
    | changeReplicationFilter
    | purgeBinaryLogs
    | resetMaster
    | resetSlave
    | startSlave
    | stopSlave
    | startGroupReplication
    | stopGroupReplication
    | xaStartTransaction
    | xaEndTransaction
    | xaPrepareStatement
    | xaCommitWork
    | xaRollbackWork
    | xaRecoverWork
    ;

preparedStatement
    : prepareStatement
    | executeStatement
    | deallocatePrepare
    ;

administrationStatement
    : alterUser
    | createUser
    | dropUser
    | grantStatement
    | grantProxy
    | renameUser
    | revokeStatement
    | revokeProxy
    | analyzeTable
    | checkTable
    | checksumTable
    | optimizeTable
    | repairTable
    | createUdfunction
    | installPlugin
    | uninstallPlugin
    | setStatement
    | showStatement
    | binlogStatement
    | cacheIndexStatement
    | flushStatement
    | killStatement
    | loadIndexIntoCache
    | resetStatement
    | shutdownStatement
    ;

utilityStatement
    : simpleDescribeStatement
    | fullDescribeStatement
    | helpStatement
    | useStatement
    | signalStatement
    | resignalStatement
    | diagnosticsStatement
    ;

createDatabase
    : CREATE (DATABASE | SCHEMA) ifNotExists? uid createDatabaseOption*
    ;

createEvent
    : CREATE ownerStatement? EVENT ifNotExists? fullId ON SCHEDULE scheduleExpression (ON COMPLETION NOT? PRESERVE)? enableType? (COMMENT STRING_LITERAL)? DO routineBody
    ;

createIndex
    : CREATE (ONLINE | OFFLINE)? (UNIQUE | FULLTEXT | SPATIAL)? INDEX uid indexType? ON tableName indexColumnNames indexOption* (ALGORITHM EQUAL_SYMBOL? (DEFAULT | INPLACE | COPY) | LOCK EQUAL_SYMBOL? (DEFAULT | NONE | SHARED | EXCLUSIVE))*
    ;

createLogfileGroup
    : CREATE LOGFILE GROUP uid ADD UNDOFILE STRING_LITERAL (INITIAL_SIZE '='? fileSizeLiteral)? (UNDO_BUFFER_SIZE '='? fileSizeLiteral)? (REDO_BUFFER_SIZE '='? fileSizeLiteral)? (NODEGROUP '='? uid)? WAIT? (COMMENT '='? STRING_LITERAL)? ENGINE '='? engineName
    ;

createProcedure
    : CREATE ownerStatement? PROCEDURE fullId '(' procedureParameter? (',' procedureParameter)* ')' routineOption* routineBody
    ;

createFunction
    : CREATE ownerStatement? AGGREGATE? FUNCTION ifNotExists? fullId '(' functionParameter? (',' functionParameter)* ')' RETURNS dataType routineOption* (routineBody | returnStatement)
    ;

createServer
    : CREATE SERVER uid FOREIGN DATA WRAPPER (MYSQL | STRING_LITERAL) OPTIONS '(' serverOption (',' serverOption)* ')'
    ;

createTable
    : CREATE TEMPORARY? TABLE ifNotExists? tableName (LIKE tableName | '(' LIKE tableName ')')
    | CREATE TEMPORARY? TABLE ifNotExists? tableName createDefinitions? (tableOption (','? tableOption)*)? partitionDefinitions? (IGNORE | REPLACE)? AS? selectStatement
    | CREATE TEMPORARY? TABLE ifNotExists? tableName createDefinitions (tableOption (','? tableOption)*)? partitionDefinitions?
    ;

createTablespaceInnodb
    : CREATE TABLESPACE uid ADD DATAFILE STRING_LITERAL (FILE_BLOCK_SIZE '=' fileSizeLiteral)? (ENGINE '='? engineName)?
    ;

createTablespaceNdb
    : CREATE TABLESPACE uid ADD DATAFILE STRING_LITERAL USE LOGFILE GROUP uid (EXTENT_SIZE '='? fileSizeLiteral)? (INITIAL_SIZE '='? fileSizeLiteral)? (AUTOEXTEND_SIZE '='? fileSizeLiteral)? (MAX_SIZE '='? fileSizeLiteral)? (NODEGROUP '='? uid)? WAIT? (COMMENT '='? STRING_LITERAL)? ENGINE '='? engineName
    ;

createTrigger
    : CREATE ownerStatement? TRIGGER fullId (BEFORE | AFTER) (INSERT | UPDATE | DELETE) ON tableName FOR EACH ROW ((FOLLOWS | PRECEDES) fullId)? routineBody
    ;

createView
    : CREATE orReplace? (ALGORITHM '=' (UNDEFINED | MERGE | TEMPTABLE))? ownerStatement? (SQL SECURITY (DEFINER | INVOKER))? VIEW fullId ('(' uidList ')')? AS ('(' withClause? selectStatement ')' | withClause? selectStatement (WITH (CASCADED | LOCAL)? CHECK OPTION)?)
    ;

createRole
    : CREATE ROLE ifNotExists? roleName (',' roleName)*
    ;

alterDatabase
    : ALTER (DATABASE | SCHEMA) uid? createDatabaseOption+
    | ALTER (DATABASE | SCHEMA) uid UPGRADE DATA DIRECTORY NAME
    ;

alterEvent
    : ALTER ownerStatement? EVENT fullId (ON SCHEDULE scheduleExpression)? (ON COMPLETION NOT? PRESERVE)? (RENAME TO fullId)? enableType? (COMMENT STRING_LITERAL)? (DO routineBody)?
    ;

alterFunction
    : ALTER FUNCTION fullId routineOption*
    ;

alterInstance
    : ALTER INSTANCE ROTATE INNODB MASTER KEY
    ;

alterLogfileGroup
    : ALTER LOGFILE GROUP uid ADD UNDOFILE STRING_LITERAL (INITIAL_SIZE '='? fileSizeLiteral)? WAIT? ENGINE '='? engineName
    ;

alterProcedure
    : ALTER PROCEDURE fullId routineOption*
    ;

alterServer
    : ALTER SERVER uid OPTIONS '(' serverOption (',' serverOption)* ')'
    ;

alterTable
    : ALTER (ONLINE | OFFLINE)? IGNORE? TABLE tableName waitNowaitClause? (alterSpecification (',' alterSpecification)*)? partitionDefinitions?
    ;

alterTablespace
    : ALTER TABLESPACE uid (ADD | DROP) DATAFILE STRING_LITERAL (INITIAL_SIZE '=' fileSizeLiteral)? WAIT? ENGINE '='? engineName
    ;

alterView
    : ALTER (ALGORITHM '=' (UNDEFINED | MERGE | TEMPTABLE))? ownerStatement? (SQL SECURITY (DEFINER | INVOKER))? VIEW fullId ('(' uidList ')')? AS selectStatement (WITH (CASCADED | LOCAL)? CHECK OPTION)?
    ;

dropDatabase
    : DROP (DATABASE | SCHEMA) ifExists? uid
    ;

dropEvent
    : DROP EVENT ifExists? fullId
    ;

dropIndex
    : DROP INDEX (ONLINE | OFFLINE)? uid ON tableName (ALGORITHM '='? (DEFAULT | INPLACE | COPY) | LOCK '='? (DEFAULT | NONE | SHARED | EXCLUSIVE))*
    ;

dropLogfileGroup
    : DROP LOGFILE GROUP uid ENGINE '=' engineName
    ;

dropProcedure
    : DROP PROCEDURE ifExists? fullId
    ;

dropFunction
    : DROP FUNCTION ifExists? fullId
    ;

dropServer
    : DROP SERVER ifExists? uid
    ;

dropTable
    : DROP TEMPORARY? TABLE ifExists? tables (RESTRICT | CASCADE)?
    ;

dropTablespace
    : DROP TABLESPACE uid (ENGINE '='? engineName)?
    ;

dropTrigger
    : DROP TRIGGER ifExists? fullId
    ;

dropView
    : DROP VIEW ifExists? fullId (',' fullId)* (RESTRICT | CASCADE)?
    ;

dropRole
    : DROP ROLE ifExists? roleName (',' roleName)*
    ;

setRole
    : SET DEFAULT ROLE (NONE | ALL | roleName (',' roleName)*) TO (userName | uid) (',' (userName | uid))*
    | SET ROLE roleOption
    ;

renameTable
    : RENAME TABLE renameTableClause (',' renameTableClause)*
    ;

truncateTable
    : TRUNCATE TABLE? tableName
    ;

selectStatement
    : querySpecification lockClause?
    | queryExpression lockClause?
    | querySpecificationNointo unionStatement+ (UNION (ALL | DISTINCT)? (querySpecification | queryExpression))? orderByClause? limitClause? lockClause?
    | queryExpressionNointo unionParenthesis+ (UNION (ALL | DISTINCT)? queryExpression)? orderByClause? limitClause? lockClause?
    | querySpecificationNointo (',' lateralStatement)+
    ;

insertStatement
    : INSERT (LOW_PRIORITY | DELAYED | HIGH_PRIORITY)? IGNORE? INTO? tableName (PARTITION '(' uidList? ')')? (('(' fullColumnNameList ')')? insertStatementValue (AS? uid)? | SET updatedElement (',' updatedElement)*) (ON DUPLICATE KEY UPDATE updatedElement (',' updatedElement)*)?
    ;

updateStatement
    : singleUpdateStatement
    | multipleUpdateStatement
    ;

deleteStatement
    : singleDeleteStatement
    | multipleDeleteStatement
    ;

replaceStatement
    : REPLACE (LOW_PRIORITY | DELAYED)? INTO? tableName (PARTITION '(' uidList ')')? (('(' uidList ')')? insertStatementValue | SET updatedElement (',' updatedElement)*)
    ;

callStatement
    : CALL fullId ('(' (constants | expressions)? ')')?
    ;

loadDataStatement
    : LOAD DATA (LOW_PRIORITY | CONCURRENT)? LOCAL? INFILE STRING_LITERAL (REPLACE | IGNORE)? INTO TABLE tableName (PARTITION '(' uidList ')')? (CHARACTER SET charsetName)? ((FIELDS | COLUMNS) selectFieldsInto+)? (LINES selectLinesInto+)? (IGNORE decimalLiteral (LINES | ROWS))? ('(' assignmentField (',' assignmentField)* ')')? (SET updatedElement (',' updatedElement)*)?
    ;

loadXmlStatement
    : LOAD XML (LOW_PRIORITY | CONCURRENT)? LOCAL? INFILE STRING_LITERAL (REPLACE | IGNORE)? INTO TABLE tableName (CHARACTER SET charsetName)? (ROWS IDENTIFIED BY '<' STRING_LITERAL '>')? (IGNORE decimalLiteral (LINES | ROWS))? ('(' assignmentField (',' assignmentField)* ')')? (SET updatedElement (',' updatedElement)*)?
    ;

doStatement
    : DO expressions
    ;

handlerStatement
    : handlerOpenStatement
    | handlerReadIndexStatement
    | handlerReadStatement
    | handlerCloseStatement
    ;

valuesStatement
    : VALUES '(' expressionsWithDefaults? ')' (',' '(' expressionsWithDefaults? ')')*
    ;

withStatement
    : WITH RECURSIVE? commonTableExpressions (',' commonTableExpressions)*
    ;

tableStatement
    : TABLE tableName orderByClause? limitClause?
    ;

startTransaction
    : START TRANSACTION (transactionMode (',' transactionMode)*)?
    ;

beginWork
    : BEGIN WORK?
    ;

commitWork
    : COMMIT WORK? (AND NO? CHAIN)? (NO? RELEASE)?
    ;

rollbackWork
    : ROLLBACK WORK? (AND NO? CHAIN)? (NO? RELEASE)?
    ;

savepointStatement
    : SAVEPOINT uid
    ;

rollbackStatement
    : ROLLBACK WORK? TO SAVEPOINT? uid
    ;

releaseStatement
    : RELEASE SAVEPOINT uid
    ;

lockTables
    : LOCK (TABLE | TABLES) lockTableElement (',' lockTableElement)* waitNowaitClause?
    ;

unlockTables
    : UNLOCK TABLES
    ;

changeMaster
    : CHANGE MASTER TO masterOption (',' masterOption)* channelOption?
    ;

changeReplicationFilter
    : CHANGE REPLICATION FILTER replicationFilter (',' replicationFilter)*
    ;

purgeBinaryLogs
    : PURGE (BINARY | MASTER) LOGS (TO STRING_LITERAL | BEFORE STRING_LITERAL)
    ;

resetMaster
    : RESET MASTER
    ;

resetSlave
    : RESET SLAVE ALL? channelOption?
    ;

startSlave
    : START SLAVE (threadType (',' threadType)*)? (UNTIL untilOption)? connectionOption* channelOption?
    ;

stopSlave
    : STOP SLAVE (threadType (',' threadType)*)?
    ;

startGroupReplication
    : START GROUP_REPLICATION
    ;

stopGroupReplication
    : STOP GROUP_REPLICATION
    ;

xaStartTransaction
    : XA (START | BEGIN) xid (JOIN | RESUME)?
    ;

xaEndTransaction
    : XA END xid (SUSPEND (FOR MIGRATE)?)?
    ;

xaPrepareStatement
    : XA PREPARE xid
    ;

xaCommitWork
    : XA COMMIT xid (ONE PHASE)?
    ;

xaRollbackWork
    : XA ROLLBACK xid
    ;

xaRecoverWork
    : XA RECOVER (CONVERT xid)?
    ;

prepareStatement
    : PREPARE uid FROM (STRING_LITERAL | LOCAL_ID)
    ;

executeStatement
    : EXECUTE uid (USING userVariables)?
    ;

deallocatePrepare
    : (DEALLOCATE | DROP) PREPARE uid
    ;

compoundStatement
    : blockStatement
    | caseStatement
    | ifStatement
    | leaveStatement
    | loopStatement
    | repeatStatement
    | whileStatement
    | iterateStatement
    | returnStatement
    | cursorStatement
    ;

blockStatement
    : (uid ':')? BEGIN (declareVariable SEMI)* (declareCondition SEMI)* (declareCursor SEMI)* (declareHandler SEMI)* procedureSqlStatement* END uid?
    ;

caseStatement
    : CASE (uid | expression)? caseAlternative+ (ELSE procedureSqlStatement+)? END CASE
    ;

ifStatement
    : IF expression THEN procedureSqlStatement+ elifAlternative* (ELSE procedureSqlStatement+)? END IF
    ;

leaveStatement
    : LEAVE uid
    ;

loopStatement
    : (uid ':')? LOOP procedureSqlStatement+ END LOOP uid?
    ;

repeatStatement
    : (uid ':')? REPEAT procedureSqlStatement+ UNTIL expression END REPEAT uid?
    ;

whileStatement
    : (uid ':')? WHILE expression DO procedureSqlStatement+ END WHILE uid?
    ;

iterateStatement
    : ITERATE uid
    ;

returnStatement
    : RETURN expression
    ;

cursorStatement
    : CLOSE uid
    | FETCH (NEXT? FROM)? uid INTO uidList
    | OPEN uid
    ;

alterUser
    : ALTER USER userSpecification (',' userSpecification)*
    | ALTER USER ifExists? userAuthOption (',' userAuthOption)* (REQUIRE (NONE | tlsOption (AND? tlsOption)*))? (WITH userResourceOption+)? (userPasswordOption | userLockOption)* (COMMENT STRING_LITERAL | ATTRIBUTE STRING_LITERAL)?
    | ALTER USER ifExists? (userName | uid) DEFAULT ROLE roleOption
    ;

createUser
    : CREATE USER userAuthOption (',' userAuthOption)*
    | CREATE USER ifNotExists? userAuthOption (',' userAuthOption)* (DEFAULT ROLE roleOption)? (REQUIRE (NONE | tlsOption (AND? tlsOption)*))? (WITH userResourceOption+)? (userPasswordOption | userLockOption)* (COMMENT STRING_LITERAL | ATTRIBUTE STRING_LITERAL)?
    ;

dropUser
    : DROP USER ifExists? userName (',' userName)*
    ;

grantStatement
    : GRANT privelegeClause (',' privelegeClause)* ON (TABLE | FUNCTION | PROCEDURE)? privilegeLevel TO userAuthOption (',' userAuthOption)* (REQUIRE (NONE | tlsOption (AND? tlsOption)*))? (WITH (GRANT OPTION | userResourceOption)*)? (AS userName WITH ROLE roleOption)?
    | GRANT (userName | uid) (',' (userName | uid))* TO (userName | uid) (',' (userName | uid))* (WITH ADMIN OPTION)?
    ;

grantProxy
    : GRANT PROXY ON userName TO userName (',' userName)* (WITH GRANT OPTION)?
    ;

renameUser
    : RENAME USER renameUserClause (',' renameUserClause)*
    ;

revokeStatement
    : REVOKE privelegeClause (',' privelegeClause)* ON (TABLE | FUNCTION | PROCEDURE)? privilegeLevel FROM userName (',' userName)*
    | REVOKE ALL PRIVILEGES? ',' GRANT OPTION FROM userName (',' userName)*
    | REVOKE (userName | uid) (',' (userName | uid))* FROM (userName | uid) (',' (userName | uid))*
    ;

revokeProxy
    : REVOKE PROXY ON userName FROM userName (',' userName)*
    ;

analyzeTable
    : ANALYZE (NO_WRITE_TO_BINLOG | LOCAL)? (TABLE | TABLES) tables (UPDATE HISTOGRAM ON fullColumnName (',' fullColumnName)* (WITH decimalLiteral BUCKETS)?)? (DROP HISTOGRAM ON fullColumnName (',' fullColumnName)*)?
    ;

checkTable
    : CHECK TABLE tables checkTableOption*
    ;

checksumTable
    : CHECKSUM TABLE tables (QUICK | EXTENDED)?
    ;

optimizeTable
    : OPTIMIZE (NO_WRITE_TO_BINLOG | LOCAL)? (TABLE | TABLES) tables
    ;

repairTable
    : REPAIR (NO_WRITE_TO_BINLOG | LOCAL)? TABLE tables QUICK? EXTENDED? USE_FRM?
    ;

createUdfunction
    : CREATE AGGREGATE? FUNCTION ifNotExists? uid RETURNS (STRING | INTEGER | REAL | DECIMAL) SONAME STRING_LITERAL
    ;

installPlugin
    : INSTALL PLUGIN uid SONAME STRING_LITERAL
    ;

uninstallPlugin
    : UNINSTALL PLUGIN uid
    ;

setStatement
    : SET variableClause ('=' | ':=') (expression | ON) (',' variableClause ('=' | ':=') (expression | ON))*
    | SET charSet (charsetName | DEFAULT)
    | SET NAMES (charsetName (COLLATE collationName)? | DEFAULT)
    | setPasswordStatement
    | setTransactionStatement
    | setAutocommitStatement
    | SET fullId ('=' | ':=') expression (',' fullId ('=' | ':=') expression)*
    ;

showStatement
    : SHOW (BINARY | MASTER) LOGS
    | SHOW (BINLOG | RELAYLOG) EVENTS (IN STRING_LITERAL)? (FROM decimalLiteral)? (LIMIT (decimalLiteral ',')? decimalLiteral)?
    | SHOW showCommonEntity showFilter?
    | SHOW FULL? (COLUMNS | FIELDS) (FROM | IN) tableName ((FROM | IN) uid)? showFilter?
    | SHOW CREATE (DATABASE | SCHEMA) ifNotExists? uid
    | SHOW CREATE (EVENT | FUNCTION | PROCEDURE | TABLE | TRIGGER | VIEW) fullId
    | SHOW CREATE USER userName
    | SHOW ENGINE engineName (STATUS | MUTEX)
    | SHOW showGlobalInfoClause
    | SHOW (ERRORS | WARNINGS) (LIMIT (decimalLiteral ',')? decimalLiteral)?
    | SHOW COUNT '(' '*' ')' (ERRORS | WARNINGS)
    | SHOW showSchemaEntity ((FROM | IN) uid)? showFilter?
    | SHOW (FUNCTION | PROCEDURE) CODE fullId
    | SHOW GRANTS (FOR userName)?
    | SHOW (INDEX | INDEXES | KEYS) (FROM | IN) tableName ((FROM | IN) uid)? (WHERE expression)?
    | SHOW OPEN TABLES ((FROM | IN) uid)? showFilter?
    | SHOW PROFILE showProfileType (',' showProfileType)* (FOR QUERY decimalLiteral)? LIMIT (decimalLiteral ',')? decimalLiteral
    | SHOW SLAVE STATUS (FOR CHANNEL STRING_LITERAL)?
    ;

binlogStatement
    : BINLOG STRING_LITERAL
    ;

cacheIndexStatement
    : CACHE INDEX tableIndexes (',' tableIndexes)* (PARTITION '(' (uidList | ALL) ')')? IN uid
    ;

flushStatement
    : FLUSH (NO_WRITE_TO_BINLOG | LOCAL)? flushOption (',' flushOption)*
    ;

killStatement
    : KILL (CONNECTION | QUERY)? expression
    ;

loadIndexIntoCache
    : LOAD INDEX INTO CACHE loadedTableIndexes (',' loadedTableIndexes)*
    ;

resetStatement
    : RESET QUERY CACHE
    ;

shutdownStatement
    : SHUTDOWN
    ;

simpleDescribeStatement
    : (EXPLAIN | DESCRIBE | DESC) tableName (uid | STRING_LITERAL)?
    ;

fullDescribeStatement
    : (EXPLAIN | DESCRIBE | DESC) ((EXTENDED | PARTITIONS | FORMAT) '=' (TRADITIONAL | JSON))? describeObjectClause
    ;

helpStatement
    : HELP STRING_LITERAL
    ;

useStatement
    : USE uid
    ;

signalStatement
    : SIGNAL (SQLSTATE VALUE? stringLiteral | ID | REVERSE_QUOTE_ID) (SET signalConditionInformation (',' signalConditionInformation)*)?
    ;

resignalStatement
    : RESIGNAL (SQLSTATE VALUE? stringLiteral | ID | REVERSE_QUOTE_ID)? (SET signalConditionInformation (',' signalConditionInformation)*)?
    ;

diagnosticsStatement
    : GET (CURRENT | STACKED)? DIAGNOSTICS (variableClause '=' (NUMBER | ROW_COUNT) (',' variableClause '=' (NUMBER | ROW_COUNT))* | CONDITION (decimalLiteral | variableClause) variableClause '=' diagnosticsConditionInformationName (',' variableClause '=' diagnosticsConditionInformationName)*)
    ;

ifNotExists
    : IF NOT EXISTS
    ;

uid
    : simpleId
    | CHARSET_REVERSE_QOUTE_STRING
    | STRING_LITERAL
    ;

createDatabaseOption
    : DEFAULT? charSet '='? (charsetName | DEFAULT)
    | DEFAULT? COLLATE '='? collationName
    | DEFAULT? ENCRYPTION '='? STRING_LITERAL
    | READ ONLY '='? (DEFAULT | ZERO_DECIMAL | ONE_DECIMAL)
    ;

ownerStatement
    : DEFINER '=' (userName | currentUserExpression)
    ;

fullId
    : uid (DOT_ID | '.' uid)?
    ;

scheduleExpression
    : AT timestampValue intervalExpr*
    | EVERY (decimalLiteral | expression) intervalType (STARTS timestampValue intervalExpr*)? (ENDS timestampValue intervalExpr*)?
    ;

enableType
    : ENABLE
    | DISABLE
    | DISABLE ON SLAVE
    ;

routineBody
    : blockStatement
    | sqlStatement
    ;

indexType
    : USING (BTREE | HASH)
    ;

tableName
    : fullId
    ;

indexColumnNames
    : '(' indexColumnName (',' indexColumnName)* ')'
    ;

indexOption
    : KEY_BLOCK_SIZE EQUAL_SYMBOL? fileSizeLiteral
    | indexType
    | WITH PARSER uid
    | COMMENT STRING_LITERAL
    | VISIBLE
    | INVISIBLE
    | ENGINE_ATTRIBUTE EQUAL_SYMBOL? STRING_LITERAL
    | SECONDARY_ENGINE_ATTRIBUTE EQUAL_SYMBOL? STRING_LITERAL
    ;

fileSizeLiteral
    : FILESIZE_LITERAL
    | decimalLiteral
    ;

engineName
    : engineNameBase
    | ID
    | STRING_LITERAL
    ;

procedureParameter
    : (IN | OUT | INOUT)? uid dataType
    ;

routineOption
    : COMMENT STRING_LITERAL
    | LANGUAGE SQL
    | NOT? DETERMINISTIC
    | CONTAINS SQL
    | NO SQL
    | READS SQL DATA
    | MODIFIES SQL DATA
    | SQL SECURITY (DEFINER | INVOKER)
    ;

functionParameter
    : uid dataType
    ;

dataType
    : (CHAR | CHARACTER | VARCHAR | TINYTEXT | TEXT | MEDIUMTEXT | LONGTEXT | NCHAR | NVARCHAR | LONG) VARYING? lengthOneDimension? BINARY? (charSet charsetName)? (COLLATE collationName | BINARY)?
    | NATIONAL (CHAR | CHARACTER) VARYING lengthOneDimension? BINARY?
    | NATIONAL (VARCHAR | CHARACTER | CHAR) lengthOneDimension? BINARY?
    | NCHAR VARCHAR lengthOneDimension? BINARY?
    | (TINYINT | SMALLINT | MEDIUMINT | INT | INTEGER | BIGINT | MIDDLEINT | INT1 | INT2 | INT3 | INT4 | INT8) lengthOneDimension? (SIGNED | UNSIGNED | ZEROFILL)*
    | REAL lengthTwoDimension? (SIGNED | UNSIGNED | ZEROFILL)*
    | DOUBLE PRECISION? lengthTwoDimension? (SIGNED | UNSIGNED | ZEROFILL)*
    | (DECIMAL | DEC | FIXED | NUMERIC | FLOAT | FLOAT4 | FLOAT8) lengthTwoOptionalDimension? (SIGNED | UNSIGNED | ZEROFILL)*
    | DATE
    | TINYBLOB
    | MEDIUMBLOB
    | LONGBLOB
    | BOOL
    | BOOLEAN
    | SERIAL
    | (BIT | TIME | TIMESTAMP | DATETIME | BINARY | VARBINARY | BLOB | YEAR) lengthOneDimension?
    | (ENUM | SET) collectionOptions BINARY? (charSet charsetName)?
    | (GEOMETRYCOLLECTION | GEOMCOLLECTION | LINESTRING | MULTILINESTRING | MULTIPOINT | MULTIPOLYGON | POINT | POLYGON | JSON | GEOMETRY) (SRID decimalLiteral)?
    | LONG VARCHAR? BINARY? (charSet charsetName)? (COLLATE collationName)?
    | LONG VARBINARY
    ;

roleName
    : userName
    | uid
    ;

serverOption
    : HOST STRING_LITERAL
    | DATABASE STRING_LITERAL
    | USER STRING_LITERAL
    | PASSWORD STRING_LITERAL
    | SOCKET STRING_LITERAL
    | OWNER STRING_LITERAL
    | PORT decimalLiteral
    ;

createDefinitions
    : '(' createDefinition (',' createDefinition)* ')'
    ;

tableOption
    : ENGINE '='? engineName?
    | ENGINE_ATTRIBUTE '='? STRING_LITERAL
    | AUTOEXTEND_SIZE '='? decimalLiteral
    | AUTO_INCREMENT '='? decimalLiteral
    | AVG_ROW_LENGTH '='? decimalLiteral
    | DEFAULT? charSet '='? (charsetName | DEFAULT)
    | (CHECKSUM | PAGE_CHECKSUM) '='? ('0' | '1')
    | DEFAULT? COLLATE '='? collationName
    | COMMENT '='? STRING_LITERAL
    | COMPRESSION '='? (STRING_LITERAL | ID)
    | CONNECTION '='? STRING_LITERAL
    | (DATA | INDEX) DIRECTORY '='? STRING_LITERAL
    | DELAY_KEY_WRITE '='? ('0' | '1')
    | ENCRYPTION '='? STRING_LITERAL
    | (PAGE_COMPRESSED | STRING_LITERAL) '='? ('0' | '1')
    | (PAGE_COMPRESSION_LEVEL | STRING_LITERAL) '='? decimalLiteral
    | ENCRYPTION_KEY_ID '='? decimalLiteral
    | INDEX DIRECTORY '='? STRING_LITERAL
    | INSERT_METHOD '='? (NO | FIRST | LAST)
    | KEY_BLOCK_SIZE '='? fileSizeLiteral
    | MAX_ROWS '='? decimalLiteral
    | MIN_ROWS '='? decimalLiteral
    | PACK_KEYS '='? ('0' | '1' | DEFAULT)
    | PASSWORD '='? STRING_LITERAL
    | ROW_FORMAT '='? (DEFAULT | DYNAMIC | FIXED | COMPRESSED | REDUNDANT | COMPACT | ID)
    | START TRANSACTION
    | SECONDARY_ENGINE_ATTRIBUTE '='? STRING_LITERAL
    | STATS_AUTO_RECALC '='? (DEFAULT | '0' | '1')
    | STATS_PERSISTENT '='? (DEFAULT | '0' | '1')
    | STATS_SAMPLE_PAGES '='? (DEFAULT | decimalLiteral)
    | TABLESPACE uid tablespaceStorage?
    | TABLE_TYPE '=' tableType
    | tablespaceStorage
    | TRANSACTIONAL '='? ('0' | '1')
    | UNION '='? '(' tables ')'
    ;

partitionDefinitions
    : PARTITION BY partitionFunctionDefinition (PARTITIONS decimalLiteral)? (SUBPARTITION BY subpartitionFunctionDefinition (SUBPARTITIONS decimalLiteral)?)? ('(' partitionDefinition (',' partitionDefinition)* ')')?
    ;

withClause
    : WITH RECURSIVE? commonTableExpressions
    ;

commonTableExpressions
    : cteName ('(' cteColumnName (',' cteColumnName)* ')')? AS '(' dmlStatement ')' (',' commonTableExpressions)?
    ;

cteName
    : uid
    ;

cteColumnName
    : uid
    ;

orReplace
    : OR REPLACE
    ;

uidList
    : uid (',' uid)*
    ;

charSet
    : CHARACTER SET
    | CHARSET
    | CHAR SET
    ;

charsetName
    : BINARY
    | charsetNameBase
    | STRING_LITERAL
    | CHARSET_REVERSE_QOUTE_STRING
    ;

collationName
    : uid
    | STRING_LITERAL
    ;

currentUserExpression
    : CURRENT_USER ('(' ')')?
    ;

userName
    : simpleUserName
    | simpleUserName hostName
    | currentUserExpression
    ;

timestampValue
    : CURRENT_TIMESTAMP
    | stringLiteral
    | decimalLiteral
    | expression
    ;

intervalExpr
    : '+' INTERVAL (decimalLiteral | expression) intervalType
    ;

decimalLiteral
    : DECIMAL_LITERAL
    | ZERO_DECIMAL
    | ONE_DECIMAL
    | TWO_DECIMAL
    | REAL_LITERAL
    ;

expression
    : (NOT | '!') expression
    | expression logicalOperator expression
    | predicate IS NOT? (TRUE | FALSE | UNKNOWN)
    | predicate
    ;

intervalType
    : intervalTypeBase
    | YEAR
    | YEAR_MONTH
    | DAY_HOUR
    | DAY_MINUTE
    | DAY_SECOND
    | HOUR_MINUTE
    | HOUR_SECOND
    | MINUTE_SECOND
    | SECOND_MICROSECOND
    | MINUTE_MICROSECOND
    | HOUR_MICROSECOND
    | DAY_MICROSECOND
    ;

stringLiteral
    : (STRING_CHARSET_NAME? STRING_LITERAL | START_NATIONAL_STRING_LITERAL) STRING_LITERAL+
    | (STRING_CHARSET_NAME? STRING_LITERAL | START_NATIONAL_STRING_LITERAL) (COLLATE collationName)?
    ;

intervalTypeBase
    : QUARTER
    | MONTH
    | DAY
    | HOUR
    | MINUTE
    | WEEK
    | SECOND
    | MICROSECOND
    ;

createDefinition
    : fullColumnName columnDefinition
    | tableConstraint NOT? ENFORCED?
    | indexColumnDefinition
    ;

fullColumnName
    : uid (dottedId dottedId?)?
    | .? dottedId dottedId?
    ;

columnDefinition
    : dataType columnConstraint* NOT? ENFORCED?
    ;

tableConstraint
    : (CONSTRAINT uid?)? PRIMARY KEY uid? indexType? indexColumnNames indexOption*
    | (CONSTRAINT uid?)? UNIQUE (INDEX | KEY)? uid? indexType? indexColumnNames indexOption*
    | (CONSTRAINT uid?)? FOREIGN KEY uid? indexColumnNames referenceDefinition
    | (CONSTRAINT uid?)? CHECK '(' expression ')'
    ;

indexColumnDefinition
    : (INDEX | KEY) uid? indexType? indexColumnNames indexOption*
    | (FULLTEXT | SPATIAL) (INDEX | KEY)? uid? indexColumnNames indexOption*
    ;

columnConstraint
    : nullNotnull
    | DEFAULT defaultValue
    | VISIBLE
    | INVISIBLE
    | AUTO_INCREMENT
    | ON UPDATE currentTimestamp
    | PRIMARY? KEY
    | UNIQUE KEY?
    | COMMENT STRING_LITERAL
    | COLUMN_FORMAT (FIXED | DYNAMIC | DEFAULT)
    | STORAGE (DISK | MEMORY | DEFAULT)
    | referenceDefinition
    | COLLATE collationName
    | (GENERATED ALWAYS)? AS '(' expression ')' (VIRTUAL | STORED)?
    | SERIAL DEFAULT VALUE
    | (CONSTRAINT uid?)? CHECK '(' expression ')'
    ;

nullNotnull
    : NOT? (NULL_LITERAL | NULL_SPEC_LITERAL)
    ;

defaultValue
    : NULL_LITERAL
    | CAST '(' expression AS convertedDataType ')'
    | unaryOperator? constant
    | currentTimestamp (ON UPDATE currentTimestamp)?
    | '(' expression ')'
    | '(' fullId ')'
    ;

currentTimestamp
    : (CURRENT_TIMESTAMP | LOCALTIME | LOCALTIMESTAMP) ('(' decimalLiteral? ')')?
    | NOW '(' decimalLiteral? ')'
    ;

referenceDefinition
    : REFERENCES tableName indexColumnNames? (MATCH (FULL | PARTIAL | SIMPLE))? referenceAction?
    ;

referenceAction
    : ON DELETE referenceControlType (ON UPDATE referenceControlType)?
    | ON UPDATE referenceControlType (ON DELETE referenceControlType)?
    ;

referenceControlType
    : RESTRICT
    | CASCADE
    | SET NULL_LITERAL
    | NO ACTION
    | SET DEFAULT
    ;

tablespaceStorage
    : STORAGE (DISK | MEMORY | DEFAULT)
    ;

tableType
    : MYSQL
    | ODBC
    ;

tables
    : tableName (',' tableName)*
    ;

partitionFunctionDefinition
    : LINEAR? HASH '(' expression ')'
    | LINEAR? KEY (ALGORITHM '=' ('1' | '2'))? '(' uidList? ')'
    | RANGE ('(' expression ')' | COLUMNS '(' uidList ')')
    | LIST ('(' expression ')' | COLUMNS '(' uidList ')')
    ;

subpartitionFunctionDefinition
    : LINEAR? HASH '(' expression ')'
    | LINEAR? KEY (ALGORITHM '=' ('1' | '2'))? '(' uidList ')'
    ;

partitionDefinition
    : PARTITION uid VALUES LESS THAN '(' partitionDefinerAtom (',' partitionDefinerAtom)* ')' partitionOption* ('(' subpartitionDefinition (',' subpartitionDefinition)* ')')?
    | PARTITION uid VALUES LESS THAN partitionDefinerAtom partitionOption* ('(' subpartitionDefinition (',' subpartitionDefinition)* ')')?
    | PARTITION uid VALUES IN '(' partitionDefinerAtom (',' partitionDefinerAtom)* ')' partitionOption* ('(' subpartitionDefinition (',' subpartitionDefinition)* ')')?
    | PARTITION uid VALUES IN '(' partitionDefinerVector (',' partitionDefinerVector)* ')' partitionOption* ('(' subpartitionDefinition (',' subpartitionDefinition)* ')')?
    | PARTITION uid partitionOption* ('(' subpartitionDefinition (',' subpartitionDefinition)* ')')?
    ;

partitionDefinerAtom
    : constant
    | expression
    | MAXVALUE
    ;

partitionOption
    : DEFAULT? STORAGE? ENGINE '='? engineName
    | COMMENT '='? STRING_LITERAL
    | DATA DIRECTORY '='? STRING_LITERAL
    | INDEX DIRECTORY '='? STRING_LITERAL
    | MAX_ROWS '='? decimalLiteral
    | MIN_ROWS '='? decimalLiteral
    | TABLESPACE '='? uid
    | NODEGROUP '='? uid
    ;

subpartitionDefinition
    : SUBPARTITION uid partitionOption*
    ;

partitionDefinerVector
    : '(' partitionDefinerAtom (',' partitionDefinerAtom)+ ')'
    ;

constant
    : stringLiteral
    | decimalLiteral
    | '-' decimalLiteral
    | hexadecimalLiteral
    | booleanLiteral
    | REAL_LITERAL
    | BIT_STRING
    | NOT? (NULL_LITERAL | NULL_SPEC_LITERAL)
    ;

waitNowaitClause
    : WAIT decimalLiteral
    | NOWAIT
    ;

alterSpecification
    : tableOption (','? tableOption)*
    | ADD COLUMN? uid columnDefinition (FIRST | AFTER uid)?
    | ADD COLUMN? '(' uid columnDefinition (',' uid columnDefinition)* ')'
    | ADD (INDEX | KEY) uid? indexType? indexColumnNames indexOption*
    | ADD (CONSTRAINT uid?)? PRIMARY KEY uid? indexType? indexColumnNames indexOption*
    | ADD (CONSTRAINT uid?)? UNIQUE (INDEX | KEY)? uid? indexType? indexColumnNames indexOption*
    | ADD (FULLTEXT | SPATIAL) (INDEX | KEY)? uid? indexColumnNames indexOption*
    | ADD (CONSTRAINT uid?)? FOREIGN KEY uid? indexColumnNames referenceDefinition
    | ADD (CONSTRAINT uid?)? CHECK (uid | stringLiteral | '(' expression ')') NOT? ENFORCED?
    | ALTER (CONSTRAINT uid?)? CHECK (uid | stringLiteral | '(' expression ')') NOT? ENFORCED?
    | ADD (CONSTRAINT uid?)? CHECK '(' expression ')'
    | ALGORITHM '='? (DEFAULT | INSTANT | INPLACE | COPY)
    | ALTER COLUMN? uid (SET DEFAULT defaultValue | DROP DEFAULT)
    | CHANGE COLUMN? uid uid columnDefinition (FIRST | AFTER uid)?
    | RENAME COLUMN uid TO uid
    | LOCK '='? (DEFAULT | NONE | SHARED | EXCLUSIVE)
    | MODIFY COLUMN? uid columnDefinition (FIRST | AFTER uid)?
    | DROP COLUMN? uid RESTRICT?
    | DROP (CONSTRAINT | CHECK) uid
    | DROP PRIMARY KEY
    | DROP (INDEX | KEY) uid
    | RENAME (INDEX | KEY) uid TO uid
    | ALTER COLUMN? uid (SET DEFAULT (stringLiteral | '(' expression ')') | SET (VISIBLE | INVISIBLE) | DROP DEFAULT)
    | ALTER INDEX uid (VISIBLE | INVISIBLE)
    | DROP FOREIGN KEY uid
    | DISABLE KEYS
    | ENABLE KEYS
    | RENAME (TO | AS)? (uid | fullId)
    | ORDER BY uidList
    | CONVERT TO (CHARSET | CHARACTER SET) charsetName (COLLATE collationName)?
    | DEFAULT? CHARACTER SET '=' charsetName (COLLATE '=' collationName)?
    | DISCARD TABLESPACE
    | IMPORT TABLESPACE
    | FORCE
    | (WITHOUT | WITH) VALIDATION
    | ADD COLUMN? '(' createDefinition (',' createDefinition)* ')'
    | alterPartitionSpecification
    ;

alterPartitionSpecification
    : ADD PARTITION '(' partitionDefinition (',' partitionDefinition)* ')'
    | DROP PARTITION uidList
    | DISCARD PARTITION (uidList | ALL) TABLESPACE
    | IMPORT PARTITION (uidList | ALL) TABLESPACE
    | TRUNCATE PARTITION (uidList | ALL)
    | COALESCE PARTITION decimalLiteral
    | REORGANIZE PARTITION uidList INTO '(' partitionDefinition (',' partitionDefinition)* ')'
    | EXCHANGE PARTITION uid WITH TABLE tableName ((WITH | WITHOUT) VALIDATION)?
    | ANALYZE PARTITION (uidList | ALL)
    | CHECK PARTITION (uidList | ALL)
    | OPTIMIZE PARTITION (uidList | ALL)
    | REBUILD PARTITION (uidList | ALL)
    | REPAIR PARTITION (uidList | ALL)
    | REMOVE PARTITIONING
    | UPGRADE PARTITIONING
    ;

ifExists
    : IF EXISTS
    ;

roleOption
    : DEFAULT
    | NONE
    | ALL (EXCEPT userName (',' userName)*)?
    | userName (',' userName)*
    ;

renameTableClause
    : tableName TO tableName
    ;

constants
    : constant (',' constant)*
    ;

expressions
    : expression (',' expression)*
    ;

singleDeleteStatement
    : DELETE LOW_PRIORITY? QUICK? IGNORE? FROM tableName (AS? uid)? (PARTITION '(' uidList ')')? (WHERE expression)? orderByClause? (LIMIT limitClauseAtom)?
    ;

multipleDeleteStatement
    : DELETE LOW_PRIORITY? QUICK? IGNORE? (tableName ('.' '*')? (',' tableName ('.' '*')?)* FROM tableSources | FROM tableName ('.' '*')? (',' tableName ('.' '*')?)* USING tableSources) (WHERE expression)?
    ;

handlerOpenStatement
    : HANDLER tableName OPEN (AS? uid)?
    ;

handlerReadIndexStatement
    : HANDLER tableName READ uid (comparisonOperator '(' constants ')' | FIRST | NEXT | PREV | LAST) (WHERE expression)? (LIMIT limitClauseAtom)?
    ;

handlerReadStatement
    : HANDLER tableName READ (FIRST | NEXT) (WHERE expression)? (LIMIT limitClauseAtom)?
    ;

handlerCloseStatement
    : HANDLER tableName CLOSE
    ;

fullColumnNameList
    : fullColumnName (',' fullColumnName)*
    ;

insertStatementValue
    : selectStatement
    | (VALUES | VALUE) '(' expressionsWithDefaults? ')' (',' '(' expressionsWithDefaults? ')')*
    ;

updatedElement
    : fullColumnName '=' (expression | DEFAULT)
    ;

selectFieldsInto
    : TERMINATED BY STRING_LITERAL
    | OPTIONALLY? ENCLOSED BY STRING_LITERAL
    | ESCAPED BY STRING_LITERAL
    ;

selectLinesInto
    : STARTING BY STRING_LITERAL
    | TERMINATED BY STRING_LITERAL
    ;

assignmentField
    : uid
    | LOCAL_ID
    ;

querySpecification
    : SELECT selectSpec* selectElements selectIntoExpression? fromClause groupByClause? havingClause? windowClause? orderByClause? limitClause?
    | SELECT selectSpec* selectElements fromClause groupByClause? havingClause? windowClause? orderByClause? limitClause? selectIntoExpression?
    ;

lockClause
    : FOR UPDATE
    | LOCK IN SHARE MODE
    ;

queryExpression
    : '(' querySpecification ')'
    | '(' queryExpression ')'
    ;

querySpecificationNointo
    : SELECT selectSpec* selectElements fromClause groupByClause? havingClause? windowClause? orderByClause? limitClause?
    ;

unionStatement
    : UNION (ALL | DISTINCT)? (querySpecificationNointo | queryExpressionNointo)
    ;

orderByClause
    : ORDER BY orderByExpression (',' orderByExpression)*
    ;

limitClause
    : LIMIT ((limitClauseAtom ',')? limitClauseAtom | limitClauseAtom OFFSET limitClauseAtom)
    ;

queryExpressionNointo
    : '(' querySpecificationNointo ')'
    | '(' queryExpressionNointo ')'
    ;

unionParenthesis
    : UNION (ALL | DISTINCT)? queryExpressionNointo
    ;

lateralStatement
    : LATERAL (querySpecificationNointo | queryExpressionNointo | '(' (querySpecificationNointo | queryExpressionNointo) ')' (AS? uid)?)
    ;

singleUpdateStatement
    : UPDATE LOW_PRIORITY? IGNORE? tableName (AS? uid)? SET updatedElement (',' updatedElement)* (WHERE expression)? orderByClause? limitClause?
    ;

multipleUpdateStatement
    : UPDATE LOW_PRIORITY? IGNORE? tableSources SET updatedElement (',' updatedElement)* (WHERE expression)?
    ;

expressionsWithDefaults
    : expressionOrDefault (',' expressionOrDefault)*
    ;

limitClauseAtom
    : decimalLiteral
    | mysqlVariable
    | simpleId
    ;

tableSources
    : tableSource (',' tableSource)*
    ;

comparisonOperator
    : '='
    | '>'
    | '<'
    | '<' '='
    | '>' '='
    | '<' '>'
    | '!' '='
    | '<' '=' '>'
    ;

orderByExpression
    : expression (ASC | DESC)?
    ;

tableSource
    : tableSourceItem joinPart*
    | '(' tableSourceItem joinPart* ')'
    | jsonTable
    ;

tableSourceItem
    : tableName (PARTITION '(' uidList ')')? (AS? uid)? (indexHint (',' indexHint)*)?
    | (selectStatement | '(' selectStatement ')') AS? uid
    | '(' tableSources ')'
    ;

joinPart
    : (INNER | CROSS)? JOIN LATERAL? tableSourceItem joinSpec*
    | STRAIGHT_JOIN tableSourceItem (ON expression)*
    | (LEFT | RIGHT) OUTER? JOIN LATERAL? tableSourceItem joinSpec*
    | NATURAL ((LEFT | RIGHT) OUTER?)? JOIN tableSourceItem
    ;

jsonTable
    : JSON_TABLE '(' STRING_LITERAL ',' STRING_LITERAL COLUMNS '(' jsonColumnList ')' ')' (AS? uid)?
    ;

indexHint
    : (USE | IGNORE | FORCE) (INDEX | KEY) (FOR indexHintType)? '(' uidList ')'
    ;

indexHintType
    : JOIN
    | ORDER BY
    | GROUP BY
    ;

joinSpec
    : ON expression
    | USING '(' uidList ')'
    ;

selectSpec
    : ALL
    | DISTINCT
    | DISTINCTROW
    | HIGH_PRIORITY
    | STRAIGHT_JOIN
    | SQL_SMALL_RESULT
    | SQL_BIG_RESULT
    | SQL_BUFFER_RESULT
    | SQL_CACHE
    | SQL_NO_CACHE
    | SQL_CALC_FOUND_ROWS
    ;

selectElements
    : ('*' | selectElement) (',' selectElement)*
    ;

selectIntoExpression
    : INTO assignmentField (',' assignmentField)*
    | INTO DUMPFILE STRING_LITERAL
    | INTO OUTFILE STRING_LITERAL (CHARACTER SET charsetName)? ((FIELDS | COLUMNS) selectFieldsInto+)? (LINES selectLinesInto+)?
    ;

fromClause
    : (FROM tableSources)? (WHERE expression)?
    ;

groupByClause
    : GROUP BY groupByItem (',' groupByItem)* (WITH ROLLUP)?
    ;

havingClause
    : HAVING expression
    ;

windowClause
    : WINDOW windowName AS '(' windowSpec ')' (',' windowName AS '(' windowSpec ')')*
    ;

jsonColumnList
    : jsonColumn (',' jsonColumn)*
    ;

jsonColumn
    : fullColumnName (FOR ORDINALITY | dataType (PATH STRING_LITERAL jsonOnEmpty? jsonOnError? | EXISTS PATH STRING_LITERAL))
    | NESTED PATH? STRING_LITERAL COLUMNS '(' jsonColumnList ')'
    ;

jsonOnEmpty
    : (NULL_LITERAL | ERROR | DEFAULT defaultValue) ON EMPTY
    ;

jsonOnError
    : (NULL_LITERAL | ERROR | DEFAULT defaultValue) ON ERROR
    ;

selectElement
    : fullId '.' '*'
    | fullColumnName (AS? uid)?
    | functionCall (AS? uid)?
    | (LOCAL_ID VAR_ASSIGN)? expression (AS? uid)?
    ;

functionCall
    : specificFunction
    | aggregateWindowedFunction
    | nonAggregateWindowedFunction
    | scalarFunctionName '(' functionArgs? ')'
    | fullId '(' functionArgs? ')'
    | passwordFunctionClause
    ;

groupByItem
    : expression (ASC | DESC)?
    ;

windowName
    : uid
    ;

windowSpec
    : windowName? partitionClause? orderByClause? frameClause?
    ;

mysqlVariable
    : LOCAL_ID
    | GLOBAL_ID
    ;

simpleId
    : ID
    | charsetNameBase
    | transactionLevelBase
    | engineNameBase
    | privilegesBase
    | intervalTypeBase
    | dataTypeBase
    | keywordsCanBeId
    | scalarFunctionName
    ;

transactionMode
    : WITH CONSISTENT SNAPSHOT
    | READ WRITE
    | READ ONLY
    ;

lockTableElement
    : tableName (AS? uid)? lockAction
    ;

setAutocommitStatement
    : SET AUTOCOMMIT '=' ('0' | '1')
    ;

setTransactionStatement
    : SET (GLOBAL | SESSION)? TRANSACTION transactionOption (',' transactionOption)*
    ;

transactionOption
    : ISOLATION LEVEL transactionLevel
    | READ WRITE
    | READ ONLY
    ;

lockAction
    : READ LOCAL?
    | LOW_PRIORITY? WRITE
    ;

transactionLevel
    : REPEATABLE READ
    | READ COMMITTED
    | READ UNCOMMITTED
    | SERIALIZABLE
    ;

masterOption
    : stringMasterOption '=' STRING_LITERAL
    | decimalMasterOption '=' decimalLiteral
    | boolMasterOption '=' ('0' | '1')
    | MASTER_HEARTBEAT_PERIOD '=' REAL_LITERAL
    | IGNORE_SERVER_IDS '=' '(' (uid (',' uid)*)? ')'
    ;

channelOption
    : FOR CHANNEL STRING_LITERAL
    ;

replicationFilter
    : REPLICATE_DO_DB '=' '(' uidList ')'
    | REPLICATE_IGNORE_DB '=' '(' uidList ')'
    | REPLICATE_DO_TABLE '=' '(' tables ')'
    | REPLICATE_IGNORE_TABLE '=' '(' tables ')'
    | REPLICATE_WILD_DO_TABLE '=' '(' simpleStrings ')'
    | REPLICATE_WILD_IGNORE_TABLE '=' '(' simpleStrings ')'
    | REPLICATE_REWRITE_DB '=' '(' tablePair (',' tablePair)* ')'
    ;

threadType
    : IO_THREAD
    | SQL_THREAD
    ;

untilOption
    : (SQL_BEFORE_GTIDS | SQL_AFTER_GTIDS) '=' gtuidSet
    | MASTER_LOG_FILE '=' STRING_LITERAL ',' MASTER_LOG_POS '=' decimalLiteral
    | RELAY_LOG_FILE '=' STRING_LITERAL ',' RELAY_LOG_POS '=' decimalLiteral
    | SQL_AFTER_MTS_GAPS
    ;

connectionOption
    : USER '=' STRING_LITERAL
    | PASSWORD '=' STRING_LITERAL
    | DEFAULT_AUTH '=' STRING_LITERAL
    | PLUGIN_DIR '=' STRING_LITERAL
    ;

stringMasterOption
    : MASTER_BIND
    | MASTER_HOST
    | MASTER_USER
    | MASTER_PASSWORD
    | MASTER_LOG_FILE
    | RELAY_LOG_FILE
    | MASTER_SSL_CA
    | MASTER_SSL_CAPATH
    | MASTER_SSL_CERT
    | MASTER_SSL_CRL
    | MASTER_SSL_CRLPATH
    | MASTER_SSL_KEY
    | MASTER_SSL_CIPHER
    | MASTER_TLS_VERSION
    ;

decimalMasterOption
    : MASTER_PORT
    | MASTER_CONNECT_RETRY
    | MASTER_RETRY_COUNT
    | MASTER_DELAY
    | MASTER_LOG_POS
    | RELAY_LOG_POS
    ;

boolMasterOption
    : MASTER_AUTO_POSITION
    | MASTER_SSL
    | MASTER_SSL_VERIFY_SERVER_CERT
    ;

simpleStrings
    : STRING_LITERAL (',' STRING_LITERAL)*
    ;

tablePair
    : '(' tableName ',' tableName ')'
    ;

gtuidSet
    : uuidSet (',' uuidSet)*
    | STRING_LITERAL
    ;

uuidSet
    : decimalLiteral '-' decimalLiteral '-' decimalLiteral '-' decimalLiteral '-' decimalLiteral (':' decimalLiteral '-' decimalLiteral)+
    ;

xid
    : xuidStringId (',' xuidStringId (',' decimalLiteral)?)?
    ;

userVariables
    : LOCAL_ID (',' LOCAL_ID)*
    ;

declareVariable
    : DECLARE uidList dataType (DEFAULT expression)?
    ;

declareCondition
    : DECLARE uid CONDITION FOR (decimalLiteral | SQLSTATE VALUE? STRING_LITERAL)
    ;

declareCursor
    : DECLARE uid CURSOR FOR selectStatement
    ;

declareHandler
    : DECLARE (CONTINUE | EXIT | UNDO) HANDLER FOR handlerConditionValue (',' handlerConditionValue)* routineBody
    ;

procedureSqlStatement
    : (compoundStatement | sqlStatement) SEMI
    ;

caseAlternative
    : WHEN (constant | expression) THEN procedureSqlStatement+
    ;

elifAlternative
    : ELSEIF expression THEN procedureSqlStatement+
    ;

handlerConditionValue
    : decimalLiteral
    | SQLSTATE VALUE? STRING_LITERAL
    | uid
    | SQLWARNING
    | NOT FOUND
    | SQLEXCEPTION
    ;

userSpecification
    : userName userPasswordOption
    ;

userAuthOption
    : userName IDENTIFIED BY PASSWORD STRING_LITERAL
    | userName IDENTIFIED BY RANDOM PASSWORD authOptionClause
    | userName IDENTIFIED BY STRING_LITERAL authOptionClause
    | userName IDENTIFIED WITH authenticationRule
    | userName
    ;

tlsOption
    : SSL
    | X509
    | CIPHER STRING_LITERAL
    | ISSUER STRING_LITERAL
    | SUBJECT STRING_LITERAL
    ;

userResourceOption
    : MAX_QUERIES_PER_HOUR decimalLiteral
    | MAX_UPDATES_PER_HOUR decimalLiteral
    | MAX_CONNECTIONS_PER_HOUR decimalLiteral
    | MAX_USER_CONNECTIONS decimalLiteral
    ;

userPasswordOption
    : PASSWORD EXPIRE (DEFAULT | NEVER | INTERVAL decimalLiteral DAY)?
    | PASSWORD HISTORY (DEFAULT | decimalLiteral)
    | PASSWORD REUSE INTERVAL (DEFAULT | decimalLiteral DAY)
    | PASSWORD REQUIRE CURRENT (OPTIONAL | DEFAULT)?
    | FAILED_LOGIN_ATTEMPTS decimalLiteral
    | PASSWORD_LOCK_TIME (decimalLiteral | UNBOUNDED)
    ;

userLockOption
    : ACCOUNT (LOCK | UNLOCK)
    ;

privelegeClause
    : privilege ('(' uidList ')')?
    ;

privilegeLevel
    : '*'
    | '*' '.' '*'
    | uid '.' '*'
    | uid '.' uid
    | uid dottedId
    | uid
    ;

renameUserClause
    : userName TO userName
    ;

setPasswordStatement
    : SET PASSWORD (FOR userName)? '=' (passwordFunctionClause | STRING_LITERAL)
    ;

passwordFunctionClause
    : (PASSWORD | OLD_PASSWORD) '(' functionArg ')'
    ;

authOptionClause
    : (REPLACE STRING_LITERAL)? (RETAIN CURRENT PASSWORD)?
    ;

authenticationRule
    : authPlugin ((BY | USING | AS) (STRING_LITERAL | RANDOM PASSWORD) authOptionClause)?
    | authPlugin USING passwordFunctionClause
    ;

authPlugin
    : uid
    | STRING_LITERAL
    ;

privilege
    : ALL PRIVILEGES?
    | ALTER ROUTINE?
    | CREATE (TEMPORARY TABLES | ROUTINE | VIEW | USER | TABLESPACE | ROLE)?
    | DELETE
    | DROP ROLE?
    | EVENT
    | EXECUTE
    | FILE
    | GRANT OPTION
    | INDEX
    | INSERT
    | LOCK TABLES
    | PROCESS
    | PROXY
    | REFERENCES
    | RELOAD
    | REPLICATION (CLIENT | SLAVE)
    | SELECT
    | SHOW (VIEW | DATABASES)
    | SHUTDOWN
    | SUPER
    | TRIGGER
    | UPDATE
    | USAGE
    | APPLICATION_PASSWORD_ADMIN
    | AUDIT_ABORT_EXEMPT
    | AUDIT_ADMIN
    | AUTHENTICATION_POLICY_ADMIN
    | BACKUP_ADMIN
    | BINLOG_ADMIN
    | BINLOG_ENCRYPTION_ADMIN
    | CLONE_ADMIN
    | CONNECTION_ADMIN
    | ENCRYPTION_KEY_ADMIN
    | FIREWALL_ADMIN
    | FIREWALL_EXEMPT
    | FIREWALL_USER
    | FLUSH_OPTIMIZER_COSTS
    | FLUSH_STATUS
    | FLUSH_TABLES
    | FLUSH_USER_RESOURCES
    | GROUP_REPLICATION_ADMIN
    | INNODB_REDO_LOG_ARCHIVE
    | INNODB_REDO_LOG_ENABLE
    | NDB_STORED_USER
    | PASSWORDLESS_USER_ADMIN
    | PERSIST_RO_VARIABLES_ADMIN
    | REPLICATION_APPLIER
    | REPLICATION_SLAVE_ADMIN
    | RESOURCE_GROUP_ADMIN
    | RESOURCE_GROUP_USER
    | ROLE_ADMIN
    | SERVICE_CONNECTION_ADMIN
    | SESSION_VARIABLES_ADMIN
    | SET_USER_ID
    | SKIP_QUERY_REWRITE
    | SHOW_ROUTINE
    | SYSTEM_USER
    | SYSTEM_VARIABLES_ADMIN
    | TABLE_ENCRYPTION_ADMIN
    | TP_CONNECTION_ADMIN
    | VERSION_TOKEN_ADMIN
    | XA_RECOVER_ADMIN
    | LOAD FROM S3
    | SELECT INTO S3
    | INVOKE LAMBDA
    ;

dottedId
    : DOT_ID
    | '.' uid
    ;

checkTableOption
    : FOR UPGRADE
    | QUICK
    | FAST
    | MEDIUM
    | EXTENDED
    | CHANGED
    ;

variableClause
    : LOCAL_ID
    | GLOBAL_ID
    | (('@' '@')? (GLOBAL | SESSION | LOCAL))? uid
    ;

showCommonEntity
    : CHARACTER SET
    | COLLATION
    | DATABASES
    | SCHEMAS
    | FUNCTION STATUS
    | PROCEDURE STATUS
    | (GLOBAL | SESSION)? (STATUS | VARIABLES)
    ;

showFilter
    : LIKE STRING_LITERAL
    | WHERE expression
    ;

showGlobalInfoClause
    : STORAGE? ENGINES
    | MASTER STATUS
    | PLUGINS
    | PRIVILEGES
    | FULL? PROCESSLIST
    | PROFILES
    | SLAVE HOSTS
    | AUTHORS
    | CONTRIBUTORS
    ;

showSchemaEntity
    : EVENTS
    | TABLE STATUS
    | FULL? TABLES
    | TRIGGERS
    ;

showProfileType
    : ALL
    | BLOCK IO
    | CONTEXT SWITCHES
    | CPU
    | IPC
    | MEMORY
    | PAGE FAULTS
    | SOURCE
    | SWAPS
    ;

tableIndexes
    : tableName ((INDEX | KEY)? '(' uidList ')')?
    ;

flushOption
    : DES_KEY_FILE
    | HOSTS
    | (BINARY | ENGINE | ERROR | GENERAL | RELAY | SLOW)? LOGS
    | OPTIMIZER_COSTS
    | PRIVILEGES
    | QUERY CACHE
    | STATUS
    | USER_RESOURCES
    | TABLES (WITH READ LOCK)?
    | RELAY LOGS channelOption?
    | (TABLE | TABLES) tables? flushTableOption?
    ;

loadedTableIndexes
    : tableName (PARTITION '(' (uidList | ALL) ')')? ((INDEX | KEY)? '(' uidList ')')? (IGNORE LEAVES)?
    ;

flushTableOption
    : WITH READ LOCK
    | FOR EXPORT
    ;

describeObjectClause
    : selectStatement
    | deleteStatement
    | insertStatement
    | replaceStatement
    | updateStatement
    | FOR CONNECTION uid
    ;

signalConditionInformation
    : (CLASS_ORIGIN | SUBCLASS_ORIGIN | MESSAGE_TEXT | MYSQL_ERRNO | CONSTRAINT_CATALOG | CONSTRAINT_SCHEMA | CONSTRAINT_NAME | CATALOG_NAME | SCHEMA_NAME | TABLE_NAME | COLUMN_NAME | CURSOR_NAME) '=' (stringLiteral | DECIMAL_LITERAL | mysqlVariable | simpleId)
    ;

diagnosticsConditionInformationName
    : CLASS_ORIGIN
    | SUBCLASS_ORIGIN
    | RETURNED_SQLSTATE
    | MESSAGE_TEXT
    | MYSQL_ERRNO
    | CONSTRAINT_CATALOG
    | CONSTRAINT_SCHEMA
    | CONSTRAINT_NAME
    | CATALOG_NAME
    | SCHEMA_NAME
    | TABLE_NAME
    | COLUMN_NAME
    | CURSOR_NAME
    ;

indexColumnName
    : ((uid | STRING_LITERAL) ('(' decimalLiteral ')')? | expression) (ASC | DESC)?
    ;

simpleUserName
    : STRING_LITERAL
    | ID
    | ADMIN
    | keywordsCanBeId
    ;

keywordsCanBeId
    : ACCOUNT
    | ACTION
    | ADMIN
    | AFTER
    | AGGREGATE
    | ALGORITHM
    | ANY
    | ARRAY
    | AT
    | AUDIT_ADMIN
    | AUDIT_ABORT_EXEMPT
    | AUTHORS
    | AUTOCOMMIT
    | AUTOEXTEND_SIZE
    | AUTO_INCREMENT
    | AUTHENTICATION_POLICY_ADMIN
    | AVG
    | AVG_ROW_LENGTH
    | ATTRIBUTE
    | BACKUP_ADMIN
    | BEGIN
    | BINLOG
    | BINLOG_ADMIN
    | BINLOG_ENCRYPTION_ADMIN
    | BIT
    | BIT_AND
    | BIT_OR
    | BIT_XOR
    | BLOCK
    | BOOL
    | BOOLEAN
    | BTREE
    | BUCKETS
    | CACHE
    | CASCADED
    | CHAIN
    | CHANGED
    | CHANNEL
    | CHECKSUM
    | PAGE_CHECKSUM
    | CATALOG_NAME
    | CIPHER
    | CLASS_ORIGIN
    | CLIENT
    | CLONE_ADMIN
    | CLOSE
    | CLUSTERING
    | COALESCE
    | CODE
    | COLUMNS
    | COLUMN_FORMAT
    | COLUMN_NAME
    | COMMENT
    | COMMIT
    | COMPACT
    | COMPLETION
    | COMPRESSED
    | COMPRESSION
    | CONCURRENT
    | CONDITION
    | CONNECT
    | CONNECTION
    | CONNECTION_ADMIN
    | CONSISTENT
    | CONSTRAINT_CATALOG
    | CONSTRAINT_NAME
    | CONSTRAINT_SCHEMA
    | CONTAINS
    | CONTEXT
    | CONTRIBUTORS
    | COPY
    | COUNT
    | CPU
    | CURRENT
    | CURRENT_USER
    | CURSOR_NAME
    | DATA
    | DATAFILE
    | DEALLOCATE
    | DEFAULT
    | DEFAULT_AUTH
    | DEFINER
    | DELAY_KEY_WRITE
    | DES_KEY_FILE
    | DIAGNOSTICS
    | DIRECTORY
    | DISABLE
    | DISCARD
    | DISK
    | DO
    | DUMPFILE
    | DUPLICATE
    | DYNAMIC
    | EMPTY
    | ENABLE
    | ENCRYPTION
    | ENCRYPTION_KEY_ADMIN
    | END
    | ENDS
    | ENGINE
    | ENGINE_ATTRIBUTE
    | ENGINES
    | ENFORCED
    | ERROR
    | ERRORS
    | ESCAPE
    | EUR
    | EVEN
    | EVENT
    | EVENTS
    | EVERY
    | EXCEPT
    | EXCHANGE
    | EXCLUSIVE
    | EXPIRE
    | EXPORT
    | EXTENDED
    | EXTENT_SIZE
    | FAILED_LOGIN_ATTEMPTS
    | FAST
    | FAULTS
    | FIELDS
    | FILE_BLOCK_SIZE
    | FILTER
    | FIREWALL_ADMIN
    | FIREWALL_EXEMPT
    | FIREWALL_USER
    | FIRST
    | FIXED
    | FLUSH
    | FOLLOWS
    | FOUND
    | FULL
    | FUNCTION
    | GENERAL
    | GLOBAL
    | GRANTS
    | GROUP
    | GROUP_CONCAT
    | GROUP_REPLICATION
    | GROUP_REPLICATION_ADMIN
    | HANDLER
    | HASH
    | HELP
    | HISTORY
    | HOST
    | HOSTS
    | IDENTIFIED
    | IGNORED
    | IGNORE_SERVER_IDS
    | IMPORT
    | INDEXES
    | INITIAL_SIZE
    | INNODB_REDO_LOG_ARCHIVE
    | INPLACE
    | INSERT_METHOD
    | INSTALL
    | INSTANCE
    | INSTANT
    | INTERNAL
    | INVOKE
    | INVOKER
    | IO
    | IO_THREAD
    | IPC
    | ISO
    | ISOLATION
    | ISSUER
    | JIS
    | JSON
    | KEY_BLOCK_SIZE
    | LAMBDA
    | LANGUAGE
    | LAST
    | LATERAL
    | LEAVES
    | LESS
    | LEVEL
    | LIST
    | LOCAL
    | LOGFILE
    | LOGS
    | MASTER
    | MASTER_AUTO_POSITION
    | MASTER_CONNECT_RETRY
    | MASTER_DELAY
    | MASTER_HEARTBEAT_PERIOD
    | MASTER_HOST
    | MASTER_LOG_FILE
    | MASTER_LOG_POS
    | MASTER_PASSWORD
    | MASTER_PORT
    | MASTER_RETRY_COUNT
    | MASTER_SSL
    | MASTER_SSL_CA
    | MASTER_SSL_CAPATH
    | MASTER_SSL_CERT
    | MASTER_SSL_CIPHER
    | MASTER_SSL_CRL
    | MASTER_SSL_CRLPATH
    | MASTER_SSL_KEY
    | MASTER_TLS_VERSION
    | MASTER_USER
    | MAX_CONNECTIONS_PER_HOUR
    | MAX_QUERIES_PER_HOUR
    | MAX
    | MAX_ROWS
    | MAX_SIZE
    | MAX_UPDATES_PER_HOUR
    | MAX_USER_CONNECTIONS
    | MEDIUM
    | MEMBER
    | MEMORY
    | MERGE
    | MESSAGE_TEXT
    | MID
    | MIGRATE
    | MIN
    | MIN_ROWS
    | MODE
    | MODIFY
    | MUTEX
    | MYSQL
    | MYSQL_ERRNO
    | NAME
    | NAMES
    | NCHAR
    | NDB_STORED_USER
    | NESTED
    | NEVER
    | NEXT
    | NO
    | NOCOPY
    | NODEGROUP
    | NONE
    | NOWAIT
    | NUMBER
    | ODBC
    | OFFLINE
    | OFFSET
    | OF
    | OJ
    | OLD_PASSWORD
    | ONE
    | ONLINE
    | ONLY
    | OPEN
    | OPTIMIZER_COSTS
    | OPTIONAL
    | OPTIONS
    | ORDER
    | ORDINALITY
    | OWNER
    | PACK_KEYS
    | PAGE
    | PARSER
    | PARTIAL
    | PARTITIONING
    | PARTITIONS
    | PASSWORD
    | PASSWORDLESS_USER_ADMIN
    | PASSWORD_LOCK_TIME
    | PATH
    | PERSIST_RO_VARIABLES_ADMIN
    | PHASE
    | PLUGINS
    | PLUGIN_DIR
    | PLUGIN
    | PORT
    | PRECEDES
    | PREPARE
    | PRESERVE
    | PREV
    | PRIMARY
    | PROCESSLIST
    | PROFILE
    | PROFILES
    | PROXY
    | QUERY
    | QUICK
    | REBUILD
    | RECOVER
    | RECURSIVE
    | REDO_BUFFER_SIZE
    | REDUNDANT
    | RELAY
    | RELAYLOG
    | RELAY_LOG_FILE
    | RELAY_LOG_POS
    | REMOVE
    | REORGANIZE
    | REPAIR
    | REPLICATE_DO_DB
    | REPLICATE_DO_TABLE
    | REPLICATE_IGNORE_DB
    | REPLICATE_IGNORE_TABLE
    | REPLICATE_REWRITE_DB
    | REPLICATE_WILD_DO_TABLE
    | REPLICATE_WILD_IGNORE_TABLE
    | REPLICATION
    | REPLICATION_APPLIER
    | REPLICATION_SLAVE_ADMIN
    | RESET
    | RESOURCE_GROUP_ADMIN
    | RESOURCE_GROUP_USER
    | RESUME
    | RETURNED_SQLSTATE
    | RETURNS
    | REUSE
    | ROLE
    | ROLE_ADMIN
    | ROLLBACK
    | ROLLUP
    | ROTATE
    | ROW
    | ROWS
    | ROW_FORMAT
    | RTREE
    | S3
    | SAVEPOINT
    | SCHEDULE
    | SCHEMA_NAME
    | SECURITY
    | SECONDARY_ENGINE_ATTRIBUTE
    | SERIAL
    | SERVER
    | SESSION
    | SESSION_VARIABLES_ADMIN
    | SET_USER_ID
    | SHARE
    | SHARED
    | SHOW_ROUTINE
    | SIGNED
    | SIMPLE
    | SLAVE
    | SLOW
    | SKIP_QUERY_REWRITE
    | SNAPSHOT
    | SOCKET
    | SOME
    | SONAME
    | SOUNDS
    | SOURCE
    | SQL_AFTER_GTIDS
    | SQL_AFTER_MTS_GAPS
    | SQL_BEFORE_GTIDS
    | SQL_BUFFER_RESULT
    | SQL_CACHE
    | SQL_NO_CACHE
    | SQL_THREAD
    | STACKED
    | START
    | STARTS
    | STATS_AUTO_RECALC
    | STATS_PERSISTENT
    | STATS_SAMPLE_PAGES
    | STATUS
    | STD
    | STDDEV
    | STDDEV_POP
    | STDDEV_SAMP
    | STOP
    | STORAGE
    | STRING
    | SUBCLASS_ORIGIN
    | SUBJECT
    | SUBPARTITION
    | SUBPARTITIONS
    | SUM
    | SUSPEND
    | SWAPS
    | SWITCHES
    | SYSTEM_VARIABLES_ADMIN
    | TABLE_NAME
    | TABLESPACE
    | TABLE_ENCRYPTION_ADMIN
    | TABLE_TYPE
    | TEMPORARY
    | TEMPTABLE
    | THAN
    | TP_CONNECTION_ADMIN
    | TRADITIONAL
    | TRANSACTION
    | TRANSACTIONAL
    | TRIGGERS
    | TRUNCATE
    | UNBOUNDED
    | UNDEFINED
    | UNDOFILE
    | UNDO_BUFFER_SIZE
    | UNINSTALL
    | UNKNOWN
    | UNTIL
    | UPGRADE
    | USA
    | USER
    | USE_FRM
    | USER_RESOURCES
    | VALIDATION
    | VALUE
    | VAR_POP
    | VAR_SAMP
    | VARIABLES
    | VARIANCE
    | VERSION_TOKEN_ADMIN
    | VIEW
    | VIRTUAL
    | WAIT
    | WARNINGS
    | WITHOUT
    | WORK
    | WRAPPER
    | X509
    | XA
    | XA_RECOVER_ADMIN
    | XML
    ;

hostName
    : LOCAL_ID
    | HOST_IP_ADDRESS
    | '@'
    ;

charsetNameBase
    : ARMSCII8
    | ASCII
    | BIG5
    | BINARY
    | CP1250
    | CP1251
    | CP1256
    | CP1257
    | CP850
    | CP852
    | CP866
    | CP932
    | DEC8
    | EUCJPMS
    | EUCKR
    | GB18030
    | GB2312
    | GBK
    | GEOSTD8
    | GREEK
    | HEBREW
    | HP8
    | KEYBCS2
    | KOI8R
    | KOI8U
    | LATIN1
    | LATIN2
    | LATIN5
    | LATIN7
    | MACCE
    | MACROMAN
    | SJIS
    | SWE7
    | TIS620
    | UCS2
    | UJIS
    | UTF16
    | UTF16LE
    | UTF32
    | UTF8
    | UTF8MB3
    | UTF8MB4
    ;

engineNameBase
    : ARCHIVE
    | BLACKHOLE
    | CONNECT
    | CSV
    | FEDERATED
    | INNODB
    | MEMORY
    | MRG_MYISAM
    | MYISAM
    | NDB
    | NDBCLUSTER
    | PERFORMANCE_SCHEMA
    | TOKUDB
    ;

xuidStringId
    : STRING_LITERAL
    | BIT_STRING
    | HEXADECIMAL_LITERAL+
    ;

transactionLevelBase
    : REPEATABLE
    | COMMITTED
    | UNCOMMITTED
    | SERIALIZABLE
    ;

privilegesBase
    : TABLES
    | ROUTINE
    | EXECUTE
    | FILE
    | PROCESS
    | RELOAD
    | SHUTDOWN
    | SUPER
    | PRIVILEGES
    ;

dataTypeBase
    : DATE
    | TIME
    | TIMESTAMP
    | DATETIME
    | YEAR
    | ENUM
    | TEXT
    ;

scalarFunctionName
    : functionNameBase
    | ASCII
    | CURDATE
    | CURRENT_DATE
    | CURRENT_TIME
    | CURRENT_TIMESTAMP
    | CURTIME
    | DATE_ADD
    | DATE_SUB
    | IF
    | INSERT
    | LOCALTIME
    | LOCALTIMESTAMP
    | MID
    | NOW
    | REPEAT
    | REPLACE
    | SUBSTR
    | SUBSTRING
    | SYSDATE
    | TRIM
    | UTC_DATE
    | UTC_TIME
    | UTC_TIMESTAMP
    ;

booleanLiteral
    : TRUE
    | FALSE
    ;

hexadecimalLiteral
    : STRING_CHARSET_NAME? HEXADECIMAL_LITERAL
    ;

lengthOneDimension
    : '(' decimalLiteral ')'
    ;

lengthTwoDimension
    : '(' decimalLiteral ',' decimalLiteral ')'
    ;

lengthTwoOptionalDimension
    : '(' decimalLiteral (',' decimalLiteral)? ')'
    ;

collectionOptions
    : '(' STRING_LITERAL (',' STRING_LITERAL)* ')'
    ;

convertedDataType
    : ((BINARY | NCHAR) lengthOneDimension? | CHAR lengthOneDimension? (charSet charsetName)? | DATE | DATETIME | TIME | JSON | INT | INTEGER | (DECIMAL | DEC) lengthTwoOptionalDimension? | (SIGNED | UNSIGNED) (INTEGER | INT)?) ARRAY?
    ;

expressionOrDefault
    : expression
    | DEFAULT
    ;

unaryOperator
    : '!'
    | '~'
    | '+'
    | '-'
    | NOT
    ;

specificFunction
    : (CURRENT_DATE | CURRENT_TIME | CURRENT_TIMESTAMP | LOCALTIME | UTC_TIMESTAMP | SCHEMA) ('(' ')')?
    | currentUserExpression
    | CONVERT '(' expression ',' convertedDataType ')'
    | CONVERT '(' expression USING charsetName ')'
    | CAST '(' expression AS convertedDataType ')'
    | VALUES '(' fullColumnName ')'
    | CASE expression caseFuncAlternative+ (ELSE functionArg)? END
    | CASE caseFuncAlternative+ (ELSE functionArg)? END
    | CHAR '(' functionArgs (USING charsetName)? ')'
    | POSITION '(' (stringLiteral | expression) IN (stringLiteral | expression) ')'
    | (SUBSTR | SUBSTRING) '(' (stringLiteral | expression) FROM (decimalLiteral | expression) (FOR (decimalLiteral | expression))? ')'
    | TRIM '(' (BOTH | LEADING | TRAILING) (stringLiteral | expression)? FROM (stringLiteral | expression) ')'
    | TRIM '(' (stringLiteral | expression) FROM (stringLiteral | expression) ')'
    | WEIGHT_STRING '(' (stringLiteral | expression) (AS (CHAR | BINARY) '(' decimalLiteral ')')? levelsInWeightString? ')'
    | EXTRACT '(' intervalType FROM (stringLiteral | expression) ')'
    | GET_FORMAT '(' (DATE | TIME | DATETIME) ',' stringLiteral ')'
    | JSON_VALUE '(' expression ',' expression (RETURNING convertedDataType)? jsonOnEmpty? jsonOnError? ')'
    ;

aggregateWindowedFunction
    : (AVG | MAX | MIN | SUM) '(' (ALL | DISTINCT)? functionArg ')' overClause?
    | COUNT '(' ('*' | ALL? functionArg | DISTINCT functionArgs) ')' overClause?
    | (BIT_AND | BIT_OR | BIT_XOR | STD | STDDEV | STDDEV_POP | STDDEV_SAMP | VAR_POP | VAR_SAMP | VARIANCE) '(' ALL? functionArg ')' overClause?
    | GROUP_CONCAT '(' DISTINCT? functionArgs (ORDER BY orderByExpression (',' orderByExpression)*)? (SEPARATOR STRING_LITERAL)? ')'
    ;

nonAggregateWindowedFunction
    : (LAG | LEAD) '(' expression (',' decimalLiteral)? (',' decimalLiteral)? ')' overClause
    | (FIRST_VALUE | LAST_VALUE) '(' expression ')' overClause
    | (CUME_DIST | DENSE_RANK | PERCENT_RANK | RANK | ROW_NUMBER) '(' ')' overClause
    | NTH_VALUE '(' expression ',' decimalLiteral ')' overClause
    | NTILE '(' decimalLiteral ')' overClause
    ;

functionArgs
    : (constant | fullColumnName | functionCall | expression) (',' (constant | fullColumnName | functionCall | expression))*
    ;

caseFuncAlternative
    : WHEN functionArg THEN functionArg
    ;

functionArg
    : constant
    | fullColumnName
    | functionCall
    | expression
    ;

levelsInWeightString
    : LEVEL levelInWeightListElement (',' levelInWeightListElement)*
    | LEVEL decimalLiteral '-' decimalLiteral
    ;

levelInWeightListElement
    : decimalLiteral (ASC | DESC | REVERSE)?
    ;

overClause
    : OVER ('(' windowSpec ')' | windowName)
    ;

partitionClause
    : PARTITION BY expression (',' expression)*
    ;

frameClause
    : frameUnits frameExtent
    ;

frameUnits
    : ROWS
    | RANGE
    ;

frameExtent
    : frameRange
    | frameBetween
    ;

frameRange
    : CURRENT ROW
    | UNBOUNDED (PRECEDING | FOLLOWING)
    | expression (PRECEDING | FOLLOWING)
    ;

frameBetween
    : BETWEEN frameRange AND frameRange
    ;

functionNameBase
    : ABS
    | ACOS
    | ADDDATE
    | ADDTIME
    | AES_DECRYPT
    | AES_ENCRYPT
    | AREA
    | ASBINARY
    | ASIN
    | ASTEXT
    | ASWKB
    | ASWKT
    | ASYMMETRIC_DECRYPT
    | ASYMMETRIC_DERIVE
    | ASYMMETRIC_ENCRYPT
    | ASYMMETRIC_SIGN
    | ASYMMETRIC_VERIFY
    | ATAN
    | ATAN2
    | BENCHMARK
    | BIN
    | BIT_COUNT
    | BIT_LENGTH
    | BUFFER
    | CEIL
    | CEILING
    | CENTROID
    | CHARACTER_LENGTH
    | CHARSET
    | CHAR_LENGTH
    | COERCIBILITY
    | COLLATION
    | COMPRESS
    | CONCAT
    | CONCAT_WS
    | CONNECTION_ID
    | CONV
    | CONVERT_TZ
    | COS
    | COT
    | COUNT
    | CRC32
    | CREATE_ASYMMETRIC_PRIV_KEY
    | CREATE_ASYMMETRIC_PUB_KEY
    | CREATE_DH_PARAMETERS
    | CREATE_DIGEST
    | CROSSES
    | CUME_DIST
    | DATABASE
    | DATE
    | DATEDIFF
    | DATE_FORMAT
    | DAY
    | DAYNAME
    | DAYOFMONTH
    | DAYOFWEEK
    | DAYOFYEAR
    | DECODE
    | DEGREES
    | DENSE_RANK
    | DES_DECRYPT
    | DES_ENCRYPT
    | DIMENSION
    | DISJOINT
    | ELT
    | ENCODE
    | ENCRYPT
    | ENDPOINT
    | ENVELOPE
    | EQUALS
    | EXP
    | EXPORT_SET
    | EXTERIORRING
    | EXTRACTVALUE
    | FIELD
    | FIND_IN_SET
    | FIRST_VALUE
    | FLOOR
    | FORMAT
    | FOUND_ROWS
    | FROM_BASE64
    | FROM_DAYS
    | FROM_UNIXTIME
    | GEOMCOLLFROMTEXT
    | GEOMCOLLFROMWKB
    | GEOMETRYCOLLECTION
    | GEOMETRYCOLLECTIONFROMTEXT
    | GEOMETRYCOLLECTIONFROMWKB
    | GEOMETRYFROMTEXT
    | GEOMETRYFROMWKB
    | GEOMETRYN
    | GEOMETRYTYPE
    | GEOMFROMTEXT
    | GEOMFROMWKB
    | GET_FORMAT
    | GET_LOCK
    | GLENGTH
    | GREATEST
    | GTID_SUBSET
    | GTID_SUBTRACT
    | HEX
    | HOUR
    | IFNULL
    | INET6_ATON
    | INET6_NTOA
    | INET_ATON
    | INET_NTOA
    | INSTR
    | INTERIORRINGN
    | INTERSECTS
    | INVISIBLE
    | ISCLOSED
    | ISEMPTY
    | ISNULL
    | ISSIMPLE
    | IS_FREE_LOCK
    | IS_IPV4
    | IS_IPV4_COMPAT
    | IS_IPV4_MAPPED
    | IS_IPV6
    | IS_USED_LOCK
    | LAG
    | LAST_INSERT_ID
    | LAST_VALUE
    | LCASE
    | LEAD
    | LEAST
    | LEFT
    | LENGTH
    | LINEFROMTEXT
    | LINEFROMWKB
    | LINESTRING
    | LINESTRINGFROMTEXT
    | LINESTRINGFROMWKB
    | LN
    | LOAD_FILE
    | LOCATE
    | LOG
    | LOG10
    | LOG2
    | LOWER
    | LPAD
    | LTRIM
    | MAKEDATE
    | MAKETIME
    | MAKE_SET
    | MASTER_POS_WAIT
    | MBRCONTAINS
    | MBRDISJOINT
    | MBREQUAL
    | MBRINTERSECTS
    | MBROVERLAPS
    | MBRTOUCHES
    | MBRWITHIN
    | MD5
    | MICROSECOND
    | MINUTE
    | MLINEFROMTEXT
    | MLINEFROMWKB
    | MOD
    | MONTH
    | MONTHNAME
    | MPOINTFROMTEXT
    | MPOINTFROMWKB
    | MPOLYFROMTEXT
    | MPOLYFROMWKB
    | MULTILINESTRING
    | MULTILINESTRINGFROMTEXT
    | MULTILINESTRINGFROMWKB
    | MULTIPOINT
    | MULTIPOINTFROMTEXT
    | MULTIPOINTFROMWKB
    | MULTIPOLYGON
    | MULTIPOLYGONFROMTEXT
    | MULTIPOLYGONFROMWKB
    | NAME_CONST
    | NTH_VALUE
    | NTILE
    | NULLIF
    | NUMGEOMETRIES
    | NUMINTERIORRINGS
    | NUMPOINTS
    | OCT
    | OCTET_LENGTH
    | ORD
    | OVERLAPS
    | PERCENT_RANK
    | PERIOD_ADD
    | PERIOD_DIFF
    | PI
    | POINT
    | POINTFROMTEXT
    | POINTFROMWKB
    | POINTN
    | POLYFROMTEXT
    | POLYFROMWKB
    | POLYGON
    | POLYGONFROMTEXT
    | POLYGONFROMWKB
    | POSITION
    | POW
    | POWER
    | QUARTER
    | QUOTE
    | RADIANS
    | RAND
    | RANDOM
    | RANK
    | RANDOM_BYTES
    | RELEASE_LOCK
    | REVERSE
    | RIGHT
    | ROUND
    | ROW_COUNT
    | ROW_NUMBER
    | RPAD
    | RTRIM
    | SCHEMA
    | SECOND
    | SEC_TO_TIME
    | SESSION_USER
    | SESSION_VARIABLES_ADMIN
    | SHA
    | SHA1
    | SHA2
    | SIGN
    | SIN
    | SLEEP
    | SOUNDEX
    | SQL_THREAD_WAIT_AFTER_GTIDS
    | SQRT
    | SRID
    | STARTPOINT
    | STRCMP
    | STR_TO_DATE
    | ST_AREA
    | ST_ASBINARY
    | ST_ASTEXT
    | ST_ASWKB
    | ST_ASWKT
    | ST_BUFFER
    | ST_CENTROID
    | ST_CONTAINS
    | ST_CROSSES
    | ST_DIFFERENCE
    | ST_DIMENSION
    | ST_DISJOINT
    | ST_DISTANCE
    | ST_ENDPOINT
    | ST_ENVELOPE
    | ST_EQUALS
    | ST_EXTERIORRING
    | ST_GEOMCOLLFROMTEXT
    | ST_GEOMCOLLFROMTXT
    | ST_GEOMCOLLFROMWKB
    | ST_GEOMETRYCOLLECTIONFROMTEXT
    | ST_GEOMETRYCOLLECTIONFROMWKB
    | ST_GEOMETRYFROMTEXT
    | ST_GEOMETRYFROMWKB
    | ST_GEOMETRYN
    | ST_GEOMETRYTYPE
    | ST_GEOMFROMTEXT
    | ST_GEOMFROMWKB
    | ST_INTERIORRINGN
    | ST_INTERSECTION
    | ST_INTERSECTS
    | ST_ISCLOSED
    | ST_ISEMPTY
    | ST_ISSIMPLE
    | ST_LINEFROMTEXT
    | ST_LINEFROMWKB
    | ST_LINESTRINGFROMTEXT
    | ST_LINESTRINGFROMWKB
    | ST_NUMGEOMETRIES
    | ST_NUMINTERIORRING
    | ST_NUMINTERIORRINGS
    | ST_NUMPOINTS
    | ST_OVERLAPS
    | ST_POINTFROMTEXT
    | ST_POINTFROMWKB
    | ST_POINTN
    | ST_POLYFROMTEXT
    | ST_POLYFROMWKB
    | ST_POLYGONFROMTEXT
    | ST_POLYGONFROMWKB
    | ST_SRID
    | ST_STARTPOINT
    | ST_SYMDIFFERENCE
    | ST_TOUCHES
    | ST_UNION
    | ST_WITHIN
    | ST_X
    | ST_Y
    | SUBDATE
    | SUBSTRING_INDEX
    | SUBTIME
    | SYSTEM_USER
    | TAN
    | TIME
    | TIMEDIFF
    | TIMESTAMP
    | TIMESTAMPADD
    | TIMESTAMPDIFF
    | TIME_FORMAT
    | TIME_TO_SEC
    | TOUCHES
    | TO_BASE64
    | TO_DAYS
    | TO_SECONDS
    | UCASE
    | UNCOMPRESS
    | UNCOMPRESSED_LENGTH
    | UNHEX
    | UNIX_TIMESTAMP
    | UPDATEXML
    | UPPER
    | UUID
    | UUID_SHORT
    | VALIDATE_PASSWORD_STRENGTH
    | VERSION
    | VISIBLE
    | WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS
    | WEEK
    | WEEKDAY
    | WEEKOFYEAR
    | WEIGHT_STRING
    | WITHIN
    | YEAR
    | YEARWEEK
    | Y_FUNCTION
    | X_FUNCTION
    | JSON_ARRAY
    | JSON_OBJECT
    | JSON_QUOTE
    | JSON_CONTAINS
    | JSON_CONTAINS_PATH
    | JSON_EXTRACT
    | JSON_KEYS
    | JSON_OVERLAPS
    | JSON_SEARCH
    | JSON_VALUE
    | JSON_ARRAY_APPEND
    | JSON_ARRAY_INSERT
    | JSON_INSERT
    | JSON_MERGE
    | JSON_MERGE_PATCH
    | JSON_MERGE_PRESERVE
    | JSON_REMOVE
    | JSON_REPLACE
    | JSON_SET
    | JSON_UNQUOTE
    | JSON_DEPTH
    | JSON_LENGTH
    | JSON_TYPE
    | JSON_VALID
    | JSON_TABLE
    | JSON_SCHEMA_VALID
    | JSON_SCHEMA_VALIDATION_REPORT
    | JSON_PRETTY
    | JSON_STORAGE_FREE
    | JSON_STORAGE_SIZE
    | JSON_ARRAYAGG
    | JSON_OBJECTAGG
    ;

logicalOperator
    : AND
    | '&' '&'
    | XOR
    | OR
    | '|' '|'
    ;

predicate
    : predicate NOT? IN '(' (selectStatement | expressions) ')'
    | predicate IS nullNotnull
    | predicate comparisonOperator predicate
    | predicate comparisonOperator (ALL | ANY | SOME) '(' selectStatement ')'
    | predicate NOT? BETWEEN predicate AND predicate
    | predicate SOUNDS LIKE predicate
    | predicate NOT? LIKE predicate (ESCAPE STRING_LITERAL)?
    | predicate NOT? (REGEXP | RLIKE) predicate
    | predicate MEMBER OF '(' predicate ')'
    | expressionAtom
    ;

expressionAtom
    : constant
    | fullColumnName
    | functionCall
    | expressionAtom COLLATE collationName
    | mysqlVariable
    | unaryOperator expressionAtom
    | BINARY expressionAtom
    | LOCAL_ID VAR_ASSIGN expressionAtom
    | '(' expression (',' expression)* ')'
    | ROW '(' expression (',' expression)+ ')'
    | EXISTS '(' selectStatement ')'
    | '(' selectStatement ')'
    | INTERVAL expression intervalType
    | expressionAtom bitOperator expressionAtom
    | expressionAtom mathOperator expressionAtom
    | expressionAtom jsonOperator expressionAtom
    ;

bitOperator
    : '<' '<'
    | '>' '>'
    | '&'
    | '^'
    | '|'
    ;

mathOperator
    : '*'
    | '/'
    | '%'
    | DIV
    | MOD
    | '+'
    | '-'
    ;

jsonOperator
    : '-' '>'
    | '-' '>' '>'
    ;

