You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kudu.apache.org by da...@apache.org on 2016/07/19 21:26:03 UTC

incubator-kudu git commit: [c++-client] add LESS and GREATER column predicates

Repository: incubator-kudu
Updated Branches:
  refs/heads/master 5668d2c48 -> 7e2783c67


[c++-client] add LESS and GREATER column predicates

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


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

Branch: refs/heads/master
Commit: 7e2783c673d4559f74e205a797ae42b67ffb689c
Parents: 5668d2c
Author: Dan Burkert <da...@cloudera.com>
Authored: Tue Jul 19 01:52:16 2016 -0700
Committer: Dan Burkert <da...@cloudera.com>
Committed: Tue Jul 19 21:25:42 2016 +0000

----------------------------------------------------------------------
 src/kudu/client/predicate-test.cc        | 108 ++++++++++++++++++++++++++
 src/kudu/client/scan_predicate.cc        |  12 +++
 src/kudu/client/scan_predicate.h         |   4 +-
 src/kudu/common/column_predicate-test.cc |  37 +++++++++
 src/kudu/common/column_predicate.cc      |  22 ++++++
 src/kudu/common/column_predicate.h       |  13 +++-
 6 files changed, 194 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-kudu/blob/7e2783c6/src/kudu/client/predicate-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/client/predicate-test.cc b/src/kudu/client/predicate-test.cc
index 0d175d9..8170670 100644
--- a/src/kudu/client/predicate-test.cc
+++ b/src/kudu/client/predicate-test.cc
@@ -248,6 +248,26 @@ class PredicateTest : public KuduTest {
         }));
       }
 
+      { // value > v
+        int count = count_if(values.begin(), values.end(),
+                             [&] (T value) { return value > v; });
+        ASSERT_EQ(count, CountRows(table, {
+              table->NewComparisonPredicate("value",
+                                            KuduPredicate::GREATER,
+                                            KuduValue::FromInt(v)),
+        }));
+      }
+
+      { // value < v
+        int count = count_if(values.begin(), values.end(),
+                             [&] (T value) { return value < v; });
+        ASSERT_EQ(count, CountRows(table, {
+              table->NewComparisonPredicate("value",
+                                            KuduPredicate::LESS,
+                                            KuduValue::FromInt(v)),
+        }));
+      }
+
       { // value >= 0
         // value <= v
         int count = count_if(values.begin(), values.end(),
@@ -323,6 +343,26 @@ class PredicateTest : public KuduTest {
         }));
       }
 
+      { // value > v
+        int count = count_if(values.begin(), values.end(),
+                             [&] (const string& value) { return value > v; });
+        ASSERT_EQ(count, CountRows(table, {
+              table->NewComparisonPredicate("value",
+                                            KuduPredicate::GREATER,
+                                            KuduValue::CopyString(v)),
+        }));
+      }
+
+      { // value < v
+        int count = count_if(values.begin(), values.end(),
+                             [&] (const string& value) { return value < v; });
+        ASSERT_EQ(count, CountRows(table, {
+              table->NewComparisonPredicate("value",
+                                            KuduPredicate::LESS,
+                                            KuduValue::CopyString(v)),
+        }));
+      }
+
       { // value >= "a"
         // value <= v
         int count = count_if(values.begin(), values.end(),
@@ -418,6 +458,34 @@ TEST_F(PredicateTest, TestBoolPredicates) {
                                                         KuduValue::FromBool(true));
     ASSERT_EQ(2, CountRows(table, { pred }));
   }
+
+  { // value > true
+    KuduPredicate* pred = table->NewComparisonPredicate("value",
+                                                        KuduPredicate::GREATER,
+                                                        KuduValue::FromBool(true));
+    ASSERT_EQ(0, CountRows(table, { pred }));
+  }
+
+  { // value > false
+    KuduPredicate* pred = table->NewComparisonPredicate("value",
+                                                        KuduPredicate::GREATER,
+                                                        KuduValue::FromBool(false));
+    ASSERT_EQ(1, CountRows(table, { pred }));
+  }
+
+  { // value < false
+    KuduPredicate* pred = table->NewComparisonPredicate("value",
+                                                        KuduPredicate::LESS,
+                                                        KuduValue::FromBool(false));
+    ASSERT_EQ(0, CountRows(table, { pred }));
+  }
+
+  { // value < true
+    KuduPredicate* pred = table->NewComparisonPredicate("value",
+                                                        KuduPredicate::LESS,
+                                                        KuduValue::FromBool(true));
+    ASSERT_EQ(1, CountRows(table, { pred }));
+  }
 }
 
 TEST_F(PredicateTest, TestInt8Predicates) {
@@ -573,6 +641,26 @@ TEST_F(PredicateTest, TestFloatPredicates) {
       }));
     }
 
