Repository: cassandra Updated Branches: refs/heads/cassandra-2.2 65f8bb6c4 -> e06dae81f
Fix filtering on clustering columns when 2i is used Patch by Alex Petrov; reviewed by Benjamin Lerer for CASSANDRA-11907 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/c857919b Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/c857919b Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/c857919b Branch: refs/heads/cassandra-2.2 Commit: c857919b40b9fb27139424944e9fb6cc58befc48 Parents: bd6ad43 Author: Alex Petrov <oleksandr.pet...@gmail.com> Authored: Mon Jul 4 14:15:39 2016 +0200 Committer: Benjamin Lerer <b.le...@gmail.com> Committed: Mon Jul 4 14:15:39 2016 +0200 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../cql3/statements/SelectStatement.java | 10 ++- .../cql3/validation/operations/SelectTest.java | 64 ++++++++++++++++++++ 3 files changed, 74 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/c857919b/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index 3aa5ea9..0967ce4 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 2.1.16 + * Fix filtering on clustering columns when 2i is used (CASSANDRA-11907) * Reduce contention getting instances of CompositeType (CASSANDRA-10433) 2.1.15 http://git-wip-us.apache.org/repos/asf/cassandra/blob/c857919b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java index 6351bb5..245e64e 100644 --- a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java @@ -1582,6 +1582,7 @@ public class SelectStatement implements CQLStatement int numberOfRestrictionsEvaluatedWithSlices = 0; + Restriction lastSliceRestriction = null; for (ColumnDefinition def : cfm.clusteringColumns()) { // Remove clustering column restrictions that can be handled by slices; the remainder will be @@ -1589,10 +1590,17 @@ public class SelectStatement implements CQLStatement Boolean indexed = stmt.restrictedColumns.get(def); if (indexed == null) break; - if (!(indexed && stmt.usesSecondaryIndexing) && stmt.columnRestrictions[def.position()].canEvaluateWithSlices()) + + Restriction restriction = stmt.columnRestrictions[def.position()]; + if (lastSliceRestriction != null && !restriction.equals(lastSliceRestriction)) + break; + + if (!(indexed && stmt.usesSecondaryIndexing) && restriction.canEvaluateWithSlices()) { stmt.restrictedColumns.remove(def); numberOfRestrictionsEvaluatedWithSlices++; + if (restriction.isSlice()) + lastSliceRestriction = restriction; } } http://git-wip-us.apache.org/repos/asf/cassandra/blob/c857919b/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 6acab6f..68cf6f8 100644 --- a/test/unit/org/apache/cassandra/cql3/validation/operations/SelectTest.java +++ b/test/unit/org/apache/cassandra/cql3/validation/operations/SelectTest.java @@ -1264,4 +1264,68 @@ public class SelectTest extends CQLTester "SELECT * FROM %s WHERE a = 'foo' AND b= 'bar' AND c IN (?, ?)", new String(TOO_BIG.array()), new String(TOO_BIG.array())); } + + @Test + public void testFilteringWithSecondaryIndex() throws Throwable + { + createTable("CREATE TABLE %s (pk int, " + + "c1 int, " + + "c2 int, " + + "c3 int, " + + "v int, " + + "PRIMARY KEY (pk, c1, c2, c3))"); + createIndex("CREATE INDEX v_idx_1 ON %s (v);"); + + for (int i = 1; i <= 5; i++) + { + execute("INSERT INTO %s (pk, c1, c2, c3, v) VALUES (?, ?, ?, ?, ?)", 1, 1, 1, 1, i); + execute("INSERT INTO %s (pk, c1, c2, c3, v) VALUES (?, ?, ?, ?, ?)", 1, 1, 1, i, i); + execute("INSERT INTO %s (pk, c1, c2, c3, v) VALUES (?, ?, ?, ?, ?)", 1, 1, i, i, i); + execute("INSERT INTO %s (pk, c1, c2, c3, v) VALUES (?, ?, ?, ?, ?)", 1, i, i, i, i); + } + + assertRows(execute("SELECT * FROM %s WHERE pk = 1 AND c1 > 0 AND c1 < 5 AND c2 = 1 AND v = 3 ALLOW FILTERING;"), + row(1, 1, 1, 3, 3)); + + assertEmpty(execute("SELECT * FROM %s WHERE pk = 1 AND c1 > 1 AND c1 < 5 AND c2 = 1 AND v = 3 ALLOW FILTERING;")); + + assertRows(execute("SELECT * FROM %s WHERE pk = 1 AND c1 > 1 AND c2 > 2 AND c3 > 2 AND v = 3 ALLOW FILTERING;"), + row(1, 3, 3, 3, 3)); + + assertRows(execute("SELECT * FROM %s WHERE pk = 1 AND c1 > 1 AND c2 > 2 AND c3 = 3 AND v = 3 ALLOW FILTERING;"), + row(1, 3, 3, 3, 3)); + + assertRows(execute("SELECT * FROM %s WHERE pk = 1 AND (c1, c2) > (1, 3) AND c3 = 3 AND v = 3 ALLOW FILTERING;"), + row(1, 3, 3, 3, 3)); + + assertInvalidMessage("Clustering column \"c1\" cannot be restricted by an IN relation", + "SELECT * FROM %s WHERE pk = 1 AND c1 IN(0,1,2) AND c2 = 1 AND v = 3 ALLOW FILTERING;"); + + assertInvalidMessage("Clustering column \"c1\" cannot be restricted by an IN relation", + "SELECT * FROM %s WHERE pk = 1 AND c1 IN(0,1,2) AND c2 = 1 AND v = 3"); + + assertInvalidMessage("PRIMARY KEY column \"c2\" cannot be restricted (preceding column \"c1\" is restricted by a non-EQ relation)", + "SELECT * FROM %s WHERE pk = 1 AND c1 > 0 AND c1 < 5 AND c2 = 1 ALLOW FILTERING;"); + + assertInvalidMessage("PRIMARY KEY column \"c2\" cannot be restricted (preceding column \"c1\" is not restricted)", + "SELECT * FROM %s WHERE pk = 1 AND c2 = 1 ALLOW FILTERING;"); + } + + @Test + public void testIndexQueryWithCompositePartitionKey() throws Throwable + { + createTable("CREATE TABLE %s (p1 int, p2 int, v int, PRIMARY KEY ((p1, p2)))"); + assertInvalidMessage("Partition key part p2 must be restricted since preceding part is", + "SELECT * FROM %s WHERE p1 = 1 AND v = 3 ALLOW FILTERING"); + + createIndex("CREATE INDEX ON %s(v)"); + + execute("INSERT INTO %s(p1, p2, v) values (?, ?, ?)", 1, 1, 3); + execute("INSERT INTO %s(p1, p2, v) values (?, ?, ?)", 1, 2, 3); + execute("INSERT INTO %s(p1, p2, v) values (?, ?, ?)", 2, 1, 3); + + assertRows(execute("SELECT * FROM %s WHERE p1 = 1 AND v = 3 ALLOW FILTERING"), + row(1, 2, 3), + row(1, 1, 3)); + } }