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);