diff --git a/.gitattributes b/.gitattributes index ff14de0d..e1ddbbb2 100644 --- a/.gitattributes +++ b/.gitattributes @@ -5,5 +5,9 @@ composer.json export-ignore phpcs.xml.dist export-ignore phpunit.xml.dist export-ignore -tests/*.php export-ignore +/grammar-tools export-ignore +/tests export-ignore +/wip export-ignore +/wp-includes/mysql export-ignore +/wp-includes/parser export-ignore wp-includes/sqlite/class-wp-sqlite-crosscheck-db.php export-ignore diff --git a/composer.json b/composer.json index fb6b2899..dce2c54b 100644 --- a/composer.json +++ b/composer.json @@ -11,6 +11,7 @@ "php": ">=7.0" }, "require-dev": { + "ext-mbstring": "*", "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", "squizlabs/php_codesniffer": "^3.7", "wp-coding-standards/wpcs": "^3.1", diff --git a/grammar-tools/MySQLParser.g4 b/grammar-tools/MySQLParser.g4 new file mode 100644 index 00000000..b8fc8312 --- /dev/null +++ b/grammar-tools/MySQLParser.g4 @@ -0,0 +1,5709 @@ +/* + * Grammar from: https://github.com/mysql/mysql-workbench/blob/8.0.38/library/parsers/grammars/MySQLParser.g4 + * + * The grammar was manually fixed and factored. The original grammar is kept below in its entirety. + * The adjusted rules were kept in place, but commented out and redefined below with manual fixes. + */ + +parser grammar MySQLParser; + +/* + * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, + * as published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * Merged in all changes up to mysql-trunk git revision [6d4f66a] (16. January 2020). + * + * MySQL grammar for ANTLR 4.5+ with language features from MySQL 5.6.0 up to MySQL 8.0. + * The server version in the generated parser can be switched at runtime, making it so possible + * to switch the supported feature set dynamically. + * + * The coverage of the MySQL language should be 100%, but there might still be bugs or omissions. + * + * To use this grammar you will need a few support classes (which should be close to where you found this grammar). + * These classes implement the target specific action code, so we don't clutter the grammar with that + * and make it simpler to adjust it for other targets. See the demo/test project for further details. + * + * Written by Mike Lischke. Direct all bug reports, omissions etc. to mike.lischke@oracle.com. + */ + +//---------------------------------------------------------------------------------------------------------------------- + +// $antlr-format alignTrailingComments on, columnLimit 130, minEmptyLines 1, maxEmptyLinesToKeep 1, reflowComments off +// $antlr-format useTab off, allowShortRulesOnASingleLine off, allowShortBlocksOnASingleLine on, alignSemicolons ownLine + +options { + superClass = MySQLBaseRecognizer; + tokenVocab = MySQLLexer; + exportMacro = PARSERS_PUBLIC_TYPE; +} + +//---------------------------------------------------------------------------------------------------------------------- + +@header {/* + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2.0, + * as published by the Free Software Foundation. + * + * This program is designed to work with certain software (including + * but not limited to OpenSSL) that is licensed under separate terms, as + * designated in a particular file or component or in included license + * documentation. The authors of MySQL hereby grant you an additional + * permission to link the program and your derivative works with the + * separately licensed software that they have either included with + * the program or referenced in the documentation. + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License, version 2.0, for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +} + +@postinclude { +#include "MySQLBaseRecognizer.h" +} + +//---------------------------------------------------------------------------------------------------------------------- + +query: + EOF + | (simpleStatement | beginWork) (SEMICOLON_SYMBOL EOF? | EOF) +; + +simpleStatement: + // DDL + alterStatement + | createStatement + | dropStatement + | renameTableStatement + | truncateTableStatement + | {serverVersion >= 80000}? importStatement + + // DML + | callStatement + | deleteStatement + | doStatement + | handlerStatement + | insertStatement + | loadStatement + | replaceStatement + | selectStatement + | updateStatement + | transactionOrLockingStatement + | replicationStatement + | preparedStatement + + // Data Directory + | {serverVersion >= 80000}? cloneStatement + + // Database administration + | accountManagementStatement + | tableAdministrationStatement + | installUninstallStatment + | setStatement // SET PASSWORD is handled in accountManagementStatement. + | showStatement + | {serverVersion >= 80000}? resourceGroupManagement + | otherAdministrativeStatement + + // MySQL utilitity statements + | utilityStatement + | {serverVersion >= 50604}? getDiagnostics + | signalStatement + | resignalStatement +; + +//----------------- DDL statements ------------------------------------------------------------------------------------- + +alterStatement: + ALTER_SYMBOL ( + alterTable + | alterDatabase + | PROCEDURE_SYMBOL procedureRef routineAlterOptions? + | FUNCTION_SYMBOL functionRef routineAlterOptions? + | alterView + | alterEvent + | alterTablespace + | {serverVersion >= 80014}? alterUndoTablespace + | alterLogfileGroup + | alterServer + // ALTER USER is part of the user management rule. + | alterInstance /* @FIX: Add support for "ALTER INSTANCE ..." statement. */ + ) +; + +/* + * @FIX: + * Add support for "ALTER INSTANCE ..." statement. + */ +alterInstance: + {serverVersion >= 50711}? INSTANCE_SYMBOL ( + ROTATE_SYMBOL (INNODB_SYMBOL | {serverVersion >= 80016}? BINLOG_SYMBOL) MASTER_SYMBOL KEY_SYMBOL + | {serverVersion >= 80016}? RELOAD_SYMBOL TLS_SYMBOL (NO_SYMBOL ROLLBACK_SYMBOL ON_SYMBOL ERROR_SYMBOL)? + | {serverVersion >= 80021}? RELOAD_SYMBOL TLS_SYMBOL FOR_SYMBOL CHANNEL_SYMBOL identifier (NO_SYMBOL ROLLBACK_SYMBOL ON_SYMBOL ERROR_SYMBOL)? + | {serverVersion >= 80021}? (ENABLE_SYMBOL | DISABLE_SYMBOL) INNODB_SYMBOL REDO_LOG_SYMBOL + | {serverVersion >= 80024}? RELOAD_SYMBOL KEYRING_SYMBOL + ) +; + +alterDatabase: + /* @FIX: Make "schemaRef" optional. */ + DATABASE_SYMBOL schemaRef? ( + createDatabaseOption+ + | {serverVersion < 80000}? UPGRADE_SYMBOL DATA_SYMBOL DIRECTORY_SYMBOL NAME_SYMBOL + ) +; + +alterEvent: + definerClause? EVENT_SYMBOL eventRef (ON_SYMBOL SCHEDULE_SYMBOL schedule)? ( + ON_SYMBOL COMPLETION_SYMBOL NOT_SYMBOL? PRESERVE_SYMBOL + )? (RENAME_SYMBOL TO_SYMBOL identifier)? ( + ENABLE_SYMBOL + | DISABLE_SYMBOL (ON_SYMBOL SLAVE_SYMBOL)? + )? (COMMENT_SYMBOL textLiteral)? (DO_SYMBOL compoundStatement)? +; + +alterLogfileGroup: + LOGFILE_SYMBOL GROUP_SYMBOL logfileGroupRef ADD_SYMBOL UNDOFILE_SYMBOL textLiteral alterLogfileGroupOptions? +; + +alterLogfileGroupOptions: + alterLogfileGroupOption (COMMA_SYMBOL? alterLogfileGroupOption)* +; + +alterLogfileGroupOption: + tsOptionInitialSize + | tsOptionEngine + | tsOptionWait +; + +alterServer: + SERVER_SYMBOL serverRef serverOptions +; + +alterTable: + onlineOption? ({serverVersion < 50700}? IGNORE_SYMBOL)? TABLE_SYMBOL tableRef alterTableActions? +; + +/*alterTableActions: + alterCommandList (partitionClause | removePartitioning)? + | partitionClause + | removePartitioning + | (alterCommandsModifierList COMMA_SYMBOL)? standaloneAlterCommands +;*/ + +/* + * @FIX: + * Fix "alterTableActions" to solve conflicts between "alterCommandsModifierList" and "alterCommandList". + */ +alterTableActions: + (alterCommandsModifierList COMMA_SYMBOL)? standaloneAlterCommands + | alterCommandList (partitionClause | removePartitioning)? + | partitionClause + | removePartitioning +; + +/*alterCommandList: + alterCommandsModifierList + | (alterCommandsModifierList COMMA_SYMBOL)? alterList +;*/ + +/* + * @FIX: + * Fix "alterCommandList" to solve conflicts between "alterCommandsModifierList" prefixes. + */ +alterCommandList: + alterCommandsModifierList (COMMA_SYMBOL alterList)? + | alterList +; + +alterCommandsModifierList: + alterCommandsModifier (COMMA_SYMBOL alterCommandsModifier)* +; + +standaloneAlterCommands: + DISCARD_SYMBOL TABLESPACE_SYMBOL + | IMPORT_SYMBOL TABLESPACE_SYMBOL + | alterPartition + | {serverVersion >= 80014}? (SECONDARY_LOAD_SYMBOL | SECONDARY_UNLOAD_SYMBOL) +; + +alterPartition: + ADD_SYMBOL PARTITION_SYMBOL noWriteToBinLog? ( + partitionDefinitions + | PARTITIONS_SYMBOL real_ulong_number + ) + | DROP_SYMBOL PARTITION_SYMBOL identifierList + | REBUILD_SYMBOL PARTITION_SYMBOL noWriteToBinLog? allOrPartitionNameList + + // yes, twice "no write to bin log". + | OPTIMIZE_SYMBOL PARTITION_SYMBOL noWriteToBinLog? allOrPartitionNameList noWriteToBinLog? + | ANALYZE_SYMBOL PARTITION_SYMBOL noWriteToBinLog? allOrPartitionNameList + | CHECK_SYMBOL PARTITION_SYMBOL allOrPartitionNameList checkOption* + | REPAIR_SYMBOL PARTITION_SYMBOL noWriteToBinLog? allOrPartitionNameList repairType* + | COALESCE_SYMBOL PARTITION_SYMBOL noWriteToBinLog? real_ulong_number + | TRUNCATE_SYMBOL PARTITION_SYMBOL allOrPartitionNameList + | REORGANIZE_SYMBOL PARTITION_SYMBOL noWriteToBinLog? ( + identifierList INTO_SYMBOL partitionDefinitions + )? + | EXCHANGE_SYMBOL PARTITION_SYMBOL identifier WITH_SYMBOL TABLE_SYMBOL tableRef withValidation? + | {serverVersion >= 50704}? DISCARD_SYMBOL PARTITION_SYMBOL allOrPartitionNameList TABLESPACE_SYMBOL + | {serverVersion >= 50704}? IMPORT_SYMBOL PARTITION_SYMBOL allOrPartitionNameList TABLESPACE_SYMBOL +; + +alterList: + (alterListItem | createTableOptionsSpaceSeparated) ( + COMMA_SYMBOL ( + alterListItem + | alterCommandsModifier + | createTableOptionsSpaceSeparated + ) + )* +; + +alterCommandsModifier: + alterAlgorithmOption + | alterLockOption + | withValidation +; + +alterListItem: + ADD_SYMBOL COLUMN_SYMBOL? ( + identifier fieldDefinition checkOrReferences? place? + | OPEN_PAR_SYMBOL tableElementList CLOSE_PAR_SYMBOL + ) + | ADD_SYMBOL tableConstraintDef + | CHANGE_SYMBOL COLUMN_SYMBOL? columnInternalRef identifier fieldDefinition place? + | MODIFY_SYMBOL COLUMN_SYMBOL? columnInternalRef fieldDefinition place? + | DROP_SYMBOL ( + COLUMN_SYMBOL? columnInternalRef restrict? + | FOREIGN_SYMBOL KEY_SYMBOL ( + // This part is no longer optional starting with 5.7. + {serverVersion >= 50700}? columnInternalRef + | {serverVersion < 50700}? columnInternalRef? + ) + | PRIMARY_SYMBOL KEY_SYMBOL + | keyOrIndex indexRef + | {serverVersion >= 80017}? CHECK_SYMBOL identifier + | {serverVersion >= 80019}? CONSTRAINT_SYMBOL identifier + ) + | DISABLE_SYMBOL KEYS_SYMBOL + | ENABLE_SYMBOL KEYS_SYMBOL + | ALTER_SYMBOL COLUMN_SYMBOL? columnInternalRef ( + SET_SYMBOL DEFAULT_SYMBOL ( + {serverVersion >= 80014}? exprWithParentheses + | signedLiteral + ) + | DROP_SYMBOL DEFAULT_SYMBOL + | {serverVersion >= 80023}? SET_SYMBOL visibility /* @FIX: Add missing SET VISIBLE/INVISIBLE clause. */ + ) + | {serverVersion >= 80000}? ALTER_SYMBOL INDEX_SYMBOL indexRef visibility + | {serverVersion >= 80017}? ALTER_SYMBOL CHECK_SYMBOL identifier constraintEnforcement + | {serverVersion >= 80019}? ALTER_SYMBOL CONSTRAINT_SYMBOL identifier constraintEnforcement + | {serverVersion >= 80000}? RENAME_SYMBOL COLUMN_SYMBOL columnInternalRef TO_SYMBOL identifier + | RENAME_SYMBOL (TO_SYMBOL | AS_SYMBOL)? tableName + | {serverVersion >= 50700}? RENAME_SYMBOL keyOrIndex indexRef TO_SYMBOL indexName + | CONVERT_SYMBOL TO_SYMBOL charset ( + {serverVersion >= 80014}? DEFAULT_SYMBOL + | charsetName + ) collate? + | FORCE_SYMBOL + | ORDER_SYMBOL BY_SYMBOL alterOrderList + | {serverVersion >= 50708 && serverVersion < 80000}? UPGRADE_SYMBOL PARTITIONING_SYMBOL +; + +place: + AFTER_SYMBOL identifier + | FIRST_SYMBOL +; + +restrict: + RESTRICT_SYMBOL + | CASCADE_SYMBOL +; + +/*alterOrderList: + identifier direction? (COMMA_SYMBOL identifier direction?)* +;*/ + +/* + * @FIX: + * Fix ALTER TABLE with ORDER to use 'qualifiedIdentifier' instead of just 'identifier'. + * This is necessary to support "t.id" in a query like "ALTER TABLE t ORDER BY t.id". + */ +alterOrderList: + qualifiedIdentifier direction? (COMMA_SYMBOL qualifiedIdentifier direction?)* +; + +alterAlgorithmOption: + ALGORITHM_SYMBOL EQUAL_OPERATOR? (DEFAULT_SYMBOL | identifier) +; + +alterLockOption: + LOCK_SYMBOL EQUAL_OPERATOR? (DEFAULT_SYMBOL | identifier) +; + +indexLockAndAlgorithm: + alterAlgorithmOption alterLockOption? + | alterLockOption alterAlgorithmOption? +; + +withValidation: + {serverVersion >= 50706}? (WITH_SYMBOL | WITHOUT_SYMBOL) VALIDATION_SYMBOL +; + +removePartitioning: + REMOVE_SYMBOL PARTITIONING_SYMBOL +; + +allOrPartitionNameList: + ALL_SYMBOL + | identifierList +; + +alterTablespace: + TABLESPACE_SYMBOL tablespaceRef ( + (ADD_SYMBOL | DROP_SYMBOL) DATAFILE_SYMBOL textLiteral alterTablespaceOptions? + | {serverVersion < 80000}? ( + | CHANGE_SYMBOL DATAFILE_SYMBOL textLiteral ( + changeTablespaceOption (COMMA_SYMBOL? changeTablespaceOption)* + )? + | (READ_ONLY_SYMBOL | READ_WRITE_SYMBOL) + | NOT_SYMBOL ACCESSIBLE_SYMBOL + ) + | RENAME_SYMBOL TO_SYMBOL identifier + | {serverVersion >= 80014}? alterTablespaceOptions + ) +; + +alterUndoTablespace: + UNDO_SYMBOL TABLESPACE_SYMBOL tablespaceRef SET_SYMBOL ( + ACTIVE_SYMBOL + | INACTIVE_SYMBOL + ) undoTableSpaceOptions? +; + +undoTableSpaceOptions: + undoTableSpaceOption (COMMA_SYMBOL? undoTableSpaceOption)* +; + +undoTableSpaceOption: + tsOptionEngine +; + +alterTablespaceOptions: + alterTablespaceOption (COMMA_SYMBOL? alterTablespaceOption)* +; + +alterTablespaceOption: + INITIAL_SIZE_SYMBOL EQUAL_OPERATOR? sizeNumber + | tsOptionAutoextendSize + | tsOptionMaxSize + | tsOptionEngine + | {serverVersion >= 80021}? tsOptionEngineAttribute /* @FIX: Add missing "ENGINE_ATTRIBUTE" option. */ + | tsOptionWait + | tsOptionEncryption +; + +changeTablespaceOption: + INITIAL_SIZE_SYMBOL EQUAL_OPERATOR? sizeNumber + | tsOptionAutoextendSize + | tsOptionMaxSize +; + +alterView: + viewAlgorithm? definerClause? viewSuid? VIEW_SYMBOL viewRef viewTail +; + +// This is not the full view_tail from sql_yacc.yy as we have either a view name or a view reference, +// depending on whether we come from createView or alterView. Everything until this difference is duplicated in those rules. +viewTail: + columnInternalRefList? AS_SYMBOL viewSelect +; + +viewSelect: + queryExpressionOrParens viewCheckOption? +; + +viewCheckOption: + WITH_SYMBOL (CASCADED_SYMBOL | LOCAL_SYMBOL)? CHECK_SYMBOL OPTION_SYMBOL +; + +//---------------------------------------------------------------------------------------------------------------------- + +createStatement: + CREATE_SYMBOL ( + createDatabase + | createTable + | createFunction + | createProcedure + | createUdf + | createLogfileGroup + | createView + | createTrigger + | createIndex + | createServer + | createTablespace + | createEvent + | {serverVersion >= 80000}? createRole + | {serverVersion >= 80011}? createSpatialReference + | {serverVersion >= 80014}? createUndoTablespace + ) +; + +createDatabase: + DATABASE_SYMBOL ifNotExists? schemaName createDatabaseOption* +; + +createDatabaseOption: + defaultCharset + | defaultCollation + | {serverVersion >= 80016}? defaultEncryption +; + +/*createTable: + TEMPORARY_SYMBOL? TABLE_SYMBOL ifNotExists? tableName ( + (OPEN_PAR_SYMBOL tableElementList CLOSE_PAR_SYMBOL)? createTableOptions? partitionClause? duplicateAsQueryExpression? + | LIKE_SYMBOL tableRef + | OPEN_PAR_SYMBOL LIKE_SYMBOL tableRef CLOSE_PAR_SYMBOL + ) +;*/ + +/* + * @FIX: + * Fix "createTable" to solve support "LIKE tableRef" and "LIKE (tableRef)". + * They need to come before "tableElementList" to avoid misinterpreting "LIKE". + */ +createTable: + TEMPORARY_SYMBOL? TABLE_SYMBOL ifNotExists? tableName ( + LIKE_SYMBOL tableRef + | OPEN_PAR_SYMBOL LIKE_SYMBOL tableRef CLOSE_PAR_SYMBOL + | (OPEN_PAR_SYMBOL tableElementList CLOSE_PAR_SYMBOL)? createTableOptions? partitionClause? duplicateAsQueryExpression? + ) +; + +tableElementList: + tableElement (COMMA_SYMBOL tableElement)* +; + +tableElement: + columnDefinition + | tableConstraintDef +; + +duplicateAsQueryExpression: (REPLACE_SYMBOL | IGNORE_SYMBOL)? AS_SYMBOL? queryExpressionOrParens +; + +queryExpressionOrParens: + queryExpression + | queryExpressionParens +; + +createRoutine: // Rule for external use only. + CREATE_SYMBOL (createProcedure | createFunction | createUdf) SEMICOLON_SYMBOL? EOF +; + +/* + * @FIX: + * Add missing "ifNotExists?". + */ +createProcedure: + definerClause? PROCEDURE_SYMBOL ({serverVersion >= 80029}? ifNotExists?) procedureName OPEN_PAR_SYMBOL ( + procedureParameter (COMMA_SYMBOL procedureParameter)* + )? CLOSE_PAR_SYMBOL routineCreateOption* compoundStatement +; + +/* + * @FIX: + * Add missing "ifNotExists?". + */ +createFunction: + definerClause? FUNCTION_SYMBOL ({serverVersion >= 80029}? ifNotExists?) functionName OPEN_PAR_SYMBOL ( + functionParameter (COMMA_SYMBOL functionParameter)* + )? CLOSE_PAR_SYMBOL RETURNS_SYMBOL typeWithOptCollate routineCreateOption* compoundStatement +; + +createUdf: + AGGREGATE_SYMBOL? FUNCTION_SYMBOL udfName RETURNS_SYMBOL type = ( + STRING_SYMBOL + | INT_SYMBOL + | REAL_SYMBOL + | DECIMAL_SYMBOL + ) SONAME_SYMBOL textLiteral +; + +routineCreateOption: + routineOption + | NOT_SYMBOL? DETERMINISTIC_SYMBOL +; + +routineAlterOptions: + routineCreateOption+ +; + +routineOption: + option = COMMENT_SYMBOL textLiteral + | option = LANGUAGE_SYMBOL SQL_SYMBOL + | option = NO_SYMBOL SQL_SYMBOL + | option = CONTAINS_SYMBOL SQL_SYMBOL + | option = READS_SYMBOL SQL_SYMBOL DATA_SYMBOL + | option = MODIFIES_SYMBOL SQL_SYMBOL DATA_SYMBOL + | option = SQL_SYMBOL SECURITY_SYMBOL security = ( + DEFINER_SYMBOL + | INVOKER_SYMBOL + ) +; + +createIndex: + onlineOption? ( + UNIQUE_SYMBOL? type = INDEX_SYMBOL ( + {serverVersion >= 80014}? indexName indexTypeClause? + | indexNameAndType? + ) createIndexTarget indexOption* + | type = FULLTEXT_SYMBOL INDEX_SYMBOL indexName createIndexTarget fulltextIndexOption* + | type = SPATIAL_SYMBOL INDEX_SYMBOL indexName createIndexTarget spatialIndexOption* + ) indexLockAndAlgorithm? +; + +/* + The syntax for defining an index is: + + ... INDEX [index_name] [USING|TYPE] ... + + The problem is that whereas USING is a reserved word, TYPE is not. We can + still handle it if an index name is supplied, i.e.: + + ... INDEX type TYPE ... + + here the index's name is unmbiguously 'type', but for this: + + ... INDEX TYPE ... + + it's impossible to know what this actually mean - is 'type' the name or the + type? For this reason we accept the TYPE syntax only if a name is supplied. +*/ +/*indexNameAndType: + indexName (USING_SYMBOL indexType)? + | indexName TYPE_SYMBOL indexType +;*/ + +/* + * @FIX: + * Fix "indexNameAndType" to solve conflicts between "indexName USING_SYMBOL" + * and "indexName TYPE_SYMBOL" prefix by moving them to a single branch. + */ +indexNameAndType: + indexName? ((USING_SYMBOL | TYPE_SYMBOL) indexType)? +; + +createIndexTarget: + ON_SYMBOL tableRef keyListVariants +; + +createLogfileGroup: + LOGFILE_SYMBOL GROUP_SYMBOL logfileGroupName ADD_SYMBOL ( + UNDOFILE_SYMBOL + | REDOFILE_SYMBOL // No longer used from 8.0 onwards. Taken out by lexer. + ) textLiteral logfileGroupOptions? +; + +logfileGroupOptions: + logfileGroupOption (COMMA_SYMBOL? logfileGroupOption)* +; + +logfileGroupOption: + tsOptionInitialSize + | tsOptionUndoRedoBufferSize + | tsOptionNodegroup + | tsOptionEngine + | tsOptionWait + | tsOptionComment +; + +createServer: + SERVER_SYMBOL serverName FOREIGN_SYMBOL DATA_SYMBOL WRAPPER_SYMBOL textOrIdentifier serverOptions +; + +serverOptions: + OPTIONS_SYMBOL OPEN_PAR_SYMBOL serverOption (COMMA_SYMBOL serverOption)* CLOSE_PAR_SYMBOL +; + +// Options for CREATE/ALTER SERVER, used for the federated storage engine. +serverOption: + option = HOST_SYMBOL textLiteral + | option = DATABASE_SYMBOL textLiteral + | option = USER_SYMBOL textLiteral + | option = PASSWORD_SYMBOL textLiteral + | option = SOCKET_SYMBOL textLiteral + | option = OWNER_SYMBOL textLiteral + | option = PORT_SYMBOL ulong_number +; + +createTablespace: + TABLESPACE_SYMBOL tablespaceName tsDataFileName ( + USE_SYMBOL LOGFILE_SYMBOL GROUP_SYMBOL logfileGroupRef + )? tablespaceOptions? +; + +createUndoTablespace: + UNDO_SYMBOL TABLESPACE_SYMBOL tablespaceName ADD_SYMBOL tsDataFile undoTableSpaceOptions? +; + +tsDataFileName: + {serverVersion >= 80014}? (ADD_SYMBOL tsDataFile)? + | ADD_SYMBOL tsDataFile +; + +tsDataFile: + DATAFILE_SYMBOL textLiteral +; + +tablespaceOptions: + tablespaceOption (COMMA_SYMBOL? tablespaceOption)* +; + +tablespaceOption: + tsOptionInitialSize + | tsOptionAutoextendSize + | tsOptionMaxSize + | tsOptionExtentSize + | tsOptionNodegroup + | tsOptionEngine + | {serverVersion >= 80021}? tsOptionEngineAttribute /* @FIX: Add missing "ENGINE_ATTRIBUTE" option. */ + | tsOptionWait + | tsOptionComment + | {serverVersion >= 50707}? tsOptionFileblockSize + | {serverVersion >= 80014}? tsOptionEncryption +; + +tsOptionInitialSize: + INITIAL_SIZE_SYMBOL EQUAL_OPERATOR? sizeNumber +; + +tsOptionUndoRedoBufferSize: + (UNDO_BUFFER_SIZE_SYMBOL | REDO_BUFFER_SIZE_SYMBOL) EQUAL_OPERATOR? sizeNumber +; + +tsOptionAutoextendSize: + AUTOEXTEND_SIZE_SYMBOL EQUAL_OPERATOR? sizeNumber +; + +tsOptionMaxSize: + MAX_SIZE_SYMBOL EQUAL_OPERATOR? sizeNumber +; + +tsOptionExtentSize: + EXTENT_SIZE_SYMBOL EQUAL_OPERATOR? sizeNumber +; + +tsOptionNodegroup: + NODEGROUP_SYMBOL EQUAL_OPERATOR? real_ulong_number +; + +tsOptionEngine: + STORAGE_SYMBOL? ENGINE_SYMBOL EQUAL_OPERATOR? engineRef +; + +/* + * @FIX: + * Add missing "ENGINE_ATTRIBUTE" option. + */ +tsOptionEngineAttribute: + ENGINE_ATTRIBUTE_SYMBOL EQUAL_OPERATOR? textStringLiteral +; + +tsOptionWait: (WAIT_SYMBOL | NO_WAIT_SYMBOL) +; + +tsOptionComment: + COMMENT_SYMBOL EQUAL_OPERATOR? textLiteral +; + +tsOptionFileblockSize: + FILE_BLOCK_SIZE_SYMBOL EQUAL_OPERATOR? sizeNumber +; + +tsOptionEncryption: + ENCRYPTION_SYMBOL EQUAL_OPERATOR? textStringLiteral +; + +createView: + viewReplaceOrAlgorithm? definerClause? viewSuid? VIEW_SYMBOL viewName viewTail +; + +viewReplaceOrAlgorithm: + OR_SYMBOL REPLACE_SYMBOL viewAlgorithm? + | viewAlgorithm +; + +viewAlgorithm: + ALGORITHM_SYMBOL EQUAL_OPERATOR algorithm = ( + UNDEFINED_SYMBOL + | MERGE_SYMBOL + | TEMPTABLE_SYMBOL + ) +; + +viewSuid: + SQL_SYMBOL SECURITY_SYMBOL (DEFINER_SYMBOL | INVOKER_SYMBOL) +; + +/* + * @FIX: + * Add missing "ifNotExists?". + */ +createTrigger: + definerClause? TRIGGER_SYMBOL ({serverVersion >= 80029}? ifNotExists?) triggerName timing = (BEFORE_SYMBOL | AFTER_SYMBOL) event = ( + INSERT_SYMBOL + | UPDATE_SYMBOL + | DELETE_SYMBOL + ) ON_SYMBOL tableRef FOR_SYMBOL EACH_SYMBOL ROW_SYMBOL triggerFollowsPrecedesClause? compoundStatement +; + +triggerFollowsPrecedesClause: + {serverVersion >= 50700}? ordering = (FOLLOWS_SYMBOL | PRECEDES_SYMBOL) textOrIdentifier // not a trigger reference! +; + +createEvent: + definerClause? EVENT_SYMBOL ifNotExists? eventName ON_SYMBOL SCHEDULE_SYMBOL schedule ( + ON_SYMBOL COMPLETION_SYMBOL NOT_SYMBOL? PRESERVE_SYMBOL + )? (ENABLE_SYMBOL | DISABLE_SYMBOL (ON_SYMBOL SLAVE_SYMBOL)?)? ( + COMMENT_SYMBOL textLiteral + )? DO_SYMBOL compoundStatement +; + +createRole: + // The server grammar has a clear_privileges rule here, which is only used to clear internal state. + ROLE_SYMBOL ifNotExists? roleList +; + +createSpatialReference: + OR_SYMBOL REPLACE_SYMBOL SPATIAL_SYMBOL REFERENCE_SYMBOL SYSTEM_SYMBOL real_ulonglong_number srsAttribute* + | SPATIAL_SYMBOL REFERENCE_SYMBOL SYSTEM_SYMBOL ifNotExists? real_ulonglong_number srsAttribute* +; + +srsAttribute: + NAME_SYMBOL TEXT_SYMBOL textStringNoLinebreak + | DEFINITION_SYMBOL TEXT_SYMBOL textStringNoLinebreak + | ORGANIZATION_SYMBOL textStringNoLinebreak IDENTIFIED_SYMBOL BY_SYMBOL real_ulonglong_number + | DESCRIPTION_SYMBOL TEXT_SYMBOL textStringNoLinebreak +; + +//---------------------------------------------------------------------------------------------------------------------- + +dropStatement: + DROP_SYMBOL ( + dropDatabase + | dropEvent + | dropFunction + | dropProcedure + | dropIndex + | dropLogfileGroup + | dropServer + | dropTable + | dropTableSpace + | dropTrigger + | dropView + | {serverVersion >= 80000}? dropRole + | {serverVersion >= 80011}? dropSpatialReference + | {serverVersion >= 80014}? dropUndoTablespace + ) +; + +dropDatabase: + DATABASE_SYMBOL ifExists? schemaRef +; + +dropEvent: + EVENT_SYMBOL ifExists? eventRef +; + +dropFunction: + FUNCTION_SYMBOL ifExists? functionRef // Including UDFs. +; + +dropProcedure: + PROCEDURE_SYMBOL ifExists? procedureRef +; + +dropIndex: + onlineOption? type = INDEX_SYMBOL indexRef ON_SYMBOL tableRef indexLockAndAlgorithm? +; + +dropLogfileGroup: + LOGFILE_SYMBOL GROUP_SYMBOL logfileGroupRef ( + dropLogfileGroupOption (COMMA_SYMBOL? dropLogfileGroupOption)* + )? +; + +dropLogfileGroupOption: + tsOptionWait + | tsOptionEngine +; + +dropServer: + SERVER_SYMBOL ifExists? serverRef +; + +dropTable: + TEMPORARY_SYMBOL? type = (TABLE_SYMBOL | TABLES_SYMBOL) ifExists? tableRefList ( + RESTRICT_SYMBOL + | CASCADE_SYMBOL + )? +; + +dropTableSpace: + TABLESPACE_SYMBOL tablespaceRef ( + dropLogfileGroupOption (COMMA_SYMBOL? dropLogfileGroupOption)* + )? +; + +dropTrigger: + TRIGGER_SYMBOL ifExists? triggerRef +; + +dropView: + VIEW_SYMBOL ifExists? viewRefList (RESTRICT_SYMBOL | CASCADE_SYMBOL)? +; + +dropRole: + ROLE_SYMBOL ifExists? roleList +; + +dropSpatialReference: + SPATIAL_SYMBOL REFERENCE_SYMBOL SYSTEM_SYMBOL ifExists? real_ulonglong_number +; + +dropUndoTablespace: + UNDO_SYMBOL TABLESPACE_SYMBOL tablespaceRef undoTableSpaceOptions? +; + +//---------------------------------------------------------------------------------------------------------------------- + +renameTableStatement: + RENAME_SYMBOL (TABLE_SYMBOL | TABLES_SYMBOL) renamePair (COMMA_SYMBOL renamePair)* +; + +renamePair: + tableRef TO_SYMBOL tableName +; + +//---------------------------------------------------------------------------------------------------------------------- + +truncateTableStatement: + TRUNCATE_SYMBOL TABLE_SYMBOL? tableRef +; + +//---------------------------------------------------------------------------------------------------------------------- + +importStatement: + IMPORT_SYMBOL TABLE_SYMBOL FROM_SYMBOL textStringLiteralList +; + +//--------------- DML statements --------------------------------------------------------------------------------------- + +callStatement: + CALL_SYMBOL procedureRef (OPEN_PAR_SYMBOL exprList? CLOSE_PAR_SYMBOL)? +; + +deleteStatement: + ({serverVersion >= 80000}? withClause)? DELETE_SYMBOL deleteStatementOption* ( + FROM_SYMBOL ( + tableAliasRefList USING_SYMBOL tableReferenceList whereClause? // Multi table variant 1. + | tableRef ({serverVersion >= 80017}? tableAlias)? partitionDelete? + whereClause? orderClause? simpleLimitClause? // Single table delete. + ) + | tableAliasRefList FROM_SYMBOL tableReferenceList whereClause? // Multi table variant 2. + ) +; + +partitionDelete: + {serverVersion >= 50602}? PARTITION_SYMBOL OPEN_PAR_SYMBOL identifierList CLOSE_PAR_SYMBOL +; + +deleteStatementOption: // opt_delete_option in sql_yacc.yy, but the name collides with another rule (delete_options). + QUICK_SYMBOL + | LOW_PRIORITY_SYMBOL + | QUICK_SYMBOL + | IGNORE_SYMBOL +; + +/*doStatement: + DO_SYMBOL ( + {serverVersion < 50709}? exprList + | {serverVersion >= 50709}? selectItemList + ) +;*/ + +/* + * @FIX: + * Reorder "selectItemList" and "exprList" to match "selectItemList", as we don't handle versions yet. + */ +doStatement: + DO_SYMBOL ( + {serverVersion >= 50709}? selectItemList + | {serverVersion < 50709}? exprList + ) +; + +handlerStatement: + HANDLER_SYMBOL ( + tableRef OPEN_SYMBOL tableAlias? + | identifier ( + CLOSE_SYMBOL + | READ_SYMBOL handlerReadOrScan whereClause? limitClause? + ) + ) +; + +handlerReadOrScan: + (FIRST_SYMBOL | NEXT_SYMBOL) // Scan function. + | identifier ( + // The rkey part. + (FIRST_SYMBOL | NEXT_SYMBOL | PREV_SYMBOL | LAST_SYMBOL) + | ( + EQUAL_OPERATOR + | LESS_THAN_OPERATOR + | GREATER_THAN_OPERATOR + | LESS_OR_EQUAL_OPERATOR + | GREATER_OR_EQUAL_OPERATOR + ) OPEN_PAR_SYMBOL values CLOSE_PAR_SYMBOL + ) +; + +//---------------------------------------------------------------------------------------------------------------------- + +insertStatement: + INSERT_SYMBOL insertLockOption? IGNORE_SYMBOL? INTO_SYMBOL? tableRef usePartition? ( + insertFromConstructor ({ serverVersion >= 80018}? valuesReference)? + | SET_SYMBOL updateList ({ serverVersion >= 80018}? valuesReference)? + | insertQueryExpression + ) insertUpdateList? +; + +insertLockOption: + LOW_PRIORITY_SYMBOL + | DELAYED_SYMBOL // Only allowed if no select is used. Check in the semantic phase. + | HIGH_PRIORITY_SYMBOL +; + +insertFromConstructor: + (OPEN_PAR_SYMBOL fields? CLOSE_PAR_SYMBOL)? insertValues +; + +fields: + insertIdentifier (COMMA_SYMBOL insertIdentifier)* +; + +insertValues: + (VALUES_SYMBOL | VALUE_SYMBOL) valueList +; + +insertQueryExpression: + queryExpressionOrParens + | OPEN_PAR_SYMBOL fields? CLOSE_PAR_SYMBOL queryExpressionOrParens +; + +valueList: + OPEN_PAR_SYMBOL values? CLOSE_PAR_SYMBOL ( + COMMA_SYMBOL OPEN_PAR_SYMBOL values? CLOSE_PAR_SYMBOL + )* +; + +values: + (expr | DEFAULT_SYMBOL) (COMMA_SYMBOL (expr | DEFAULT_SYMBOL))* +; + +valuesReference: + AS_SYMBOL identifier columnInternalRefList? +; + +insertUpdateList: + ON_SYMBOL DUPLICATE_SYMBOL KEY_SYMBOL UPDATE_SYMBOL updateList +; + +//---------------------------------------------------------------------------------------------------------------------- + +loadStatement: + LOAD_SYMBOL dataOrXml (LOW_PRIORITY_SYMBOL | CONCURRENT_SYMBOL)? LOCAL_SYMBOL? INFILE_SYMBOL textLiteral ( + REPLACE_SYMBOL + | IGNORE_SYMBOL + )? INTO_SYMBOL TABLE_SYMBOL tableRef usePartition? charsetClause? xmlRowsIdentifiedBy? fieldsClause? linesClause? + loadDataFileTail +; + +dataOrXml: + DATA_SYMBOL + | XML_SYMBOL +; + +xmlRowsIdentifiedBy: + ROWS_SYMBOL IDENTIFIED_SYMBOL BY_SYMBOL textString +; + +loadDataFileTail: + (IGNORE_SYMBOL INT_NUMBER (LINES_SYMBOL | ROWS_SYMBOL))? loadDataFileTargetList? ( + SET_SYMBOL updateList + )? +; + +loadDataFileTargetList: + OPEN_PAR_SYMBOL fieldOrVariableList? CLOSE_PAR_SYMBOL +; + +fieldOrVariableList: + (columnRef | userVariable) (COMMA_SYMBOL (columnRef | userVariable))* +; + +//---------------------------------------------------------------------------------------------------------------------- + +replaceStatement: + REPLACE_SYMBOL (LOW_PRIORITY_SYMBOL | DELAYED_SYMBOL)? INTO_SYMBOL? tableRef usePartition? ( + insertFromConstructor + | SET_SYMBOL updateList + | insertQueryExpression + ) +; + +//---------------------------------------------------------------------------------------------------------------------- + +/*selectStatement: + queryExpression lockingClauseList? + | queryExpressionParens + | selectStatementWithInto +;*/ + +/* + * @FIX: + * Fix "selectStatement" to solve conflicts between "queryExpressionParens" and "selectStatementWithInto". + * Since "queryExpression" already contains "queryExpressionParens" as a subrule, we can remove it here. + */ +selectStatement: + queryExpression lockingClauseList? + | selectStatementWithInto +; + +/* + From the server grammar: + + MySQL has a syntax extension that allows into clauses in any one of two + places. They may appear either before the from clause or at the end. All in + a top-level select statement. This extends the standard syntax in two + ways. First, we don't have the restriction that the result can contain only + one row: the into clause might be INTO OUTFILE/DUMPFILE in which case any + number of rows is allowed. Hence MySQL does not have any special case for + the standard's syntax all the way down to the . So instead we solve it by writing an ambiguous grammar and use + precedence rules to sort out the shift/reduce conflict. + + The problem is when the parser has seen SELECT