liquibase: SQLFileChange broken relative path resolving

Search first

  • I searched and no similar issues were found

Description

After upgrading from 4.15.0 to 4.21.1 we found exception, when execute our scripts.

We are often using relative pathes to our changes. So it works correctly until we updates to last release.

Steps To Reproduce

We have changeset into another changeset with relative path to parent

<changeSet author="nufefelov" id="Create_tables" runOrder="first">
        <comment>Создание таблиц</comment>
        <sqlFile relativeToChangelogFile="true"
                 path="../../oracle/crtable.sql"
                 encoding="Cp1251"
                 dbms="oracle"/>
        <sqlFile relativeToChangelogFile="true"
                 path="../../postgresql/crtable.sql"
                 encoding="UTF-8"
                 dbms="postgresql"/>
    </changeSet>

Since update we got error liquibase.exception.LiquibaseException: liquibase.exception.UnexpectedLiquibaseException: java.io.FileNotFoundException: JAR entry com/asuproject/usoi/db/manage/scripts/liquibase/scheme/…/…/oracle/crtable.sql not found in D:\usoi5\master\core\build\libs\exploded\core.war\WEB-INF\lib\com.asuproject-usoi-db-scripts-5.x.jar

Expected/Desired Behavior

I found, that there are changes in SQLFileChange.java

There is method, that calculates relative path correctly (4.15.0)

@Override
    public InputStream openSqlStream() throws IOException {
        if (path == null) {
            return null;
        }

        InputStream inputStream;
        try {
            String relativeTo = null;
            if (ObjectUtil.defaultIfNull(isRelativeToChangelogFile(), false)) {
                relativeTo = getChangeSet().getChangeLog().getPhysicalFilePath();
            }
            inputStream = Scope.getCurrentScope().getResourceAccessor().openStream(relativeTo, path);
        } catch (IOException e) {
            throw new IOException("Unable to read file '" + path + "'", e);
        }

        if (inputStream != null) {
            return inputStream;
        }
        throw new IOException(FileUtil.getFileNotFoundMessage(path));
    }

And there is new version of this code, that does’not work from 4.21.1

@Override
    public InputStream openSqlStream() throws IOException {
        if (path == null) {
            return null;
        }

        ResourceAccessor resourceAccessor = Scope.getCurrentScope().getResourceAccessor();
        if (ObjectUtil.defaultIfNull(isRelativeToChangelogFile(), false)) {
            return resourceAccessor.get(getChangeSet().getChangeLog().getPhysicalFilePath()).resolveSibling(path).openInputStream();
        } else {
            return resourceAccessor.getExisting(path).openInputStream();
        }
    }

The method resolveSiblings() does’nt resolve it.

Liquibase Version

4.21.1

Database Vendor & Version

No response

Liquibase Integration

No response

Liquibase Extensions

No response

OS and/or Infrastructure Type/Provider

Windows 10

Additional Context

No response

Are you willing to submit a PR?

  • I’m willing to submit a PR (Thank you!)

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 15 (13 by maintainers)

Most upvoted comments

Hi @MalloD12,

Sorry for the late reply.

I perform some simple tests with the latest Liquibase version as of writing, 4.23.1, and I was unable to reproduce the issue.

The same is true for the issue #3200, the provided failing test case now success.

Please, be aware that, in contrast, I experienced some strange behavior when testing the YAML example proposed for the #3200 issue. It is the following.

The YAML provided in the issue doesn’t define an author field:

databaseChangeLog:
  - changeSet:
      id: create-schema
      changes:
        - sqlFile:
            path: sql/sql-file.sql
            relativeToChangelogFile: true
            splitStatements: false

If you try to perform liquibase update then it will cause the following error:

Unexpected error running Liquibase: La columna "AUTHOR" no permite valores nulos (NULL)
NULL not allowed for column "AUTHOR"; SQL statement:
INSERT INTO PUBLIC.DATABASECHANGELOG (ID, AUTHOR, FILENAME, DATEEXECUTED, ORDEREXECUTED, MD5SUM, DESCRIPTION, COMMENTS, EXECTYPE, CONTEXTS, LABELS, LIQUIBASE, DEPLOYMENT_ID) VALUES (...)

Please, note that it causes that the corresponding migration record will not be inserted in DATABASECHANGELOG but the migration script is executed, the test table referenced in sql-file.sql is created.

If you try updating again, after including author in the YAML file, then Liquibase will fail because as stated, the test table defined in the migration script already exists.

Probably it would be convenient to check for the existence of the field author before executing the changeSet to avoid this type of problems.

Hi @jccampanero,

No worries, I was just checking as I was going through some of the tickets on our list.

Thanks, Daniel.

Sorry for the late reply @filipelautert.

Thank you very much for the feedback, I will try reviewing it in version 4.23.0.

Thank you very much again!!