Skip to content

Commit

Permalink
Merge pull request #2398 from liquibase/escape-names-in-getTables
Browse files Browse the repository at this point in the history
Escape schema/tablenames in metadata.getTables()
  • Loading branch information
nvoxland committed Feb 14, 2022
2 parents e9e17dc + fd08168 commit 9333465
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 8 deletions.
Expand Up @@ -1029,8 +1029,8 @@ public List<CachedRow> fastFetchQuery() throws SQLException, DatabaseException {

String catalog = ((AbstractJdbcDatabase) database).getJdbcCatalogName(catalogAndSchema);
String schema = ((AbstractJdbcDatabase) database).getJdbcSchemaName(catalogAndSchema);
return extract(databaseMetaData.getTables(catalog, schema, ((table == null) ?
SQL_FILTER_MATCH_ALL : table), new String[]{"TABLE"}));
return extract(databaseMetaData.getTables(catalog, escapeForLike(schema), ((table == null) ?
SQL_FILTER_MATCH_ALL : escapeForLike(table)), new String[]{"TABLE"}));
}

@Override
Expand All @@ -1049,7 +1049,7 @@ public List<CachedRow> bulkFetchQuery() throws SQLException, DatabaseException {

String catalog = ((AbstractJdbcDatabase) database).getJdbcCatalogName(catalogAndSchema);
String schema = ((AbstractJdbcDatabase) database).getJdbcSchemaName(catalogAndSchema);
return extract(databaseMetaData.getTables(catalog, schema, SQL_FILTER_MATCH_ALL, new String[]{"TABLE"}));
return extract(databaseMetaData.getTables(catalog, escapeForLike(schema), SQL_FILTER_MATCH_ALL, new String[]{"TABLE"}));
}

private List<CachedRow> queryMssql(CatalogAndSchema catalogAndSchema, String tableName) throws DatabaseException, SQLException {
Expand Down Expand Up @@ -1133,8 +1133,8 @@ private List<CachedRow> queryDb2Zos(CatalogAndSchema catalogAndSchema, String ta
private List<CachedRow> queryPostgres(CatalogAndSchema catalogAndSchema, String tableName) throws SQLException {
String catalog = ((AbstractJdbcDatabase) database).getJdbcCatalogName(catalogAndSchema);
String schema = ((AbstractJdbcDatabase) database).getJdbcSchemaName(catalogAndSchema);
return extract(databaseMetaData.getTables(catalog, schema, ((tableName == null) ?
SQL_FILTER_MATCH_ALL : tableName), new String[]{"TABLE", "PARTITIONED TABLE"}));
return extract(databaseMetaData.getTables(catalog, escapeForLike(schema), ((tableName == null) ?
SQL_FILTER_MATCH_ALL : escapeForLike(tableName)), new String[]{"TABLE", "PARTITIONED TABLE"}));

}
});
Expand Down Expand Up @@ -1186,8 +1186,8 @@ public List<CachedRow> fastFetchQuery() throws SQLException, DatabaseException {

String catalog = ((AbstractJdbcDatabase) database).getJdbcCatalogName(catalogAndSchema);
String schema = ((AbstractJdbcDatabase) database).getJdbcSchemaName(catalogAndSchema);
return extract(databaseMetaData.getTables(catalog, schema, ((view == null) ? SQL_FILTER_MATCH_ALL
: view), new String[]{"VIEW"}));
return extract(databaseMetaData.getTables(catalog, escapeForLike(schema), ((view == null) ? SQL_FILTER_MATCH_ALL
: escapeForLike(view)), new String[]{"VIEW"}));
}

@Override
Expand All @@ -1200,7 +1200,7 @@ public List<CachedRow> bulkFetchQuery() throws SQLException, DatabaseException {

String catalog = ((AbstractJdbcDatabase) database).getJdbcCatalogName(catalogAndSchema);
String schema = ((AbstractJdbcDatabase) database).getJdbcSchemaName(catalogAndSchema);
return extract(databaseMetaData.getTables(catalog, schema, SQL_FILTER_MATCH_ALL, new String[]{"VIEW"}));
return extract(databaseMetaData.getTables(catalog, escapeForLike(schema), SQL_FILTER_MATCH_ALL, new String[]{"VIEW"}));
}


Expand Down Expand Up @@ -1698,4 +1698,13 @@ private String getAllCatalogsStringScratchData() {
return (String) JdbcDatabaseSnapshot.this.getScratchData(ALL_CATALOGS_STRING_SCRATCH_KEY);
}

private String escapeForLike(String string) {
if (string == null) {
return null;
}
return string
.replace("%", "\\%")
.replace("_", "\\_");
}

}
@@ -0,0 +1,49 @@
package liquibase.snapshot

import liquibase.Scope
import liquibase.database.DatabaseFactory
import liquibase.database.jvm.JdbcConnection
import liquibase.extension.testing.testsystem.DatabaseTestSystem
import liquibase.extension.testing.testsystem.TestSystemFactory
import liquibase.statement.SqlStatement
import liquibase.statement.core.RawSqlStatement
import liquibase.structure.core.Table
import liquibase.structure.core.View
import org.junit.Rule
import spock.lang.Shared
import spock.lang.Specification
import spock.lang.Unroll

import java.sql.Connection

class JdbcDatabaseSnapshotTest extends Specification {

@Rule
public DatabaseTestSystem h2 = Scope.currentScope.getSingleton(TestSystemFactory).getTestSystem("h2")

@Unroll
def "getTables and getViews works with underscores in schema names"() {
when:
def connection = h2.getConnection()
def db = DatabaseFactory.instance.findCorrectDatabaseImplementation(new JdbcConnection(connection))
db.execute([
new RawSqlStatement("create schema if not exists \"TEST_SCHEMA\""),
new RawSqlStatement("create schema if not exists \"TEST-SCHEMA\""),
new RawSqlStatement("create table if not exists \"TEST-SCHEMA\".test_table (id int)"),
new RawSqlStatement("create view if not exists \"TEST-SCHEMA\".test_view as select * from \"TEST-SCHEMA\".test_table"),
] as SqlStatement[], null)

then:
SnapshotGeneratorFactory.instance.has(new Table(null, "TEST-SCHEMA", "TEST_TABLE"), db)
!SnapshotGeneratorFactory.instance.has(new Table(null, "TEST_SCHEMA", "TEST_TABLE"), db)

SnapshotGeneratorFactory.instance.has(new View(null, "TEST-SCHEMA", "TEST_VIEW"), db)
!SnapshotGeneratorFactory.instance.has(new View(null, "TEST_SCHEMA", "TEST_VIEW"), db)

cleanup:
db.execute([
new RawSqlStatement("drop schema \"test_schema\" if exists"),
new RawSqlStatement("drop schema \"test-schema\" if exists"),
] as SqlStatement[], null)
}
}

0 comments on commit 9333465

Please sign in to comment.