diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index fc639501a..e7cb6c8ad 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -349,6 +349,7 @@ Ram Satish Ramesh Reddy Randall Hauch Raphael Auv +Raúl Estrada Raúl Tovar Renato Mefi René Kerner diff --git a/debezium-connector-mysql/src/main/java/io/debezium/connector/mysql/antlr/MySqlAntlrDdlParser.java b/debezium-connector-mysql/src/main/java/io/debezium/connector/mysql/antlr/MySqlAntlrDdlParser.java index 516e4941a..2d16a7290 100644 --- a/debezium-connector-mysql/src/main/java/io/debezium/connector/mysql/antlr/MySqlAntlrDdlParser.java +++ b/debezium-connector-mysql/src/main/java/io/debezium/connector/mysql/antlr/MySqlAntlrDdlParser.java @@ -111,6 +111,7 @@ protected DataTypeResolver initializeDataTypeResolver() { new DataTypeEntry(Types.VARCHAR, MySqlParser.TEXT), new DataTypeEntry(Types.VARCHAR, MySqlParser.MEDIUMTEXT), new DataTypeEntry(Types.VARCHAR, MySqlParser.LONGTEXT), + new DataTypeEntry(Types.VARCHAR, MySqlParser.LONG), new DataTypeEntry(Types.NCHAR, MySqlParser.NCHAR), new DataTypeEntry(Types.NVARCHAR, MySqlParser.NCHAR, MySqlParser.VARYING), new DataTypeEntry(Types.NVARCHAR, MySqlParser.NVARCHAR), diff --git a/debezium-ddl-parser/src/main/antlr4/io/debezium/ddl/parser/mysql/generated/MySqlLexer.g4 b/debezium-ddl-parser/src/main/antlr4/io/debezium/ddl/parser/mysql/generated/MySqlLexer.g4 index 32d971534..0271967e3 100644 --- a/debezium-ddl-parser/src/main/antlr4/io/debezium/ddl/parser/mysql/generated/MySqlLexer.g4 +++ b/debezium-ddl-parser/src/main/antlr4/io/debezium/ddl/parser/mysql/generated/MySqlLexer.g4 @@ -4,7 +4,7 @@ The MIT License (MIT). Copyright (c) 2015-2017, Ivan Kochurkin (kvanttt@gmail.com), Positive Technologies. Copyright (c) 2017, Ivan Khudyashev (IHudyashov@ptsecurity.com) -https://github.com/antlr/grammars-v4/blob/master/mysql/MySqlLexer.g4 +https://github.com/antlr/grammars-v4/blob/master/sql/mysql/Positive-Technologies/MySqlLexer.g4 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -23,7 +23,6 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ lexer grammar MySqlLexer; @@ -36,8 +35,8 @@ SPACE: [ \t\r\n]+ -> channel(HIDDEN); SPEC_MYSQL_COMMENT: '/*!' .+? '*/' -> channel(MYSQLCOMMENT); COMMENT_INPUT: '/*' .*? '*/' -> channel(HIDDEN); LINE_COMMENT: ( - ('--' [ \t] | '#') ~[\r\n]* ('\r'? '\n' | EOF) - | '--' ('\r'? '\n' | EOF) + ('--' [ \t] | '#') ~[\r\n]* ('\r'? '\n' | EOF) + | '--' ('\r'? '\n' | EOF) ) -> channel(HIDDEN); @@ -45,7 +44,6 @@ LINE_COMMENT: ( // Common Keywords ADD: 'ADD'; -ADMIN: 'ADMIN'; ALL: 'ALL'; ALTER: 'ALTER'; ALWAYS: 'ALWAYS'; @@ -165,10 +163,10 @@ OPTIONAL: 'OPTIONAL'; OPTIONALLY: 'OPTIONALLY'; OR: 'OR'; ORDER: 'ORDER'; -OVER: 'OVER'; OUT: 'OUT'; OUTER: 'OUTER'; OUTFILE: 'OUTFILE'; +OVER: 'OVER'; PARTITION: 'PARTITION'; PRIMARY: 'PRIMARY'; PROCEDURE: 'PROCEDURE'; @@ -185,6 +183,7 @@ REPLACE: 'REPLACE'; REQUIRE: 'REQUIRE'; RESIGNAL: 'RESIGNAL'; RESTRICT: 'RESTRICT'; +RETAIN: 'RETAIN'; RETURN: 'RETURN'; REVOKE: 'REVOKE'; RIGHT: 'RIGHT'; @@ -208,6 +207,7 @@ SQL_SMALL_RESULT: 'SQL_SMALL_RESULT'; SSL: 'SSL'; STACKED: 'STACKED'; STARTING: 'STARTING'; +STATEMENT: 'STATEMENT'; STRAIGHT_JOIN: 'STRAIGHT_JOIN'; TABLE: 'TABLE'; TERMINATED: 'TERMINATED'; @@ -233,7 +233,6 @@ WITH: 'WITH'; WRITE: 'WRITE'; XOR: 'XOR'; ZEROFILL: 'ZEROFILL'; -STATEMENT: 'STATEMENT'; // DATA TYPE Keywords @@ -291,7 +290,7 @@ DAY_MINUTE: 'DAY_MINUTE'; DAY_SECOND: 'DAY_SECOND'; HOUR_MINUTE: 'HOUR_MINUTE'; HOUR_SECOND: 'HOUR_SECOND'; -MINUTE_SECOND: 'MINUTE_SECOND'; +MINUTE_SECOND: 'MINUTE_SECOND'; SECOND_MICROSECOND: 'SECOND_MICROSECOND'; MINUTE_MICROSECOND: 'MINUTE_MICROSECOND'; HOUR_MICROSECOND: 'HOUR_MICROSECOND'; @@ -458,11 +457,9 @@ DUMPFILE: 'DUMPFILE'; DUPLICATE: 'DUPLICATE'; DYNAMIC: 'DYNAMIC'; ENABLE: 'ENABLE'; -ENCRYPTION: 'ENCRYPTION'; ENCRYPTED: 'ENCRYPTED'; +ENCRYPTION: 'ENCRYPTION'; ENCRYPTION_KEY_ID: 'ENCRYPTION_KEY_ID'; -PAGE_COMPRESSED: 'PAGE_COMPRESSED'; -PAGE_COMPRESSION_LEVEL: 'PAGE_COMPRESSION_LEVEL'; END: 'END'; ENDS: 'ENDS'; ENGINE: 'ENGINE'; @@ -584,7 +581,6 @@ NOCYCLE: 'NOCYCLE'; NOMAXVALUE: 'NOMAXVALUE'; NOMINVALUE: 'NOMINVALUE'; NOWAIT: 'NOWAIT'; -YES: 'YES'; NODEGROUP: 'NODEGROUP'; NONE: 'NONE'; ODBC: 'ODBC'; @@ -602,6 +598,8 @@ OPTIONS: 'OPTIONS'; OWNER: 'OWNER'; PACK_KEYS: 'PACK_KEYS'; PAGE: 'PAGE'; +PAGE_COMPRESSED: 'PAGE_COMPRESSED'; +PAGE_COMPRESSION_LEVEL: 'PAGE_COMPRESSION_LEVEL'; PARSER: 'PARSER'; PARTIAL: 'PARTIAL'; PARTITIONING: 'PARTITIONING'; @@ -738,7 +736,7 @@ WRAPPER: 'WRAPPER'; X509: 'X509'; XA: 'XA'; XML: 'XML'; - +YES: 'YES'; // Date format Keywords @@ -763,15 +761,7 @@ MICROSECOND: 'MICROSECOND'; // PRIVILEGES -TABLES: 'TABLES'; -ROUTINE: 'ROUTINE'; -EXECUTE: 'EXECUTE'; -FILE: 'FILE'; -PROCESS: 'PROCESS'; -RELOAD: 'RELOAD'; -SHUTDOWN: 'SHUTDOWN'; -SUPER: 'SUPER'; -PRIVILEGES: 'PRIVILEGES'; +ADMIN: 'ADMIN'; APPLICATION_PASSWORD_ADMIN: 'APPLICATION_PASSWORD_ADMIN'; AUDIT_ADMIN: 'AUDIT_ADMIN'; BACKUP_ADMIN: 'BACKUP_ADMIN'; @@ -780,6 +770,8 @@ BINLOG_ENCRYPTION_ADMIN: 'BINLOG_ENCRYPTION_ADMIN'; CLONE_ADMIN: 'CLONE_ADMIN'; CONNECTION_ADMIN: 'CONNECTION_ADMIN'; ENCRYPTION_KEY_ADMIN: 'ENCRYPTION_KEY_ADMIN'; +EXECUTE: 'EXECUTE'; +FILE: 'FILE'; FIREWALL_ADMIN: 'FIREWALL_ADMIN'; FIREWALL_USER: 'FIREWALL_USER'; FLUSH_OPTIMIZER_COSTS: 'FLUSH_OPTIMIZER_COSTS'; @@ -794,17 +786,24 @@ LAMBDA: 'LAMBDA'; NDB_STORED_USER: 'NDB_STORED_USER'; PASSWORDLESS_USER_ADMIN: 'PASSWORDLESS_USER_ADMIN'; PERSIST_RO_VARIABLES_ADMIN: 'PERSIST_RO_VARIABLES_ADMIN'; +PRIVILEGES: 'PRIVILEGES'; +PROCESS: 'PROCESS'; +RELOAD: 'RELOAD'; REPLICATION_APPLIER: 'REPLICATION_APPLIER'; REPLICATION_SLAVE_ADMIN: 'REPLICATION_SLAVE_ADMIN'; RESOURCE_GROUP_ADMIN: 'RESOURCE_GROUP_ADMIN'; RESOURCE_GROUP_USER: 'RESOURCE_GROUP_USER'; ROLE_ADMIN: 'ROLE_ADMIN'; +ROUTINE: 'ROUTINE'; S3: 'S3'; SERVICE_CONNECTION_ADMIN: 'SERVICE_CONNECTION_ADMIN'; SESSION_VARIABLES_ADMIN: QUOTE_SYMB? 'SESSION_VARIABLES_ADMIN' QUOTE_SYMB?; SET_USER_ID: 'SET_USER_ID'; SHOW_ROUTINE: 'SHOW_ROUTINE'; +SHUTDOWN: 'SHUTDOWN'; +SUPER: 'SUPER'; SYSTEM_VARIABLES_ADMIN: 'SYSTEM_VARIABLES_ADMIN'; +TABLES: 'TABLES'; TABLE_ENCRYPTION_ADMIN: 'TABLE_ENCRYPTION_ADMIN'; VERSION_TOKEN_ADMIN: 'VERSION_TOKEN_ADMIN'; XA_RECOVER_ADMIN: 'XA_RECOVER_ADMIN'; @@ -1075,7 +1074,6 @@ RADIANS: 'RADIANS'; RAND: 'RAND'; RANDOM_BYTES: 'RANDOM_BYTES'; RELEASE_LOCK: 'RELEASE_LOCK'; -RETAIN: 'RETAIN'; REVERSE: 'REVERSE'; ROUND: 'ROUND'; ROW_COUNT: 'ROW_COUNT'; @@ -1315,14 +1313,17 @@ ID: ID_LITERAL; // DOUBLE_QUOTE_ID: '"' ~'"'+ '"'; REVERSE_QUOTE_ID: '`' ~'`'+ '`'; STRING_USER_NAME: ( - SQUOTA_STRING | DQUOTA_STRING + SQUOTA_STRING | DQUOTA_STRING | BQUOTA_STRING | ID_LITERAL - ) '@' + ) '@' ( - SQUOTA_STRING | DQUOTA_STRING + SQUOTA_STRING | DQUOTA_STRING | BQUOTA_STRING | ID_LITERAL - | [0-9]+ '.' [0-9]+ '.' [0-9]+ '.' [0-9]+ - | [0-9A-Fa-f:]+ + | IP_ADDRESS + ); +IP_ADDRESS: ( + [0-9]+ '.' [0-9.]+ + | [0-9A-F:]+ ':' [0-9A-F:]+ ); STRING_USER_NAME_MARIADB: ( SQUOTA_STRING | DQUOTA_STRING @@ -1344,14 +1345,14 @@ GLOBAL_ID: '@' '@' // Fragments for Literal primitives -fragment CHARSET_NAME: ARMSCII8 | ASCII | BIG5 | BINARY | CP1250 - | CP1251 | CP1256 | CP1257 | CP850 - | CP852 | CP866 | CP932 | DEC8 | EUCJPMS - | EUCKR | GB2312 | GBK | GEOSTD8 | GREEK - | HEBREW | HP8 | KEYBCS2 | KOI8R | KOI8U - | LATIN1 | LATIN2 | LATIN5 | LATIN7 - | MACCE | MACROMAN | SJIS | SWE7 | TIS620 - | UCS2 | UJIS | UTF16 | UTF16LE | UTF32 +fragment CHARSET_NAME: ARMSCII8 | ASCII | BIG5 | BINARY | CP1250 + | CP1251 | CP1256 | CP1257 | CP850 + | CP852 | CP866 | CP932 | DEC8 | EUCJPMS + | EUCKR | 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; fragment EXPONENT_NUM_PART: 'E' [-+]? DEC_DIGIT+; diff --git a/debezium-ddl-parser/src/main/antlr4/io/debezium/ddl/parser/mysql/generated/MySqlParser.g4 b/debezium-ddl-parser/src/main/antlr4/io/debezium/ddl/parser/mysql/generated/MySqlParser.g4 index 8a7b639cf..cfdaad89f 100644 --- a/debezium-ddl-parser/src/main/antlr4/io/debezium/ddl/parser/mysql/generated/MySqlParser.g4 +++ b/debezium-ddl-parser/src/main/antlr4/io/debezium/ddl/parser/mysql/generated/MySqlParser.g4 @@ -4,7 +4,7 @@ The MIT License (MIT). Copyright (c) 2015-2017, Ivan Kochurkin (kvanttt@gmail.com), Positive Technologies. Copyright (c) 2017, Ivan Khudyashev (IHudyashov@ptsecurity.com) -https://github.com/antlr/grammars-v4/blob/master/mysql/MySqlParser.g4 +https://github.com/antlr/grammars-v4/blob/master/sql/mysql/Positive-Technologies/MySqlParser.g4 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -42,11 +42,15 @@ sqlStatements ; sqlStatement - : setStatementFor? (ddlStatement | dmlStatement | transactionStatement // setStatementFor is is MariaDB-specific only + : setStatementFor? (ddlStatement | dmlStatement | transactionStatement // setStatementFor is MariaDB-specific only | replicationStatement | preparedStatement | administrationStatement | utilityStatement) ; +setStatementFor // setStatementFor is MariaDB-specific only + :SET STATEMENT ID EQUAL_SYMBOL constant (COMMA ID EQUAL_SYMBOL constant)* FOR + ; + emptyStatement : SEMI ; @@ -55,8 +59,7 @@ ddlStatement : createDatabase | createEvent | createIndex | createLogfileGroup | createProcedure | createFunction | createServer | createTable | createTablespaceInnodb - | createTablespaceNdb | createTrigger | createView - | createRole | createSequence + | createTablespaceNdb | createTrigger | createView | createRole | createSequence | alterDatabase | alterEvent | alterFunction | alterInstance | alterLogfileGroup | alterProcedure | alterServer | alterTable | alterTablespace | alterView | alterSequence @@ -107,7 +110,7 @@ administrationStatement | grantProxy | renameUser | revokeStatement | revokeProxy | analyzeTable | checkTable | checksumTable | optimizeTable | repairTable - | createUdfFunction | installPlugin | uninstallPlugin + | createUdfunction | installPlugin | uninstallPlugin | setStatement | showStatement | binlogStatement | cacheIndexStatement | flushStatement | killStatement | loadIndexIntoCache | resetStatement @@ -139,13 +142,13 @@ createEvent ; createIndex - : CREATE (OR REPLACE)? // OR is MariaDB-specific only + : CREATE orReplace? // orReplace is MariaDB-specific only intimeAction=(ONLINE | OFFLINE)? indexCategory=(UNIQUE | FULLTEXT | SPATIAL)? INDEX - (IF NOT EXISTS)? // MariaDB-specific only + ifNotExists? // ifNotExists is MariaDB-specific only uid indexType? ON tableName indexColumnNames - waitNowaitClause? // MariaDB-specific only + waitNowaitClause? // waitNowaitClause is MariaDB-specific only indexOption* ( ALGORITHM EQUAL_SYMBOL? algType=(DEFAULT | INPLACE | COPY | NOCOPY | INSTANT) // NOCOPY, INSTANT are MariaDB-specific only @@ -166,7 +169,7 @@ createLogfileGroup ; createProcedure - : CREATE (OR REPLACE)? ownerStatement? + : CREATE orReplace? ownerStatement? // orReplace is MariaDB-specific only PROCEDURE fullId '(' procedureParameter? (',' procedureParameter)* ')' routineOption* @@ -174,8 +177,8 @@ createProcedure ; createFunction - : CREATE (OR REPLACE)? ownerStatement? AGGREGATE? - FUNCTION ifNotExists? fullId + : CREATE orReplace? ownerStatement? AGGREGATE? // orReplace is MariaDB-specific only + FUNCTION ifNotExists? fullId // ifNotExists is MariaDB-specific only '(' functionParameter? (',' functionParameter)* ')' RETURNS dataType routineOption* @@ -183,7 +186,7 @@ createFunction ; createRole - : CREATE ROLE (IF NOT EXISTS)? roleName (',' roleName)* + : CREATE ROLE ifNotExists? roleName (',' roleName)* ; createServer @@ -193,18 +196,18 @@ createServer ; createTable - : CREATE (OR REPLACE)? TEMPORARY? TABLE ifNotExists? // OR is MariaDB-specific only + : CREATE orReplace? TEMPORARY? TABLE ifNotExists? // orReplace is MariaDB-specific only tableName ( LIKE tableName | '(' LIKE parenthesisTable=tableName ')' ) #copyCreateTable - | CREATE (OR REPLACE)? TEMPORARY? TABLE ifNotExists? // OR is MariaDB-specific only + | CREATE orReplace? TEMPORARY? TABLE ifNotExists? // orReplace is MariaDB-specific only tableName createDefinitions? ( tableOption (','? tableOption)* )? partitionDefinitions? keyViolate=(IGNORE | REPLACE)? AS? selectStatement #queryCreateTable - | CREATE (OR REPLACE)? TEMPORARY? TABLE ifNotExists? // OR is MariaDB-specific only + | CREATE orReplace? TEMPORARY? TABLE ifNotExists? // orReplace is MariaDB-specific only tableName createDefinitions ( tableOption (','? tableOption)* )? partitionDefinitions? #columnCreateTable @@ -232,7 +235,7 @@ createTablespaceNdb ; createTrigger - : CREATE (OR REPLACE)? ownerStatement? // OR is MariaDB-specific only + : CREATE orReplace? ownerStatement? // orReplace is MariaDB-specific only TRIGGER thisTrigger=fullId triggerTime=(BEFORE | AFTER) triggerEvent=(INSERT | UPDATE | DELETE) @@ -259,7 +262,7 @@ cteColumnName ; createView - : CREATE (OR REPLACE)? + : CREATE orReplace? // orReplace is MariaDB-specific only ( ALGORITHM '=' algType=(UNDEFINED | MERGE | TEMPTABLE) )? @@ -274,7 +277,7 @@ createView ; createSequence - : CREATE (OR REPLACE)? TEMPORARY? SEQUENCE ifNotExists? fullId + : CREATE orReplace? TEMPORARY? SEQUENCE ifNotExists? fullId // orReplace is MariaDB-specific only (sequenceSpec | tableOption)* ; @@ -297,12 +300,18 @@ sequenceSpec // details createDatabaseOption - : DEFAULT? (CHARACTER SET | CHARSET | CHAR SET) '='? (charsetName | DEFAULT) + : DEFAULT? charSet '='? (charsetName | DEFAULT) | DEFAULT? COLLATE '='? collationName | DEFAULT? ENCRYPTION '='? STRING_LITERAL | READ ONLY '='? (DEFAULT | ZERO_DECIMAL | ONE_DECIMAL) ; +charSet + : CHARACTER SET + | CHARSET + | CHAR SET + ; + ownerStatement : DEFINER '=' (userName | CURRENT_USER ( '(' ')')? | CURRENT_ROLE) // CURRENT_ROLE is MariaDB-specific only ; @@ -360,15 +369,11 @@ indexOption ; procedureParameter - : parameter + : direction=(IN | OUT | INOUT)? uid dataType ; functionParameter - : parameter - ; - -parameter - : direction=(IN | OUT | INOUT | IN_OUT)? uid dataType + : uid dataType ; routineOption @@ -409,7 +414,8 @@ columnDefinition columnConstraint : nullNotnull #nullColumnConstraint | DEFAULT defaultValue #defaultColumnConstraint - | (VISIBLE | INVISIBLE) #invisibleColumnConstraint + | VISIBLE #visibilityColumnConstraint + | INVISIBLE #invisibilityColumnConstraint | (AUTO_INCREMENT | ON UPDATE currentTimestamp) #autoIncrementColumnConstraint | PRIMARY? KEY #primaryKeyColumnConstraint | UNIQUE KEY? #uniqueKeyColumnConstraint @@ -473,7 +479,7 @@ tableOption | AUTOEXTEND_SIZE '='? decimalLiteral #tableOptionAutoextendSize | AUTO_INCREMENT '='? decimalLiteral #tableOptionAutoIncrement | AVG_ROW_LENGTH '='? decimalLiteral #tableOptionAverage - | DEFAULT? (CHARACTER SET | CHARSET | CHAR SET) '='? (charsetName|DEFAULT) #tableOptionCharset + | DEFAULT? charSet '='? (charsetName|DEFAULT) #tableOptionCharset | (CHECKSUM | PAGE_CHECKSUM) '='? boolValue=('0' | '1') #tableOptionChecksum | DEFAULT? COLLATE '='? collationName #tableOptionCollate | COMMENT '='? STRING_LITERAL #tableOptionComment @@ -548,10 +554,10 @@ partitionDefinition partitionDefinerAtom (',' partitionDefinerAtom)* ')' partitionOption* - ( '(' subpartitionDefinition (',' subpartitionDefinition)* ')' )? #partitionComparision + ( '(' subpartitionDefinition (',' subpartitionDefinition)* ')' )? #partitionComparison | PARTITION uid VALUES LESS THAN partitionDefinerAtom partitionOption* - ( '(' subpartitionDefinition (',' subpartitionDefinition)* ')' )? #partitionComparision + ( '(' subpartitionDefinition (',' subpartitionDefinition)* ')' )? #partitionComparison | PARTITION uid VALUES IN '(' partitionDefinerAtom (',' partitionDefinerAtom)* @@ -661,20 +667,20 @@ alterView ; alterSequence - : ALTER SEQUENCE ifExists? fullId sequenceSpec+ + : ALTER SEQUENCE ifExists? fullId sequenceSpec+ // MariaDB-specific only ; // details alterSpecification : tableOption (','? tableOption)* #alterByTableOption - | ADD COLUMN? ifNotExists? uid columnDefinition (FIRST | AFTER uid)? #alterByAddColumn // ifNotExists is MariaDB-specific - | ADD COLUMN? ifNotExists? + | ADD COLUMN? ifNotExists? uid columnDefinition (FIRST | AFTER uid)? #alterByAddColumn // ifNotExists is MariaDB-specific only + | ADD COLUMN? ifNotExists? // ifNotExists is MariaDB-specific only '(' uid columnDefinition ( ',' uid columnDefinition)* - ')' #alterByAddColumns // ifNotExists is MariaDB-specific - | ADD indexFormat=(INDEX | KEY) ifNotExists? uid? indexType? - indexColumnNames indexOption* #alterByAddIndex // ifNotExists is MariaDB-specific + ')' #alterByAddColumns + | ADD indexFormat=(INDEX | KEY) ifNotExists? uid? indexType? // ifNotExists is MariaDB-specific only + indexColumnNames indexOption* #alterByAddIndex | ADD (CONSTRAINT name=uid?)? PRIMARY KEY index=uid? indexType? indexColumnNames indexOption* #alterByAddPrimaryKey | ADD (CONSTRAINT name=uid?)? UNIQUE @@ -683,26 +689,26 @@ alterSpecification | ADD keyType=(FULLTEXT | SPATIAL) indexFormat=(INDEX | KEY)? uid? indexColumnNames indexOption* #alterByAddSpecialIndex - | ADD (CONSTRAINT name=uid?)? FOREIGN KEY ifNotExists? - indexName=uid? indexColumnNames referenceDefinition #alterByAddForeignKey // ifNotExists is MariaDB-specific + | ADD (CONSTRAINT name=uid?)? FOREIGN KEY ifNotExists? // ifNotExists is MariaDB-specific only + indexName=uid? indexColumnNames referenceDefinition #alterByAddForeignKey | ADD (CONSTRAINT name=uid?)? CHECK '(' expression ')' #alterByAddCheckTableConstraint | ALGORITHM '='? algType=(DEFAULT | INSTANT | INPLACE | COPY) #alterBySetAlgorithm | ALTER COLUMN? uid (SET DEFAULT defaultValue | DROP DEFAULT) #alterByChangeDefault - | CHANGE COLUMN? ifExists? oldColumn=uid + | CHANGE COLUMN? ifExists? oldColumn=uid // here ifExists is MariaDB-specific only newColumn=uid columnDefinition - (FIRST | AFTER afterColumn=uid)? #alterByChangeColumn // ifExists is MariaDB-specific + (FIRST | AFTER afterColumn=uid)? #alterByChangeColumn | RENAME COLUMN oldColumn=uid TO newColumn=uid #alterByRenameColumn | LOCK '='? lockType=(DEFAULT | NONE | SHARED | EXCLUSIVE) #alterByLock - | MODIFY COLUMN? ifExists? - uid columnDefinition (FIRST | AFTER uid)? #alterByModifyColumn // ifExists is MariaDB-specific - | DROP COLUMN? ifExists? uid RESTRICT? #alterByDropColumn // ifExists is MariaDB-specific - | DROP (CONSTRAINT | CHECK) ifExists? uid #alterByDropConstraintCheck // ifExists is MariaDB-specific + | MODIFY COLUMN? ifExists? // here ifExists is MariaDB-specific only + uid columnDefinition (FIRST | AFTER uid)? #alterByModifyColumn + | DROP COLUMN? ifExists? uid RESTRICT? #alterByDropColumn // here ifExists is MariaDB-specific only + | DROP (CONSTRAINT | CHECK) ifExists? uid #alterByDropConstraintCheck // here ifExists is MariaDB-specific only | DROP PRIMARY KEY #alterByDropPrimaryKey - | DROP indexFormat=(INDEX | KEY) ifExists? uid #alterByDropIndex + | DROP indexFormat=(INDEX | KEY) ifExists? uid #alterByDropIndex // here ifExists is MariaDB-specific only | RENAME indexFormat=(INDEX | KEY) uid TO uid #alterByRenameIndex | ALTER INDEX uid (VISIBLE | INVISIBLE) #alterByAlterIndexVisibility - | DROP FOREIGN KEY ifExists? uid #alterByDropForeignKey // ifExists is MariaDB-specific + | DROP FOREIGN KEY ifExists? uid #alterByDropForeignKey // here ifExists is MariaDB-specific only | DISABLE KEYS #alterByDisableKeys | ENABLE KEYS #alterByEnableKeys | RENAME renameFormat=(TO | AS)? (uid | fullId) #alterByRename @@ -715,11 +721,11 @@ alterSpecification | IMPORT TABLESPACE #alterByImportTablespace | FORCE #alterByForce | validationFormat=(WITHOUT | WITH) VALIDATION #alterByValidate - | ADD PARTITION ifNotExists? + | ADD PARTITION ifNotExists? // ifNotExists is MariaDB-specific only '(' partitionDefinition (',' partitionDefinition)* - ')' #alterByAddPartition // ifNotExists is MariaDB-specific - | DROP PARTITION ifExists? uidList #alterByDropPartition // ifExists is MariaDB-specific + ')' #alterByAddPartition + | DROP PARTITION ifExists? uidList #alterByDropPartition // here ifExists is MariaDB-specific only | DISCARD PARTITION (uidList | ALL) TABLESPACE #alterByDiscardPartition | IMPORT PARTITION (uidList | ALL) TABLESPACE #alterByImportPartition | TRUNCATE PARTITION (uidList | ALL) #alterByTruncatePartition @@ -737,8 +743,8 @@ alterSpecification | REPAIR PARTITION (uidList | ALL) #alterByRepairPartition | REMOVE PARTITIONING #alterByRemovePartitioning | UPGRADE PARTITIONING #alterByUpgradePartitioning - | ADD COLUMN? ifNotExists? - '(' createDefinition (',' createDefinition)* ')' #alterByAddDefinitions // ifNotExists is MariaDB-specific + | ADD COLUMN? ifNotExists? // ifNotExists is MariaDB-specific only + '(' createDefinition (',' createDefinition)* ')' #alterByAddDefinitions ; @@ -753,7 +759,7 @@ dropEvent ; dropIndex - : DROP INDEX ifExists? intimeAction=(ONLINE | OFFLINE)? + : DROP INDEX ifExists? intimeAction=(ONLINE | OFFLINE)? // here ifExists is MariaDB-specific only uid ON tableName ( ALGORITHM '='? algType=(DEFAULT | INPLACE | COPY) @@ -801,16 +807,16 @@ dropRole : DROP ROLE ifExists? roleName (',' roleName)* ; -dropSequence - : DROP TEMPORARY? SEQUENCE ifExists? COMMENT_INPUT? fullId (',' fullId)* - ; - setRole : SET DEFAULT ROLE (NONE | ALL | roleName (',' roleName)*) TO (userName | uid) (',' (userName | uid))* | SET ROLE roleOption ; +dropSequence + : DROP TEMPORARY? SEQUENCE ifExists? COMMENT_INPUT? fullId (',' fullId)* + ; + // Other DDL statements renameTable @@ -1089,14 +1095,14 @@ queryExpressionNointo querySpecification : SELECT selectSpec* selectElements selectIntoExpression? - fromClause? orderByClause? limitClause? + fromClause? groupByClause? havingClause? windowClause? orderByClause? limitClause? | SELECT selectSpec* selectElements - fromClause? orderByClause? limitClause? selectIntoExpression? + fromClause? groupByClause? havingClause? windowClause? orderByClause? limitClause? selectIntoExpression? ; querySpecificationNointo : SELECT selectSpec* selectElements - fromClause? orderByClause? limitClause? + fromClause? groupByClause? havingClause? windowClause? orderByClause? limitClause? ; unionParenthesis @@ -1164,13 +1170,20 @@ selectLinesInto fromClause : (FROM tableSources)? (WHERE whereExpr=expression)? - ( - GROUP BY + ; + +groupByClause + : GROUP BY groupByItem (',' groupByItem)* (WITH ROLLUP)? - )? - (HAVING havingExpr=expression)? - (WINDOW windowName AS '(' windowSpec ')' (',' windowName AS '(' windowSpec ')')*)? + ; + +havingClause + : HAVING havingExpr=expression + ; + +windowClause + : WINDOW windowName AS '(' windowSpec ')' (',' windowName AS '(' windowSpec ')')* ; groupByItem @@ -1657,8 +1670,8 @@ userAuthOption | userName IDENTIFIED BY STRING_LITERAL (RETAIN CURRENT PASSWORD)? #stringAuthOption | userName - IDENTIFIED (WITH | VIA) // VIA and OR are MariaDB only - authenticationRule (OR authenticationRule)* #moduleAuthOption + IDENTIFIED (WITH | VIA) // VIA is MariaDB-specific only + authenticationRule (OR authenticationRule)* #moduleAuthOption // OR is MariaDB-specific only | userName #simpleAuthOption ; @@ -1781,8 +1794,8 @@ checkTableOption // Plugin and udf statements -createUdfFunction - : CREATE (OR REPLACE)? AGGREGATE? FUNCTION ifNotExists? uid +createUdfunction + : CREATE orReplace? AGGREGATE? FUNCTION ifNotExists? uid // or replace is MariaDB-specific RETURNS returnType=(STRING | INTEGER | REAL | DECIMAL) SONAME STRING_LITERAL ; @@ -1801,7 +1814,7 @@ uninstallPlugin setStatement : SET variableClause ('=' | ':=') (expression | ON) (',' variableClause ('=' | ':=') (expression | ON))* #setVariable - | SET (CHARACTER SET | CHARSET | CHAR SET) (charsetName | DEFAULT) #setCharset + | SET charSet (charsetName | DEFAULT) #setCharset | SET NAMES (charsetName (COLLATE collationName)? | DEFAULT) #setNames | setPasswordStatement #setPassword @@ -1944,8 +1957,7 @@ flushOption | USER_RESOURCES | TABLES (WITH READ LOCK)? ) #simpleFlushOption | RELAY LOGS channelOption? #channelFlushOption - | TABLES tables? flushTableOption? #tableFlushOption - | TABLE tables? flushTableOption? #tableFlushOption + | (TABLE | TABLES) tables? flushTableOption? #tableFlushOption ; flushTableOption @@ -2073,7 +2085,7 @@ indexColumnName ; userName - : STRING_USER_NAME | STRING_USER_NAME_MARIADB | ID | STRING_LITERAL | keywordsCanBeId; + : STRING_USER_NAME | STRING_USER_NAME_MARIADB | ID | STRING_LITERAL | ADMIN | keywordsCanBeId; mysqlVariable : LOCAL_ID @@ -2198,11 +2210,11 @@ constant dataType : typeName=( CHAR | CHARACTER | VARCHAR | TINYTEXT | TEXT | MEDIUMTEXT | LONGTEXT - | NCHAR | NVARCHAR + | NCHAR | NVARCHAR | LONG ) VARYING? lengthOneDimension? BINARY? - ((CHARACTER SET | CHARSET | CHAR SET) charsetName)? + (charSet charsetName)? (COLLATE collationName | BINARY)? #stringDataType | NATIONAL typeName=(VARCHAR | CHARACTER) lengthOneDimension? BINARY? #nationalStringDataType @@ -2222,7 +2234,7 @@ dataType | typeName=(DECIMAL | DEC | FIXED | NUMERIC | FLOAT | FLOAT4 | FLOAT8) lengthTwoOptionalDimension? (SIGNED | UNSIGNED | ZEROFILL)* #dimensionDataType | typeName=( - DATE | TINYBLOB | MEDIUMBLOB | LONGBLOB + DATE | TINYBLOB | MEDIUMBLOB | LONGBLOB | BOOL | BOOLEAN | SERIAL ) #simpleDataType | typeName=( @@ -2232,14 +2244,14 @@ dataType lengthOneDimension? #dimensionDataType | typeName=(ENUM | SET) collectionOptions BINARY? - ((CHARACTER SET | CHARSET | CHAR SET) charsetName)? #collectionDataType + (charSet charsetName)? #collectionDataType | typeName=( GEOMETRYCOLLECTION | GEOMCOLLECTION | LINESTRING | MULTILINESTRING | MULTIPOINT | MULTIPOLYGON | POINT | POLYGON | JSON | GEOMETRY ) #spatialDataType | typeName=LONG VARCHAR? BINARY? - ((CHARACTER SET | CHARSET | CHAR SET) charsetName)? + (charSet charsetName)? (COLLATE collationName)? #longVarcharDataType // LONG VARCHAR is the same as LONG | LONG VARBINARY #longVarbinaryDataType ; @@ -2256,7 +2268,7 @@ convertedDataType : ( typeName=(BINARY| NCHAR) lengthOneDimension? - | typeName=CHAR lengthOneDimension? ((CHARACTER SET | CHARSET | CHAR SET) charsetName)? + | typeName=CHAR lengthOneDimension? (charSet charsetName)? | typeName=(DATE | DATETIME | TIME | JSON | INT | INTEGER) | typeName=DECIMAL lengthTwoOptionalDimension? | (SIGNED | UNSIGNED) INTEGER? @@ -2343,12 +2355,19 @@ expressionOrDefault ; ifExists - : IF EXISTS; - -ifNotExists - : IF NOT EXISTS; + : IF EXISTS + ; // Mariadb-specific + +ifNotExists + : IF NOT EXISTS + ; + +orReplace + : OR REPLACE + ; + waitNowaitClause : WAIT decimalLiteral | NOWAIT @@ -2373,7 +2392,7 @@ functionCall specificFunction : ( CURRENT_DATE | CURRENT_TIME | CURRENT_TIMESTAMP - | CURDATE | CURTIME // MariaDB-specific + | CURDATE | CURTIME // MariaDB-specific only | CURRENT_USER | LOCALTIME | UTC_TIMESTAMP | SCHEMA ) ('(' ')')? #simpleFunctionCall | CONVERT '(' expression separator=',' convertedDataType ')' #dataTypeFunctionCall @@ -2381,7 +2400,7 @@ specificFunction | CAST '(' expression AS convertedDataType ')' #dataTypeFunctionCall | VALUES '(' fullColumnName ')' #valuesFunctionCall | CASE expression caseFuncAlternative+ - (ELSE elseArg=functionArg)? END #caseFunctionCall + (ELSE elseArg=functionArg)? END #caseExpressionFunctionCall | CASE caseFuncAlternative+ (ELSE elseArg=functionArg)? END #caseFunctionCall | CHAR '(' functionArgs (USING charsetName)? ')' #charFunctionCall @@ -2588,9 +2607,9 @@ expression predicate : predicate NOT? IN '(' (selectStatement | expressions) ')' #inPredicate | predicate IS nullNotnull #isNullPredicate - | left=predicate comparisonOperator right=predicate #binaryComparasionPredicate + | left=predicate comparisonOperator right=predicate #binaryComparisonPredicate | predicate comparisonOperator - quantifier=(ALL | ANY | SOME) '(' selectStatement ')' #subqueryComparasionPredicate + quantifier=(ALL | ANY | SOME) '(' selectStatement ')' #subqueryComparisonPredicate | predicate NOT? BETWEEN predicate AND predicate #betweenPredicate | predicate SOUNDS LIKE predicate #soundsLikePredicate | predicate NOT? LIKE predicate (ESCAPE STRING_LITERAL)? #likePredicate @@ -2611,8 +2630,8 @@ expressionAtom | BINARY expressionAtom #binaryExpressionAtom | '(' expression (',' expression)* ')' #nestedExpressionAtom | ROW '(' expression (',' expression)+ ')' #nestedRowExpressionAtom - | EXISTS '(' selectStatement ')' #existsExpessionAtom - | '(' selectStatement ')' #subqueryExpessionAtom + | EXISTS '(' selectStatement ')' #existsExpressionAtom + | '(' selectStatement ')' #subqueryExpressionAtom | INTERVAL expression intervalType #intervalExpressionAtom | left=expressionAtom bitOperator right=expressionAtom #bitExpressionAtom | left=expressionAtom mathOperator right=expressionAtom #mathExpressionAtom @@ -2675,8 +2694,8 @@ dataTypeBase ; keywordsCanBeId - : ACCOUNT | ACTION | AFTER | AGGREGATE | ALGORITHM | ANY - | AT | ADMIN | AUDIT_ADMIN | AUTHORS | AUTOCOMMIT | AUTOEXTEND_SIZE + : ACCOUNT | ACTION | ADMIN | AFTER | AGGREGATE | ALGORITHM | ANY + | AT | AUDIT_ADMIN | AUTHORS | AUTOCOMMIT | AUTOEXTEND_SIZE | AUTO_INCREMENT | 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 @@ -2715,7 +2734,7 @@ keywordsCanBeId | NCHAR | NDB_STORED_USER | NEVER | NEXT | NO | NOCOPY | NODEGROUP | NONE | NOWAIT | NUMBER | ODBC | OFFLINE | OFFSET | OF | OJ | OLD_PASSWORD | ONE | ONLINE | ONLY | OPEN | OPTIMIZER_COSTS | OPTIONAL | OPTIONS | ORDER | OWNER | PACK_KEYS | PAGE | PARSER | PARTIAL - | PARTITIONING | PARTITIONS | PASSWORD | PASSWORD_LOCK_TIME | PERSIST_RO_VARIABLES_ADMIN | PHASE | PLUGINS + | PARTITIONING | PARTITIONS | PASSWORD | PASSWORDLESS_USER_ADMIN | PASSWORD_LOCK_TIME | 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 @@ -2740,10 +2759,10 @@ keywordsCanBeId | 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 - // MariaDB - | VIA | LASTVAL | NEXTVAL | SETVAL | PREVIOUS | PERSISTENT | REPLICATION_MASTER_ADMIN | REPLICA | READ_ONLY_ADMIN | FEDERATED_ADMIN | BINLOG_MONITOR | BINLOG_REPLAY - | ENCRYPTED | ENCRYPTION_KEY_ID | CURRENT_ROLE | SKIP_ | LOCKED | CYCLE | INCREMENT | MINVALUE | MAXVALUE | NOCACHE - | NOCYCLE | NOMINVALUE | NOMAXVALUE | RESTART | SEQUENCE | STATEMENT + // MariaDB-specific only + | BINLOG_MONITOR | BINLOG_REPLAY | CURRENT_ROLE | CYCLE | ENCRYPTED | ENCRYPTION_KEY_ID | FEDERATED_ADMIN + | INCREMENT | LASTVAL | LOCKED | MAXVALUE | MINVALUE | NEXTVAL | NOCACHE | NOCYCLE | NOMAXVALUE | NOMINVALUE + | PERSISTENT | PREVIOUS | READ_ONLY_ADMIN | REPLICA | REPLICATION_MASTER_ADMIN | RESTART | SEQUENCE | SETVAL | SKIP_ | STATEMENT | VIA ; functionNameBase @@ -2793,7 +2812,7 @@ functionNameBase | POLYFROMWKB | POLYGON | POLYGONFROMTEXT | POLYGONFROMWKB | POSITION | POW | POWER | QUARTER | QUOTE | RADIANS | RAND | RANK | RANDOM_BYTES | RELEASE_LOCK | REVERSE | RIGHT | ROUND - | ROW_COUNT | ROW_NUMBER | RPAD | RTRIM | SECOND | SEC_TO_TIME + | 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 @@ -2838,5 +2857,3 @@ functionNameBase | LASTVAL | NEXTVAL | SETVAL ; -// MariaDB statements -setStatementFor: SET STATEMENT ID EQUAL_SYMBOL constant (COMMA ID EQUAL_SYMBOL constant)* FOR; // MariaDB-specific only diff --git a/debezium-ddl-parser/src/test/resources/mysql/examples/ddl_create.sql b/debezium-ddl-parser/src/test/resources/mysql/examples/ddl_create.sql index 4f0575308..5e19c1e37 100644 --- a/debezium-ddl-parser/src/test/resources/mysql/examples/ddl_create.sql +++ b/debezium-ddl-parser/src/test/resources/mysql/examples/ddl_create.sql @@ -332,7 +332,7 @@ RETURN #end #begin -- Use UTC_TIMESTAMP without parenthesis -CREATE FUNCTION IF NOT EXISTS myfunc(IN a INT) RETURNS INT +CREATE FUNCTION IF NOT EXISTS myfunc(a INT) RETURNS INT BEGIN DECLARE result INT; SET result = UTC_TIMESTAMP;