From 47a9a2b11dbcb38c6a25d25aefab47004319ebe2 Mon Sep 17 00:00:00 2001 From: yodzhubeiskyi Date: Thu, 28 Jul 2022 13:41:05 +0300 Subject: [PATCH 1/2] DAT-11147 Fixed sequence generation for Snowflake --- ...angedSequenceChangeGeneratorSnowflake.java | 47 ++++++++++++++++ ...ssingSequenceChangeGeneratorSnowflake.java | 38 +++++++++++++ .../CreateSequenceGeneratorSnowflake.java | 54 +++++++++++++++++++ ...base.diff.output.changelog.ChangeGenerator | 2 + .../liquibase.sqlgenerator.SqlGenerator | 1 + 5 files changed, 142 insertions(+) create mode 100644 liquibase-snowflake/src/main/java/liquibase/diff/output/changelog/core/ChangedSequenceChangeGeneratorSnowflake.java create mode 100644 liquibase-snowflake/src/main/java/liquibase/diff/output/changelog/core/MissingSequenceChangeGeneratorSnowflake.java create mode 100644 liquibase-snowflake/src/main/java/liquibase/sqlgenerator/core/CreateSequenceGeneratorSnowflake.java create mode 100644 liquibase-snowflake/src/main/resources/META-INF/services/liquibase.diff.output.changelog.ChangeGenerator diff --git a/liquibase-snowflake/src/main/java/liquibase/diff/output/changelog/core/ChangedSequenceChangeGeneratorSnowflake.java b/liquibase-snowflake/src/main/java/liquibase/diff/output/changelog/core/ChangedSequenceChangeGeneratorSnowflake.java new file mode 100644 index 00000000000..7c085fa1da3 --- /dev/null +++ b/liquibase-snowflake/src/main/java/liquibase/diff/output/changelog/core/ChangedSequenceChangeGeneratorSnowflake.java @@ -0,0 +1,47 @@ +package liquibase.diff.output.changelog.core; + +import liquibase.change.Change; +import liquibase.change.core.AlterSequenceChange; +import liquibase.database.Database; +import liquibase.database.core.SnowflakeDatabase; +import liquibase.diff.ObjectDifferences; +import liquibase.diff.output.DiffOutputControl; +import liquibase.diff.output.changelog.ChangeGeneratorChain; +import liquibase.structure.DatabaseObject; +import liquibase.structure.core.Sequence; + +import java.util.ArrayList; +import java.util.List; + +public class ChangedSequenceChangeGeneratorSnowflake extends ChangedSequenceChangeGenerator{ + + @Override + public int getPriority(Class objectType, Database database) { + int priority = super.getPriority(objectType, database); + if ((Sequence.class.isAssignableFrom(objectType)) && (database instanceof SnowflakeDatabase)) { + priority += PRIORITY_DATABASE; + } + return priority; + } + + @Override + public Change[] fixChanged(DatabaseObject changedObject, ObjectDifferences differences, DiffOutputControl control, Database referenceDatabase, Database comparisonDatabase, ChangeGeneratorChain chain) { + Sequence sequence = (Sequence) changedObject; + + List changes = new ArrayList<>(); + AlterSequenceChange accumulatedChange = createAlterSequenceChange(sequence, control); + + if (differences.isDifferent("incrementBy")) { + AlterSequenceChange change = createAlterSequenceChange(sequence, control); + change.setIncrementBy(sequence.getIncrementBy()); + accumulatedChange.setIncrementBy(sequence.getIncrementBy()); + changes.add(change); + } + + if (changes.isEmpty()) { + return null; + } else { + return changes.toArray(new Change[changes.size()]); + } + } +} diff --git a/liquibase-snowflake/src/main/java/liquibase/diff/output/changelog/core/MissingSequenceChangeGeneratorSnowflake.java b/liquibase-snowflake/src/main/java/liquibase/diff/output/changelog/core/MissingSequenceChangeGeneratorSnowflake.java new file mode 100644 index 00000000000..85b398c04f3 --- /dev/null +++ b/liquibase-snowflake/src/main/java/liquibase/diff/output/changelog/core/MissingSequenceChangeGeneratorSnowflake.java @@ -0,0 +1,38 @@ +package liquibase.diff.output.changelog.core; + +import liquibase.change.Change; +import liquibase.change.core.CreateSequenceChange; +import liquibase.database.Database; +import liquibase.database.core.SnowflakeDatabase; +import liquibase.diff.output.DiffOutputControl; +import liquibase.diff.output.changelog.ChangeGeneratorChain; +import liquibase.structure.DatabaseObject; +import liquibase.structure.core.Sequence; + +public class MissingSequenceChangeGeneratorSnowflake extends MissingSequenceChangeGenerator{ + + @Override + public int getPriority(Class objectType, Database database) { + int priority = super.getPriority(objectType, database); + if ((Sequence.class.isAssignableFrom(objectType)) && (database instanceof SnowflakeDatabase)) { + priority += PRIORITY_DATABASE; + } + return priority; + } + + @Override + public Change[] fixMissing(DatabaseObject missingObject, DiffOutputControl control, Database referenceDatabase, Database comparisonDatabase, ChangeGeneratorChain chain) { + Sequence sequence = (Sequence) missingObject; + + CreateSequenceChange change = new CreateSequenceChange(); + change.setSequenceName(sequence.getName()); + if (control.getIncludeSchema()) { + change.setSchemaName(sequence.getSchema().getName()); + } + change.setStartValue(sequence.getStartValue()); + change.setIncrementBy(sequence.getIncrementBy()); + + return new Change[] { change }; + + } +} diff --git a/liquibase-snowflake/src/main/java/liquibase/sqlgenerator/core/CreateSequenceGeneratorSnowflake.java b/liquibase-snowflake/src/main/java/liquibase/sqlgenerator/core/CreateSequenceGeneratorSnowflake.java new file mode 100644 index 00000000000..0187f03d205 --- /dev/null +++ b/liquibase-snowflake/src/main/java/liquibase/sqlgenerator/core/CreateSequenceGeneratorSnowflake.java @@ -0,0 +1,54 @@ +package liquibase.sqlgenerator.core; + +import liquibase.database.Database; +import liquibase.database.core.*; +import liquibase.exception.ValidationErrors; +import liquibase.sql.Sql; +import liquibase.sql.UnparsedSql; +import liquibase.sqlgenerator.SqlGeneratorChain; +import liquibase.statement.core.CreateSequenceStatement; + +public class CreateSequenceGeneratorSnowflake extends CreateSequenceGenerator{ + + @Override + public int getPriority() { + return PRIORITY_DATABASE; + } + + @Override + public boolean supports(CreateSequenceStatement statement, Database database) { + return database instanceof SnowflakeDatabase; + } + + @Override + public ValidationErrors validate(CreateSequenceStatement statement, Database database, SqlGeneratorChain sqlGeneratorChain) { + ValidationErrors validationErrors = new ValidationErrors(); + + validationErrors.checkRequiredField("sequenceName", statement.getSequenceName()); + + validationErrors.checkDisallowedField("minValue", statement.getMinValue(), database, SnowflakeDatabase.class); + validationErrors.checkDisallowedField("maxValue", statement.getMaxValue(), database, SnowflakeDatabase.class); + validationErrors.checkDisallowedField("cacheSize", statement.getCacheSize(), database, SnowflakeDatabase.class); + validationErrors.checkDisallowedField("cycle", statement.getCycle(), database, SnowflakeDatabase.class); + validationErrors.checkDisallowedField("datatype", statement.getDataType(), database, SnowflakeDatabase.class); + validationErrors.checkDisallowedField("ordered", statement.getOrdered(), database, SnowflakeDatabase.class); + + return validationErrors; + } + + @Override + public Sql[] generateSql(CreateSequenceStatement statement, Database database, SqlGeneratorChain sqlGeneratorChain) { + StringBuilder queryStringBuilder = new StringBuilder(); + queryStringBuilder.append("CREATE SEQUENCE "); + queryStringBuilder.append(database.escapeSequenceName(statement.getCatalogName(), statement.getSchemaName(), statement.getSequenceName())); + if (database instanceof SnowflakeDatabase) { + if (statement.getStartValue() != null) { + queryStringBuilder.append(" START WITH ").append(statement.getStartValue()); + } + if (statement.getIncrementBy() != null) { + queryStringBuilder.append(" INCREMENT BY ").append(statement.getIncrementBy()); + } + } + return new Sql[]{new UnparsedSql(queryStringBuilder.toString(), getAffectedSequence(statement))}; + } +} diff --git a/liquibase-snowflake/src/main/resources/META-INF/services/liquibase.diff.output.changelog.ChangeGenerator b/liquibase-snowflake/src/main/resources/META-INF/services/liquibase.diff.output.changelog.ChangeGenerator new file mode 100644 index 00000000000..6e95f700fe3 --- /dev/null +++ b/liquibase-snowflake/src/main/resources/META-INF/services/liquibase.diff.output.changelog.ChangeGenerator @@ -0,0 +1,2 @@ +liquibase.diff.output.changelog.core.ChangedSequenceChangeGeneratorSnowflake +liquibase.diff.output.changelog.core.MissingSequenceChangeGeneratorSnowflake \ No newline at end of file diff --git a/liquibase-snowflake/src/main/resources/META-INF/services/liquibase.sqlgenerator.SqlGenerator b/liquibase-snowflake/src/main/resources/META-INF/services/liquibase.sqlgenerator.SqlGenerator index 3279eac2d7c..a12fd56b3dc 100644 --- a/liquibase-snowflake/src/main/resources/META-INF/services/liquibase.sqlgenerator.SqlGenerator +++ b/liquibase-snowflake/src/main/resources/META-INF/services/liquibase.sqlgenerator.SqlGenerator @@ -1,3 +1,4 @@ +liquibase.sqlgenerator.core.CreateSequenceGeneratorSnowflake liquibase.sqlgenerator.core.DropDefaultValueGeneratorSnowflake liquibase.sqlgenerator.core.DropProcedureGeneratorSnowflake liquibase.sqlgenerator.core.InsertOrUpdateGeneratorSnowflake From be18faaa54b93099f80de4a1451b9963606b55c4 Mon Sep 17 00:00:00 2001 From: yodzhubeiskyi Date: Tue, 2 Aug 2022 15:46:53 +0300 Subject: [PATCH 2/2] DAT-11147 Returned catalog attribute to MissingSequenceChangeGenerator --- .../core/MissingSequenceChangeGeneratorSnowflake.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/liquibase-snowflake/src/main/java/liquibase/diff/output/changelog/core/MissingSequenceChangeGeneratorSnowflake.java b/liquibase-snowflake/src/main/java/liquibase/diff/output/changelog/core/MissingSequenceChangeGeneratorSnowflake.java index 85b398c04f3..0ac1ccd49e8 100644 --- a/liquibase-snowflake/src/main/java/liquibase/diff/output/changelog/core/MissingSequenceChangeGeneratorSnowflake.java +++ b/liquibase-snowflake/src/main/java/liquibase/diff/output/changelog/core/MissingSequenceChangeGeneratorSnowflake.java @@ -26,6 +26,9 @@ public Change[] fixMissing(DatabaseObject missingObject, DiffOutputControl contr CreateSequenceChange change = new CreateSequenceChange(); change.setSequenceName(sequence.getName()); + if (control.getIncludeCatalog()) { + change.setCatalogName(sequence.getSchema().getCatalogName()); + } if (control.getIncludeSchema()) { change.setSchemaName(sequence.getSchema().getName()); }