Repository: cassandra
Updated Branches:
  refs/heads/trunk 30bfa07a4 -> c83729f41


Make sure that indexing/filtering restrictions are picked up correctly even if 
the columns are given in order

Patch by Alex Petrov; reviewed by Sam Tunnicliffe and Benjamin Lerer for 
CASSANDRA-11310


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/c83729f4
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/c83729f4
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/c83729f4

Branch: refs/heads/trunk
Commit: c83729f41d358ce3ca2ac0323704ef516dff9298
Parents: 30bfa07
Author: Alex Petrov <[email protected]>
Authored: Tue Apr 19 10:43:12 2016 +0200
Committer: Sam Tunnicliffe <[email protected]>
Committed: Tue Apr 19 18:05:29 2016 +0100

----------------------------------------------------------------------
 .../restrictions/StatementRestrictions.java     | 39 +++++++-------
 .../entities/FrozenCollectionsTest.java         |  2 +-
 .../cql3/validation/operations/SelectTest.java  | 56 ++++++++++++++++++++
 3 files changed, 77 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/c83729f4/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java
----------------------------------------------------------------------
diff --git 
a/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java 
b/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java
index b146cfd..c4d7622 100644
--- a/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java
@@ -42,7 +42,6 @@ import org.apache.cassandra.utils.btree.BTreeSet;
 
 import static 
org.apache.cassandra.cql3.statements.RequestValidations.checkFalse;
 import static 
org.apache.cassandra.cql3.statements.RequestValidations.checkNotNull;
-import static 
org.apache.cassandra.cql3.statements.RequestValidations.checkTrue;
 import static 
