This is an automated email from the ASF dual-hosted git repository.

abukor pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kudu.git

commit 768b6885485dcb74f2731ba59fdebf2e28d0a3a3
Author: Attila Bukor <[email protected]>
AuthorDate: Tue Oct 1 18:01:23 2019 +0200

    KUDU-1938 Add range partition support pt 6
    
    Change-Id: Ib82985f09fef8d3372f40412156cd7a8ce69d61c
    Reviewed-on: http://gerrit.cloudera.org:8080/14333
    Reviewed-by: Grant Henke <[email protected]>
    Tested-by: Kudu Jenkins
---
 src/kudu/common/partition-test.cc           | 54 +++++++++++++++++++++++++
 src/kudu/common/partition.cc                | 11 +++++
 src/kudu/common/partition.h                 |  1 +
 src/kudu/integration-tests/varchar-itest.cc | 62 +++++++++++++++++++++++++++--
 4 files changed, 125 insertions(+), 3 deletions(-)

diff --git a/src/kudu/common/partition-test.cc 
b/src/kudu/common/partition-test.cc
index 799d292..9091eed 100644
--- a/src/kudu/common/partition-test.cc
+++ b/src/kudu/common/partition-test.cc
@@ -803,4 +803,58 @@ TEST_F(PartitionTest, 
TestIncrementRangePartitionStringBounds) {
     check(test, false);
   }
 }
+
+TEST_F(PartitionTest, TestVarcharRangePartitions) {
+  Schema schema({ ColumnSchema("c1", VARCHAR, false, nullptr, nullptr,
+                               ColumnStorageAttributes(), 
ColumnTypeAttributes(10)),
+                  ColumnSchema("c2", VARCHAR, false, nullptr, nullptr,
+                               ColumnStorageAttributes(), 
ColumnTypeAttributes(10)) },
+                  { ColumnId(0), ColumnId(1) }, 2);
+
+  PartitionSchemaPB schema_builder;
+  PartitionSchema partition_schema;
+  ASSERT_OK(PartitionSchema::FromPB(schema_builder, schema, 
&partition_schema));
+
+  vector<vector<boost::optional<string>>> tests {
+    { string("a"), string("b"), string("a"), string("b\0", 2) },
+    { string("a"), boost::none, string("a"), string("\0", 1) },
+  };
+
+  auto check = [&] (const vector<boost::optional<string>>& test, bool 
lower_bound) {
+    CHECK_EQ(4, test.size());
+    KuduPartialRow bound(&schema);
+    if (test[0]) ASSERT_OK(bound.SetVarchar("c1", *test[0]));
+    if (test[1]) ASSERT_OK(bound.SetVarchar("c2", *test[1]));
+
+    vector<string> components;
+    partition_schema.AppendRangeDebugStringComponentsOrMin(bound, &components);
+    SCOPED_TRACE(JoinStrings(components, ", "));
+    SCOPED_TRACE(lower_bound ? "lower bound" : "upper bound");
+
+    if (lower_bound) {
+      
ASSERT_OK(partition_schema.MakeLowerBoundRangePartitionKeyInclusive(&bound));
+    } else {
+      
ASSERT_OK(partition_schema.MakeUpperBoundRangePartitionKeyExclusive(&bound));
+    }
+
+    Slice val;
+    if (test[2]) {
+      ASSERT_OK(bound.GetVarchar("c1", &val));
+      ASSERT_EQ(*test[2], val);
+    } else {
+      ASSERT_FALSE(bound.IsColumnSet("c1"));
+    }
+    if (test[3]) {
+      ASSERT_OK(bound.GetVarchar("c2", &val));
+      ASSERT_EQ(*test[3], val);
+    } else {
+      ASSERT_FALSE(bound.IsColumnSet("c2"));
+    }
+  };
+
+  for (const auto& test : tests) {
+    check(test, true);
+    check(test, false);
+  }
+}
 } // namespace kudu
