MySQL database type plugin for Flyway database migration engine providing specialized MySQL and MariaDB support for schema migrations.
—
SQL parsing classes provide MySQL and MariaDB-specific SQL parsing capabilities, handling database-specific syntax, delimiters, comments, and statement types. They ensure proper parsing of MySQL/MariaDB SQL scripts during migrations.
MySQL-specific SQL parser that handles MySQL syntax, delimiters, comments, and stored procedures.
/**
* MySQL-specific SQL parser
* Handles MySQL SQL syntax, delimiters, comments, and statement parsing
*/
public class MySQLParser extends Parser {
/**
* Creates a new MySQL parser instance
* @param configuration Flyway configuration
* @param parsingContext Context for parsing operations
*/
public MySQLParser(Configuration configuration, ParsingContext parsingContext);
/**
* Handles DELIMITER command processing
* MySQL allows changing statement delimiters with DELIMITER command
* @param reader Source reader for SQL content
* @param context Parser context and state
* @param pos Current position in source
* @param line Current line number
* @param col Current column number
* @param keyword The "DELIMITER" keyword
* @return Token representing the new delimiter
* @throws IOException if reading fails
*/
@Override
protected Token handleKeyword(PeekingReader reader, ParserContext context, int pos, int line, int col, String keyword) throws IOException;
/**
* Returns the identifier quote character for MySQL
* @return '`' (backtick) for MySQL identifiers
*/
@Override
protected char getIdentifierQuote();
/**
* Returns the alternative string literal quote character
* @return '"' (double quote) for alternative string literals
*/
@Override
protected char getAlternativeStringLiteralQuote();
/**
* Determines if a character sequence is a single-line comment
* Supports both -- and # comment styles
* @param peek Character sequence to check
* @param context Parser context
* @param col Current column position
* @return true if sequence is a single-line comment
*/
@Override
protected boolean isSingleLineComment(String peek, ParserContext context, int col);
/**
* Handles string literal parsing with MySQL-specific escaping
* @param reader Source reader
* @param context Parser context
* @param pos Current position
* @param line Current line number
* @param col Current column number
* @return String literal token
* @throws IOException if reading fails
*/
@Override
protected Token handleStringLiteral(PeekingReader reader, ParserContext context, int pos, int line, int col) throws IOException;
/**
* Handles alternative string literal parsing (double quotes)
* @param reader Source reader
* @param context Parser context
* @param pos Current position
* @param line Current line number
* @param col Current column number
* @return String literal token
* @throws IOException if reading fails
*/
@Override
protected Token handleAlternativeStringLiteral(PeekingReader reader, ParserContext context, int pos, int line, int col) throws IOException;
/**
* Handles MySQL comment directives (/*! ... */)
* @param reader Source reader
* @param context Parser context
* @param pos Current position
* @param line Current line number
* @param col Current column number
* @return Comment directive token
* @throws IOException if reading fails
*/
@Override
protected Token handleCommentDirective(PeekingReader reader, ParserContext context, int pos, int line, int col) throws IOException;
/**
* Determines if text is a MySQL comment directive
* MySQL comment directives start with /*! and contain version-specific SQL
* @param text Text to check
* @return true if text is a comment directive
*/
@Override
protected boolean isCommentDirective(String text);
/**
* Detects MySQL statement types including stored procedures
* @param simplifiedStatement Simplified statement text
* @param context Parser context
* @param reader Source reader for additional parsing
* @return Statement type classification
*/
@Override
protected StatementType detectStatementType(String simplifiedStatement, ParserContext context, PeekingReader reader);
/**
* Determines if block depth should be adjusted for MySQL syntax
* @param context Parser context
* @param tokens Current token list
* @param token Current token being processed
* @return true if block depth adjustment needed
*/
@Override
protected boolean shouldAdjustBlockDepth(ParserContext context, List<Token> tokens, Token token);
/**
* Adjusts block depth for MySQL control structures
* @param context Parser context
* @param tokens Current token list
* @param keyword Current keyword token
* @param reader Source reader for lookahead
*/
@Override
protected void adjustBlockDepth(ParserContext context, List<Token> tokens, Token keyword, PeekingReader reader);
/**
* Resets delimiter state (MySQL preserves delimiters across statements)
* @param context Parser context
*/
@Override
protected void resetDelimiter(ParserContext context);
}Constants:
// Comment and parsing constants
private static final char ALTERNATIVE_SINGLE_LINE_COMMENT = '#';
private static final Pattern STORED_PROGRAM_REGEX = Pattern.compile(
"^CREATE\\s(((DEFINER\\s(\\w+\\s)?@\\s(\\w+\\s)?)?(PROCEDURE|FUNCTION|EVENT))|TRIGGER)",
Pattern.CASE_INSENSITIVE);
private static final StatementType STORED_PROGRAM_STATEMENT = new StatementType();
}Usage Examples:
// Parser creation via DatabaseType
MySQLDatabaseType dbType = new MySQLDatabaseType();
MySQLParser parser = (MySQLParser) dbType.createParser(configuration, resourceProvider, parsingContext);
// Parse MySQL script with DELIMITER changes
String sql = """
DELIMITER $$
CREATE PROCEDURE test_proc()
BEGIN
SELECT 'Hello World';
END$$
DELIMITER ;
""";
List<SqlStatement> statements = parser.parse(sql);MariaDB-specific SQL parser extending MySQL parser with MariaDB-specific syntax support.
/**
* MariaDB-specific SQL parser
* Extends MySQLParser with MariaDB-specific syntax and features
*/
public class MariaDBParser extends MySQLParser {
/**
* Creates a new MariaDB parser instance
* @param configuration Flyway configuration
* @param parsingContext Context for parsing operations
*/
public MariaDBParser(Configuration configuration, ParsingContext parsingContext);
/**
* Detects MariaDB-specific statement types
* Includes support for BEGIN NOT ATOMIC and other MariaDB extensions
* @param simplifiedStatement Simplified statement text
* @param context Parser context
* @param reader Source reader for additional parsing
* @return Statement type classification
*/
@Override
protected StatementType detectStatementType(String simplifiedStatement, ParserContext context, PeekingReader reader);
/**
* Adjusts block depth for MariaDB-specific control structures
* Handles BEGIN NOT ATOMIC and other MariaDB syntax
* @param context Parser context
* @param tokens Current token list
* @param keyword Current keyword token
* @param reader Source reader for lookahead
*/
@Override
protected void adjustBlockDepth(ParserContext context, List<Token> tokens, Token keyword, PeekingReader reader);
}Usage Example:
// MariaDB parser creation
MariaDBDatabaseType dbType = new MariaDBDatabaseType();
MariaDBParser parser = (MariaDBParser) dbType.createParser(configuration, resourceProvider, parsingContext);
// Parse MariaDB-specific syntax
String mariadbSql = """
BEGIN NOT ATOMIC
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;
SELECT 'MariaDB specific syntax';
END;
""";
List<SqlStatement> statements = parser.parse(mariadbSql);MySQL supports changing statement delimiters:
-- Default delimiter is semicolon
SELECT * FROM users;
-- Change delimiter for stored procedures
DELIMITER $$
CREATE PROCEDURE get_users()
BEGIN
SELECT * FROM users;
END$$
-- Reset delimiter
DELIMITER ;Parser Behavior:
DELIMITER commandTwo formats supported:
-- Standard SQL comment
SELECT * FROM users; -- End of line comment
# MySQL hash comment
SELECT * FROM users; # Alternative comment styleNote: Hash comments (#) are disabled when # is set as delimiter.
/* Standard multi-line comment */
SELECT * FROM users;
/*! MySQL-specific comment directive */
/*!50717 SELECT * FROM users */; -- Only execute on MySQL 5.7.17+SELECT 'Hello World';
SELECT 'Don\'t worry'; -- Escaped quoteSELECT "Hello World";
SELECT "Don\"t worry"; -- Escaped quoteParser Features:
\', \", \\)MySQL uses backticks for identifiers:
SELECT `column name with spaces` FROM `table name`;
CREATE TABLE `order` (`index` INT); -- Reserved word quotingDetects MySQL stored procedures, functions, events, and triggers:
// Pattern for stored program detection
"^CREATE\\s(((DEFINER\\s(\\w+\\s)?@\\s(\\w+\\s)?)?(PROCEDURE|FUNCTION|EVENT))|TRIGGER)"Supported Patterns:
CREATE PROCEDURE proc_name() ...
CREATE FUNCTION func_name() RETURNS INT ...
CREATE EVENT event_name ...
CREATE TRIGGER trigger_name ...
CREATE DEFINER=`user`@`host` PROCEDURE ...Block depth tracking for MySQL control structures:
BEGIN...END blocksIF...END IF statementsWHILE...END WHILE loopsREPEAT...UNTIL loopsCASE...END CASE statementsMariaDB supports BEGIN NOT ATOMIC for compound statements:
BEGIN NOT ATOMIC
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;
INSERT INTO logs VALUES ('Starting operation');
-- More statements
END;Parser Behavior:
BEGIN NOT ATOMIC patternMariaDB parser extends MySQL detection with:
BEGIN NOT ATOMIC compound statementsMySQL comment directives provide version-specific SQL:
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!50717 SELECT JSON_EXTRACT(data, '$.key') FROM table1 */;Parsers maintain block depth for:
Parser context tracks:
Common parsing scenarios:
Parsers implement recovery for:
Parsers use efficient lookahead for:
Optimized processing for:
Install with Tessl CLI
npx tessl i tessl/maven-org-flywaydb--flyway-mysql