org.apache.cassandra.cql3.statements.RequestValidations.invalidRequest;
 
 /**
@@ -471,35 +470,37 @@ public final class StatementRestrictions
             checkFalse(clusteringColumnsRestrictions.hasIN() && 
selectsComplexColumn,
                        "Cannot restrict clustering columns by IN relations 
when a collection is selected by the query");
             checkFalse(clusteringColumnsRestrictions.hasContains() && 
!hasQueriableIndex && !allowFiltering,
-                       "Cannot restrict clustering columns by a CONTAINS 
relation without a secondary index");
 
+                       "Clustering columns can only be restricted with 
CONTAINS with a secondary index or filtering");
 
-            if (hasClusteringColumnsRestriction())
+            if (hasClusteringColumnsRestriction() && 
clusteringColumnsRestrictions.needFiltering())
             {
-                List<ColumnDefinition> clusteringColumns = 
cfm.clusteringColumns();
-                List<ColumnDefinition> restrictedColumns = new 
LinkedList<>(clusteringColumnsRestrictions.getColumnDefs());
-
-                for (int i = 0, m = restrictedColumns.size(); i < m; i++)
+                if (hasQueriableIndex || forView)
+                {
+                    usesSecondaryIndexing = true;
+                }
+                else
                 {
-                    ColumnDefinition clusteringColumn = 
clusteringColumns.get(i);
-                    ColumnDefinition restrictedColumn = 
restrictedColumns.get(i);
+                    List<ColumnDefinition> clusteringColumns = 
cfm.clusteringColumns();
+                    List<ColumnDefinition> restrictedColumns = new 
LinkedList<>(clusteringColumnsRestrictions.getColumnDefs());
 
-                    if (!clusteringColumn.equals(restrictedColumn) && 
!allowFiltering)
+                    for (int i = 0, m = restrictedColumns.size(); i < m; i++)
                     {
-                        checkTrue(hasQueriableIndex || forView,
-                                  "PRIMARY KEY column \"%s\" cannot be 
restricted as preceding column \"%s\" is not restricted",
-                                  restrictedColumn.name,
-                                  clusteringColumn.name);
-
-                        usesSecondaryIndexing = true; // handle gaps and 
non-keyrange cases.
-                        break;
+                        ColumnDefinition clusteringColumn = 
clusteringColumns.get(i);
+                        ColumnDefinition restrictedColumn = 
restrictedColumns.get(i);
+
+                        if (!clusteringColumn.equals(restrictedColumn) && 
!allowFiltering)
+                        {
+                            throw invalidRequest("PRIMARY KEY column \"%s\" 
cannot be restricted as preceding column \"%s\" is not restricted",
+                                                 restrictedColumn.name,
+                                                 clusteringColumn.name);
+                        }
                     }
                 }
             }
+
         }
 
-        if (clusteringColumnsRestrictions.hasContains())
-            usesSecondaryIndexing = true;
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c83729f4/test/unit/org/apache/cassandra/cql3/validation/entities/FrozenCollectionsTest.java
----------------------------------------------------------------------
diff --git 
a/test/unit/org/apache/cassandra/cql3/validation/entities/FrozenCollectionsTest.java
 
b/test/unit/org/apache/cassandra/cql3/validation/entities/FrozenCollectionsTest.java
index 4aa178a..4c7c135 100644
--- 
a/test/unit/org/apache/cassandra/cql3/validation/entities/FrozenCollectionsTest.java
+++ 
b/test/unit/org/apache/cassandra/cql3/validation/entities/FrozenCollectionsTest.java
@@ -630,7 +630,7 @@ public class FrozenCollectionsTest extends CQLTester
                              "SELECT * FROM %s WHERE c CONTAINS KEY ?", 1);
 
         // normal indexes on frozen collections don't support CONTAINS or 
CONTAINS KEY
-        assertInvalidMessage("Cannot restrict clustering columns by a CONTAINS 
relation without a secondary index",
+        assertInvalidMessage("Clustering columns can only be restricted with 
CONTAINS with a secondary index or filtering",
                              "SELECT * FROM %s WHERE b CONTAINS ?", 1);
 
         assertRows(execute("SELECT * FROM %s WHERE b CONTAINS ? ALLOW 
FILTERING", 1),

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c83729f4/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 6789baf..49e6c4b 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/operations/SelectTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/operations/SelectTest.java
@@ -2449,6 +2449,15 @@ public class SelectTest extends CQLTester
 
         beforeAndAfterFlush(() -> {
 
+            assertRows(execute("SELECT * FROM %s WHERE a = 11 AND b = 15"),
+                       row(11, 15, 16, 17));
+
+            assertInvalidMessage("Clustering column \"c\" cannot be restricted 
(preceding column \"b\" is restricted by a non-EQ relation)",
+                                 "SELECT * FROM %s WHERE a = 11 AND b > 12 AND 
c = 15");
+
+            assertRows(execute("SELECT * FROM %s WHERE a = 11 AND b = 15 AND c 
> 15"),
+                       row(11, 15, 16, 17));
+
             assertRows(execute("SELECT * FROM %s WHERE a = 11 AND b > 12 AND c 
> 13 AND d = 17 ALLOW FILTERING"),
                        row(11, 15, 16, 17));
             assertInvalidMessage("Clustering column \"c\" cannot be restricted 
(preceding column \"b\" is restricted by a non-EQ relation)",
@@ -2541,6 +2550,32 @@ public class SelectTest extends CQLTester
         //-------------------------------------------------
         // Frozen collections filtering for clustering keys
         //-------------------------------------------------
+
+        // first clustering column
+        createTable("CREATE TABLE %s (a int, b frozen<list<int>>, c int, 
PRIMARY KEY (a, b, c))");
+        execute("INSERT INTO %s (a,b,c) VALUES (?, ?, ?)", 11, list(1, 3), 14);
+        execute("INSERT INTO %s (a,b,c) VALUES (?, ?, ?)", 21, list(2, 3), 24);
+        execute("INSERT INTO %s (a,b,c) VALUES (?, ?, ?)", 21, list(3, 3), 34);
+
+        beforeAndAfterFlush(() -> {
+
+            assertRows(execute("SELECT * FROM %s WHERE a = 21 AND b CONTAINS 2 
ALLOW FILTERING"),
+                       row(21, list(2, 3), 24));
+            assertInvalidMessage("Clustering columns can only be restricted 
with CONTAINS with a secondary index or filtering",
+                                 "SELECT * FROM %s WHERE a = 21 AND b CONTAINS 
2");
+
+            assertRows(execute("SELECT * FROM %s WHERE b CONTAINS 2 ALLOW 
FILTERING"),
+                       row(21, list(2, 3), 24));
+            assertInvalidMessage("Clustering columns can only be restricted 
with CONTAINS with a secondary index or filtering",
+                                 "SELECT * FROM %s WHERE b CONTAINS 2");
+
+            assertRows(execute("SELECT * FROM %s WHERE b CONTAINS 3 ALLOW 
FILTERING"),
+                       row(11, list(1, 3), 14),
+                       row(21, list(2, 3), 24),
+                       row(21, list(3, 3), 34));
+        });
+
+        // non-first clustering column
         createTable("CREATE TABLE %s (a int, b int, c frozen<list<int>>, d 
int, PRIMARY KEY (a, b, c))");
 
         execute("INSERT INTO %s (a,b,c,d) VALUES (?, ?, ?, ?)", 11, 12, 
list(1, 3), 14);
@@ -2549,6 +2584,11 @@ public class SelectTest extends CQLTester
 
         beforeAndAfterFlush(() -> {
 
+            assertRows(execute("SELECT * FROM %s WHERE a = 21 AND c CONTAINS 2 
ALLOW FILTERING"),
+                       row(21, 22, list(2, 3), 24));
+            assertInvalidMessage("Clustering columns can only be restricted 
with CONTAINS with a secondary index or filtering",
+                                 "SELECT * FROM %s WHERE a = 21 AND c CONTAINS 
2");
+
             assertRows(execute("SELECT * FROM %s WHERE b > 20 AND c CONTAINS 2 
ALLOW FILTERING"),
                        row(21, 22, list(2, 3), 24));
             assertInvalidMessage("Clustering column \"c\" cannot be restricted 
(preceding column \"b\" is restricted by a non-EQ relation)",
@@ -2750,6 +2790,22 @@ public class SelectTest extends CQLTester
         });
     }
 
+    @Test
+    public void testCustomIndexWithFiltering() throws Throwable {
+        // Test for CASSANDRA-11310 compatibility with 2i
+        createTable("CREATE TABLE %s (a text, b int, c text, d int, PRIMARY 
KEY (a, b, c));");
+        createIndex("CREATE INDEX ON %s(c)");
+        
+        execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", "a", 0, 
"b", 1);
+        execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", "a", 1, 
"b", 2);
+        execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", "a", 2, 
"b", 3);
+        execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", "c", 3, 
"b", 4);
+
+        assertRows(executeFilteringOnly("SELECT * FROM %s WHERE a='a' AND b > 
0 AND c = 'b'"),
+                   row("a", 1, "b", 2),
+                   row("a", 2, "b", 3));
+    }
+
     private UntypedResultSet executeFilteringOnly(String statement) throws 
Throwable
     {
         assertInvalid(statement);

Reply via email to