This is an automated email from the ASF dual-hosted git repository.
blue pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iceberg.git
The following commit(s) were added to refs/heads/master by this push:
new d8cc2a2 Core: Support adding columns deleted in the same operation
(#2204)
d8cc2a2 is described below
commit d8cc2a29364e57df95c4e50f4079bacd35e4a047
Author: Thomas <[email protected]>
AuthorDate: Tue Feb 9 14:05:27 2021 -0800
Core: Support adding columns deleted in the same operation (#2204)
---
.../main/java/org/apache/iceberg/SchemaUpdate.java | 6 ++-
.../java/org/apache/iceberg/TestSchemaUpdate.java | 55 ++++++++++++++++++++++
2 files changed, 59 insertions(+), 2 deletions(-)
diff --git a/core/src/main/java/org/apache/iceberg/SchemaUpdate.java
b/core/src/main/java/org/apache/iceberg/SchemaUpdate.java
index 16ba971..e4f2593 100644
--- a/core/src/main/java/org/apache/iceberg/SchemaUpdate.java
+++ b/core/src/main/java/org/apache/iceberg/SchemaUpdate.java
@@ -136,13 +136,15 @@ class SchemaUpdate implements UpdateSchema {
parentField.type().isNestedType() &&
parentField.type().asNestedType().isStructType(),
"Cannot add to non-struct column: %s: %s", parent,
parentField.type());
parentId = parentField.fieldId();
+ Types.NestedField currentField = schema.findField(parent + "." + name);
Preconditions.checkArgument(!deletes.contains(parentId),
"Cannot add to a column that will be deleted: %s", parent);
- Preconditions.checkArgument(schema.findField(parent + "." + name) ==
null,
+ Preconditions.checkArgument(currentField == null ||
deletes.contains(currentField.fieldId()),
"Cannot add column, name already exists: %s.%s", parent, name);
fullName = schema.findColumnName(parentId) + "." + name;
} else {
- Preconditions.checkArgument(schema.findField(name) == null,
+ Types.NestedField currentField = schema.findField(name);
+ Preconditions.checkArgument(currentField == null ||
deletes.contains(currentField.fieldId()),
"Cannot add column, name already exists: %s", name);
fullName = name;
}
diff --git a/core/src/test/java/org/apache/iceberg/TestSchemaUpdate.java
b/core/src/test/java/org/apache/iceberg/TestSchemaUpdate.java
index 4e48e1d..ecd29b8 100644
--- a/core/src/test/java/org/apache/iceberg/TestSchemaUpdate.java
+++ b/core/src/test/java/org/apache/iceberg/TestSchemaUpdate.java
@@ -502,6 +502,61 @@ public class TestSchemaUpdate {
}
@Test
+ public void testDeleteThenAdd() {
+ Schema schema = new Schema(required(1, "id", Types.IntegerType.get()));
+ Schema expected = new Schema(optional(2, "id", Types.IntegerType.get()));
+
+ Schema updated = new SchemaUpdate(schema, 1)
+ .deleteColumn("id")
+ .addColumn("id", optional(2, "id", Types.IntegerType.get()).type())
+ .apply();
+
+ Assert.assertEquals("Should match with added fields", expected.asStruct(),
updated.asStruct());
+ }
+
+ @Test
+ public void testDeleteThenAddNested() {
+ Schema expectedNested = new Schema(
+ required(1, "id", Types.IntegerType.get()),
+ optional(2, "data", Types.StringType.get()),
+ optional(3, "preferences", Types.StructType.of(
+ optional(9, "feature2", Types.BooleanType.get()),
+ optional(24, "feature1", Types.BooleanType.get())
+ ), "struct of named boolean options"),
+ required(4, "locations", Types.MapType.ofRequired(10, 11,
+ Types.StructType.of(
+ required(20, "address", Types.StringType.get()),
+ required(21, "city", Types.StringType.get()),
+ required(22, "state", Types.StringType.get()),
+ required(23, "zip", Types.IntegerType.get())
+ ),
+ Types.StructType.of(
+ required(12, "lat", Types.FloatType.get()),
+ required(13, "long", Types.FloatType.get())
+ )), "map of address to coordinate"),
+ optional(5, "points", Types.ListType.ofOptional(14,
+ Types.StructType.of(
+ required(15, "x", Types.LongType.get()),
+ required(16, "y", Types.LongType.get())
+ )), "2-D cartesian points"),
+ required(6, "doubles", Types.ListType.ofRequired(17,
+ Types.DoubleType.get()
+ )),
+ optional(7, "properties", Types.MapType.ofOptional(18, 19,
+ Types.StringType.get(),
+ Types.StringType.get()
+ ), "string map of properties")
+ );
+
+ Schema updatedNested = new SchemaUpdate(SCHEMA, SCHEMA_LAST_COLUMN_ID)
+ .deleteColumn("preferences.feature1")
+ .addColumn("preferences", "feature1", Types.BooleanType.get())
+ .apply();
+
+ Assert.assertEquals("Should match with added fields",
expectedNested.asStruct(), updatedNested.asStruct());
+ }
+
+ @Test
public void testDeleteMissingColumn() {
AssertHelpers.assertThrows("Should reject delete missing column",
IllegalArgumentException.class, "missing column: col", () -> {