diff --git a/src/kudu/common/partition.cc b/src/kudu/common/partition.cc
index 02b9062..571ec4a 100644
--- a/src/kudu/common/partition.cc
+++ b/src/kudu/common/partition.cc
@@ -1013,6 +1013,9 @@ namespace {
       case UNIXTIME_MICROS:
         RETURN_NOT_OK(row->SetInt64(idx, INT64_MIN + 1));
         break;
+      case VARCHAR:
+        RETURN_NOT_OK(row->SetVarchar(idx, Slice("\0", 1)));
+        break;
       case STRING:
         RETURN_NOT_OK(row->SetStringCopy(idx, Slice("\0", 1)));
         break;
@@ -1109,6 +1112,14 @@ namespace {
         RETURN_NOT_OK(row->SetBinaryCopy(idx, incremented));
         break;
       }
+      case VARCHAR: {
+        Slice value;
+        RETURN_NOT_OK(row->GetVarchar(idx, &value));
+        string incremented = value.ToString();
+        incremented.push_back('\0');
+        RETURN_NOT_OK(row->SetVarchar(idx, incremented));
+        break;
+      }
       case STRING: {
         Slice value;
         RETURN_NOT_OK(row->GetString(idx, &value));
diff --git a/src/kudu/common/partition.h b/src/kudu/common/partition.h
index d8e499b..761e8e2 100644
--- a/src/kudu/common/partition.h
+++ b/src/kudu/common/partition.h
@@ -267,6 +267,7 @@ class PartitionSchema {
   friend class PartitionPruner;
   FRIEND_TEST(PartitionTest, TestIncrementRangePartitionBounds);
   FRIEND_TEST(PartitionTest, TestIncrementRangePartitionStringBounds);
+  FRIEND_TEST(PartitionTest, TestVarcharRangePartitions);
 
   // Returns a text description of the encoded range key suitable for debug 
printing.
   std::string RangeKeyDebugString(Slice range_key, const Schema& schema) const;
diff --git a/src/kudu/integration-tests/varchar-itest.cc 
b/src/kudu/integration-tests/varchar-itest.cc
index ad92f8a..aab7623 100644
--- a/src/kudu/integration-tests/varchar-itest.cc
+++ b/src/kudu/integration-tests/varchar-itest.cc
@@ -40,14 +40,18 @@ namespace client {
 
 using sp::shared_ptr;
 
-class VarcharItest : public ExternalMiniClusterITestBase {};
+class VarcharItest : public ExternalMiniClusterITestBase {
+ protected:
+  void SetUp() override {
+    NO_FATALS(StartCluster({}, {}, kNumServers));
+  }
 
-TEST_F(VarcharItest, TestCharVarcharTruncation) {
   const int kNumServers = 3;
   const int kNumTablets = 3;
   const char* const kTableName = "varchar-table";
-  NO_FATALS(StartCluster({}, {}, kNumServers));
+};
 
+TEST_F(VarcharItest, TestVarcharTruncation) {
   KuduSchemaBuilder builder;
   builder.AddColumn("key")->Type(KuduColumnSchema::INT64)
     ->NotNull()->PrimaryKey();
@@ -106,5 +110,57 @@ TEST_F(VarcharItest, TestInvalidLength) {
   ASSERT_FALSE(s.ok());
 }
 
+TEST_F(VarcharItest, TestVarcharRangePartition) {
+  KuduSchemaBuilder builder;
+  builder.AddColumn("key")->Type(KuduColumnSchema::VARCHAR)
+    ->Length(10)->NotNull()->PrimaryKey();
+  builder.AddColumn("value")->Type(KuduColumnSchema::VARCHAR)
+    ->Length(10);
+  KuduSchema schema;
+  ASSERT_OK(builder.Build(&schema));
+
+  KuduPartialRow* lower_bound = schema.NewRow();
+  ASSERT_OK(lower_bound->SetVarchar("key", "bar"));
+  KuduPartialRow* upper_bound = schema.NewRow();
+  ASSERT_OK(upper_bound->SetVarchar("key", "foo"));
+
+  unique_ptr<client::KuduTableCreator> 
table_creator(client_->NewTableCreator());
+  ASSERT_OK(table_creator->table_name(kTableName)
+      .schema(&schema)
+      .num_replicas(kNumServers)
+      .set_range_partition_columns({ "key" })
+      .add_range_partition(lower_bound, upper_bound)
+      .Create());
+  shared_ptr<KuduTable> table;
+  ASSERT_OK(client_->OpenTable(kTableName, &table));
+
+  shared_ptr<KuduSession> session = client_->NewSession();
+  ASSERT_OK(session->SetFlushMode(KuduSession::AUTO_FLUSH_BACKGROUND));
+  KuduInsert* insert = table->NewInsert();
+  KuduPartialRow* write = insert->mutable_row();
+
+  ASSERT_OK(write->SetVarchar("key", "baz"));
+  ASSERT_OK(write->SetVarchar("value", "foobar"));
+  ASSERT_OK(session->Apply(insert));
+  ASSERT_OK(session->Flush());
+
+  KuduScanner scanner(table.get());
+  ASSERT_OK(scanner.SetFaultTolerant());
+  ASSERT_OK(scanner.Open());
+  ASSERT_TRUE(scanner.HasMoreRows());
+  while (scanner.HasMoreRows()) {
+    KuduScanBatch batch;
+    ASSERT_OK(scanner.NextBatch(&batch));
+    for (const KuduScanBatch::RowPtr& read : batch) {
+      Slice key;
+      ASSERT_OK(read.GetVarchar("key", &key));
+      ASSERT_EQ("baz", key);
+      Slice value;
+      ASSERT_OK(read.GetVarchar("value", &value));
+      ASSERT_EQ("foobar", value);
+    }
+  }
+}
+
 } // namespace client
 } // namespace kudu

Reply via email to