+    { // value > v
+      int count = count_if(values.begin(), values.end(),
+                           [&] (float value) { return value > v; });
+      ASSERT_EQ(count, CountRows(table, {
+            table->NewComparisonPredicate("value",
+                                          KuduPredicate::GREATER,
+                                          KuduValue::FromFloat(v)),
+      }));
+    }
+
+    { // value < v
+      int count = count_if(values.begin(), values.end(),
+                           [&] (float value) { return value < v; });
+      ASSERT_EQ(count, CountRows(table, {
+            table->NewComparisonPredicate("value",
+                                          KuduPredicate::LESS,
+                                          KuduValue::FromFloat(v)),
+      }));
+    }
+
     { // value >= 0
       // value <= v
       int count = count_if(values.begin(), values.end(),
@@ -656,6 +744,26 @@ TEST_F(PredicateTest, TestDoublePredicates) {
       }));
     }
 
+    { // value > v
+      int count = count_if(values.begin(), values.end(),
+                           [&] (double value) { return value > v; });
+      ASSERT_EQ(count, CountRows(table, {
+            table->NewComparisonPredicate("value",
+                                          KuduPredicate::GREATER,
+                                          KuduValue::FromDouble(v)),
+      }));
+    }
+
+    { // value < v
+      int count = count_if(values.begin(), values.end(),
+                           [&] (double value) { return value < v; });
+      ASSERT_EQ(count, CountRows(table, {
+            table->NewComparisonPredicate("value",
+                                          KuduPredicate::LESS,
+                                          KuduValue::FromDouble(v)),
+      }));
+    }
+
     { // value >= 0.0
       // value <= v
       int count = count_if(values.begin(), values.end(),

http://git-wip-us.apache.org/repos/asf/incubator-kudu/blob/7e2783c6/src/kudu/client/scan_predicate.cc
----------------------------------------------------------------------
diff --git a/src/kudu/client/scan_predicate.cc b/src/kudu/client/scan_predicate.cc
index fc44ba7..f12bcc2 100644
--- a/src/kudu/client/scan_predicate.cc
+++ b/src/kudu/client/scan_predicate.cc
@@ -86,6 +86,18 @@ Status ComparisonPredicateData::AddToScanSpec(ScanSpec* spec, Arena* arena) {
       spec->AddPredicate(ColumnPredicate::Equality(col_, val_void));
       break;
     };
+    case KuduPredicate::LESS: {
+      spec->AddPredicate(ColumnPredicate::Range(col_, nullptr, val_void));
+      break;
+    };
+    case KuduPredicate::GREATER: {
+      optional<ColumnPredicate> pred =
+        ColumnPredicate::ExclusiveRange(col_, val_void, nullptr, arena);
+      if (pred) {
+        spec->AddPredicate(*pred);
+      }
+      break;
+    };
     default:
       return Status::InvalidArgument(Substitute("invalid comparison op: $0", op_));
   }

http://git-wip-us.apache.org/repos/asf/incubator-kudu/blob/7e2783c6/src/kudu/client/scan_predicate.h
----------------------------------------------------------------------
diff --git a/src/kudu/client/scan_predicate.h b/src/kudu/client/scan_predicate.h
index fa6ff48..c1586fe 100644
--- a/src/kudu/client/scan_predicate.h
+++ b/src/kudu/client/scan_predicate.h
@@ -35,7 +35,9 @@ class KUDU_EXPORT KuduPredicate {
   enum ComparisonOp {
     LESS_EQUAL,
     GREATER_EQUAL,
-    EQUAL
+    EQUAL,
+    LESS,
+    GREATER,
   };
 
   ~KuduPredicate();

http://git-wip-us.apache.org/repos/asf/incubator-kudu/blob/7e2783c6/src/kudu/common/column_predicate-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/common/column_predicate-test.cc b/src/kudu/common/column_predicate-test.cc
index 12461ab..55792d6 100644
--- a/src/kudu/common/column_predicate-test.cc
+++ b/src/kudu/common/column_predicate-test.cc
@@ -328,6 +328,43 @@ TEST_F(TestColumnPredicate, TestInclusiveRange) {
   }
 }
 
+// Test that the exclusive range constructor handles transforming to inclusive
+// lower bound correctly.
+TEST_F(TestColumnPredicate, TestExclusive) {
+  Arena arena(1024, 1024 * 1024);
+  {
+    ColumnSchema column("c", INT32);
+    int32_t zero = 0;
+    int32_t one = 1;
+    int32_t three = 3;
+    int32_t max = INT32_MAX;
+
+    ASSERT_EQ(ColumnPredicate::Range(column, &one, &three),
+              ColumnPredicate::ExclusiveRange(column, &zero, &three, &arena));
+
+    ASSERT_EQ(ColumnPredicate::Range(column, &one, &max),
+              ColumnPredicate::ExclusiveRange(column, &zero, &max, &arena));
+
+    ASSERT_EQ(PredicateType::None,
+              ColumnPredicate::ExclusiveRange(column, &max, nullptr, &arena).predicate_type());
+
+    ASSERT_EQ(PredicateType::None,
+              ColumnPredicate::ExclusiveRange(column, &zero, &one, &arena).predicate_type());
+
+    ASSERT_EQ(PredicateType::None,
+              ColumnPredicate::ExclusiveRange(column, &zero, &zero, &arena).predicate_type());
+  }
+  {
+    ColumnSchema column("c", STRING);
+    Slice zero("", 0);
+    Slice one("\0", 1);
+    Slice two("\0\0", 2);
+
+    ASSERT_EQ(ColumnPredicate::Range(column, &one, &two),
+              ColumnPredicate::ExclusiveRange(column, &zero, &two, &arena));
+  }
+}
+
 // Test that column predicate comparison works correctly: ordered by predicate
 // type first, then size of the column type.
 TEST_F(TestColumnPredicate, TestSelectivity) {

http://git-wip-us.apache.org/repos/asf/incubator-kudu/blob/7e2783c6/src/kudu/common/column_predicate.cc
----------------------------------------------------------------------
diff --git a/src/kudu/common/column_predicate.cc b/src/kudu/common/column_predicate.cc
index 9dc54b7..ea0fe5a 100644
--- a/src/kudu/common/column_predicate.cc
+++ b/src/kudu/common/column_predicate.cc
@@ -85,6 +85,28 @@ boost::optional<ColumnPredicate> ColumnPredicate::InclusiveRange(ColumnSchema co
   return ColumnPredicate::Range(move(column), lower, upper);
 }
 
+ColumnPredicate ColumnPredicate::ExclusiveRange(ColumnSchema column,
+                                                const void* lower,
+                                                const void* upper,
+                                                Arena* arena) {
+  CHECK(lower != nullptr || upper != nullptr);
+
+  if (lower != nullptr) {
+    // Transform the lower bound to inclusive by incrementing it.
+    // Make a copy of the value before incrementing in case it's aliased.
+    size_t size = column.type_info()->size();
+    void* buf = CHECK_NOTNULL(arena->AllocateBytes(size));
+    memcpy(buf, lower, size);
+    if (!key_util::IncrementCell(column, buf, arena)) {
+      // If incrementing the lower bound fails then the predicate can match no values.
+      return ColumnPredicate::None(move(column));
+    } else {
+      lower = buf;
+    }
+  }
+  return ColumnPredicate::Range(move(column), lower, upper);
+}
+
 ColumnPredicate ColumnPredicate::IsNotNull(ColumnSchema column) {
   CHECK(column.is_nullable());
   return ColumnPredicate(PredicateType::IsNotNull, move(column), nullptr, nullptr);

http://git-wip-us.apache.org/repos/asf/incubator-kudu/blob/7e2783c6/src/kudu/common/column_predicate.h
----------------------------------------------------------------------
diff --git a/src/kudu/common/column_predicate.h b/src/kudu/common/column_predicate.h
index e1461e1..a548317 100644
--- a/src/kudu/common/column_predicate.h
+++ b/src/kudu/common/column_predicate.h
@@ -83,7 +83,7 @@ class ColumnPredicate {
   //
   // The values are not copied, and must outlive the returned predicate. The
   // arena is used for allocating an incremented upper bound to transform the
-  // bound to a exclusive. The arena must outlive the returned predicate.
+  // bound to exclusive. The arena must outlive the returned predicate.
   //
   // If a normalized column predicate cannot be created, then boost::none will
   // be returned. This indicates that the predicate would cover the entire
@@ -93,6 +93,17 @@ class ColumnPredicate {
                                                          const void* upper,
                                                          Arena* arena);
 
+  // Creates a new range column predicate from an exclusive lower bound and an
+  // exclusive upper bound.
+  //
+  // The values are not copied, and must outlive the returned predicate. The
+  // arena is used for allocating an incremented lower bound to transform the
+  // bound to inclusive. The arena must outlive the returned predicate.
+  static ColumnPredicate ExclusiveRange(ColumnSchema column,
+                                        const void* lower,
+                                        const void* upper,
+                                        Arena* arena);
+
   // Creates a new IS NOT NULL predicate for the column.
   static ColumnPredicate IsNotNull(ColumnSchema column);