You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kudu.apache.org by to...@apache.org on 2016/08/14 22:34:29 UTC

[6/6] kudu git commit: [java-client] Reorganize range partition client API

[java-client] Reorganize range partition client API

Equivalient to the corresponding C++ commit which refactors how range
partitioning is exposed to users.

Change-Id: If9808ca5cb65c96378ad9b7cbcc5759bbff1dcd1
Reviewed-on: http://gerrit.cloudera.org:8080/3958
Tested-by: Kudu Jenkins
Reviewed-by: Adar Dembo <ad...@cloudera.com>


Project: http://git-wip-us.apache.org/repos/asf/kudu/repo
Commit: http://git-wip-us.apache.org/repos/asf/kudu/commit/5be08fd7
Tree: http://git-wip-us.apache.org/repos/asf/kudu/tree/5be08fd7
Diff: http://git-wip-us.apache.org/repos/asf/kudu/diff/5be08fd7

Branch: refs/heads/master
Commit: 5be08fd799b0186025f2e94e2f96fa55fe3717f3
Parents: ff589b5
Author: Dan Burkert <da...@cloudera.com>
Authored: Wed Aug 10 17:13:40 2016 -0700
Committer: Todd Lipcon <to...@apache.org>
Committed: Sun Aug 14 22:33:49 2016 +0000

----------------------------------------------------------------------
 .../apache/kudu/client/AlterTableOptions.java   |  63 +++++++-
 .../apache/kudu/client/CreateTableOptions.java  | 144 +++++++++++++------
 .../java/org/apache/kudu/client/Operation.java  |  43 ++++--
 .../apache/kudu/client/RangePartitionBound.java |  30 ++++
 .../org/apache/kudu/client/BaseKuduTest.java    |   4 +-
 .../org/apache/kudu/client/TestAlterTable.java  |  59 +++++++-
 .../kudu/client/TestFlexiblePartitioning.java   |   8 +-
 7 files changed, 290 insertions(+), 61 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kudu/blob/5be08fd7/java/kudu-client/src/main/java/org/apache/kudu/client/AlterTableOptions.java
