Skip to content

Flyway generates invalid SQL when running multi-statement snowflake migrations with nested if statements. #4179

@trainman

Description

@trainman

Flyway fails to properly parse and execute the following sample repeatable migration. (Actual logic redacted and replaced with select statements.)

DECLARE 
    var_one BOOLEAN;
    var_two BOOLEAN;
BEGIN
    SELECT sysdate() > '1900-01-01' INTO var_one;

    IF (var_one) THEN
        SELECT sysdate() < '1900-01-01' INTO var_two;

        SELECT 'Due to var_one, we need to handle edge cases before we continue';

        IF (var_two) THEN
            SELECT 'Edge case 1' as truth;
        ELSE
            SELECT '...or edge case 2' as truth;
        END IF;

        SELECT 'Finish the work';
    END IF;
END;

SELECT 'Do the normal thing';

When a nested IF statement exists, this results in the 1st statement being incorrectly parsed by Flyway; as confirmed in the Flyway logs and Snowflake execution history.

Flyway Log:

[REDACTED]...
Nov 17, 2025 6:41:41 PM net.snowflake.client.core.SFSession open
INFO: Connecting to [REDACTED] Snowflake domain
Current version of schema "[REDACTED]": null
DEBUG: [REDACTED].sql ...
DEBUG: Found statement at line 1: DECLARE
    var_one BOOLEAN;
    var_two BOOLEAN;
BEGIN
    SELECT sysdate() > '1900-01-01' INTO var_one;

    IF (var_one) THEN
        SELECT sysdate() < '1900-01-01' INTO var_two;

        SELECT 'Due to var_one, we need to handle edge cases before we continue';

        IF (var_two) THEN
            SELECT 'Edge case 1' as truth;
        ELSE
            SELECT '...or edge case 2' as truth;
        END IF;

        SELECT 'Finish the work';
    END IF
DEBUG: Found statement at line 20: END
DEBUG: Found statement at line 22: SELECT 'Do the normal thing'
DEBUG: Starting migration of schema "[REDACTED]" with repeatable migration "[REDACTED]" ...
Migrating schema "[REDACTED]" with repeatable migration "[REDACTED]"
DEBUG: Executing SQL: DECLARE
    var_one BOOLEAN;
    var_two BOOLEAN;
BEGIN
    SELECT sysdate() > '1900-01-01' INTO var_one;

    IF (var_one) THEN
        SELECT sysdate() < '1900-01-01' INTO var_two;

        SELECT 'Due to var_one, we need to handle edge cases before we continue';

        IF (var_two) THEN
            SELECT 'Edge case 1' as truth;
        ELSE
            SELECT '...or edge case 2' as truth;
        END IF;

        SELECT 'Finish the work';
    END IF
DEBUG: Rolling back transaction...
DEBUG: Transaction rolled back
ERROR: Migration of schema "[REDACTED]" with repeatable migration "[REDACTED]" failed! Please restore backups and roll back database and code!
DEBUG: Schema History table "[REDACTED]"."flyway_schema_history" successfully updated to reflect changes
DEBUG: Memory usage: 64 of 95M
ERROR: Unexpected error
org.flywaydb.core.internal.exception.FlywayMigrateException: Failed to execute script [REDACTED].sql
------------------------------------------------------
SQL State  : 42000
Error Code : 1003
Message    : SQL compilation error:
syntax error line 19 at position 10 unexpected '<EOF>'.
Location   : tables/[REDACTED].sql ([REDACTED]/tables/[REDACTED].sql)
Line       : 1
Statement  : DECLARE
    var_one BOOLEAN;
    var_two BOOLEAN;
BEGIN
    SELECT sysdate() > '1900-01-01' INTO var_one;

    IF (var_one) THEN
        SELECT sysdate() < '1900-01-01' INTO var_two;

        SELECT 'Due to var_one, we need to handle edge cases before we continue';

        IF (var_two) THEN
            SELECT 'Edge case 1' as truth;
        ELSE
            SELECT '...or edge case 2' as truth;
        END IF;

        SELECT 'Finish the work';
    END IF

	at org.flywaydb.core.internal.command.DbMigrate.doMigrateGroup(DbMigrate.java:380)
	at org.flywaydb.core.internal.command.DbMigrate.lambda$applyMigrations$1(DbMigrate.java:264)
	at org.flywaydb.core.internal.jdbc.TransactionalExecutionTemplate.execute(TransactionalExecutionTemplate.java:40)
	at org.flywaydb.core.internal.command.DbMigrate.applyMigrations(DbMigrate.java:263)
	at org.flywaydb.core.internal.command.DbMigrate.migrateGroup(DbMigrate.java:236)
	at org.flywaydb.core.internal.command.DbMigrate.lambda$migrateAll$0(DbMigrate.java:134)
	at org.flywaydb.core.internal.jdbc.TableLockingExecutionTemplate$1.call(TableLockingExecutionTemplate.java:21)
	at org.flywaydb.core.internal.jdbc.TransactionalExecutionTemplate.execute(TransactionalExecutionTemplate.java:40)
	at org.flywaydb.core.internal.jdbc.TableLockingExecutionTemplate.execute(TableLockingExecutionTemplate.java:16)
	at org.flywaydb.core.internal.database.base.Connection.lock(Connection.java:87)
	at org.flywaydb.core.internal.schemahistory.JdbcTableSchemaHistory.lock(JdbcTableSchemaHistory.java:145)
	at org.flywaydb.core.internal.command.DbMigrate.migrateAll(DbMigrate.java:134)
	at org.flywaydb.core.internal.command.DbMigrate.migrate(DbMigrate.java:85)
	at org.flywaydb.core.Flyway.lambda$migrate$3(Flyway.java:227)
	at org.flywaydb.core.FlywayExecutor.execute(FlywayExecutor.java:215)
	at org.flywaydb.core.FlywayExecutor.execute(FlywayExecutor.java:99)
	at org.flywaydb.core.Flyway.migrate(Flyway.java:168)
	at org.flywaydb.commandline.Main.executeOperation(Main.java:286)
	at org.flywaydb.commandline.Main.executeFlyway(Main.java:192)
	at org.flywaydb.commandline.Main.main(Main.java:119)
