You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by bl...@apache.org on 2017/03/20 11:40:49 UTC
[2/6] cassandra git commit: Fix CONTAINS filtering for null
collections
Fix CONTAINS filtering for null collections
patch by Mikkel Andersen; reviewed by Benjamin Lerer for CASSANDRA-13246
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/0eebc6e6
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/0eebc6e6
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/0eebc6e6
Branch: refs/heads/cassandra-3.11
Commit: 0eebc6e6b7cd7fc801579e57701608e7bf155ee0
Parents: 1dcb313
Author: Mikkel Andersen <mi...@gmail.com>
Authored: Mon Mar 20 12:15:34 2017 +0100
Committer: Benjamin Lerer <b....@gmail.com>
Committed: Mon Mar 20 12:22:40 2017 +0100
----------------------------------------------------------------------
CHANGES.txt | 1 +
.../apache/cassandra/db/filter/RowFilter.java | 21 ++++++----
src/java/org/apache/cassandra/db/rows/Row.java | 2 +-
.../validation/entities/SecondaryIndexTest.java | 39 ++++++++++++++++++
.../cql3/validation/operations/SelectTest.java | 43 ++++++++++++++++++++
5 files changed, 96 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/0eebc6e6/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 97d8561..10402f3 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
3.0.13
+ * Fix CONTAINS filtering for null collections (CASSANDRA-13246)
* Applying: Use a unique metric reservoir per test run when using Cassandra-wide metrics residing in MBeans (CASSANDRA-13216)
* Propagate row deletions in 2i tables on upgrade (CASSANDRA-13320)
* Slice.isEmpty() returns false for some empty slices (CASSANDRA-13305)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/0eebc6e6/src/java/org/apache/cassandra/db/filter/RowFilter.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/filter/RowFilter.java b/src/java/org/apache/cassandra/db/filter/RowFilter.java
index 11cfb87..5ffe2ab 100644
--- a/src/java/org/apache/cassandra/db/filter/RowFilter.java
+++ b/src/java/org/apache/cassandra/db/filter/RowFilter.java
@@ -670,17 +670,20 @@ public abstract class RowFilter implements Iterable<RowFilter.Expression>
if (column.isComplex())
{
ComplexColumnData complexData = row.getComplexColumnData(column);
- for (Cell cell : complexData)
+ if (complexData != null)
{
- if (type.kind == CollectionType.Kind.SET)
+ for (Cell cell : complexData)
{
- if (type.nameComparator().compare(cell.path().get(0), value) == 0)
- return true;
- }
- else
- {
- if (type.valueComparator().compare(cell.value(), value) == 0)
- return true;
+ if (type.kind == CollectionType.Kind.SET)
+ {
+ if (type.nameComparator().compare(cell.path().get(0), value) == 0)
+ return true;
+ }
+ else
+ {
+ if (type.valueComparator().compare(cell.value(), value) == 0)
+ return true;
+ }
}
}
return false;
http://git-wip-us.apache.org/repos/asf/cassandra/blob/0eebc6e6/src/java/org/apache/cassandra/db/rows/Row.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/rows/Row.java b/src/java/org/apache/cassandra/db/rows/Row.java
index 74d8664..a61f365 100644
--- a/src/java/org/apache/cassandra/db/rows/Row.java
+++ b/src/java/org/apache/cassandra/db/rows/Row.java
@@ -129,7 +129,7 @@ public interface Row extends Unfiltered, Collection<ColumnData>
* The returned object groups all the cells for the column, as well as it's complex deletion (if relevant).
*
* @param c the complex column for which to return the complex data.
- * @return the data for {@code c} or {@code null} is the row has no data for this column.
+ * @return the data for {@code c} or {@code null} if the row has no data for this column.
*/
public ComplexColumnData getComplexColumnData(ColumnDefinition c);
http://git-wip-us.apache.org/repos/asf/cassandra/blob/0eebc6e6/test/unit/org/apache/cassandra/cql3/validation/entities/SecondaryIndexTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/SecondaryIndexTest.java b/test/unit/org/apache/cassandra/cql3/validation/entities/SecondaryIndexTest.java
index 0cf13bd..5d43bd2 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/SecondaryIndexTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/SecondaryIndexTest.java
@@ -420,6 +420,45 @@ public class SecondaryIndexTest extends CQLTester
assertEmpty(execute("SELECT k, v FROM %s WHERE m CONTAINS 4"));
}
+ @Test
+ public void testSelectOnMultiIndexOnCollectionsWithNull() throws Throwable
+ {
+ createTable(" CREATE TABLE %s ( k int, v int, x text, l list<int>, s set<text>, m map<text, int>, PRIMARY KEY (k, v))");
+
+ createIndex("CREATE INDEX ON %s (x)");
+ createIndex("CREATE INDEX ON %s (v)");
+ createIndex("CREATE INDEX ON %s (s)");
+ createIndex("CREATE INDEX ON %s (m)");
+
+
+ execute("INSERT INTO %s (k, v, x, l, s, m) VALUES (0, 0, 'x', [1, 2], {'a'}, {'a' : 1})");
+ execute("INSERT INTO %s (k, v, x, l, s, m) VALUES (0, 1, 'x', [3, 4], {'b', 'c'}, {'a' : 1, 'b' : 2})");
+ execute("INSERT INTO %s (k, v, x, l, s, m) VALUES (0, 2, 'x', [1], {'a', 'c'}, {'c' : 3})");
+ execute("INSERT INTO %s (k, v, x, l, s, m) VALUES (1, 0, 'x', [1, 2, 4], {}, {'b' : 1})");
+ execute("INSERT INTO %s (k, v, x, l, s, m) VALUES (1, 1, 'x', [4, 5], {'d'}, {'a' : 1, 'b' : 3})");
+ execute("INSERT INTO %s (k, v, x, l, s, m) VALUES (1, 2, 'x', null, null, null)");
+
+ beforeAndAfterFlush(() -> {
+ // lists
+ assertRows(execute("SELECT k, v FROM %s WHERE x = 'x' AND l CONTAINS 1 ALLOW FILTERING"), row(1, 0), row(0, 0), row(0, 2));
+ assertRows(execute("SELECT k, v FROM %s WHERE x = 'x' AND k = 0 AND l CONTAINS 1 ALLOW FILTERING"), row(0, 0), row(0, 2));
+ assertRows(execute("SELECT k, v FROM %s WHERE x = 'x' AND l CONTAINS 2 ALLOW FILTERING"), row(1, 0), row(0, 0));
+ assertEmpty(execute("SELECT k, v FROM %s WHERE x = 'x' AND l CONTAINS 6 ALLOW FILTERING"));
+
+ // sets
+ assertRows(execute("SELECT k, v FROM %s WHERE x = 'x' AND s CONTAINS 'a' ALLOW FILTERING" ), row(0, 0), row(0, 2));
+ assertRows(execute("SELECT k, v FROM %s WHERE x = 'x' AND k = 0 AND s CONTAINS 'a' ALLOW FILTERING"), row(0, 0), row(0, 2));
+ assertRows(execute("SELECT k, v FROM %s WHERE x = 'x' AND s CONTAINS 'd' ALLOW FILTERING"), row(1, 1));
+ assertEmpty(execute("SELECT k, v FROM %s WHERE x = 'x' AND s CONTAINS 'e' ALLOW FILTERING"));
+
+ // maps
+ assertRows(execute("SELECT k, v FROM %s WHERE x = 'x' AND m CONTAINS 1 ALLOW FILTERING"), row(1, 0), row(1, 1), row(0, 0), row(0, 1));
+ assertRows(execute("SELECT k, v FROM %s WHERE x = 'x' AND k = 0 AND m CONTAINS 1 ALLOW FILTERING"), row(0, 0), row(0, 1));
+ assertRows(execute("SELECT k, v FROM %s WHERE x = 'x' AND m CONTAINS 2 ALLOW FILTERING"), row(0, 1));
+ assertEmpty(execute("SELECT k, v FROM %s WHERE x = 'x' AND m CONTAINS 4 ALLOW FILTERING"));
+ });
+ }
+
/**
* Migrated from cql_tests.py:TestCQL.map_keys_indexing()
*/
http://git-wip-us.apache.org/repos/asf/cassandra/blob/0eebc6e6/test/unit/org/apache/cassandra/cql3/validation/operations/SelectTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/operations/SelectTest.java b/test/unit/org/apache/cassandra/cql3/validation/operations/SelectTest.java
index a5f153e..f40ae4b 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/operations/SelectTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/operations/SelectTest.java
@@ -2923,4 +2923,47 @@ public class SelectTest extends CQLTester
});
}
}
+
+ @Test
+ public void testFilteringOnCollectionsWithNull() throws Throwable
+ {
+ createTable(" CREATE TABLE %s ( k int, v int, l list<int>, s set<text>, m map<text, int>, PRIMARY KEY (k, v))");
+
+ createIndex("CREATE INDEX ON %s (v)");
+ createIndex("CREATE INDEX ON %s (s)");
+ createIndex("CREATE INDEX ON %s (m)");
+
+
+ execute("INSERT INTO %s (k, v, l, s, m) VALUES (0, 0, [1, 2], {'a'}, {'a' : 1})");
+ execute("INSERT INTO %s (k, v, l, s, m) VALUES (0, 1, [3, 4], {'b', 'c'}, {'a' : 1, 'b' : 2})");
+ execute("INSERT INTO %s (k, v, l, s, m) VALUES (0, 2, [1], {'a', 'c'}, {'c' : 3})");
+ execute("INSERT INTO %s (k, v, l, s, m) VALUES (1, 0, [1, 2, 4], {}, {'b' : 1})");
+ execute("INSERT INTO %s (k, v, l, s, m) VALUES (1, 1, [4, 5], {'d'}, {'a' : 1, 'b' : 3})");
+ execute("INSERT INTO %s (k, v, l, s, m) VALUES (1, 2, null, null, null)");
+
+ beforeAndAfterFlush(() -> {
+ // lists
+ assertRows(execute("SELECT k, v FROM %s WHERE l CONTAINS 1 ALLOW FILTERING"), row(1, 0), row(0, 0), row(0, 2));
+ assertRows(execute("SELECT k, v FROM %s WHERE k = 0 AND l CONTAINS 1 ALLOW FILTERING"), row(0, 0), row(0, 2));
+ assertRows(execute("SELECT k, v FROM %s WHERE l CONTAINS 2 ALLOW FILTERING"), row(1, 0), row(0, 0));
+ assertEmpty(execute("SELECT k, v FROM %s WHERE l CONTAINS 6 ALLOW FILTERING"));
+
+ // sets
+ assertRows(execute("SELECT k, v FROM %s WHERE s CONTAINS 'a' ALLOW FILTERING" ), row(0, 0), row(0, 2));
+ assertRows(execute("SELECT k, v FROM %s WHERE k = 0 AND s CONTAINS 'a' ALLOW FILTERING"), row(0, 0), row(0, 2));
+ assertRows(execute("SELECT k, v FROM %s WHERE s CONTAINS 'd' ALLOW FILTERING"), row(1, 1));
+ assertEmpty(execute("SELECT k, v FROM %s WHERE s CONTAINS 'e' ALLOW FILTERING"));
+
+ // maps
+ assertRows(execute("SELECT k, v FROM %s WHERE m CONTAINS 1 ALLOW FILTERING"), row(1, 0), row(1, 1), row(0, 0), row(0, 1));
+ assertRows(execute("SELECT k, v FROM %s WHERE k = 0 AND m CONTAINS 1 ALLOW FILTERING"), row(0, 0), row(0, 1));
+ assertRows(execute("SELECT k, v FROM %s WHERE m CONTAINS 2 ALLOW FILTERING"), row(0, 1));
+ assertEmpty(execute("SELECT k, v FROM %s WHERE m CONTAINS 4 ALLOW FILTERING"));
+
+ assertRows(execute("SELECT k, v FROM %s WHERE m CONTAINS KEY 'a' ALLOW FILTERING"), row(1, 1), row(0, 0), row(0, 1));
+ assertRows(execute("SELECT k, v FROM %s WHERE k = 0 AND m CONTAINS KEY 'a' ALLOW FILTERING"), row(0, 0), row(0, 1));
+ assertRows(execute("SELECT k, v FROM %s WHERE k = 0 AND m CONTAINS KEY 'c' ALLOW FILTERING"), row(0, 2));
+ });
+ }
+
}