----------------------------------------------------------------------
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 110443d..0642bf8 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
@@ -128,6 +128,37 @@ public class AlterTableOptions {
    * @return this instance
    */
   public AlterTableOptions addRangePartition(PartialRow lowerBound, PartialRow upperBound) {
+    return addRangePartition(lowerBound, upperBound,
+                             RangePartitionBound.INCLUSIVE_BOUND,
+                             RangePartitionBound.EXCLUSIVE_BOUND);
+  }
+
+  /**
+   * Add a range partition to the table with a lower bound and upper bound.
+   *
+   * If either row is empty, then that end of the range will be unbounded. If a range column is
+   * missing a value, the logical minimum value for that column type will be used as the default.
+   *
+   * Multiple range partitions may be added as part of a single alter table transaction by calling
+   * this method multiple times. Added range partitions must not overlap with each
+   * other or any existing range partitions (unless the existing range partitions are dropped as
+   * part of the alter transaction first). The lower bound must be less than the upper bound.
+   *
+   * This client will immediately be able to write and scan the new tablets when the alter table
+   * operation returns success, however other existing clients may have to wait for a timeout period
+   * to elapse before the tablets become visible. This period is configured by the master's
+   * 'table_locations_ttl_ms' flag, and defaults to one hour.
+   *
+   * @param lowerBound lower bound, may be empty but not null
+   * @param upperBound upper bound, may be empty but not null
+   * @param lowerBoundType the type of the lower bound, either inclusive or exclusive
+   * @param upperBoundType the type of the upper bound, either inclusive or exclusive
+   * @return this instance
+   */
+  public AlterTableOptions addRangePartition(PartialRow lowerBound,
+                                             PartialRow upperBound,
+                                             RangePartitionBound lowerBoundType,
+                                             RangePartitionBound upperBoundType) {
     Preconditions.checkNotNull(lowerBound);
     Preconditions.checkNotNull(upperBound);
     Preconditions.checkArgument(lowerBound.getSchema().equals(upperBound.getSchema()));
@@ -137,7 +168,8 @@ public class AlterTableOptions {
     AlterTableRequestPB.AddRangePartition.Builder builder =
         AlterTableRequestPB.AddRangePartition.newBuilder();
     builder.setRangeBounds(
-        new Operation.OperationsEncoder().encodeLowerAndUpperBounds(lowerBound, upperBound));
+        new Operation.OperationsEncoder().encodeLowerAndUpperBounds(lowerBound, upperBound,
+                                                                    lowerBoundType, upperBoundType));
     step.setAddRangePartition(builder);
     if (!pb.hasSchema()) {
       pb.setSchema(ProtobufHelper.schemaToPb(lowerBound.getSchema()));
@@ -160,6 +192,31 @@ public class AlterTableOptions {
    * @return this instance
    */
   public AlterTableOptions dropRangePartition(PartialRow lowerBound, PartialRow upperBound) {
+    return dropRangePartition(lowerBound, upperBound,
+                              RangePartitionBound.INCLUSIVE_BOUND,
+                              RangePartitionBound.EXCLUSIVE_BOUND);
+  }
+
+  /**
+   * Drop the range partition from the table with the specified lower bound and upper bound.
+   * The bounds must match exactly, and may not span multiple range partitions.
+   *
+   * If either row is empty, then that end of the range will be unbounded. If a range column is
+   * missing a value, the logical minimum value for that column type will be used as the default.
+   *
+   * Multiple range partitions may be dropped as part of a single alter table transaction by calling
+   * this method multiple times.
+   *
+   * @param lowerBound inclusive lower bound, can be empty but not null
+   * @param upperBound exclusive upper bound, can be empty but not null
+   * @param lowerBoundType the type of the lower bound, either inclusive or exclusive
+   * @param upperBoundType the type of the upper bound, either inclusive or exclusive
+   * @return this instance
+   */
+  public AlterTableOptions dropRangePartition(PartialRow lowerBound,
+                                              PartialRow upperBound,
+                                              RangePartitionBound lowerBoundType,
+                                              RangePartitionBound upperBoundType) {
     Preconditions.checkNotNull(lowerBound);
     Preconditions.checkNotNull(upperBound);
     Preconditions.checkArgument(lowerBound.getSchema().equals(upperBound.getSchema()));
@@ -169,7 +226,9 @@ public class AlterTableOptions {
     AlterTableRequestPB.DropRangePartition.Builder builder =
         AlterTableRequestPB.DropRangePartition.newBuilder();
     builder.setRangeBounds(
-        new Operation.OperationsEncoder().encodeLowerAndUpperBounds(lowerBound, upperBound));
+        new Operation.OperationsEncoder().encodeLowerAndUpperBounds(lowerBound, upperBound,
+                                                                    lowerBoundType,
+                                                                    upperBoundType));
     step.setDropRangePartition(builder);
     if (!pb.hasSchema()) {
       pb.setSchema(ProtobufHelper.schemaToPb(lowerBound.getSchema()));

http://git-wip-us.apache.org/repos/asf/kudu/blob/5be08fd7/java/kudu-client/src/main/java/org/apache/kudu/client/CreateTableOptions.java
----------------------------------------------------------------------
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 a352183..b4bf8b2 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
@@ -25,7 +25,6 @@ import org.apache.kudu.Common;
 import org.apache.kudu.annotations.InterfaceAudience;
 import org.apache.kudu.annotations.InterfaceStability;
 import org.apache.kudu.master.Master;
-import org.apache.kudu.util.Pair;
 
 /**
  * This is a builder class for all the options that can be provided while creating a table.
@@ -36,42 +35,7 @@ public class CreateTableOptions {
 
   private Master.CreateTableRequestPB.Builder pb = Master.CreateTableRequestPB.newBuilder();
   private final List<PartialRow> splitRows = Lists.newArrayList();
-  private final List<Pair<PartialRow, PartialRow>> rangeBounds = Lists.newArrayList();
-
-  /**
-   * Add a split point for the table. The table in the end will have splits + 1 tablets.
-   * The row may be reused or modified safely after this call without changing the split point.
-   *
-   * @param row a key row for the split point
-   * @return this instance
-   */
-  public CreateTableOptions addSplitRow(PartialRow row) {
-    splitRows.add(new PartialRow(row));
-    return this;
-  }
-
-  /**
-   * Add a partition range bound to the table with an inclusive lower bound and
-   * exclusive upper bound.
-   *
-   * If either row is empty, then that end of the range will be unbounded. If a
-   * range column is missing a value, the logical minimum value for that column
-   * type will be used as the default.
-   *
-   * Multiple range bounds may be added, but they must not overlap. All split
-   * rows must fall in one of the range bounds. The lower bound must be less
-   * than the upper bound.
-   *
-   * If not provided, the table's range will be unbounded.
-   *
-   * @param lower the inclusive lower bound
-   * @param upper the exclusive upper bound
-   * @return this instance
-   */
-  public CreateTableOptions addRangeBound(PartialRow lower, PartialRow upper) {
-    rangeBounds.add(new Pair<>(new PartialRow(lower), new PartialRow(upper)));
-    return this;
-  }
+  private final List<RangePartition> rangePartitions = Lists.newArrayList();
 
   /**
    * Add a set of hash partitions to the table.
@@ -143,6 +107,73 @@ public class CreateTableOptions {
   }
 
   /**
+   * Add a range partition partition to the table with an inclusive lower bound
+   * and an exclusive upper bound.
+   *
+   * If either row is empty, then that end of the range will be unbounded. If a
+   * range column is missing a value, the logical minimum value for that column
+   * type will be used as the default.
+   *
+   * Multiple range bounds may be added, but they must not overlap. All split
+   * rows must fall in one of the range bounds. The lower bound must be less
+   * than the upper bound.
+   *
+   * If not provided, the table's range will be unbounded.
+   *
+   * @param lower the inclusive lower bound
+   * @param upper the exclusive upper bound
+   * @return this instance
+   */
+  public CreateTableOptions addRangePartition(PartialRow lower,
+                                              PartialRow upper) {
+    return addRangePartition(lower, upper,
+                             RangePartitionBound.INCLUSIVE_BOUND,
+                             RangePartitionBound.EXCLUSIVE_BOUND);
+  }
+
+  /**
+   * Add a range partition partition to the table with a lower bound and upper
+   * bound.
+   *
+   * If either row is empty, then that end of the range will be unbounded. If a
+   * range column is missing a value, the logical minimum value for that column
+   * type will be used as the default.
+   *
+   * Multiple range bounds may be added, but they must not overlap. All split
+   * rows must fall in one of the range bounds. The lower bound must be less
+   * than the upper bound.
+   *
+   * If not provided, the table's range will be unbounded.
+   *
+   * @param lower the lower bound
+   * @param upper the upper bound
+   * @param lowerBoundType the type of the lower bound, either inclusive or exclusive
+   * @param upperBoundType the type of the upper bound, either inclusive or exclusive
+   * @return this instance
+   */
+  public CreateTableOptions addRangePartition(PartialRow lower,
+                                              PartialRow upper,
+                                              RangePartitionBound lowerBoundType,
+                                              RangePartitionBound upperBoundType) {
+    rangePartitions.add(new RangePartition(lower, upper, lowerBoundType, upperBoundType));
+    return this;
+  }
+
+  /**
+   * Add a range partition split. The split row must fall in a range partition,
+   * and causes the range partition to split into two contiguous range partitions.
+   * The row may be reused or modified safely after this call without changing
+   * the split point.
+   *
+   * @param row a key row for the split point
+   * @return this instance
+   */
+  public CreateTableOptions addSplitRow(PartialRow row) {
+    splitRows.add(new PartialRow(row));
+    return this;
+  }
+
+  /**
    * Sets the number of replicas that each tablet will have. If not specified, it uses the
    * server-side default which is usually 3 unless changed by an administrator.
    *
@@ -155,18 +186,51 @@ public class CreateTableOptions {
   }
 
   Master.CreateTableRequestPB.Builder getBuilder() {
-    if (!splitRows.isEmpty() || !rangeBounds.isEmpty()) {
+    if (!splitRows.isEmpty() || !rangePartitions.isEmpty()) {
       pb.setSplitRowsRangeBounds(new Operation.OperationsEncoder()
-                                     .encodeSplitRowsRangeBounds(splitRows, rangeBounds));
+                                              .encodeRangePartitions(rangePartitions, splitRows));
     }
     return pb;
   }
 
   List<Integer> getRequiredFeatureFlags() {
-    if (rangeBounds.isEmpty()) {
+    if (rangePartitions.isEmpty()) {
       return ImmutableList.of();
     } else {
       return ImmutableList.of(Master.MasterFeatures.RANGE_PARTITION_BOUNDS_VALUE);
     }
   }
+
+  final class RangePartition {
+    private final PartialRow lowerBound;
+    private final PartialRow upperBound;
+    private final RangePartitionBound lowerBoundType;
+    private final RangePartitionBound upperBoundType;
+
+    public RangePartition(PartialRow lowerBound,
+                          PartialRow upperBound,
+                          RangePartitionBound lowerBoundType,
+                          RangePartitionBound upperBoundType) {
+      this.lowerBound = lowerBound;
+      this.upperBound = upperBound;
+      this.lowerBoundType = lowerBoundType;
+      this.upperBoundType = upperBoundType;
+    }
+
+    public PartialRow getLowerBound() {
+      return lowerBound;
+    }
+
+    public PartialRow getUpperBound() {
+      return upperBound;
+    }
+
+    public RangePartitionBound getLowerBoundType() {
+      return lowerBoundType;
+    }
+
+    public RangePartitionBound getUpperBoundType() {
+      return upperBoundType;
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/kudu/blob/5be08fd7/java/kudu-client/src/main/java/org/apache/kudu/client/Operation.java
----------------------------------------------------------------------
diff --git a/java/kudu-client/src/main/java/org/apache/kudu/client/Operation.java b/java/kudu-client/src/main/java/org/apache/kudu/client/Operation.java
index e9a718e..baf1cc6 100644
--- a/java/kudu-client/src/main/java/org/apache/kudu/client/Operation.java
+++ b/java/kudu-client/src/main/java/org/apache/kudu/client/Operation.java
@@ -60,7 +60,9 @@ public abstract class Operation extends KuduRpc<OperationResponse> {
     SPLIT_ROWS((byte)RowOperationsPB.Type.SPLIT_ROW.getNumber()),
     UPSERT((byte)RowOperationsPB.Type.UPSERT.getNumber()),
     RANGE_LOWER_BOUND((byte) RowOperationsPB.Type.RANGE_LOWER_BOUND.getNumber()),
-    RANGE_UPPER_BOUND((byte) RowOperationsPB.Type.RANGE_UPPER_BOUND.getNumber());
+    RANGE_UPPER_BOUND((byte) RowOperationsPB.Type.RANGE_UPPER_BOUND.getNumber()),
+    EXCLUSIVE_RANGE_LOWER_BOUND((byte) RowOperationsPB.Type.EXCLUSIVE_RANGE_LOWER_BOUND.getNumber()),
+    INCLUSIVE_RANGE_UPPER_BOUND((byte) RowOperationsPB.Type.INCLUSIVE_RANGE_UPPER_BOUND.getNumber());
 
     ChangeType(byte encodedByte) {
       this.encodedByte = encodedByte;
@@ -320,32 +322,49 @@ public abstract class Operation extends KuduRpc<OperationResponse> {
       return toPB();
     }
 
-    public RowOperationsPB encodeSplitRowsRangeBounds(List<PartialRow> splitRows,
-                                                      List<Pair<PartialRow, PartialRow>> rangeBounds) {
-      if (splitRows.isEmpty() && rangeBounds.isEmpty()) {
+    public RowOperationsPB encodeRangePartitions(
+        List<CreateTableOptions.RangePartition> rangePartitions,
+        List<PartialRow> splitRows) {
+
+      if (splitRows.isEmpty() && rangePartitions.isEmpty()) {
         return null;
       }
 
-      Schema schema = splitRows.isEmpty() ? rangeBounds.get(0).getFirst().getSchema()
+      Schema schema = splitRows.isEmpty() ? rangePartitions.get(0).getLowerBound().getSchema()
                                           : splitRows.get(0).getSchema();
-      init(schema, splitRows.size() + 2 * rangeBounds.size());
+      init(schema, splitRows.size() + 2 * rangePartitions.size());
 
       for (PartialRow row : splitRows) {
         encodeRow(row, ChangeType.SPLIT_ROWS);
       }
 
-      for (Pair<PartialRow, PartialRow> bound : rangeBounds) {
-        encodeRow(bound.getFirst(), ChangeType.RANGE_LOWER_BOUND);
-        encodeRow(bound.getSecond(), ChangeType.RANGE_UPPER_BOUND);
+      for (CreateTableOptions.RangePartition partition : rangePartitions) {
+        encodeRow(partition.getLowerBound(),
+                  partition.getLowerBoundType() == RangePartitionBound.INCLUSIVE_BOUND ?
+                      ChangeType.RANGE_LOWER_BOUND :
+                      ChangeType.EXCLUSIVE_RANGE_LOWER_BOUND);
+        encodeRow(partition.getUpperBound(),
+                  partition.getUpperBoundType() == RangePartitionBound.EXCLUSIVE_BOUND ?
+                      ChangeType.RANGE_UPPER_BOUND :
+                      ChangeType.INCLUSIVE_RANGE_UPPER_BOUND);
       }
 
       return toPB();
     }
 
-    public RowOperationsPB encodeLowerAndUpperBounds(PartialRow lowerBound, PartialRow upperBound) {
+    public RowOperationsPB encodeLowerAndUpperBounds(PartialRow lowerBound,
+                                                     PartialRow upperBound,
+                                                     RangePartitionBound lowerBoundType,
+                                                     RangePartitionBound upperBoundType) {
       init(lowerBound.getSchema(), 2);
-      encodeRow(lowerBound, ChangeType.RANGE_LOWER_BOUND);
-      encodeRow(upperBound, ChangeType.RANGE_UPPER_BOUND);
+      encodeRow(lowerBound,
+                lowerBoundType == RangePartitionBound.INCLUSIVE_BOUND ?
+                    ChangeType.RANGE_LOWER_BOUND :
+                    ChangeType.EXCLUSIVE_RANGE_LOWER_BOUND);
+      encodeRow(upperBound,
+                upperBoundType == RangePartitionBound.EXCLUSIVE_BOUND ?
+                    ChangeType.RANGE_UPPER_BOUND :
+                    ChangeType.INCLUSIVE_RANGE_UPPER_BOUND);
       return toPB();
     }
   }

http://git-wip-us.apache.org/repos/asf/kudu/blob/5be08fd7/java/kudu-client/src/main/java/org/apache/kudu/client/RangePartitionBound.java
----------------------------------------------------------------------
diff --git a/java/kudu-client/src/main/java/org/apache/kudu/client/RangePartitionBound.java b/java/kudu-client/src/main/java/org/apache/kudu/client/RangePartitionBound.java
new file mode 100644
index 0000000..36e5294
--- /dev/null
+++ b/java/kudu-client/src/main/java/org/apache/kudu/client/RangePartitionBound.java
@@ -0,0 +1,30 @@
+// 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.kudu.client;
+
+import org.apache.kudu.annotations.InterfaceAudience;
+import org.apache.kudu.annotations.InterfaceStability;
+
+/** Specifies whether a range partition bound is inclusive or exclusive. */
+@InterfaceAudience.Public
+@InterfaceStability.Evolving
+public enum RangePartitionBound {
+  /** An exclusive range partition bound. */
+  EXCLUSIVE_BOUND,
+  /** An inclusive range partition bound. */
+  INCLUSIVE_BOUND,
+}

http://git-wip-us.apache.org/repos/asf/kudu/blob/5be08fd7/java/kudu-client/src/test/java/org/apache/kudu/client/BaseKuduTest.java
----------------------------------------------------------------------
diff --git a/java/kudu-client/src/test/java/org/apache/kudu/client/BaseKuduTest.java b/java/kudu-client/src/test/java/org/apache/kudu/client/BaseKuduTest.java
index af9e124..99b5127 100644
--- a/java/kudu-client/src/test/java/org/apache/kudu/client/BaseKuduTest.java
+++ b/java/kudu-client/src/test/java/org/apache/kudu/client/BaseKuduTest.java
@@ -274,13 +274,13 @@ public class BaseKuduTest {
     aLowerBound.addInt("key", 0);
     PartialRow aUpperBound = schema.newPartialRow();
     aUpperBound.addInt("key", 100);
-    option.addRangeBound(aLowerBound, aUpperBound);
+    option.addRangePartition(aLowerBound, aUpperBound);
 
     PartialRow bLowerBound = schema.newPartialRow();
     bLowerBound.addInt("key", 200);
     PartialRow bUpperBound = schema.newPartialRow();
     bUpperBound.addInt("key", 300);
-    option.addRangeBound(bLowerBound, bUpperBound);
+    option.addRangePartition(bLowerBound, bUpperBound);
 
     PartialRow split = schema.newPartialRow();
     split.addInt("key", 50);

http://git-wip-us.apache.org/repos/asf/kudu/blob/5be08fd7/java/kudu-client/src/test/java/org/apache/kudu/client/TestAlterTable.java
----------------------------------------------------------------------
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 6594e9b..8041f2b 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
@@ -71,7 +71,7 @@ public class TestAlterTable extends BaseKuduTest {
       PartialRow upper = schema.newPartialRow();
       lower.addInt("c0", bound.getFirst());
       upper.addInt("c0", bound.getSecond());
-      createOptions.addRangeBound(lower, upper);
+      createOptions.addRangePartition(lower, upper);
     }
 
     return BaseKuduTest.createTable(tableName, schema, createOptions);
@@ -162,6 +162,63 @@ public class TestAlterTable extends BaseKuduTest {
     assertEquals(2, openTable(tableName).getSchema().getColumnCount());
   }
 
+  /**
+   * Test creating and altering a table with range partitions with exclusive
+   * lower bounds and inclusive upper bounds.
+   */
+  @Test
+  public void testAlterRangePartitioningExclusiveInclusive() throws Exception {
+    // Create initial table with single range partition covering (-1, 99].
+    ArrayList<ColumnSchema> columns = new ArrayList<>(1);
+    columns.add(new ColumnSchema.ColumnSchemaBuilder("c0", Type.INT32)
+                    .nullable(false)
+                    .key(true)
+                    .build());
+    columns.add(new ColumnSchema.ColumnSchemaBuilder("c1", Type.INT32)
+                    .nullable(false)
+                    .build());
+    Schema schema = new Schema(columns);
+
+    CreateTableOptions createOptions =
+        new CreateTableOptions().setRangePartitionColumns(ImmutableList.of("c0"))
+                                .setNumReplicas(1);
+
+    PartialRow lower = schema.newPartialRow();
+    PartialRow upper = schema.newPartialRow();
+    lower.addInt("c0", -1);
+    upper.addInt("c0", 99);
+    createOptions.addRangePartition(lower, upper,
+                                    RangePartitionBound.EXCLUSIVE_BOUND,
+                                    RangePartitionBound.INCLUSIVE_BOUND);
+
+    KuduTable table = BaseKuduTest.createTable(tableName, schema, createOptions);
+
+    lower.addInt("c0", 199);
+    upper.addInt("c0", 299);
+    syncClient.alterTable(tableName, new AlterTableOptions().addRangePartition(
+        lower, upper, RangePartitionBound.EXCLUSIVE_BOUND, RangePartitionBound.INCLUSIVE_BOUND));
+
+    // Insert some rows, and then drop the partition and ensure that the table is empty.
+    insertRows(table, 0, 100);
+    insertRows(table, 200, 300);
+    assertEquals(200, countRowsInTable(table));
+
+    AlterTableOptions alter = new AlterTableOptions();
+    lower.addInt("c0", 0);
+    upper.addInt("c0", 100);
+    alter.dropRangePartition(lower, upper,
+                             RangePartitionBound.INCLUSIVE_BOUND,
+                             RangePartitionBound.EXCLUSIVE_BOUND);
+    lower.addInt("c0", 199);
+    upper.addInt("c0", 299);
+    alter.dropRangePartition(lower, upper,
+                             RangePartitionBound.EXCLUSIVE_BOUND,
+                             RangePartitionBound.INCLUSIVE_BOUND);
+    syncClient.alterTable(tableName, alter);
+
+    assertEquals(0, countRowsInTable(table));
+  }
+
   @Test
   public void testAlterRangeParitioningInvalid() throws KuduException {
     // Create initial table with single range partition covering [0, 100).

http://git-wip-us.apache.org/repos/asf/kudu/blob/5be08fd7/java/kudu-client/src/test/java/org/apache/kudu/client/TestFlexiblePartitioning.java
----------------------------------------------------------------------
diff --git a/java/kudu-client/src/test/java/org/apache/kudu/client/TestFlexiblePartitioning.java b/java/kudu-client/src/test/java/org/apache/kudu/client/TestFlexiblePartitioning.java
index c9b0361..fe78ce6 100644
--- a/java/kudu-client/src/test/java/org/apache/kudu/client/TestFlexiblePartitioning.java
+++ b/java/kudu-client/src/test/java/org/apache/kudu/client/TestFlexiblePartitioning.java
@@ -260,7 +260,7 @@ public class TestFlexiblePartitioning extends BaseKuduTest {
     upperBoundA.addString("a", "3");
     upperBoundA.addString("b", "5");
     upperBoundA.addString("b", "6");
-    tableBuilder.addRangeBound(lowerBoundA, upperBoundA);
+    tableBuilder.addRangePartition(lowerBoundA, upperBoundA);
 
     PartialRow lowerBoundB = schema.newPartialRow();
     lowerBoundB.addString("a", "4");
@@ -270,7 +270,7 @@ public class TestFlexiblePartitioning extends BaseKuduTest {
     upperBoundB.addString("a", "5");
     upperBoundB.addString("b", "5");
     upperBoundB.addString("b", "6");
-    tableBuilder.addRangeBound(lowerBoundB, upperBoundB);
+    tableBuilder.addRangePartition(lowerBoundB, upperBoundB);
 
     testPartitionSchema(tableBuilder);
   }
@@ -291,7 +291,7 @@ public class TestFlexiblePartitioning extends BaseKuduTest {
     upperBoundA.addString("a", "3");
     upperBoundA.addString("b", "5");
     upperBoundA.addString("c", "6");
-    tableBuilder.addRangeBound(lowerBoundA, upperBoundA);
+    tableBuilder.addRangePartition(lowerBoundA, upperBoundA);
 
     PartialRow lowerBoundB = schema.newPartialRow();
     lowerBoundB.addString("a", "4");
@@ -301,7 +301,7 @@ public class TestFlexiblePartitioning extends BaseKuduTest {
     upperBoundB.addString("a", "5");
     upperBoundB.addString("b", "5");
     upperBoundB.addString("c", "6");
-    tableBuilder.addRangeBound(lowerBoundB, upperBoundB);
+    tableBuilder.addRangePartition(lowerBoundB, upperBoundB);
 
     tableBuilder.addHashPartitions(ImmutableList.of("a", "b", "c"), 4);