This is an automated email from the ASF dual-hosted git repository. alexey pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/kudu.git
The following commit(s) were added to refs/heads/master by this push: new e696b8a1a [java] KUDU-2671 require RANGE_SPECIFIC_HASH_SCHEMA when necessary e696b8a1a is described below commit e696b8a1a4936d5703a9d5d26469ea997a0b2d90 Author: Alexey Serbin <ale...@apache.org> AuthorDate: Thu Jun 30 20:15:41 2022 -0700 [java] KUDU-2671 require RANGE_SPECIFIC_HASH_SCHEMA when necessary With this patch, Kudu Java client requires the newly introduced feature flag RANGE_SPECIFIC_HASH_SCHEMA to be present at the server side when creating a table with range-specific hash schemas. The flag is also required when altering already existing table, adding a new range partition with custom hash schema. This patch also provides test coverage for the newly introduced functionality. This is a follow-up to https://gerrit.cloudera.org/#/c/18633 Change-Id: I7e6625277cc2fb63000999f0c74d9b3d929d5657 Reviewed-on: http://gerrit.cloudera.org:8080/18687 Reviewed-by: Attila Bukor <abu...@apache.org> Tested-by: Alexey Serbin <ale...@apache.org> --- .../org/apache/kudu/client/AlterTableOptions.java | 19 +++++++- .../org/apache/kudu/client/AlterTableRequest.java | 8 ++-- .../org/apache/kudu/client/CreateTableOptions.java | 7 ++- .../org/apache/kudu/client/CreateTableRequest.java | 6 +-- .../org/apache/kudu/client/TestAlterTable.java | 51 ++++++++++++++++++++++ .../java/org/apache/kudu/client/TestKuduTable.java | 40 +++++++++++++++++ 6 files changed, 121 insertions(+), 10 deletions(-) diff --git a/java/kudu-client/src/main/java/org/apache/kudu/client/AlterTableOptions.java b/java/kudu-client/src/main/java/org/apache/kudu/client/AlterTableOptions.java index a2e4f6476..1603d0801 100644 --- a/java/kudu-client/src/main/java/org/apache/kudu/client/AlterTableOptions.java +++ b/java/kudu-client/src/main/java/org/apache/kudu/client/AlterTableOptions.java @@ -22,9 +22,11 @@ import static org.apache.kudu.ColumnSchema.Encoding; import static org.apache.kudu.master.Master.AlterTableRequestPB; import java.util.EnumSet; +import java.util.List; import java.util.Map; import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; import com.google.protobuf.ByteString; import org.apache.yetus.audience.InterfaceAudience; import org.apache.yetus.audience.InterfaceStability; @@ -33,6 +35,7 @@ import org.apache.kudu.ColumnSchema; import org.apache.kudu.Common; import org.apache.kudu.Type; import org.apache.kudu.client.ProtobufHelper.SchemaPBConversionFlags; +import org.apache.kudu.master.Master; /** * This builder must be used to alter a table. At least one change must be specified. @@ -42,6 +45,7 @@ import org.apache.kudu.client.ProtobufHelper.SchemaPBConversionFlags; public class AlterTableOptions { private final AlterTableRequestPB.Builder pb = AlterTableRequestPB.newBuilder(); private boolean wait = true; + private boolean isAddingRangeWithCustomHashSchema = false; /** * Change a table's name. @@ -393,6 +397,7 @@ public class AlterTableOptions { EnumSet.of(SchemaPBConversionFlags.SCHEMA_PB_WITHOUT_COMMENT, SchemaPBConversionFlags.SCHEMA_PB_WITHOUT_ID))); } + isAddingRangeWithCustomHashSchema = true; return this; } @@ -529,4 +534,16 @@ public class AlterTableOptions { boolean shouldWait() { return wait; } -} + + List<Integer> getRequiredFeatureFlags() { + if (!hasAddDropRangePartitions()) { + return ImmutableList.of(); + } + if (!isAddingRangeWithCustomHashSchema) { + return ImmutableList.of(Master.MasterFeatures.RANGE_PARTITION_BOUNDS_VALUE); + } + return ImmutableList.of( + Master.MasterFeatures.RANGE_PARTITION_BOUNDS_VALUE, + Master.MasterFeatures.RANGE_SPECIFIC_HASH_SCHEMA_VALUE); + } +} \ No newline at end of file diff --git a/java/kudu-client/src/main/java/org/apache/kudu/client/AlterTableRequest.java b/java/kudu-client/src/main/java/org/apache/kudu/client/AlterTableRequest.java index c323c95e1..a27e01048 100644 --- a/java/kudu-client/src/main/java/org/apache/kudu/client/AlterTableRequest.java +++ b/java/kudu-client/src/main/java/org/apache/kudu/client/AlterTableRequest.java @@ -42,7 +42,7 @@ class AlterTableRequest extends KuduRpc<AlterTableResponse> { static final String ALTER_TABLE = "AlterTable"; private final String name; private final AlterTableRequestPB.Builder builder; - private final List<Integer> requiredFeatures; + private final List<Integer> featureFlags; AlterTableRequest(KuduTable masterTable, String name, @@ -52,9 +52,7 @@ class AlterTableRequest extends KuduRpc<AlterTableResponse> { super(masterTable, timer, timeoutMillis); this.name = name; this.builder = ato.getProtobuf(); - this.requiredFeatures = ato.hasAddDropRangePartitions() ? - ImmutableList.of(MasterFeatures.RANGE_PARTITION_BOUNDS_VALUE) : - ImmutableList.of(); + this.featureFlags = ato.getRequiredFeatureFlags(); } @Override @@ -90,6 +88,6 @@ class AlterTableRequest extends KuduRpc<AlterTableResponse> { @Override Collection<Integer> getRequiredFeatures() { - return requiredFeatures; + return featureFlags; } } diff --git a/java/kudu-client/src/main/java/org/apache/kudu/client/CreateTableOptions.java b/java/kudu-client/src/main/java/org/apache/kudu/client/CreateTableOptions.java index e1d35360c..73e14c215 100644 --- a/java/kudu-client/src/main/java/org/apache/kudu/client/CreateTableOptions.java +++ b/java/kudu-client/src/main/java/org/apache/kudu/client/CreateTableOptions.java @@ -337,7 +337,12 @@ public class CreateTableOptions { if (rangePartitions.isEmpty() && customRangePartitions.isEmpty()) { return ImmutableList.of(); } - return ImmutableList.of(Master.MasterFeatures.RANGE_PARTITION_BOUNDS_VALUE); + if (customRangePartitions.isEmpty()) { + return ImmutableList.of(Master.MasterFeatures.RANGE_PARTITION_BOUNDS_VALUE); + } + return ImmutableList.of( + Master.MasterFeatures.RANGE_PARTITION_BOUNDS_VALUE, + Master.MasterFeatures.RANGE_SPECIFIC_HASH_SCHEMA_VALUE); } boolean shouldWait() { diff --git a/java/kudu-client/src/main/java/org/apache/kudu/client/CreateTableRequest.java b/java/kudu-client/src/main/java/org/apache/kudu/client/CreateTableRequest.java index 0885fc224..4f6a07567 100644 --- a/java/kudu-client/src/main/java/org/apache/kudu/client/CreateTableRequest.java +++ b/java/kudu-client/src/main/java/org/apache/kudu/client/CreateTableRequest.java @@ -46,14 +46,14 @@ class CreateTableRequest extends KuduRpc<CreateTableResponse> { CreateTableRequest(KuduTable masterTable, String name, Schema schema, - CreateTableOptions builder, + CreateTableOptions cto, Timer timer, long timeoutMillis) { super(masterTable, timer, timeoutMillis); this.schema = schema; this.name = name; - this.builder = builder.getBuilder(); - featureFlags = builder.getRequiredFeatureFlags(); + this.builder = cto.getBuilder(); + featureFlags = cto.getRequiredFeatureFlags(); } @Override diff --git a/java/kudu-client/src/test/java/org/apache/kudu/client/TestAlterTable.java b/java/kudu-client/src/test/java/org/apache/kudu/client/TestAlterTable.java index 79ddc39c4..35ee0a8cb 100644 --- a/java/kudu-client/src/test/java/org/apache/kudu/client/TestAlterTable.java +++ b/java/kudu-client/src/test/java/org/apache/kudu/client/TestAlterTable.java @@ -774,6 +774,57 @@ public class TestAlterTable { client.deleteTable(tableName); } + @Test(timeout = 100000) + @KuduTestHarness.MasterServerConfig(flags = { + "--enable_per_range_hash_schemas=false", + }) + public void testAlterTryAddRangeWithCustomHashSchema() throws Exception { + ArrayList<ColumnSchema> columns = new ArrayList<>(2); + columns.add(new ColumnSchema.ColumnSchemaBuilder("c0", Type.INT32) + .nullable(false) + .key(true) + .build()); + columns.add(new ColumnSchema.ColumnSchemaBuilder("c1", Type.INT32) + .nullable(false) + .build()); + final Schema schema = new Schema(columns); + + CreateTableOptions createOptions = + new CreateTableOptions() + .setRangePartitionColumns(ImmutableList.of("c0")) + .addHashPartitions(ImmutableList.of("c0"), 2, 0) + .setNumReplicas(1); + + client.createTable(tableName, schema, createOptions); + + // Try adding a range partition with custom hash schema when server side + // doesn't support the RANGE_SPECIFIC_HASH_SCHEMA feature. + { + PartialRow lower = schema.newPartialRow(); + lower.addInt("c0", 0); + PartialRow upper = schema.newPartialRow(); + upper.addInt("c0", 100); + RangePartitionWithCustomHashSchema range = + new RangePartitionWithCustomHashSchema( + lower, + upper, + RangePartitionBound.INCLUSIVE_BOUND, + RangePartitionBound.EXCLUSIVE_BOUND); + range.addHashPartitions(ImmutableList.of("c0"), 3, 0); + try { + client.alterTable(tableName, new AlterTableOptions().addRangePartition(range)); + fail("shouldn't be able to add a range with custom hash schema " + + "in a table when server side doesn't support required " + + "RANGE_SPECIFIC_HASH_SCHEMA feature"); + } catch (KuduException ex) { + final String errmsg = ex.getMessage(); + assertTrue(errmsg, ex.getStatus().isRemoteError()); + assertTrue(errmsg, errmsg.matches( + ".* server sent error unsupported feature flags")); + } + } + } + @Test public void testAlterExtraConfigs() throws Exception { KuduTable table = createTable(ImmutableList.of()); diff --git a/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduTable.java b/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduTable.java index ce0e7081f..4385a5df0 100644 --- a/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduTable.java +++ b/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduTable.java @@ -1719,6 +1719,46 @@ public class TestKuduTable { } } + @Test(timeout = 100000) + @KuduTestHarness.MasterServerConfig(flags = { + "--enable_per_range_hash_schemas=false", + }) + public void testTryCreateTableRangeWithCustomHashSchema() throws Exception { + final List<ColumnSchema> columns = ImmutableList.of( + new ColumnSchema.ColumnSchemaBuilder("key", Type.INT32).key(true).build(), + new ColumnSchema.ColumnSchemaBuilder("value", Type.STRING).build()); + final Schema schema = new Schema(columns); + + CreateTableOptions options = getBasicCreateTableOptions(); + // Define the table-wide schema. + options.addHashPartitions(ImmutableList.of("key"), 2, 0); + + PartialRow lower = schema.newPartialRow(); + lower.addInt(0, -1); + PartialRow upper = schema.newPartialRow(); + upper.addInt(0, 1); + + RangePartitionWithCustomHashSchema range = + new RangePartitionWithCustomHashSchema( + lower, + upper, + RangePartitionBound.INCLUSIVE_BOUND, + RangePartitionBound.EXCLUSIVE_BOUND); + range.addHashPartitions(ImmutableList.of("key"), 3, 0); + options.addRangePartition(range); + + try { + client.createTable(tableName, schema, options); + fail("shouldn't be able to create a table with range-specific hash schema " + + "when server side doesn't support required RANGE_SPECIFIC_HASH_SCHEMA feature"); + } catch (KuduException ex) { + final String errmsg = ex.getMessage(); + assertTrue(errmsg, ex.getStatus().isRemoteError()); + assertTrue(errmsg, errmsg.matches( + ".* server sent error unsupported feature flags")); + } + } + @Test(timeout = 100000) @KuduTestHarness.MasterServerConfig(flags = { "--enable_per_range_hash_schemas=true",