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",

Reply via email to