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/09/30 04:42:45 UTC
[5/6] kudu git commit: KuduPredicate::Clone on IN list predicate
causes segfault
KuduPredicate::Clone on IN list predicate causes segfault
Jordan Birdsell uncovered this issue where a cloned IN list predicate
causes a segfault when applied to a scanner. During the clone, the
values list was being 'preallocated' using the vector(int) constructor,
which adds a bunch of default constructed values (in this case, nullptrs
since the type is const void*). We previously didn't have any test
coverage of the Clone method, so I added a check to every column
predicate test to make sure that scans with cloned predicates behave the
same as the original predicates. The test segfaults without the fix.
Change-Id: I977691390535273c37aa90c3a3663a7c09ea67fc
Reviewed-on: http://gerrit.cloudera.org:8080/4568
Reviewed-by: Adar Dembo <ad...@cloudera.com>
Tested-by: Kudu Jenkins
Reviewed-by: Jordan Birdsell <jo...@gmail.com>
Project: http://git-wip-us.apache.org/repos/asf/kudu/repo
Commit: http://git-wip-us.apache.org/repos/asf/kudu/commit/74c9e67c
Tree: http://git-wip-us.apache.org/repos/asf/kudu/tree/74c9e67c
Diff: http://git-wip-us.apache.org/repos/asf/kudu/diff/74c9e67c
Branch: refs/heads/master
Commit: 74c9e67ce326e851c39677e44cca7ab7d4955e0a
Parents: 5385af8
Author: Dan Burkert <da...@cloudera.com>
Authored: Thu Sep 29 16:52:57 2016 -0700
Committer: Dan Burkert <da...@cloudera.com>
Committed: Fri Sep 30 02:55:49 2016 +0000
----------------------------------------------------------------------
src/kudu/client/predicate-test.cc | 21 +++++++++++++++++++--
src/kudu/client/scan_predicate-internal.h | 3 ++-
2 files changed, 21 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kudu/blob/74c9e67c/src/kudu/client/predicate-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/client/predicate-test.cc b/src/kudu/client/predicate-test.cc
index 4f01219..cc0cdbb 100644
--- a/src/kudu/client/predicate-test.cc
+++ b/src/kudu/client/predicate-test.cc
@@ -85,8 +85,8 @@ class PredicateTest : public KuduTest {
}
// Count the rows in a table which satisfy the specified predicates.
- int CountRows(const shared_ptr<KuduTable>& table,
- const vector<KuduPredicate*>& predicates) {
+ int DoCountRows(const shared_ptr<KuduTable>& table,
+ const vector<KuduPredicate*>& predicates) {
KuduScanner scanner(table.get());
for (KuduPredicate* predicate : predicates) {
CHECK_OK(scanner.AddConjunctPredicate(predicate));
@@ -102,6 +102,23 @@ class PredicateTest : public KuduTest {
return rows;
}
+ // Count the rows in a table which satisfy the specified predicates. This
+ // also does a separate scan with cloned predicates, in order to test that
+ // cloned predicates behave exactly as the original.
+ int CountRows(const shared_ptr<KuduTable>& table,
+ const vector<KuduPredicate*>& predicates) {
+
+ vector<KuduPredicate*> cloned_predicates;
+ for (KuduPredicate* pred : predicates) {
+ cloned_predicates.push_back(pred->Clone());
+ }
+
+ int cloned_count = DoCountRows(table, cloned_predicates);
+ int count = DoCountRows(table, predicates);
+ CHECK_EQ(count, cloned_count);
+ return count;
+ }
+
template <typename T>
int CountMatchedRows(const vector<T>& values, const vector<T>& test_values) {
http://git-wip-us.apache.org/repos/asf/kudu/blob/74c9e67c/src/kudu/client/scan_predicate-internal.h
----------------------------------------------------------------------
diff --git a/src/kudu/client/scan_predicate-internal.h b/src/kudu/client/scan_predicate-internal.h
index 05585f6..e0757ae 100644
--- a/src/kudu/client/scan_predicate-internal.h
+++ b/src/kudu/client/scan_predicate-internal.h
@@ -100,7 +100,8 @@ class InListPredicateData : public KuduPredicate::Data {
Status AddToScanSpec(ScanSpec* spec, Arena* arena) override;
InListPredicateData* Clone() const override {
- std::vector<KuduValue*> values(vals_.size());
+ std::vector<KuduValue*> values;
+ values.reserve(vals_.size());
for (KuduValue* val : vals_) {
values.push_back(val->Clone());
}