From 26264ef7479307c47f66cd086c0a83cb9285d6c2 Mon Sep 17 00:00:00 2001 From: Nathan Voxland Date: Thu, 26 Dec 2019 11:48:08 -0600 Subject: [PATCH 1/4] Generated indexes are not including "desc" --- .../main/java/liquibase/snapshot/DatabaseSnapshot.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/liquibase-core/src/main/java/liquibase/snapshot/DatabaseSnapshot.java b/liquibase-core/src/main/java/liquibase/snapshot/DatabaseSnapshot.java index 24ef2d1ac91..ddb7b7cb958 100644 --- a/liquibase-core/src/main/java/liquibase/snapshot/DatabaseSnapshot.java +++ b/liquibase-core/src/main/java/liquibase/snapshot/DatabaseSnapshot.java @@ -351,14 +351,8 @@ protected T include(T example) throws DatabaseExcepti private void includeNestedObjects(DatabaseObject object) throws DatabaseException, InvalidExampleException, ReflectiveOperationException { for (String field : new HashSet<>(object.getAttributes())) { Object fieldValue = object.getAttribute(field, Object.class); - if ("columns".equals(field) && ((object.getClass() == PrimaryKey.class) || (object.getClass() == Index - .class) || (object.getClass() == UniqueConstraint.class))) { - if ((fieldValue != null) && !((Collection) fieldValue).isEmpty()) { - String columnName = ((Column) ((Collection) fieldValue).iterator().next()).getName(); - if (columnName.endsWith(" ASC") || columnName.endsWith(" DESC") || columnName.endsWith(" RANDOM")) { - continue; - } - } + if ("columns".equals(field) && ((object.getClass() == PrimaryKey.class) || (object.getClass() == Index.class) || (object.getClass() == UniqueConstraint.class))) { + continue; } Object newFieldValue = replaceObject(fieldValue); if (newFieldValue == null) { //sometimes an object references a non-snapshotted object. Leave it with the unsnapshotted example From 3e79b1239751380e9bc24413929fe5b13735ed48 Mon Sep 17 00:00:00 2001 From: Nathan Voxland Date: Fri, 27 Dec 2019 14:03:11 -0600 Subject: [PATCH 2/4] H2 column snapshot generator was not being used when snapshotting columns as part of a table DAT-3773 --- .../snapshot/jvm/ColumnSnapshotGenerator.java | 3 --- .../snapshot/jvm/ColumnSnapshotGeneratorH2.java | 10 +++++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/liquibase-core/src/main/java/liquibase/snapshot/jvm/ColumnSnapshotGenerator.java b/liquibase-core/src/main/java/liquibase/snapshot/jvm/ColumnSnapshotGenerator.java index bdc67882369..305c67f37bc 100644 --- a/liquibase-core/src/main/java/liquibase/snapshot/jvm/ColumnSnapshotGenerator.java +++ b/liquibase-core/src/main/java/liquibase/snapshot/jvm/ColumnSnapshotGenerator.java @@ -57,9 +57,6 @@ protected DatabaseObject snapshotObject(DatabaseObject example, DatabaseSnapshot Database database = snapshot.getDatabase(); Relation relation = ((Column) example).getRelation(); - if (((Column) example).getComputed() != null && ((Column) example).getComputed()) { - return example; - } Schema schema = relation.getSchema(); try { diff --git a/liquibase-core/src/main/java/liquibase/snapshot/jvm/ColumnSnapshotGeneratorH2.java b/liquibase-core/src/main/java/liquibase/snapshot/jvm/ColumnSnapshotGeneratorH2.java index f92fb3ce915..0a75981d2be 100644 --- a/liquibase-core/src/main/java/liquibase/snapshot/jvm/ColumnSnapshotGeneratorH2.java +++ b/liquibase-core/src/main/java/liquibase/snapshot/jvm/ColumnSnapshotGeneratorH2.java @@ -11,11 +11,15 @@ public class ColumnSnapshotGeneratorH2 extends ColumnSnapshotGenerator { @Override public int getPriority(Class objectType, Database database) { - if (Column.class.isAssignableFrom(objectType) && (database instanceof H2Database)) { - return PRIORITY_DATABASE; - } else { + if (!(database instanceof H2Database)) { return PRIORITY_NONE; } + + int priority = super.getPriority(objectType, database); + if (priority == 0) { + return priority; + } + return priority + 5; } @Override From edba083bfe0adb7cb9cb4c883c4062cde0c7ea60 Mon Sep 17 00:00:00 2001 From: Nathan Voxland Date: Thu, 2 Jan 2020 15:09:39 -0600 Subject: [PATCH 3/4] Generated indexes are not including "desc" DAT-3773 --- .../java/liquibase/snapshot/DatabaseSnapshot.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/liquibase-core/src/main/java/liquibase/snapshot/DatabaseSnapshot.java b/liquibase-core/src/main/java/liquibase/snapshot/DatabaseSnapshot.java index ddb7b7cb958..3d6990c601f 100644 --- a/liquibase-core/src/main/java/liquibase/snapshot/DatabaseSnapshot.java +++ b/liquibase-core/src/main/java/liquibase/snapshot/DatabaseSnapshot.java @@ -351,8 +351,15 @@ protected T include(T example) throws DatabaseExcepti private void includeNestedObjects(DatabaseObject object) throws DatabaseException, InvalidExampleException, ReflectiveOperationException { for (String field : new HashSet<>(object.getAttributes())) { Object fieldValue = object.getAttribute(field, Object.class); - if ("columns".equals(field) && ((object.getClass() == PrimaryKey.class) || (object.getClass() == Index.class) || (object.getClass() == UniqueConstraint.class))) { - continue; + if ("columns".equals(field) && ((object.getClass() == PrimaryKey.class) || (object.getClass() == Index + .class) || (object.getClass() == UniqueConstraint.class))) { + if ((fieldValue != null) && !((Collection) fieldValue).isEmpty()) { + final Column column = (Column) ((Collection) fieldValue).iterator().next(); + String columnName = column.getName(); + if ((column.getDescending() != null && column.getDescending()) || columnName.endsWith(" ASC") || columnName.endsWith(" DESC") || columnName.endsWith(" RANDOM")) { + continue; + } + } } Object newFieldValue = replaceObject(fieldValue); if (newFieldValue == null) { //sometimes an object references a non-snapshotted object. Leave it with the unsnapshotted example From 897a3ca22328bfb454e00732f26e4ddbb3359f31 Mon Sep 17 00:00:00 2001 From: Nathan Voxland Date: Fri, 3 Jan 2020 14:00:26 -0600 Subject: [PATCH 4/4] Generated indexes are not including "desc" DAT-3773 --- .../src/main/java/liquibase/change/ColumnConfig.java | 9 +++------ .../src/main/java/liquibase/diff/DiffResult.java | 5 +++-- .../diff/compare/core/ColumnComparator.java | 7 +++++++ .../core/UnexpectedColumnChangeGenerator.java | 3 ++- .../serializer/core/yaml/YamlSnapshotSerializer.java | 7 ++++++- .../java/liquibase/snapshot/DatabaseSnapshot.java | 3 ++- .../snapshot/jvm/ColumnSnapshotGenerator.java | 3 ++- .../main/java/liquibase/structure/core/Column.java | 12 ++++++++++++ 8 files changed, 37 insertions(+), 12 deletions(-) diff --git a/liquibase-core/src/main/java/liquibase/change/ColumnConfig.java b/liquibase-core/src/main/java/liquibase/change/ColumnConfig.java index 354bd8a006e..f7097fa532b 100644 --- a/liquibase-core/src/main/java/liquibase/change/ColumnConfig.java +++ b/liquibase-core/src/main/java/liquibase/change/ColumnConfig.java @@ -15,10 +15,7 @@ import liquibase.structure.core.PrimaryKey; import liquibase.structure.core.Table; import liquibase.structure.core.UniqueConstraint; -import liquibase.util.ISODateFormat; -import liquibase.util.ObjectUtil; -import liquibase.util.StringUtils; -import liquibase.util.NowAndTodayUtil; +import liquibase.util.*; import java.math.BigInteger; import java.text.NumberFormat; @@ -71,8 +68,8 @@ public class ColumnConfig extends AbstractLiquibaseSerializable { */ public ColumnConfig(Column columnSnapshot) { setName(columnSnapshot.getName()); - setComputed(((columnSnapshot.getComputed() != null) && columnSnapshot.getComputed()) ? Boolean.TRUE : null); - setDescending(((columnSnapshot.getDescending() != null) && columnSnapshot.getDescending()) ? Boolean.TRUE : null); + setComputed(BooleanUtils.isTrue(columnSnapshot.getComputed()) ? Boolean.TRUE : null); + setDescending(BooleanUtils.isTrue(columnSnapshot.getDescending()) ? Boolean.TRUE : null); if (columnSnapshot.getType() != null) { setType(columnSnapshot.getType().toString()); } diff --git a/liquibase-core/src/main/java/liquibase/diff/DiffResult.java b/liquibase-core/src/main/java/liquibase/diff/DiffResult.java index 055d891e9a2..74bf5613f29 100644 --- a/liquibase-core/src/main/java/liquibase/diff/DiffResult.java +++ b/liquibase-core/src/main/java/liquibase/diff/DiffResult.java @@ -9,6 +9,7 @@ import liquibase.structure.core.Catalog; import liquibase.structure.core.Column; import liquibase.structure.core.Schema; +import liquibase.util.BooleanUtils; import java.io.IOException; import java.util.*; @@ -95,7 +96,7 @@ public T getMissingObject(T example, CompareControl.S } public void addMissingObject(DatabaseObject obj) { - if ((obj instanceof Column) && (((Column) obj).getComputed() != null) && ((Column) obj).getComputed()) { + if ((obj instanceof Column) && (BooleanUtils.isTrue(((Column) obj).getComputed()) || BooleanUtils.isTrue(((Column) obj).getDescending()))) { return; //not really missing, it's a virtual column } missingObjects.add(obj); @@ -197,4 +198,4 @@ public boolean areEqual() throws DatabaseException, IOException { public Set> getComparedTypes() { return compareControl.getComparedTypes(); } -} \ No newline at end of file +} diff --git a/liquibase-core/src/main/java/liquibase/diff/compare/core/ColumnComparator.java b/liquibase-core/src/main/java/liquibase/diff/compare/core/ColumnComparator.java index 125b60c1bfe..9d889bd4a8d 100644 --- a/liquibase-core/src/main/java/liquibase/diff/compare/core/ColumnComparator.java +++ b/liquibase-core/src/main/java/liquibase/diff/compare/core/ColumnComparator.java @@ -35,6 +35,9 @@ public String[] hash(DatabaseObject databaseObject, Database accordingTo, Databa if (BooleanUtils.isTrue(column.getComputed())) { hash += ":computed"; } + if (BooleanUtils.isTrue(column.getDescending())) { + hash += ":descending"; + } return new String[] {hash.toLowerCase(Locale.US)}; } @@ -60,6 +63,10 @@ public boolean isSameObject(DatabaseObject databaseObject1, DatabaseObject datab return false; } + if (BooleanUtils.isTrue(thisColumn.getDescending()) != BooleanUtils.isTrue(otherColumn.getDescending())) { + return false; + } + return true; } diff --git a/liquibase-core/src/main/java/liquibase/diff/output/changelog/core/UnexpectedColumnChangeGenerator.java b/liquibase-core/src/main/java/liquibase/diff/output/changelog/core/UnexpectedColumnChangeGenerator.java index 7151ccd9708..638a89a5e3b 100644 --- a/liquibase-core/src/main/java/liquibase/diff/output/changelog/core/UnexpectedColumnChangeGenerator.java +++ b/liquibase-core/src/main/java/liquibase/diff/output/changelog/core/UnexpectedColumnChangeGenerator.java @@ -11,6 +11,7 @@ import liquibase.diff.output.changelog.UnexpectedObjectChangeGenerator; import liquibase.structure.DatabaseObject; import liquibase.structure.core.*; +import liquibase.util.BooleanUtils; public class UnexpectedColumnChangeGenerator extends AbstractChangeGenerator implements UnexpectedObjectChangeGenerator { @Override @@ -42,7 +43,7 @@ public Change[] fixUnexpected(DatabaseObject unexpectedObject, DiffOutputControl // continue; // } - if ((column.getComputed() != null) && column.getComputed()) { //not really a column to drop, probably part of an index or something + if (BooleanUtils.isTrue(column.getComputed()) || BooleanUtils.isTrue(column.getDescending()) ) { //not really a column to drop, probably part of an index or something return null; } if (column.getRelation() instanceof View) { diff --git a/liquibase-core/src/main/java/liquibase/serializer/core/yaml/YamlSnapshotSerializer.java b/liquibase-core/src/main/java/liquibase/serializer/core/yaml/YamlSnapshotSerializer.java index ba74fa42776..ee4bb974246 100644 --- a/liquibase-core/src/main/java/liquibase/serializer/core/yaml/YamlSnapshotSerializer.java +++ b/liquibase-core/src/main/java/liquibase/serializer/core/yaml/YamlSnapshotSerializer.java @@ -12,6 +12,8 @@ import liquibase.structure.DatabaseObject; import liquibase.structure.DatabaseObjectCollection; import liquibase.structure.DatabaseObjectComparator; +import liquibase.structure.core.Column; +import liquibase.util.BooleanUtils; import liquibase.util.ISODateFormat; import liquibase.util.StringUtils; import org.yaml.snakeyaml.nodes.Node; @@ -53,7 +55,10 @@ public void write(DatabaseSnapshot snapshot, OutputStream out) throws IOExceptio @Override protected Object toMap(final LiquibaseSerializable object) { if (object instanceof DatabaseObject) { - if (alreadySerializingObject) { + if (object instanceof Column && (BooleanUtils.isTrue(((Column) object).getDescending()) || BooleanUtils.isTrue(((Column) object).getComputed()))) { + //not really a "real" column that has a snapshot to reference, just serialize it + return super.toMap(object); + } else if (alreadySerializingObject) { String snapshotId = ((DatabaseObject) object).getSnapshotId(); if (snapshotId == null) { String name = ((DatabaseObject) object).getName(); diff --git a/liquibase-core/src/main/java/liquibase/snapshot/DatabaseSnapshot.java b/liquibase-core/src/main/java/liquibase/snapshot/DatabaseSnapshot.java index 3d6990c601f..0002b9ef34d 100644 --- a/liquibase-core/src/main/java/liquibase/snapshot/DatabaseSnapshot.java +++ b/liquibase-core/src/main/java/liquibase/snapshot/DatabaseSnapshot.java @@ -20,6 +20,7 @@ import liquibase.structure.DatabaseObject; import liquibase.structure.DatabaseObjectCollection; import liquibase.structure.core.*; +import liquibase.util.BooleanUtils; import liquibase.util.ISODateFormat; import liquibase.util.ObjectUtil; import liquibase.util.StringUtils; @@ -356,7 +357,7 @@ private void includeNestedObjects(DatabaseObject object) throws DatabaseExceptio if ((fieldValue != null) && !((Collection) fieldValue).isEmpty()) { final Column column = (Column) ((Collection) fieldValue).iterator().next(); String columnName = column.getName(); - if ((column.getDescending() != null && column.getDescending()) || columnName.endsWith(" ASC") || columnName.endsWith(" DESC") || columnName.endsWith(" RANDOM")) { + if (BooleanUtils.isTrue(column.getDescending()) || columnName.endsWith(" ASC") || columnName.endsWith(" DESC") || columnName.endsWith(" RANDOM")) { continue; } } diff --git a/liquibase-core/src/main/java/liquibase/snapshot/jvm/ColumnSnapshotGenerator.java b/liquibase-core/src/main/java/liquibase/snapshot/jvm/ColumnSnapshotGenerator.java index 305c67f37bc..71b2b97cc42 100644 --- a/liquibase-core/src/main/java/liquibase/snapshot/jvm/ColumnSnapshotGenerator.java +++ b/liquibase-core/src/main/java/liquibase/snapshot/jvm/ColumnSnapshotGenerator.java @@ -21,6 +21,7 @@ import liquibase.statement.core.RawSqlStatement; import liquibase.structure.DatabaseObject; import liquibase.structure.core.*; +import liquibase.util.BooleanUtils; import liquibase.util.SqlUtil; import liquibase.util.StringUtils; @@ -51,7 +52,7 @@ public ColumnSnapshotGenerator() { @Override protected DatabaseObject snapshotObject(DatabaseObject example, DatabaseSnapshot snapshot) throws DatabaseException { - if ((((Column) example).getComputed() != null) && ((Column) example).getComputed()) { + if (BooleanUtils.isTrue(((Column) example).getComputed()) || BooleanUtils.isTrue(((Column) example).getDescending())) { return example; } Database database = snapshot.getDatabase(); diff --git a/liquibase-core/src/main/java/liquibase/structure/core/Column.java b/liquibase-core/src/main/java/liquibase/structure/core/Column.java index 2c423d0bd12..7726b0d01ed 100644 --- a/liquibase-core/src/main/java/liquibase/structure/core/Column.java +++ b/liquibase-core/src/main/java/liquibase/structure/core/Column.java @@ -8,11 +8,13 @@ import liquibase.serializer.AbstractLiquibaseSerializable; import liquibase.structure.AbstractDatabaseObject; import liquibase.structure.DatabaseObject; +import liquibase.util.BooleanUtils; import liquibase.util.StringUtils; import java.math.BigInteger; import java.util.Arrays; import java.util.List; +import java.util.Set; public class Column extends AbstractDatabaseObject { @@ -456,5 +458,15 @@ public void load(ParsedNode parsedNode, ResourceAccessor resourceAccessor) throw this.generationType = parsedNode.getChildValue(null, "generationType", String.class); } } + + @Override + public Set getSerializableFields() { + final Set fields = super.getSerializableFields(); + //if this is a computed or indexed column, don't have the serializer try to traverse down to the relation since it may not be a "real" object with an objectId + if (BooleanUtils.isTrue(getDescending()) || BooleanUtils.isTrue(getComputed())) { + fields.remove("relation"); + } + return fields; + } }