Caused by: org.flywaydb.core.internal.sqlscript.FlywaySqlScriptException: Failed to execute script [REDACTED].sql
------------------------------------------------------
SQL State  : 42000
Error Code : 1003
Message    : SQL compilation error:
syntax error line 19 at position 10 unexpected '<EOF>'.
Location   : tables/[REDACTED].sql ([REDACTED]/tables/[REDACTED].sql)
Line       : 1
Statement  : DECLARE
    var_one BOOLEAN;
    var_two BOOLEAN;
BEGIN
    SELECT sysdate() > '1900-01-01' INTO var_one;

    IF (var_one) THEN
        SELECT sysdate() < '1900-01-01' INTO var_two;

        SELECT 'Due to var_one, we need to handle edge cases before we continue';

        IF (var_two) THEN
            SELECT 'Edge case 1' as truth;
        ELSE
            SELECT '...or edge case 2' as truth;
        END IF;

        SELECT 'Finish the work';
    END IF

	at org.flywaydb.core.internal.sqlscript.DefaultSqlScriptExecutor.handleException(DefaultSqlScriptExecutor.java:232)
	at org.flywaydb.core.internal.sqlscript.DefaultSqlScriptExecutor.executeStatement(DefaultSqlScriptExecutor.java:193)
	at org.flywaydb.core.internal.sqlscript.DefaultSqlScriptExecutor.execute(DefaultSqlScriptExecutor.java:115)
	at org.flywaydb.core.internal.resolver.sql.SqlMigrationExecutor.executeOnce(SqlMigrationExecutor.java:56)
	at org.flywaydb.core.internal.resolver.sql.SqlMigrationExecutor.lambda$execute$0(SqlMigrationExecutor.java:47)
	at org.flywaydb.core.internal.database.DefaultExecutionStrategy.execute(DefaultExecutionStrategy.java:12)
	at org.flywaydb.core.internal.resolver.sql.SqlMigrationExecutor.execute(SqlMigrationExecutor.java:46)
	at org.flywaydb.core.internal.command.DbMigrate.doMigrateGroup(DbMigrate.java:372)
	... 19 more
Caused by: net.snowflake.client.jdbc.SnowflakeSQLException: SQL compilation error:
syntax error line 19 at position 10 unexpected '<EOF>'.
	at net.snowflake.client.jdbc.SnowflakeUtil.checkErrorAndThrowExceptionSub(SnowflakeUtil.java:188)
	at net.snowflake.client.jdbc.SnowflakeUtil.checkErrorAndThrowException(SnowflakeUtil.java:120)
	at net.snowflake.client.core.StmtUtil.pollForOutput(StmtUtil.java:511)
	at net.snowflake.client.core.StmtUtil.execute(StmtUtil.java:416)
	at net.snowflake.client.core.SFStatement.executeHelper(SFStatement.java:502)
	at net.snowflake.client.core.SFStatement.executeQueryInternal(SFStatement.java:211)
	at net.snowflake.client.core.SFStatement.executeQuery(SFStatement.java:145)
	at net.snowflake.client.core.SFStatement.execute(SFStatement.java:779)
	at net.snowflake.client.core.SFStatement.execute(SFStatement.java:697)
	at net.snowflake.client.jdbc.SnowflakeStatementV1.executeInternal(SnowflakeStatementV1.java:350)
	at net.snowflake.client.jdbc.SnowflakeStatementV1.execute(SnowflakeStatementV1.java:425)
	at org.flywaydb.core.internal.jdbc.JdbcTemplate.executeStatement(JdbcTemplate.java:196)
	at org.flywaydb.core.internal.sqlscript.ParsedSqlStatement.execute(ParsedSqlStatement.java:69)
	at org.flywaydb.core.internal.sqlscript.DefaultSqlScriptExecutor.executeStatement(DefaultSqlScriptExecutor.java:188)
	... 25 more
...[REDACTED]

Logged Snowflake Query History

DECLARE 
    var_one BOOLEAN;
    var_two BOOLEAN;
BEGIN
    SELECT sysdate() > '1900-01-01' INTO var_one;

    IF (var_one) THEN
        SELECT sysdate() < '1900-01-01' INTO var_two;

        SELECT 'Due to var_one, we need to handle edge cases before we continue';

        IF (var_two) THEN
            SELECT 'Edge case 1' as truth;
        ELSE
            SELECT '...or edge case 2' as truth;
        END IF;

        SELECT 'Finish the work';
    END IF

Expected 1st statement (note the ";" at the end of "end if" and the "END;" for the declare block were both missing in the query executed by Flyway.)

DECLARE 
    var_one BOOLEAN;
    var_two BOOLEAN;
BEGIN
    SELECT sysdate() > '1900-01-01' INTO var_one;

    IF (var_one) THEN
        SELECT sysdate() < '1900-01-01' INTO var_two;

        SELECT 'Due to var_one, we need to handle edge cases before we continue';

        IF (var_two) THEN
            SELECT 'Edge case 1' as truth;
        ELSE
            SELECT '...or edge case 2' as truth;
        END IF;

        SELECT 'Finish the work';
    END IF;
END;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions