blob: 76f9fa0b28fc4aa97ce3e26d94f71215dc4ca877 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.iceberg;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import static org.apache.iceberg.expressions.Expressions.bucket;
import static org.apache.iceberg.expressions.Expressions.truncate;
@RunWith(Parameterized.class)
public class TestTableUpdatePartitionSpec extends TableTestBase {
@Parameterized.Parameters
public static Object[][] parameters() {
return new Object[][] {
new Object[] { 1 },
new Object[] { 2 },
};
}
public TestTableUpdatePartitionSpec(int formatVersion) {
super(formatVersion);
}
@Before
public void verifyInitialSpec() {
PartitionSpec initialSpec = PartitionSpec.builderFor(table.schema()).bucket("data", 16).build();
Assert.assertEquals("Should use the expected initial spec", initialSpec, table.spec());
Assert.assertEquals(1000, table.spec().lastAssignedFieldId());
Assert.assertEquals(0, table.spec().specId());
}
@Test
public void testCommitUpdatedSpec() {
table.updateSpec()
.addField(bucket("id", 8))
.commit();
PartitionSpec evolvedSpec = PartitionSpec.builderFor(table.schema())
.withSpecId(1)
.bucket("data", 16)
.bucket("id", 8, "id_bucket_8")
.build();
Assert.assertEquals("Should append a partition field to the spec", evolvedSpec, table.spec());
Assert.assertEquals(1001, table.spec().lastAssignedFieldId());
table.updateSpec()
.removeField("id_bucket_8")
.removeField("data_bucket")
.addField(truncate("data", 8))
.commit();
V1Assert.assertEquals("Should soft delete id and data buckets", PartitionSpec.builderFor(table.schema())
.withSpecId(2)
.alwaysNull("data", "data_bucket")
.alwaysNull("id", "id_bucket_8")
.truncate("data", 8, "data_trunc_8")
.build(), table.spec());
V2Assert.assertEquals("Should hard delete id and data buckets", PartitionSpec.builderFor(table.schema())
.withSpecId(2)
.add(2, 1002, "data_trunc_8", "truncate[8]")
.build(), table.spec());
Assert.assertEquals(1002, table.spec().lastAssignedFieldId());
}
@Test
public void testNoopCommit() {
TableMetadata current = table.ops().current();
int currentVersion = TestTables.metadataVersion("test");
// no-op commit due to no-op
table.updateSpec().commit();
TableMetadata updated = table.ops().current();
Integer updatedVersion = TestTables.metadataVersion("test");
Assert.assertEquals(current, updated);
currentVersion += 1;
Assert.assertEquals(currentVersion, updatedVersion.intValue());
// no-op commit due to no-op rename
table.updateSpec()
.renameField("data_bucket", "data_bucket")
.commit();
updated = table.ops().current();
updatedVersion = TestTables.metadataVersion("test");
Assert.assertEquals(current, updated);
currentVersion += 1;
Assert.assertEquals(currentVersion, updatedVersion.intValue());
}
@Test
public void testRenameField() {
table.updateSpec()
.renameField("data_bucket", "data_partition")
.addField(bucket("id", 8))
.commit();
PartitionSpec evolvedSpec = PartitionSpec.builderFor(table.schema())
.withSpecId(1)
.bucket("data", 16, "data_partition")
.bucket("id", 8, "id_bucket_8")
.build();
Assert.assertEquals("should match evolved spec", evolvedSpec, table.spec());
Assert.assertEquals(1001, table.spec().lastAssignedFieldId());
table.updateSpec()
.addField(truncate("id", 4))
.renameField("data_partition", "data_bucket")
.commit();
evolvedSpec = PartitionSpec.builderFor(table.schema())
.withSpecId(2)
.bucket("data", 16, "data_bucket")
.bucket("id", 8, "id_bucket_8")
.truncate("id", 4, "id_trunc_4")
.build();
Assert.assertEquals("should match evolved spec", evolvedSpec, table.spec());
Assert.assertEquals(1002, table.spec().lastAssignedFieldId());
}
@Test
public void testRenameOnlyEvolution() {
table.updateSpec()
.renameField("data_bucket", "data_partition")
.commit();
PartitionSpec evolvedSpec = PartitionSpec.builderFor(table.schema())
.withSpecId(1)
.bucket("data", 16, "data_partition")
.build();
Assert.assertEquals("should match evolved spec", evolvedSpec, table.spec());
Assert.assertEquals(1000, table.spec().lastAssignedFieldId());
}
@Test
public void testRemoveAndAddField() {
table.updateSpec()
.removeField("data_bucket")
.addField(bucket("id", 8))
.commit();
V1Assert.assertEquals("Should soft delete data bucket", PartitionSpec.builderFor(table.schema())
.withSpecId(1)
.alwaysNull("data", "data_bucket")
.bucket("id", 8, "id_bucket_8")
.build(), table.spec());
V2Assert.assertEquals("Should hard delete data bucket", PartitionSpec.builderFor(table.schema())
.withSpecId(1)
.add(1, 1001, "id_bucket_8", "bucket[8]")
.build(), table.spec());
Assert.assertEquals(1001, table.spec().lastAssignedFieldId());
}
@Test
public void testAddAndRemoveField() {
table.updateSpec()
.addField(bucket("data", 6))
.removeField("data_bucket")
.commit();
V1Assert.assertEquals("Should remove and then add a bucket field", PartitionSpec.builderFor(table.schema())
.withSpecId(1)
.alwaysNull("data", "data_bucket")
.bucket("data", 6, "data_bucket_6")
.build(), table.spec());
V2Assert.assertEquals("Should remove and then add a bucket field", PartitionSpec.builderFor(table.schema())
.withSpecId(1)
.add(2, 1001, "data_bucket_6", "bucket[6]")
.build(), table.spec());
Assert.assertEquals(1001, table.spec().lastAssignedFieldId());
}
@Test
public void testAddAfterLastFieldRemoved() {
table.updateSpec()
.removeField("data_bucket")
.commit();
table.updateSpec()
.addField(bucket("id", 8))
.commit();
V1Assert.assertEquals("Should add a new id bucket", PartitionSpec.builderFor(table.schema())
.withSpecId(2)
.alwaysNull("data", "data_bucket")
.bucket("id", 8, "id_bucket_8")
.build(), table.spec());
V2Assert.assertEquals("Should add a new id bucket", PartitionSpec.builderFor(table.schema())
.withSpecId(2)
.add(1, 1001, "id_bucket_8", "bucket[8]")
.build(), table.spec());
Assert.assertEquals(1001, table.spec().lastAssignedFieldId());
}
}