Skip to content

Commit

Permalink
fully qualify names for Snowflake unique constraints (DAT-16598) (#5919)
Browse files Browse the repository at this point in the history
fully qualify names for Snowflake unique constraints
  • Loading branch information
StevenMassaro committed May 22, 2024
1 parent ada4abf commit 4a61105
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package liquibase.command


import liquibase.Scope
import liquibase.extension.testing.testsystem.DatabaseTestSystem
import liquibase.extension.testing.testsystem.TestSystemFactory
import liquibase.extension.testing.testsystem.spock.LiquibaseIntegrationTest
import liquibase.structure.core.Table
import liquibase.structure.core.UniqueConstraint
import liquibase.util.StringUtil
import spock.lang.Shared
import spock.lang.Specification

import static liquibase.command.util.CommandUtil.takeDatabaseSnapshot

@LiquibaseIntegrationTest
class SnapshotSnowflakeIntegrationTest extends Specification{

@Shared
private DatabaseTestSystem snowflake = Scope.currentScope.getSingleton(TestSystemFactory).getTestSystem("snowflake") as DatabaseTestSystem

def "snapshot table in another schema"() {
def schemaName = StringUtil.randomIdentifier(10).toUpperCase()
when:
snowflake.executeSql("CREATE SCHEMA ${schemaName}")
snowflake.executeSql("""
CREATE TABLE ${schemaName}.TABLE4 (
col1 INTEGER NOT NULL,
col2 INTEGER NOT NULL
);
""")
snowflake.executeSql("ALTER TABLE ${schemaName}.table4 ADD CONSTRAINT UNIQUENESS UNIQUE(col1, col2) ENFORCED;")
// Close the connection to force a new connection to be created using the default schema name (not the schema name from above)
snowflake.getConnection().close()

then:
def snapshot = takeDatabaseSnapshot(snowflake.getDatabaseFromFactory(), schemaName)
snapshot != null
def tables = snapshot.get(Table.class)
tables.size() == 1
tables[0].getName() == "TABLE4"
tables[0].getSchema().getName() == schemaName
def uniqueConstraints = snapshot.get(UniqueConstraint)
uniqueConstraints.size() == 1
uniqueConstraints[0].getTable().getName() == "TABLE4"
uniqueConstraints[0].getName() == "UNIQUENESS"

cleanup:
snowflake.executeSql("DROP SCHEMA ${schemaName}")
}

}
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package liquibase.command.util

import liquibase.CatalogAndSchema
import liquibase.Scope
import liquibase.TagVersionEnum
import liquibase.UpdateSummaryEnum
import liquibase.changelog.ChangeLogHistoryService
import liquibase.changelog.ChangeLogHistoryServiceFactory
import liquibase.command.CommandScope
import liquibase.command.core.*
import liquibase.command.core.helpers.*
Expand All @@ -14,6 +17,7 @@ import liquibase.lockservice.LockServiceFactory
import liquibase.resource.ResourceAccessor
import liquibase.resource.SearchPathResourceAccessor
import liquibase.sdk.resource.MockResourceAccessor
import liquibase.snapshot.DatabaseSnapshot

class CommandUtil {

Expand Down Expand Up @@ -83,6 +87,28 @@ class CommandUtil {
commandScope.execute()
}

/**
* Take a snapshot of the database and the specified schemas.
*/
static DatabaseSnapshot takeDatabaseSnapshot(Database database, String... schema) {
final ChangeLogHistoryService changeLogService = ChangeLogHistoryServiceFactory.getInstance().getChangeLogService(database)
changeLogService.init()
changeLogService.reset()

CatalogAndSchema[] schemas = new CatalogAndSchema[schema.size()]
for(int i = 0; i < schema.size(); i++) {
schemas[i] = new CatalogAndSchema(null, schema[i])
}
CommandScope snapshotCommand = new CommandScope("internalSnapshot")
snapshotCommand
.addArgumentValue(InternalSnapshotCommandStep.DATABASE_ARG, database)
.addArgumentValue(InternalSnapshotCommandStep.SCHEMAS_ARG, schemas)
.addArgumentValue(InternalSnapshotCommandStep.SERIALIZER_FORMAT_ARG, "txt")

def snapshotResults = snapshotCommand.execute()
return (DatabaseSnapshot) snapshotResults.getResult("snapshot")
}

static void runDiff(DatabaseTestSystem db, Database targetDatabase, Database referenceDatabase,
String outputFile) throws CommandExecutionException {
CommandScope commandScope = new CommandScope(DiffCommandStep.COMMAND_NAME)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@
import liquibase.snapshot.SnapshotGenerator;
import liquibase.statement.core.RawSqlStatement;
import liquibase.structure.DatabaseObject;
import liquibase.structure.core.*;
import liquibase.structure.core.Relation;
import liquibase.structure.core.Schema;
import liquibase.structure.core.Table;
import liquibase.structure.core.UniqueConstraint;

import java.sql.SQLException;
import java.util.List;
Expand Down Expand Up @@ -48,7 +51,7 @@ protected List<CachedRow> listConstraints(Table table, DatabaseSnapshot snapshot
String tableName = database.correctObjectName(table.getName(), Table.class);
String constraintName = database.correctObjectName(name, UniqueConstraint.class);

String showSql = "SHOW UNIQUE KEYS IN " + tableName;
String showSql = "SHOW UNIQUE KEYS IN " + database.escapeObjectName(table.getSchema().getCatalogName(), table.getSchema().getName(), tableName, Table.class);
String sql = "SELECT \"column_name\" AS COLUMN_NAME FROM TABLE(result_scan(last_query_id())) WHERE \"constraint_name\"= '" + constraintName +"'";

Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor("jdbc", database)
Expand Down

0 comments on commit 4a61105

Please sign in to comment.