You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by ty...@apache.org on 2015/06/26 21:58:17 UTC

[1/4] cassandra git commit: Fix suboptimal 2i selection when clustering col is indexed

Repository: cassandra
Updated Branches:
  refs/heads/trunk a5fbb3205 -> 9e2893853


Fix suboptimal 2i selection when clustering col is indexed

Patch by Benjamin Lerer; reviewed by Tyler Hobbs for CASSANDRA-9631


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

Branch: refs/heads/trunk
Commit: f2db756abd135cc6ca4cf657d29fb2601764d50f
Parents: 5aaa5ca
Author: blerer <be...@datastax.com>
Authored: Fri Jun 26 14:40:37 2015 -0500
Committer: Tyler Hobbs <ty...@gmail.com>
Committed: Fri Jun 26 14:40:37 2015 -0500

----------------------------------------------------------------------
 CHANGES.txt                                     |  2 +
 .../cql3/statements/SelectStatement.java        |  2 +-
 .../cassandra/cql3/MultiColumnRelationTest.java | 69 +++++++++++++++++---
 .../cql3/SingleColumnRelationTest.java          | 18 ++++-
 4 files changed, 81 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/f2db756a/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 68a9bf4..32f0873 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,6 @@
 2.0.17
+ * Fix suboptimal secondary index selection when restricted
+   clustering column is also indexed (CASSANDRA-9631)
  * (cqlsh) Add min_threshold to DTCS option autocomplete (CASSANDRA-9385)
  * Fix error message when attempting to create an index on a column
    in a COMPACT STORAGE table with clustering columns (CASSANDRA-9527)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/f2db756a/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 1c19760..341ce81 100644
--- a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
@@ -1606,7 +1606,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache
                 Boolean indexed = stmt.restrictedNames.get(clusteringColumn);
                 if (indexed == null)
                     break;
-                if (!indexed)
+                if (!indexed || !stmt.usesSecondaryIndexing)
                     stmt.restrictedNames.remove(clusteringColumn);
             }
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/f2db756a/test/unit/org/apache/cassandra/cql3/MultiColumnRelationTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/MultiColumnRelationTest.java b/test/unit/org/apache/cassandra/cql3/MultiColumnRelationTest.java
index 30b7f0f..65ff3e7 100644
--- a/test/unit/org/apache/cassandra/cql3/MultiColumnRelationTest.java
+++ b/test/unit/org/apache/cassandra/cql3/MultiColumnRelationTest.java
@@ -1368,38 +1368,68 @@ public class MultiColumnRelationTest
         checkRow(1, results, 0, 1, 1, 0, 1);
         checkRow(2, results, 0, 1, 1, 1, 2);
 
-        results = execute("SELECT * FROM %s.multiple_clustering_with_indices  WHERE (b, c) = (1, 1) ALLOW FILTERING");
+        results = execute("SELECT * FROM %s.multiple_clustering_with_indices WHERE (b, c) = (1, 1) ALLOW FILTERING");
         assertEquals(2, results.size());
         checkRow(0, results, 0, 1, 1, 0, 1);
         checkRow(1, results, 0, 1, 1, 1, 2);
 
-        results = execute("SELECT * FROM %s.multiple_clustering_with_indices  WHERE (b, c) = (1, 1) AND e = 2 ALLOW FILTERING");
+        results = execute("SELECT * FROM %s.multiple_clustering_with_indices WHERE a = 0 AND (b, c) = (1, 1) AND e = 2");
         assertEquals(1, results.size());
         checkRow(0, results, 0, 1, 1, 1, 2);
 
-        results = execute("SELECT * FROM %s.multiple_clustering_with_indices  WHERE (b) IN ((1)) AND e = 2 ALLOW FILTERING");
+        results = execute("SELECT * FROM %s.multiple_clustering_with_indices WHERE (b, c) = (1, 1) AND e = 2 ALLOW FILTERING");
         assertEquals(1, results.size());
         checkRow(0, results, 0, 1, 1, 1, 2);
 
-        results = execute("SELECT * FROM %s.multiple_clustering_with_indices  WHERE (b) IN ((0), (1)) AND e = 2 ALLOW FILTERING");
+        results = execute("SELECT * FROM %s.multiple_clustering_with_indices WHERE a = 0 AND (b) IN ((1)) AND e = 2");
+        assertEquals(1, results.size());
+        checkRow(0, results, 0, 1, 1, 1, 2);
+
+        results = execute("SELECT * FROM %s.multiple_clustering_with_indices WHERE (b) IN ((1)) AND e = 2 ALLOW FILTERING");
+        assertEquals(1, results.size());
+        checkRow(0, results, 0, 1, 1, 1, 2);
+
+        results = execute("SELECT * FROM %s.multiple_clustering_with_indices WHERE a = 0 AND (b) IN ((0), (1)) AND e = 2");
         assertEquals(2, results.size());
         checkRow(0, results, 0, 0, 1, 1, 2);
         checkRow(1, results, 0, 1, 1, 1, 2);
 
-        results = execute("SELECT * FROM %s.multiple_clustering_with_indices  WHERE (b, c) IN ((0, 1)) AND e = 2 ALLOW FILTERING");
+        results = execute("SELECT * FROM %s.multiple_clustering_with_indices WHERE (b) IN ((0), (1)) AND e = 2 ALLOW FILTERING");
+        assertEquals(2, results.size());
+        checkRow(0, results, 0, 0, 1, 1, 2);
+        checkRow(1, results, 0, 1, 1, 1, 2);
+
+        results = execute("SELECT * FROM %s.multiple_clustering_with_indices WHERE a = 0 AND (b, c) IN ((0, 1)) AND e = 2");
         assertEquals(1, results.size());
         checkRow(0, results, 0, 0, 1, 1, 2);
 
-        results = execute("SELECT * FROM %s.multiple_clustering_with_indices  WHERE (b, c) IN ((0, 1), (1, 1)) AND e = 2 ALLOW FILTERING");
+        results = execute("SELECT * FROM %s.multiple_clustering_with_indices WHERE (b, c) IN ((0, 1)) AND e = 2 ALLOW FILTERING");
+        assertEquals(1, results.size());
+        checkRow(0, results, 0, 0, 1, 1, 2);
+
+        results = execute("SELECT * FROM %s.multiple_clustering_with_indices WHERE a = 0 AND (b, c) IN ((0, 1), (1, 1)) AND e = 2");
+        assertEquals(2, results.size());
+        checkRow(0, results, 0, 0, 1, 1, 2);
+        checkRow(1, results, 0, 1, 1, 1, 2);
+
+        results = execute("SELECT * FROM %s.multiple_clustering_with_indices WHERE (b, c) IN ((0, 1), (1, 1)) AND e = 2 ALLOW FILTERING");
         assertEquals(2, results.size());
         checkRow(0, results, 0, 0, 1, 1, 2);
         checkRow(1, results, 0, 1, 1, 1, 2);
 
-        results = execute("SELECT * FROM %s.multiple_clustering_with_indices  WHERE (b) >= (1) AND e = 2 ALLOW FILTERING");
+        results = execute("SELECT * FROM %s.multiple_clustering_with_indices WHERE a = 0 AND (b) >= (1) AND e = 2");
         assertEquals(1, results.size());
         checkRow(0, results, 0, 1, 1, 1, 2);
 
-        results = execute("SELECT * FROM %s.multiple_clustering_with_indices  WHERE (b, c) >= (1, 1) AND e = 2 ALLOW FILTERING");
+        results = execute("SELECT * FROM %s.multiple_clustering_with_indices WHERE (b) >= (1) AND e = 2 ALLOW FILTERING");
+        assertEquals(1, results.size());
+        checkRow(0, results, 0, 1, 1, 1, 2);
+
+        results = execute("SELECT * FROM %s.multiple_clustering_with_indices WHERE a = 0 AND (b, c) >= (1, 1) AND e = 2");
+        assertEquals(1, results.size());
+        checkRow(0, results, 0, 1, 1, 1, 2);
+
+        results = execute("SELECT * FROM %s.multiple_clustering_with_indices WHERE (b, c) >= (1, 1) AND e = 2 ALLOW FILTERING");
         assertEquals(1, results.size());
         checkRow(0, results, 0, 1, 1, 1, 2);
     }
@@ -1428,24 +1458,47 @@ public class MultiColumnRelationTest
         checkRow(0, results, 0, 0, 1, 1, 0, 4);
         checkRow(1, results, 0, 0, 1, 1, 1, 5);
 
+        results = execute("SELECT * FROM %s.partition_with_indices WHERE a = 0 AND b = 0 AND (c) IN ((1)) AND f = 5");
+        assertEquals(1, results.size());
+        checkRow(0, results, 0, 0, 1, 1, 1, 5);
+
         results = execute("SELECT * FROM %s.partition_with_indices WHERE a = 0  AND (c) IN ((1)) AND f = 5 ALLOW FILTERING");
         assertEquals(1, results.size());
         checkRow(0, results, 0, 0, 1, 1, 1, 5);
 
+        results = execute("SELECT * FROM %s.partition_with_indices WHERE a = 0 AND b = 0 AND (c) IN ((1), (2)) AND f = 5");
+        assertEquals(2, results.size());
+        checkRow(0, results, 0, 0, 1, 1, 1, 5);
+        checkRow(1, results, 0, 0, 2, 0, 0, 5);
+
         results = execute("SELECT * FROM %s.partition_with_indices WHERE a = 0 AND (c) IN ((1), (2)) AND f = 5 ALLOW FILTERING");
         assertEquals(2, results.size());
         checkRow(0, results, 0, 0, 1, 1, 1, 5);
         checkRow(1, results, 0, 0, 2, 0, 0, 5);
 
+        results = execute("SELECT * FROM %s.partition_with_indices WHERE a = 0 AND b = 0 AND (c, d) IN ((1, 0)) AND f = 3");
+        assertEquals(1, results.size());
+        checkRow(0, results, 0, 0, 1, 0, 0, 3);
+
         results = execute("SELECT * FROM %s.partition_with_indices WHERE a = 0  AND (c, d) IN ((1, 0)) AND f = 3 ALLOW FILTERING");
         assertEquals(1, results.size());
         checkRow(0, results, 0, 0, 1, 0, 0, 3);
 
+        results = execute("SELECT * FROM %s.partition_with_indices WHERE a = 0 AND b = 0 AND (c) >= (1) AND f = 5");
+        assertEquals(2, results.size());
+        checkRow(0, results, 0, 0, 1, 1, 1, 5);
+        checkRow(1, results, 0, 0, 2, 0, 0, 5);
+
         results = execute("SELECT * FROM %s.partition_with_indices WHERE a = 0 AND (c) >= (1) AND f = 5 ALLOW FILTERING");
         assertEquals(2, results.size());
         checkRow(0, results, 0, 0, 1, 1, 1, 5);
         checkRow(1, results, 0, 0, 2, 0, 0, 5);
 
+        results = execute("SELECT * FROM %s.partition_with_indices WHERE a = 0 AND b = 0 AND (c, d) >= (1, 1) AND f = 5");
+        assertEquals(2, results.size());
+        checkRow(0, results, 0, 0, 1, 1, 1, 5);
+        checkRow(1, results, 0, 0, 2, 0, 0, 5);
+
         results = execute("SELECT * FROM %s.partition_with_indices WHERE a = 0 AND (c, d) >= (1, 1) AND f = 5 ALLOW FILTERING");
         assertEquals(2, results.size());
         checkRow(0, results, 0, 0, 1, 1, 1, 5);

http://git-wip-us.apache.org/repos/asf/cassandra/blob/f2db756a/test/unit/org/apache/cassandra/cql3/SingleColumnRelationTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/SingleColumnRelationTest.java b/test/unit/org/apache/cassandra/cql3/SingleColumnRelationTest.java
index 34d3bf1..c8c67aa 100644
--- a/test/unit/org/apache/cassandra/cql3/SingleColumnRelationTest.java
+++ b/test/unit/org/apache/cassandra/cql3/SingleColumnRelationTest.java
@@ -96,17 +96,33 @@ public class SingleColumnRelationTest
 
         execute("INSERT INTO %s.partition_with_indices (a, b, c, d, e, f) VALUES (0, 0, 2, 0, 0, 5)");
 
-        UntypedResultSet results = execute("SELECT * FROM %s.partition_with_indices WHERE a = 0 AND c = 1 ALLOW FILTERING");
+        UntypedResultSet results = execute("SELECT * FROM %s.partition_with_indices WHERE a = 0 AND b = 0 AND c = 1");
         assertEquals(3, results.size());
         checkRow(0, results, 0, 0, 1, 0, 0, 3);
         checkRow(1, results, 0, 0, 1, 1, 0, 4);
         checkRow(2, results, 0, 0, 1, 1, 1, 5);
 
+        results = execute("SELECT * FROM %s.partition_with_indices WHERE a = 0 AND c = 1 ALLOW FILTERING");
+        assertEquals(3, results.size());
+        checkRow(0, results, 0, 0, 1, 0, 0, 3);
+        checkRow(1, results, 0, 0, 1, 1, 0, 4);
+        checkRow(2, results, 0, 0, 1, 1, 1, 5);
+
+        results = execute("SELECT * FROM %s.partition_with_indices WHERE a = 0 AND b = 0 AND c = 1 AND d = 1");
+        assertEquals(2, results.size());
+        checkRow(0, results, 0, 0, 1, 1, 0, 4);
+        checkRow(1, results, 0, 0, 1, 1, 1, 5);
+
         results = execute("SELECT * FROM %s.partition_with_indices WHERE a = 0 AND c = 1 AND d = 1 ALLOW FILTERING");
         assertEquals(2, results.size());
         checkRow(0, results, 0, 0, 1, 1, 0, 4);
         checkRow(1, results, 0, 0, 1, 1, 1, 5);
 
+        results = execute("SELECT * FROM %s.partition_with_indices WHERE a = 0 AND b = 0 AND c >= 1 AND f = 5");
+        assertEquals(2, results.size());
+        checkRow(0, results, 0, 0, 1, 1, 1, 5);
+        checkRow(1, results, 0, 0, 2, 0, 0, 5);
+
         results = execute("SELECT * FROM %s.partition_with_indices WHERE a = 0 AND c >= 1 AND f = 5 ALLOW FILTERING");
         assertEquals(2, results.size());
         checkRow(0, results, 0, 0, 1, 1, 1, 5);


[4/4] cassandra git commit: Merge branch 'cassandra-2.2' into trunk

Posted by ty...@apache.org.
Merge branch 'cassandra-2.2' into trunk


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

Branch: refs/heads/trunk
Commit: 9e28938531931746589c0b2cf0df62256421a36f
Parents: a5fbb32 2a4ab87
Author: Tyler Hobbs <ty...@gmail.com>
Authored: Fri Jun 26 14:58:03 2015 -0500
Committer: Tyler Hobbs <ty...@gmail.com>
Committed: Fri Jun 26 14:58:03 2015 -0500

----------------------------------------------------------------------
 .../SelectMultiColumnRelationTest.java          | 29 ++++++++++++++++++++
 .../SelectSingleColumnRelationTest.java         |  8 ++++++
 2 files changed, 37 insertions(+)
----------------------------------------------------------------------



[3/4] cassandra git commit: Merge branch 'cassandra-2.1' into cassandra-2.2

Posted by ty...@apache.org.
Merge branch 'cassandra-2.1' into cassandra-2.2


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

Branch: refs/heads/trunk
Commit: 2a4ab8716a8aa4f80a91b3128ecbe9ab6e764ddc
Parents: 239927d 2c58581
Author: Tyler Hobbs <ty...@gmail.com>
Authored: Fri Jun 26 14:57:27 2015 -0500
Committer: Tyler Hobbs <ty...@gmail.com>
Committed: Fri Jun 26 14:57:27 2015 -0500

----------------------------------------------------------------------
 .../SelectMultiColumnRelationTest.java          | 29 ++++++++++++++++++++
 .../SelectSingleColumnRelationTest.java         |  8 ++++++
 2 files changed, 37 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/2a4ab871/test/unit/org/apache/cassandra/cql3/validation/operations/SelectMultiColumnRelationTest.java
----------------------------------------------------------------------
diff --cc test/unit/org/apache/cassandra/cql3/validation/operations/SelectMultiColumnRelationTest.java
index 552e39e,954f89d..39412b9
--- a/test/unit/org/apache/cassandra/cql3/validation/operations/SelectMultiColumnRelationTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/operations/SelectMultiColumnRelationTest.java
@@@ -791,26 -738,20 +795,33 @@@ public class SelectMultiColumnRelationT
                     row(0, 1, 0, 0, 0),
                     row(0, 1, 1, 0, 1),
                     row(0, 1, 1, 1, 2));
 +
 +        assertInvalidMessage("Cannot execute this query as it might involve data filtering",
 +                             "SELECT * FROM %s WHERE (b, c) = (?, ?)", 1, 1);
+         assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c) = (?, ?)", 0, 1, 1),
+                    row(0, 1, 1, 0, 1),
+                    row(0, 1, 1, 1, 2));
          assertRows(execute("SELECT * FROM %s WHERE (b, c) = (?, ?) ALLOW FILTERING", 1, 1),
                     row(0, 1, 1, 0, 1),
                     row(0, 1, 1, 1, 2));
 +
+         assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c) = (?, ?) AND e = ?", 0, 1, 1, 2),
+                    row(0, 1, 1, 1, 2));
 +        assertInvalidMessage("Cannot execute this query as it might involve data filtering",
 +                             "SELECT * FROM %s WHERE (b, c) = (?, ?) AND e = ?", 1, 1, 2);
          assertRows(execute("SELECT * FROM %s WHERE (b, c) = (?, ?) AND e = ? ALLOW FILTERING", 1, 1, 2),
                     row(0, 1, 1, 1, 2));
 -        assertRows(execute("SELECT * FROM %s WHERE (b) IN ((?)) AND e = ? ", 1, 2),
 +
++        assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) IN ((?)) AND e = ? ALLOW FILTERING", 0, 1, 2),
++                   row(0, 1, 1, 1, 2));
 +        assertInvalidMessage("Cannot execute this query as it might involve data filtering",
 +                             "SELECT * FROM %s WHERE (b) IN ((?)) AND e = ?", 1, 2);
 +        assertRows(execute("SELECT * FROM %s WHERE (b) IN ((?)) AND e = ? ALLOW FILTERING", 1, 2),
                     row(0, 1, 1, 1, 2));
  
 -        assertRows(execute("SELECT * FROM %s WHERE (b) IN ((?), (?)) AND e = ?", 0, 1, 2),
 +        assertInvalidMessage("Cannot execute this query as it might involve data filtering",
 +                             "SELECT * FROM %s WHERE (b) IN ((?), (?)) AND e = ?", 0, 1, 2);
 +        assertRows(execute("SELECT * FROM %s WHERE (b) IN ((?), (?)) AND e = ? ALLOW FILTERING", 0, 1, 2),
                     row(0, 0, 1, 1, 2),
                     row(0, 1, 1, 1, 2));
  
@@@ -825,15 -762,12 +836,16 @@@
                     row(0, 0, 1, 1, 2),
                     row(0, 1, 1, 1, 2));
  
 -        assertRows(execute("SELECT * FROM %s WHERE (b) >= (?) AND e = ?", 1, 2),
 +        assertInvalidMessage("Cannot execute this query as it might involve data filtering",
 +                             "SELECT * FROM %s WHERE (b) >= (?) AND e = ?", 1, 2);
 +        assertRows(execute("SELECT * FROM %s WHERE (b) >= (?) AND e = ? ALLOW FILTERING", 1, 2),
                     row(0, 1, 1, 1, 2));
  
 -        assertRows(execute("SELECT * FROM %s WHERE (b, c) >= (?, ?) AND e = ?", 1, 1, 2),
 +        assertInvalidMessage("Cannot execute this query as it might involve data filtering",
 +                             "SELECT * FROM %s WHERE (b, c) >= (?, ?) AND e = ?", 1, 1, 2);
 +        assertRows(execute("SELECT * FROM %s WHERE (b, c) >= (?, ?) AND e = ? ALLOW FILTERING", 1, 1, 2),
                     row(0, 1, 1, 1, 2));
+ 
      }
  
      @Test
@@@ -866,36 -796,44 +878,53 @@@
                     row(0, 0, 1, 1, 0, 4),
                     row(0, 0, 1, 1, 1, 5));
  
 -        assertInvalidMessage("Partition key part b must be restricted since preceding part is",
 +        assertInvalidMessage("Partition key parts: b must be restricted as other parts are",
                               "SELECT * FROM %s WHERE a = ? AND (c, d) IN ((?, ?)) ALLOW FILTERING", 0, 1, 1);
  
 -        assertInvalidMessage("Partition key part b must be restricted since preceding part is",
 +        assertInvalidMessage("Partition key parts: b must be restricted as other parts are",
                               "SELECT * FROM %s WHERE a = ? AND (c, d) >= (?, ?) ALLOW FILTERING", 0, 1, 1);
  
+         assertRows(execute("SELECT * FROM %s WHERE a = ? AND b = ? AND (c) IN ((?)) AND f = ?", 0, 0, 1, 5),
+                    row(0, 0, 1, 1, 1, 5));
 -
 +        assertInvalidMessage("Cannot execute this query as it might involve data filtering",
 +                             "SELECT * FROM %s WHERE a = ? AND (c) IN ((?)) AND f = ?", 0, 1, 5);
          assertRows(execute("SELECT * FROM %s WHERE a = ? AND (c) IN ((?)) AND f = ? ALLOW FILTERING", 0, 1, 5),
                     row(0, 0, 1, 1, 1, 5));
  
 +        assertInvalidMessage("Cannot execute this query as it might involve data filtering",
 +                             "SELECT * FROM %s WHERE a = ? AND (c) IN ((?), (?)) AND f = ?", 0, 1, 2, 5);
++
+         assertRows(execute("SELECT * FROM %s WHERE a = ? AND b = ? AND (c) IN ((?), (?)) AND f = ?", 0, 0, 1, 2, 5),
+                    row(0, 0, 1, 1, 1, 5),
+                    row(0, 0, 2, 0, 0, 5));
+ 
          assertRows(execute("SELECT * FROM %s WHERE a = ? AND (c) IN ((?), (?)) AND f = ? ALLOW FILTERING", 0, 1, 2, 5),
                     row(0, 0, 1, 1, 1, 5),
                     row(0, 0, 2, 0, 0, 5));
  
+         assertRows(execute("SELECT * FROM %s WHERE a = ? AND b = ? AND (c, d) IN ((?, ?)) AND f = ?", 0, 0, 1, 0, 3),
+                    row(0, 0, 1, 0, 0, 3));
 -
 +        assertInvalidMessage("Cannot execute this query as it might involve data filtering",
 +                             "SELECT * FROM %s WHERE a = ? AND (c, d) IN ((?, ?)) AND f = ?", 0, 1, 0, 3);
          assertRows(execute("SELECT * FROM %s WHERE a = ? AND (c, d) IN ((?, ?)) AND f = ? ALLOW FILTERING", 0, 1, 0, 3),
                     row(0, 0, 1, 0, 0, 3));
  
 +        assertInvalidMessage("Cannot execute this query as it might involve data filtering",
 +                             "SELECT * FROM %s WHERE a = ? AND (c) >= (?) AND f = ?", 0, 1, 5);
++
+         assertRows(execute("SELECT * FROM %s WHERE a = ? AND b = ? AND (c) >= (?) AND f = ?", 0, 0, 1, 5),
+                    row(0, 0, 1, 1, 1, 5),
+                    row(0, 0, 2, 0, 0, 5));
+ 
          assertRows(execute("SELECT * FROM %s WHERE a = ? AND (c) >= (?) AND f = ? ALLOW FILTERING", 0, 1, 5),
                     row(0, 0, 1, 1, 1, 5),
                     row(0, 0, 2, 0, 0, 5));
  
+         assertRows(execute("SELECT * FROM %s WHERE a = ? AND b = ? AND (c, d) >= (?, ?) AND f = ?", 0, 0, 1, 1, 5),
+                    row(0, 0, 1, 1, 1, 5),
+                    row(0, 0, 2, 0, 0, 5));
 -
 +        assertInvalidMessage("Cannot execute this query as it might involve data filtering",
 +                             "SELECT * FROM %s WHERE a = ? AND (c, d) >= (?, ?) AND f = ?", 0, 1, 1, 5);
          assertRows(execute("SELECT * FROM %s WHERE a = ? AND (c, d) >= (?, ?) AND f = ? ALLOW FILTERING", 0, 1, 1, 5),
                     row(0, 0, 1, 1, 1, 5),
                     row(0, 0, 2, 0, 0, 5));

http://git-wip-us.apache.org/repos/asf/cassandra/blob/2a4ab871/test/unit/org/apache/cassandra/cql3/validation/operations/SelectSingleColumnRelationTest.java
----------------------------------------------------------------------
diff --cc test/unit/org/apache/cassandra/cql3/validation/operations/SelectSingleColumnRelationTest.java
index fd43a51,05bb88b..57b8a86
--- a/test/unit/org/apache/cassandra/cql3/validation/operations/SelectSingleColumnRelationTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/operations/SelectSingleColumnRelationTest.java
@@@ -471,85 -93,24 +471,93 @@@ public class SelectSingleColumnRelation
                     row(0, 0, 1, 1, 0, 4),
                     row(0, 0, 1, 1, 1, 5));
  
 -        assertInvalidMessage("Partition key part b must be restricted since preceding part is",
 +        assertInvalidMessage("Partition key parts: b must be restricted as other parts are",
 +                             "SELECT * FROM %s WHERE a = ? AND c IN (?) AND  d IN (?) ALLOW FILTERING", 0, 1, 1);
 +
 +        assertInvalidMessage("Partition key parts: b must be restricted as other parts are",
 +                             "SELECT * FROM %s WHERE a = ? AND (c, d) >= (?, ?) ALLOW FILTERING", 0, 1, 1);
 +
 +        assertInvalidMessage("Cannot execute this query as it might involve data filtering",
 +                             "SELECT * FROM %s WHERE a = ? AND c IN (?) AND f = ?", 0, 1, 5);
 +        assertRows(execute("SELECT * FROM %s WHERE a = ? AND c IN (?) AND f = ? ALLOW FILTERING", 0, 1, 5),
 +                   row(0, 0, 1, 1, 1, 5));
 +
 +        assertInvalidMessage("Cannot execute this query as it might involve data filtering",
 +                             "SELECT * FROM %s WHERE a = ? AND c IN (?, ?) AND f = ?", 0, 1, 2, 5);
 +        assertRows(execute("SELECT * FROM %s WHERE a = ? AND c IN (?, ?) AND f = ? ALLOW FILTERING", 0, 1, 2, 5),
 +                   row(0, 0, 1, 1, 1, 5),
 +                   row(0, 0, 2, 0, 0, 5));
 +
 +        assertInvalidMessage("Cannot execute this query as it might involve data filtering",
 +                             "SELECT * FROM %s WHERE a = ? AND c IN (?) AND d IN (?) AND f = ?", 0, 1, 0, 3);
 +        assertRows(execute("SELECT * FROM %s WHERE a = ? AND c IN (?) AND d IN (?) AND f = ? ALLOW FILTERING", 0, 1, 0, 3),
 +                   row(0, 0, 1, 0, 0, 3));
 +
 +        assertInvalidMessage("Partition key parts: b must be restricted as other parts are",
                               "SELECT * FROM %s WHERE a = ? AND c >= ? ALLOW FILTERING", 0, 1);
  
 +        assertInvalidMessage("Cannot execute this query as it might involve data filtering",
 +                             "SELECT * FROM %s WHERE a = ? AND c >= ? AND f = ?", 0, 1, 5);
+         assertRows(execute("SELECT * FROM %s WHERE a = ? AND b = ? AND c >= ? AND f = ?", 0, 0, 1, 5),
+                    row(0, 0, 1, 1, 1, 5),
+                    row(0, 0, 2, 0, 0, 5));
+ 
          assertRows(execute("SELECT * FROM %s WHERE a = ? AND c >= ? AND f = ? ALLOW FILTERING", 0, 1, 5),
                     row(0, 0, 1, 1, 1, 5),
                     row(0, 0, 2, 0, 0, 5));
  
 +        assertInvalidMessage("Cannot execute this query as it might involve data filtering",
 +                             "SELECT * FROM %s WHERE a = ? AND c = ? AND d >= ? AND f = ?", 0, 1, 1, 5);
++
+         assertRows(execute("SELECT * FROM %s WHERE a = ? AND b = ? AND c = ? AND d >= ? AND f = ?", 0, 0, 1, 1, 5),
+                    row(0, 0, 1, 1, 1, 5));
+ 
          assertRows(execute("SELECT * FROM %s WHERE a = ? AND c = ? AND d >= ? AND f = ? ALLOW FILTERING", 0, 1, 1, 5),
                     row(0, 0, 1, 1, 1, 5));
 +    }
  
 -        assertInvalidMessage("Cannot execute this query as it might involve data filtering and thus may have unpredictable performance. If you want to execute this query despite the performance unpredictability, use ALLOW FILTERING",
 -                             "SELECT * FROM %s WHERE a = ? AND d >= ? AND f = ?", 0, 1, 5);
 +    @Test
 +    public void testFunctionCallWithUnset() throws Throwable
 +    {
 +        createTable("CREATE TABLE %s (k int PRIMARY KEY, s text, i int)");
 +
 +        assertInvalidMessage("Invalid unset value for argument in call to function token",
 +                             "SELECT * FROM %s WHERE token(k) >= token(?)", unset());
 +        assertInvalidMessage("Invalid unset value for argument in call to function blobasint",
 +                             "SELECT * FROM %s WHERE k = blobAsInt(?)", unset());
 +    }
 +
 +    @Test
 +    public void testLimitWithUnset() throws Throwable
 +    {
 +        createTable("CREATE TABLE %s (k int PRIMARY KEY, i int)");
 +        execute("INSERT INTO %s (k, i) VALUES (1, 1)");
 +        execute("INSERT INTO %s (k, i) VALUES (2, 1)");
 +        assertRows(execute("SELECT k FROM %s LIMIT ?", unset()), // treat as 'unlimited'
 +                row(1),
 +                row(2)
 +        );
 +    }
 +
 +    @Test
 +    public void testWithUnsetValues() throws Throwable
 +    {
 +        createTable("CREATE TABLE %s (k int, i int, j int, s text, PRIMARY KEY(k,i,j))");
 +        createIndex("CREATE INDEX s_index ON %s (s)");
 +        // partition key
 +        assertInvalidMessage("Invalid unset value for column k", "SELECT * from %s WHERE k = ?", unset());
 +        assertInvalidMessage("Invalid unset value for column k", "SELECT * from %s WHERE k IN ?", unset());
 +        assertInvalidMessage("Invalid unset value for column k", "SELECT * from %s WHERE k IN(?)", unset());
 +        assertInvalidMessage("Invalid unset value for column k", "SELECT * from %s WHERE k IN(?,?)", 1, unset());
 +        // clustering column
 +        assertInvalidMessage("Invalid unset value for column i", "SELECT * from %s WHERE k = 1 AND i = ?", unset());
 +        assertInvalidMessage("Invalid unset value for column i", "SELECT * from %s WHERE k = 1 AND i IN ?", unset());
 +        assertInvalidMessage("Invalid unset value for column i", "SELECT * from %s WHERE k = 1 AND i IN(?)", unset());
 +        assertInvalidMessage("Invalid unset value for column i", "SELECT * from %s WHERE k = 1 AND i IN(?,?)", 1, unset());
 +        assertInvalidMessage("Invalid unset value for column i", "SELECT * from %s WHERE i = ? ALLOW FILTERING", unset());
 +        // indexed column
 +        assertInvalidMessage("Unsupported unset value for indexed column s", "SELECT * from %s WHERE s = ?", unset());
 +        // range
 +        assertInvalidMessage("Invalid unset value for column i", "SELECT * from %s WHERE k = 1 AND i > ?", unset());
      }
  }


[2/4] cassandra git commit: Merge branch 'cassandra-2.0' into cassandra-2.1

Posted by ty...@apache.org.
Merge branch 'cassandra-2.0' into cassandra-2.1


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

Branch: refs/heads/trunk
Commit: 2c5858133a6cab8001e07b486e3de7da9b7cb231
Parents: d5698f4 f2db756
Author: Tyler Hobbs <ty...@gmail.com>
Authored: Fri Jun 26 14:54:23 2015 -0500
Committer: Tyler Hobbs <ty...@gmail.com>
Committed: Fri Jun 26 14:54:23 2015 -0500

----------------------------------------------------------------------
 CHANGES.txt                                     |  2 ++
 .../cql3/statements/SelectStatement.java        |  2 +-
 .../SelectMultiColumnRelationTest.java          | 30 +++++++++++++++++++-
 .../SelectSingleColumnRelationTest.java         |  7 +++++
 4 files changed, 39 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/2c585813/CHANGES.txt
----------------------------------------------------------------------
diff --cc CHANGES.txt
index 0611bac,32f0873..0b0cf83
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@@ -1,11 -1,6 +1,13 @@@
 -2.0.17
 +2.1.8
 + * Fix IndexOutOfBoundsException when inserting tuple with too many
 +   elements using the string literal notation (CASSANDRA-9559)
 + * Allow JMX over SSL directly from nodetool (CASSANDRA-9090)
 + * Fix incorrect result for IN queries where column not found (CASSANDRA-9540)
 + * Enable describe on indices (CASSANDRA-7814)
 + * ColumnFamilyStore.selectAndReference may block during compaction (CASSANDRA-9637)
 +Merged from 2.0
+  * Fix suboptimal secondary index selection when restricted
+    clustering column is also indexed (CASSANDRA-9631)
   * (cqlsh) Add min_threshold to DTCS option autocomplete (CASSANDRA-9385)
   * Fix error message when attempting to create an index on a column
     in a COMPACT STORAGE table with clustering columns (CASSANDRA-9527)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/2c585813/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
index 540cb8c,341ce81..6fea8cb
--- a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
@@@ -1571,20 -1598,16 +1571,20 @@@ public class SelectStatement implement
              if (stmt.isKeyRange && hasQueriableClusteringColumnIndex)
                  stmt.usesSecondaryIndexing = true;
  
 -            // The clustering columns that can be used to perform a slice filtering on the secondary index do not
 -            // need to be converted into IndexExpressions. Therefore, if they are not indexed by an index that support
 -            // the relation in which they have been specified, we can removes them from the restrictedNames map.
 -            for (Name clusteringColumn : cfDef.clusteringColumns())
 +            int numberOfRestrictionsEvaluatedWithSlices = 0;
 +
 +            for (ColumnDefinition def : cfm.clusteringColumns())
              {
 -                Boolean indexed = stmt.restrictedNames.get(clusteringColumn);
 +                // Remove clustering column restrictions that can be handled by slices; the remainder will be
 +                // handled by filters (which may require a secondary index).
 +                Boolean indexed = stmt.restrictedColumns.get(def);
                  if (indexed == null)
                      break;
-                 if (!indexed && stmt.columnRestrictions[def.position()].canEvaluateWithSlices())
 -                if (!indexed || !stmt.usesSecondaryIndexing)
 -                    stmt.restrictedNames.remove(clusteringColumn);
++                if (!(indexed && stmt.usesSecondaryIndexing) && stmt.columnRestrictions[def.position()].canEvaluateWithSlices())
 +                {
 +                    stmt.restrictedColumns.remove(def);
 +                    numberOfRestrictionsEvaluatedWithSlices++;
 +                }
              }
  
              // Even if usesSecondaryIndexing is false at this point, we'll still have to use one if

http://git-wip-us.apache.org/repos/asf/cassandra/blob/2c585813/test/unit/org/apache/cassandra/cql3/validation/operations/SelectMultiColumnRelationTest.java
----------------------------------------------------------------------
diff --cc test/unit/org/apache/cassandra/cql3/validation/operations/SelectMultiColumnRelationTest.java
index b56ab8c,0000000..954f89d
mode 100644,000000..100644
--- a/test/unit/org/apache/cassandra/cql3/validation/operations/SelectMultiColumnRelationTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/operations/SelectMultiColumnRelationTest.java
@@@ -1,982 -1,0 +1,1010 @@@
 +/*
 + * Licensed to the Apache Software Foundation (ASF) under one
 + * or more contributor license agreements.  See the NOTICE file
 + * distributed with this work for additional information
 + * regarding copyright ownership.  The ASF licenses this file
 + * to you under the Apache License, Version 2.0 (the
 + * "License"); you may not use this file except in compliance
 + * with the License.  You may obtain a copy of the License at
 + *
 + *     http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +package org.apache.cassandra.cql3.validation.operations;
 +
 +import org.junit.Ignore;
 +import org.junit.Test;
 +
 +import org.apache.cassandra.cql3.CQLTester;
 +
 +import static org.junit.Assert.assertEquals;
 +
 +public class SelectMultiColumnRelationTest extends CQLTester
 +{
 +    @Test
 +    public void testSingleClusteringInvalidQueries() throws Throwable
 +    {
 +        for (String compactOption : new String[]{"", " WITH COMPACT STORAGE"})
 +        {
 +            createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))" + compactOption);
 +
 +            assertInvalidSyntax("SELECT * FROM %s WHERE () = (?, ?)", 1, 2);
 +            assertInvalidMessage("Column \"b\" cannot be restricted by an equality relation and an inequality relation",
 +                                 "SELECT * FROM %s WHERE a = 0 AND (b) = (?) AND (b) > (?)", 0, 0);
 +            assertInvalidMessage("More than one restriction was found for the start bound on b",
 +                                 "SELECT * FROM %s WHERE a = 0 AND (b) > (?) AND (b) > (?)", 0, 1);
 +            assertInvalidMessage("Multi-column relations can only be applied to clustering columns: a",
 +                                 "SELECT * FROM %s WHERE (a, b) = (?, ?)", 0, 0);
 +        }
 +    }
 +
 +    @Test
 +    public void testMultiClusteringInvalidQueries() throws Throwable
 +    {
 +        for (String compactOption : new String[]{"", " WITH COMPACT STORAGE"})
 +        {
 +            createTable("CREATE TABLE %s (a int, b int, c int, d int, PRIMARY KEY (a, b, c, d))" + compactOption);
 +
 +            assertInvalidSyntax("SELECT * FROM %s WHERE a = 0 AND (b, c) > ()");
 +            assertInvalidMessage("Expected 2 elements in value tuple, but got 3: (?, ?, ?)",
 +                                 "SELECT * FROM %s WHERE a = 0 AND (b, c) > (?, ?, ?)", 1, 2, 3);
 +            assertInvalidMessage("Invalid null value in condition for column c",
 +                                 "SELECT * FROM %s WHERE a = 0 AND (b, c) > (?, ?)", 1, null);
 +
 +            // Wrong order of columns
 +            assertInvalidMessage("Clustering columns must appear in the PRIMARY KEY order in multi-column relations: (d, c, b) = (?, ?, ?)",
 +                                 "SELECT * FROM %s WHERE a = 0 AND (d, c, b) = (?, ?, ?)", 0, 0, 0);
 +            assertInvalidMessage("Clustering columns must appear in the PRIMARY KEY order in multi-column relations: (d, c, b) > (?, ?, ?)",
 +                                 "SELECT * FROM %s WHERE a = 0 AND (d, c, b) > (?, ?, ?)", 0, 0, 0);
 +
 +            // Wrong number of values
 +            assertInvalidMessage("Expected 3 elements in value tuple, but got 2: (?, ?)",
 +                                 "SELECT * FROM %s WHERE a=0 AND (b, c, d) IN ((?, ?))", 0, 1);
 +            assertInvalidMessage("Expected 3 elements in value tuple, but got 5: (?, ?, ?, ?, ?)",
 +                                 "SELECT * FROM %s WHERE a=0 AND (b, c, d) IN ((?, ?, ?, ?, ?))", 0, 1, 2, 3, 4);
 +
 +            // Missing first clustering column
 +            assertInvalidMessage("PRIMARY KEY column \"c\" cannot be restricted (preceding column \"b\" is not restricted)",
 +                                 "SELECT * FROM %s WHERE a = 0 AND (c, d) = (?, ?)", 0, 0);
 +            assertInvalidMessage("PRIMARY KEY column \"c\" cannot be restricted (preceding column \"b\" is not restricted)",
 +                                 "SELECT * FROM %s WHERE a = 0 AND (c, d) > (?, ?)", 0, 0);
 +
 +            // Nulls
 +            assertInvalidMessage("Invalid null value in condition for column d",
 +                                 "SELECT * FROM %s WHERE a = 0 AND (b, c, d) IN ((?, ?, ?))", 1, 2, null);
 +
 +            // Wrong type for 'd'
 +            assertInvalidMessage("Expected 4 or 0 byte int (6)",
 +                                 "SELECT * FROM %s WHERE a = 0 AND (b, c, d) = (?, ?, ?)", 1, 2, "foobar");
 +
 +            assertInvalidMessage("Invalid tuple type literal for b of type int",
 +                                 "SELECT * FROM %s WHERE a = 0 AND b = (?, ?, ?)", 1, 2, 3);
 +
 +            // Mix single and tuple inequalities
 +            assertInvalidMessage("Column \"b\" cannot be restricted by both a tuple notation inequality and a single column inequality (b < ?)",
 +                                 "SELECT * FROM %s WHERE a = 0 AND (b, c, d) > (?, ?, ?) AND b < ?", 0, 1, 0, 1);
 +            assertInvalidMessage("Column \"c\" cannot be restricted by both a tuple notation inequality and a single column inequality (c < ?)",
 +                                 "SELECT * FROM %s WHERE a = 0 AND (b, c, d) > (?, ?, ?) AND c < ?", 0, 1, 0, 1);
 +            assertInvalidMessage("Column \"b\" cannot have both tuple-notation inequalities and single-column inequalities: (b, c, d) < (?, ?, ?)",
 +                                 "SELECT * FROM %s WHERE a = 0 AND b > ? AND (b, c, d) < (?, ?, ?)", 1, 1, 1, 0);
 +            assertInvalidMessage("Column \"c\" cannot have both tuple-notation inequalities and single-column inequalities: (b, c, d) < (?, ?, ?)",
 +                                 "SELECT * FROM %s WHERE a = 0 AND c > ? AND (b, c, d) < (?, ?, ?)", 1, 1, 1, 0);
 +
 +            assertInvalidMessage("Multi-column relations can only be applied to clustering columns: a",
 +                                 "SELECT * FROM %s WHERE (a, b, c, d) IN ((?, ?, ?, ?))", 0, 1, 2, 3);
 +            assertInvalidMessage("PRIMARY KEY column \"c\" cannot be restricted (preceding column \"b\" is not restricted)",
 +                                 "SELECT * FROM %s WHERE (c, d) IN ((?, ?))", 0, 1);
 +            assertInvalidMessage("PRIMARY KEY column \"c\" cannot be restricted (preceding column \"b\" is restricted by a non-EQ relation)",
 +                                 "SELECT * FROM %s WHERE a = ? AND b > ?  AND (c, d) IN ((?, ?))", 0, 0, 0, 0);
 +
 +            assertInvalidMessage("PRIMARY KEY column \"c\" cannot be restricted (preceding column \"b\" is restricted by a non-EQ relation)",
 +                                 "SELECT * FROM %s WHERE a = ? AND b > ?  AND (c, d) > (?, ?)", 0, 0, 0, 0);
 +            assertInvalidMessage("PRIMARY KEY column \"c\" cannot be restricted (preceding column \"b\" is restricted by a non-EQ relation)",
 +                                 "SELECT * FROM %s WHERE a = ? AND (c, d) > (?, ?) AND b > ?  ", 0, 0, 0, 0);
 +            assertInvalidMessage("Column \"c\" cannot be restricted by two tuple-notation inequalities not starting with the same column: (c) < (?)",
 +                                 "SELECT * FROM %s WHERE a = ? AND (b, c) > (?, ?) AND (b) < (?) AND (c) < (?)", 0, 0, 0, 0, 0);
 +            assertInvalidMessage("Column \"c\" cannot be restricted by two tuple-notation inequalities not starting with the same column: (b, c) > (?, ?)",
 +                                 "SELECT * FROM %s WHERE a = ? AND (c) < (?) AND (b, c) > (?, ?) AND (b) < (?)", 0, 0, 0, 0, 0);
 +            assertInvalidMessage("Column \"c\" cannot be restricted by two tuple-notation inequalities not starting with the same column: (b, c) > (?, ?)",
 +                                 "SELECT * FROM %s WHERE a = ? AND (b) < (?) AND (c) < (?) AND (b, c) > (?, ?)", 0, 0, 0, 0, 0);
 +
 +            assertInvalidMessage("Column \"c\" cannot be restricted by two tuple-notation inequalities not starting with the same column: (c) < (?)",
 +                                 "SELECT * FROM %s WHERE a = ? AND (b, c) > (?, ?) AND (c) < (?)", 0, 0, 0, 0);
 +
 +            assertInvalidMessage("PRIMARY KEY column \"d\" cannot be restricted (preceding column \"c\" is restricted by an IN tuple notation)",
 +                                 "SELECT * FROM %s WHERE a = ? AND (b, c) in ((?, ?), (?, ?)) AND d > ?", 0, 0, 0, 0, 0, 0);
 +        }
 +    }
 +
 +    @Test
 +    public void testMultiAndSingleColumnRelationMix() throws Throwable
 +    {
 +        for (String compactOption : new String[]{"", " WITH COMPACT STORAGE"})
 +        {
 +            createTable("CREATE TABLE %s (a int, b int, c int, d int, PRIMARY KEY (a, b, c, d))" + compactOption);
 +
 +            execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 0, 0);
 +            execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 1, 0);
 +            execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 1, 1);
 +
 +            execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 0, 0);
 +            execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 1, 0);
 +            execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 1, 1);
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? and b = ? and (c, d) = (?, ?)", 0, 1, 0, 0),
 +                       row(0, 1, 0, 0));
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? and b = ? and (c) IN ((?))", 0, 1, 0),
 +                       row(0, 1, 0, 0));
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? and b = ? and (c) IN ((?), (?))", 0, 1, 0, 1),
 +                       row(0, 1, 0, 0),
 +                       row(0, 1, 1, 0),
 +                       row(0, 1, 1, 1));
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? and b = ? and (c, d) IN ((?, ?))", 0, 1, 0, 0),
 +                       row(0, 1, 0, 0));
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? and b = ? and (c, d) IN ((?, ?), (?, ?))", 0, 1, 0, 0, 1, 1),
 +                       row(0, 1, 0, 0),
 +                       row(0, 1, 1, 1));
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? and b = ? and (c, d) > (?, ?)", 0, 1, 0, 0),
 +                       row(0, 1, 1, 0),
 +                       row(0, 1, 1, 1));
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? and b = ? and (c, d) > (?, ?) and (c) <= (?) ", 0, 1, 0, 0, 1),
 +                       row(0, 1, 1, 0),
 +                       row(0, 1, 1, 1));
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? and b = ? and (c, d) >= (?, ?) and (c, d) < (?, ?)", 0, 1, 0, 0, 1, 1),
 +                       row(0, 1, 0, 0),
 +                       row(0, 1, 1, 0));
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? and (b, c) = (?, ?) and d = ?", 0, 0, 1, 0),
 +                       row(0, 0, 1, 0));
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? and b = ? and (c) = (?) and d = ?", 0, 0, 1, 0),
 +                       row(0, 0, 1, 0));
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? and (b, c) = (?, ?) and d IN (?, ?)", 0, 0, 1, 0, 2),
 +                       row(0, 0, 1, 0));
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? and b = ? and (c) = (?) and d IN (?, ?)", 0, 0, 1, 0, 2),
 +                       row(0, 0, 1, 0));
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? and (b, c) = (?, ?) and d >= ?", 0, 0, 1, 0),
 +                       row(0, 0, 1, 0),
 +                       row(0, 0, 1, 1));
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? and d < 1 and (b, c) = (?, ?) and d >= ?", 0, 0, 1, 0),
 +                       row(0, 0, 1, 0));
 +        }
 +    }
 +
 +    @Test
 +    public void testMultipleMultiColumnRelation() throws Throwable
 +    {
 +        for (String compactOption : new String[]{"", " WITH COMPACT STORAGE"})
 +        {
 +            createTable("CREATE TABLE %s (a int, b int, c int, d int, PRIMARY KEY (a, b, c, d))" + compactOption);
 +
 +            execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 0, 0);
 +            execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 1, 0);
 +            execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 1, 1);
 +
 +            execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 0, 0);
 +            execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 1, 0);
 +            execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 1, 1);
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? and (b) = (?) and (c, d) = (?, ?)", 0, 1, 0, 0),
 +                       row(0, 1, 0, 0));
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? and (b) = (?) and (c) = (?) and (d) = (?)", 0, 1, 0, 0),
 +                       row(0, 1, 0, 0));
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? and (b) = (?) and (c) IN ((?))", 0, 1, 0),
 +                       row(0, 1, 0, 0));
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? and (b) = (?) and (c) IN ((?), (?))", 0, 1, 0, 1),
 +                       row(0, 1, 0, 0),
 +                       row(0, 1, 1, 0),
 +                       row(0, 1, 1, 1));
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? and (b) = (?) and (c, d) IN ((?, ?))", 0, 1, 0, 0),
 +                       row(0, 1, 0, 0));
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? and (b) = (?) and (c, d) IN ((?, ?), (?, ?))", 0, 1, 0, 0, 1, 1),
 +                       row(0, 1, 0, 0),
 +                       row(0, 1, 1, 1));
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? and (b) = (?) and (c, d) > (?, ?)", 0, 1, 0, 0),
 +                       row(0, 1, 1, 0),
 +                       row(0, 1, 1, 1));
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? and (b) = (?) and (c, d) > (?, ?) and (c) <= (?) ", 0, 1, 0, 0, 1),
 +                       row(0, 1, 1, 0),
 +                       row(0, 1, 1, 1));
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? and (b) = (?) and (c, d) >= (?, ?) and (c, d) < (?, ?)", 0, 1, 0, 0, 1, 1),
 +                       row(0, 1, 0, 0),
 +                       row(0, 1, 1, 0));
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? and (b, c) = (?, ?) and (d) = (?)", 0, 0, 1, 0),
 +                       row(0, 0, 1, 0));
 +        }
 +    }
 +
 +    @Test
 +    public void testSinglePartitionInvalidQueries() throws Throwable
 +    {
 +        for (String compactOption : new String[]{"", " WITH COMPACT STORAGE"})
 +        {
 +            createTable("CREATE TABLE %s (a int PRIMARY KEY, b int)" + compactOption);
 +
 +            assertInvalid("SELECT * FROM %s WHERE (a) > (?)", 0);
 +            assertInvalid("SELECT * FROM %s WHERE (a) = (?)", 0);
 +            assertInvalid("SELECT * FROM %s WHERE (b) = (?)", 0);
 +        }
 +    }
 +
 +    @Test
 +    public void testSingleClustering() throws Throwable
 +    {
 +        for (String compactOption : new String[]{"", " WITH COMPACT STORAGE"})
 +        {
 +            createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))" + compactOption);
 +
 +            execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 0, 0, 0);
 +            execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 0, 1, 0);
 +            execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 0, 2, 0);
 +
 +            // Equalities
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) = (?)", 0, 1),
 +                    row(0, 1, 0)
 +            );
 +
 +            // Same but check the whole tuple can be prepared
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) = ?", 0, tuple(1)),
 +                    row(0, 1, 0)
 +            );
 +
 +            assertEmpty(execute("SELECT * FROM %s WHERE a = ? AND (b) = (?)", 0, 3));
 +
 +            // Inequalities
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) > (?)", 0, 0),
 +                    row(0, 1, 0),
 +                    row(0, 2, 0)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) >= (?)", 0, 1),
 +                    row(0, 1, 0),
 +                    row(0, 2, 0)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) < (?)", 0, 2),
 +                    row(0, 0, 0),
 +                    row(0, 1, 0)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) <= (?)", 0, 1),
 +                    row(0, 0, 0),
 +                    row(0, 1, 0)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) > (?) AND (b) < (?)", 0, 0, 2),
 +                    row(0, 1, 0)
 +            );
 +        }
 +    }
 +
 +    @Test
 +    public void testNonEqualsRelation() throws Throwable
 +    {
 +        for (String compactOption : new String[]{"", " WITH COMPACT STORAGE"})
 +        {
 +            createTable("CREATE TABLE %s (a int PRIMARY KEY, b int)" + compactOption);
 +            assertInvalid("SELECT * FROM %s WHERE a = 0 AND (b) != (0)");
 +        }
 +    }
 +
 +    @Test
 +    public void testMultipleClustering() throws Throwable
 +    {
 +        for (String compactOption : new String[]{"", " WITH COMPACT STORAGE"})
 +        {
 +            createTable("CREATE TABLE %s (a int, b int, c int, d int, PRIMARY KEY (a, b, c, d))" + compactOption);
 +
 +            execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 0, 0);
 +            execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 1, 0);
 +            execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 1, 1);
 +
 +            execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 0, 0);
 +            execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 1, 0);
 +            execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 1, 1);
 +
 +            // Empty query
 +            assertEmpty(execute("SELECT * FROM %s WHERE a = 0 AND (b, c, d) IN ()"));
 +
 +            // Equalities
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) = (?)", 0, 1),
 +                    row(0, 1, 0, 0),
 +                    row(0, 1, 1, 0),
 +                    row(0, 1, 1, 1)
 +            );
 +
 +            // Same with whole tuple prepared
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) = ?", 0, tuple(1)),
 +                    row(0, 1, 0, 0),
 +                    row(0, 1, 1, 0),
 +                    row(0, 1, 1, 1)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c) = (?, ?)", 0, 1, 1),
 +                    row(0, 1, 1, 0),
 +                    row(0, 1, 1, 1)
 +            );
 +
 +            // Same with whole tuple prepared
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c) = ?", 0, tuple(1, 1)),
 +                    row(0, 1, 1, 0),
 +                    row(0, 1, 1, 1)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) = (?, ?, ?)", 0, 1, 1, 1),
 +                    row(0, 1, 1, 1)
 +            );
 +
 +            // Same with whole tuple prepared
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) = ?", 0, tuple(1, 1, 1)),
 +                    row(0, 1, 1, 1)
 +            );
 +
 +            // Inequalities
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) > (?)", 0, 0),
 +                    row(0, 1, 0, 0),
 +                    row(0, 1, 1, 0),
 +                    row(0, 1, 1, 1)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) >= (?)", 0, 0),
 +                    row(0, 0, 0, 0),
 +                    row(0, 0, 1, 0),
 +                    row(0, 0, 1, 1),
 +                    row(0, 1, 0, 0),
 +                    row(0, 1, 1, 0),
 +                    row(0, 1, 1, 1)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c) > (?, ?)", 0, 1, 0),
 +                    row(0, 1, 1, 0),
 +                    row(0, 1, 1, 1)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c) >= (?, ?)", 0, 1, 0),
 +                    row(0, 1, 0, 0),
 +                    row(0, 1, 1, 0),
 +                    row(0, 1, 1, 1)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) > (?, ?, ?)", 0, 1, 1, 0),
 +                    row(0, 1, 1, 1)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) >= (?, ?, ?)", 0, 1, 1, 0),
 +                    row(0, 1, 1, 0),
 +                    row(0, 1, 1, 1)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) < (?)", 0, 1),
 +                    row(0, 0, 0, 0),
 +                    row(0, 0, 1, 0),
 +                    row(0, 0, 1, 1)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) <= (?)", 0, 1),
 +                    row(0, 0, 0, 0),
 +                    row(0, 0, 1, 0),
 +                    row(0, 0, 1, 1),
 +                    row(0, 1, 0, 0),
 +                    row(0, 1, 1, 0),
 +                    row(0, 1, 1, 1)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c) < (?, ?)", 0, 0, 1),
 +                    row(0, 0, 0, 0)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c) <= (?, ?)", 0, 0, 1),
 +                    row(0, 0, 0, 0),
 +                    row(0, 0, 1, 0),
 +                    row(0, 0, 1, 1)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) < (?, ?, ?)", 0, 0, 1, 1),
 +                    row(0, 0, 0, 0),
 +                    row(0, 0, 1, 0)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) <= (?, ?, ?)", 0, 0, 1, 1),
 +                    row(0, 0, 0, 0),
 +                    row(0, 0, 1, 0),
 +                    row(0, 0, 1, 1)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) > (?, ?, ?) AND (b) < (?)", 0, 0, 1, 0, 1),
 +                    row(0, 0, 1, 1)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) > (?, ?, ?) AND (b, c) < (?, ?)", 0, 0, 1, 1, 1, 1),
 +                    row(0, 1, 0, 0)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) > (?, ?, ?) AND (b, c, d) < (?, ?, ?)", 0, 0, 1, 1, 1, 1, 0),
 +                    row(0, 1, 0, 0)
 +            );
 +
 +            // Same with whole tuple prepared
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) > ? AND (b, c, d) < ?", 0, tuple(0, 1, 1), tuple(1, 1, 0)),
 +                    row(0, 1, 0, 0)
 +            );
 +
 +            // reversed
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) > (?) ORDER BY b DESC, c DESC, d DESC", 0, 0),
 +                    row(0, 1, 1, 1),
 +                    row(0, 1, 1, 0),
 +                    row(0, 1, 0, 0)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) >= (?) ORDER BY b DESC, c DESC, d DESC", 0, 0),
 +                    row(0, 1, 1, 1),
 +                    row(0, 1, 1, 0),
 +                    row(0, 1, 0, 0),
 +                    row(0, 0, 1, 1),
 +                    row(0, 0, 1, 0),
 +                    row(0, 0, 0, 0)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c) > (?, ?) ORDER BY b DESC, c DESC, d DESC", 0, 1, 0),
 +                    row(0, 1, 1, 1),
 +                    row(0, 1, 1, 0)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c) >= (?, ?) ORDER BY b DESC, c DESC, d DESC", 0, 1, 0),
 +                    row(0, 1, 1, 1),
 +                    row(0, 1, 1, 0),
 +                    row(0, 1, 0, 0)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) > (?, ?, ?) ORDER BY b DESC, c DESC, d DESC", 0, 1, 1, 0),
 +                    row(0, 1, 1, 1)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) >= (?, ?, ?) ORDER BY b DESC, c DESC, d DESC", 0, 1, 1, 0),
 +                    row(0, 1, 1, 1),
 +                    row(0, 1, 1, 0)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) < (?) ORDER BY b DESC, c DESC, d DESC", 0, 1),
 +                    row(0, 0, 1, 1),
 +                    row(0, 0, 1, 0),
 +                    row(0, 0, 0, 0)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) <= (?) ORDER BY b DESC, c DESC, d DESC", 0, 1),
 +                    row(0, 1, 1, 1),
 +                    row(0, 1, 1, 0),
 +                    row(0, 1, 0, 0),
 +                    row(0, 0, 1, 1),
 +                    row(0, 0, 1, 0),
 +                    row(0, 0, 0, 0)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c) < (?, ?) ORDER BY b DESC, c DESC, d DESC", 0, 0, 1),
 +                    row(0, 0, 0, 0)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c) <= (?, ?) ORDER BY b DESC, c DESC, d DESC", 0, 0, 1),
 +                    row(0, 0, 1, 1),
 +                    row(0, 0, 1, 0),
 +                    row(0, 0, 0, 0)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) < (?, ?, ?) ORDER BY b DESC, c DESC, d DESC", 0, 0, 1, 1),
 +                    row(0, 0, 1, 0),
 +                    row(0, 0, 0, 0)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) <= (?, ?, ?) ORDER BY b DESC, c DESC, d DESC", 0, 0, 1, 1),
 +                    row(0, 0, 1, 1),
 +                    row(0, 0, 1, 0),
 +                    row(0, 0, 0, 0)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) > (?, ?, ?) AND (b) < (?) ORDER BY b DESC, c DESC, d DESC", 0, 0, 1, 0, 1),
 +                    row(0, 0, 1, 1)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) > (?, ?, ?) AND (b, c) < (?, ?) ORDER BY b DESC, c DESC, d DESC", 0, 0, 1, 1, 1, 1),
 +                    row(0, 1, 0, 0)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) > (?, ?, ?) AND (b, c, d) < (?, ?, ?) ORDER BY b DESC, c DESC, d DESC", 0, 0, 1, 1, 1, 1, 0),
 +                    row(0, 1, 0, 0)
 +            );
 +
 +            // IN
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) IN ((?, ?, ?), (?, ?, ?))", 0, 0, 1, 0, 0, 1, 1),
 +                    row(0, 0, 1, 0),
 +                    row(0, 0, 1, 1)
 +            );
 +
 +            // same query but with whole tuple prepared
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) IN (?, ?)", 0, tuple(0, 1, 0), tuple(0, 1, 1)),
 +                    row(0, 0, 1, 0),
 +                    row(0, 0, 1, 1)
 +            );
 +
 +            // same query but with whole IN list prepared
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) IN ?", 0, list(tuple(0, 1, 0), tuple(0, 1, 1))),
 +                    row(0, 0, 1, 0),
 +                    row(0, 0, 1, 1)
 +            );
 +
 +            // same query, but reversed order for the IN values
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) IN (?, ?)", 0, tuple(0, 1, 1), tuple(0, 1, 0)),
 +                    row(0, 0, 1, 0),
 +                    row(0, 0, 1, 1)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? and (b, c) IN ((?, ?))", 0, 0, 1),
 +                    row(0, 0, 1, 0),
 +                    row(0, 0, 1, 1)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? and (b) IN ((?))", 0, 0),
 +                    row(0, 0, 0, 0),
 +                    row(0, 0, 1, 0),
 +                    row(0, 0, 1, 1)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c) IN ((?, ?)) ORDER BY b DESC, c DESC, d DESC", 0, 0, 1),
 +                    row(0, 0, 1, 1),
 +                    row(0, 0, 1, 0)
 +            );
 +
 +            // IN on both partition key and clustering key
 +            execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 1, 0, 0, 0);
 +            execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 1, 0, 1, 0);
 +            execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 1, 0, 1, 1);
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a IN (?, ?) AND (b, c, d) IN (?, ?)", 0, 1, tuple(0, 1, 0), tuple(0, 1, 1)),
 +                    row(0, 0, 1, 0),
 +                    row(0, 0, 1, 1),
 +                    row(1, 0, 1, 0),
 +                    row(1, 0, 1, 1)
 +            );
 +
 +            // same but with whole IN lists prepared
 +            assertRows(execute("SELECT * FROM %s WHERE a IN ? AND (b, c, d) IN ?", list(0, 1), list(tuple(0, 1, 0), tuple(0, 1, 1))),
 +                    row(0, 0, 1, 0),
 +                    row(0, 0, 1, 1),
 +                    row(1, 0, 1, 0),
 +                    row(1, 0, 1, 1)
 +            );
 +
 +            // same query, but reversed order for the IN values
 +            assertRows(execute("SELECT * FROM %s WHERE a IN (?, ?) AND (b, c, d) IN (?, ?)", 1, 0, tuple(0, 1, 1), tuple(0, 1, 0)),
 +                    row(1, 0, 1, 0),
 +                    row(1, 0, 1, 1),
 +                    row(0, 0, 1, 0),
 +                    row(0, 0, 1, 1)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a IN (?, ?) and (b, c) IN ((?, ?))", 0, 1, 0, 1),
 +                    row(0, 0, 1, 0),
 +                    row(0, 0, 1, 1),
 +                    row(1, 0, 1, 0),
 +                    row(1, 0, 1, 1)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a IN (?, ?) and (b) IN ((?))", 0, 1, 0),
 +                    row(0, 0, 0, 0),
 +                    row(0, 0, 1, 0),
 +                    row(0, 0, 1, 1),
 +                    row(1, 0, 0, 0),
 +                    row(1, 0, 1, 0),
 +                    row(1, 0, 1, 1)
 +            );
 +        }
 +    }
 +
 +    @Test
 +    public void testMultipleClusteringReversedComponents() throws Throwable
 +    {
 +        for (String compactOption : new String[]{"", " COMPACT STORAGE AND"})
 +        {
 +            createTable("CREATE TABLE %s (a int, b int, c int, d int, PRIMARY KEY (a, b, c, d)) WITH" + compactOption + " CLUSTERING ORDER BY (b DESC, c ASC, d DESC)");
 +
 +            // b and d are reversed in the clustering order
 +            execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 0, 0);
 +            execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 1, 1);
 +            execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 1, 0);
 +
 +            execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 0, 0);
 +            execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 1, 1);
 +            execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 1, 0);
 +
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) > (?)", 0, 0),
 +                    row(0, 1, 0, 0),
 +                    row(0, 1, 1, 1),
 +                    row(0, 1, 1, 0)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) >= (?)", 0, 0),
 +                    row(0, 1, 0, 0),
 +                    row(0, 1, 1, 1),
 +                    row(0, 1, 1, 0),
 +                    row(0, 0, 0, 0),
 +                    row(0, 0, 1, 1),
 +                    row(0, 0, 1, 0)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) < (?)", 0, 1),
 +                    row(0, 0, 0, 0),
 +                    row(0, 0, 1, 1),
 +                    row(0, 0, 1, 0)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) <= (?)", 0, 1),
 +                    row(0, 1, 0, 0),
 +                    row(0, 1, 1, 1),
 +                    row(0, 1, 1, 0),
 +                    row(0, 0, 0, 0),
 +                    row(0, 0, 1, 1),
 +                    row(0, 0, 1, 0)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a=? AND (b, c, d) IN ((?, ?, ?), (?, ?, ?))", 0, 1, 1, 1, 0, 1, 1),
 +                    row(0, 1, 1, 1),
 +                    row(0, 0, 1, 1)
 +            );
 +
 +            // same query, but reversed order for the IN values
 +            assertRows(execute("SELECT * FROM %s WHERE a=? AND (b, c, d) IN ((?, ?, ?), (?, ?, ?))", 0, 0, 1, 1, 1, 1, 1),
 +                    row(0, 1, 1, 1),
 +                    row(0, 0, 1, 1)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c, d) IN (?, ?, ?, ?, ?, ?)",
 +                            0, tuple(1, 0, 0), tuple(1, 1, 1), tuple(1, 1, 0), tuple(0, 0, 0), tuple(0, 1, 1), tuple(0, 1, 0)),
 +                    row(0, 1, 0, 0),
 +                    row(0, 1, 1, 1),
 +                    row(0, 1, 1, 0),
 +                    row(0, 0, 0, 0),
 +                    row(0, 0, 1, 1),
 +                    row(0, 0, 1, 0)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c) IN (?)", 0, tuple(0, 1)),
 +                    row(0, 0, 1, 1),
 +                    row(0, 0, 1, 0)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c) IN (?)", 0, tuple(0, 0)),
 +                    row(0, 0, 0, 0)
 +            );
 +
 +            assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b) IN ((?))", 0, 0),
 +                    row(0, 0, 0, 0),
 +                    row(0, 0, 1, 1),
 +                    row(0, 0, 1, 0)
 +            );
 +
 +            // preserve pre-6875 behavior (even though the query result is technically incorrect)
 +            assertEmpty(execute("SELECT * FROM %s WHERE a = ? AND (b, c) > (?, ?)", 0, 1, 0));
 +        }
 +    }
 +
 +    @Test
 +    public void testMultipleClusteringWithIndex() throws Throwable
 +    {
 +        createTable("CREATE TABLE %s (a int, b int, c int, d int, e int, PRIMARY KEY (a, b, c, d))");
 +        createIndex("CREATE INDEX ON %s (b)");
 +        createIndex("CREATE INDEX ON %s (e)");
 +        execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 0, 0, 0, 0);
 +        execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 0, 1, 0, 1);
 +        execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 0, 1, 1, 2);
 +        execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 1, 0, 0, 0);
 +        execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 1, 1, 0, 1);
 +        execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 1, 1, 1, 2);
 +        execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 2, 0, 0, 0);
++        assertRows(execute("SELECT * FROM %s WHERE a= ? AND (b) = (?)", 0, 1),
++                   row(0, 1, 0, 0, 0),
++                   row(0, 1, 1, 0, 1),
++                   row(0, 1, 1, 1, 2));
 +        assertRows(execute("SELECT * FROM %s WHERE (b) = (?)", 1),
 +                   row(0, 1, 0, 0, 0),
 +                   row(0, 1, 1, 0, 1),
 +                   row(0, 1, 1, 1, 2));
++        assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c) = (?, ?)", 0, 1, 1),
++                   row(0, 1, 1, 0, 1),
++                   row(0, 1, 1, 1, 2));
 +        assertRows(execute("SELECT * FROM %s WHERE (b, c) = (?, ?) ALLOW FILTERING", 1, 1),
 +                   row(0, 1, 1, 0, 1),
 +                   row(0, 1, 1, 1, 2));
++        assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c) = (?, ?) AND e = ?", 0, 1, 1, 2),
++                   row(0, 1, 1, 1, 2));
 +        assertRows(execute("SELECT * FROM %s WHERE (b, c) = (?, ?) AND e = ? ALLOW FILTERING", 1, 1, 2),
 +                   row(0, 1, 1, 1, 2));
-         assertRows(execute("SELECT * FROM %s WHERE (b) IN ((?)) AND e = ?", 1, 2),
++        assertRows(execute("SELECT * FROM %s WHERE (b) IN ((?)) AND e = ? ", 1, 2),
 +                   row(0, 1, 1, 1, 2));
 +
 +        assertRows(execute("SELECT * FROM %s WHERE (b) IN ((?), (?)) AND e = ?", 0, 1, 2),
 +                   row(0, 0, 1, 1, 2),
 +                   row(0, 1, 1, 1, 2));
 +
 +        assertRows(execute("SELECT * FROM %s WHERE (b, c) IN ((?, ?)) AND e = ?", 0, 1, 2),
 +                   row(0, 0, 1, 1, 2));
 +
 +        assertRows(execute("SELECT * FROM %s WHERE (b, c) IN ((?, ?), (?, ?)) AND e = ?", 0, 1, 1, 1, 2),
 +                   row(0, 0, 1, 1, 2),
 +                   row(0, 1, 1, 1, 2));
 +
 +        assertRows(execute("SELECT * FROM %s WHERE (b) >= (?) AND e = ?", 1, 2),
 +                   row(0, 1, 1, 1, 2));
 +
 +        assertRows(execute("SELECT * FROM %s WHERE (b, c) >= (?, ?) AND e = ?", 1, 1, 2),
 +                   row(0, 1, 1, 1, 2));
++
 +    }
 +
 +    @Test
 +    public void testMultiplePartitionKeyAndMultiClusteringWithIndex() throws Throwable
 +    {
 +        createTable("CREATE TABLE %s (a int, b int, c int, d int, e int, f int, PRIMARY KEY ((a, b), c, d, e))");
 +        createIndex("CREATE INDEX ON %s (c)");
 +        createIndex("CREATE INDEX ON %s (f)");
 +
 +        execute("INSERT INTO %s (a, b, c, d, e, f) VALUES (?, ?, ?, ?, ?, ?)", 0, 0, 0, 0, 0, 0);
 +        execute("INSERT INTO %s (a, b, c, d, e, f) VALUES (?, ?, ?, ?, ?, ?)", 0, 0, 0, 1, 0, 1);
 +        execute("INSERT INTO %s (a, b, c, d, e, f) VALUES (?, ?, ?, ?, ?, ?)", 0, 0, 0, 1, 1, 2);
 +
 +        execute("INSERT INTO %s (a, b, c, d, e, f) VALUES (?, ?, ?, ?, ?, ?)", 0, 0, 1, 0, 0, 3);
 +        execute("INSERT INTO %s (a, b, c, d, e, f) VALUES (?, ?, ?, ?, ?, ?)", 0, 0, 1, 1, 0, 4);
 +        execute("INSERT INTO %s (a, b, c, d, e, f) VALUES (?, ?, ?, ?, ?, ?)", 0, 0, 1, 1, 1, 5);
 +
 +        execute("INSERT INTO %s (a, b, c, d, e, f) VALUES (?, ?, ?, ?, ?, ?)", 0, 0, 2, 0, 0, 5);
 +
 +        assertRows(execute("SELECT * FROM %s WHERE a = ? AND (c) = (?) ALLOW FILTERING", 0, 1),
 +                   row(0, 0, 1, 0, 0, 3),
 +                   row(0, 0, 1, 1, 0, 4),
 +                   row(0, 0, 1, 1, 1, 5));
 +
 +        assertRows(execute("SELECT * FROM %s WHERE a = ? AND (c, d) = (?, ?) ALLOW FILTERING", 0, 1, 1),
 +                   row(0, 0, 1, 1, 0, 4),
 +                   row(0, 0, 1, 1, 1, 5));
 +
 +        assertInvalidMessage("Partition key part b must be restricted since preceding part is",
 +                             "SELECT * FROM %s WHERE a = ? AND (c, d) IN ((?, ?)) ALLOW FILTERING", 0, 1, 1);
 +
 +        assertInvalidMessage("Partition key part b must be restricted since preceding part is",
 +                             "SELECT * FROM %s WHERE a = ? AND (c, d) >= (?, ?) ALLOW FILTERING", 0, 1, 1);
 +
++        assertRows(execute("SELECT * FROM %s WHERE a = ? AND b = ? AND (c) IN ((?)) AND f = ?", 0, 0, 1, 5),
++                   row(0, 0, 1, 1, 1, 5));
++
 +        assertRows(execute("SELECT * FROM %s WHERE a = ? AND (c) IN ((?)) AND f = ? ALLOW FILTERING", 0, 1, 5),
 +                   row(0, 0, 1, 1, 1, 5));
 +
++        assertRows(execute("SELECT * FROM %s WHERE a = ? AND b = ? AND (c) IN ((?), (?)) AND f = ?", 0, 0, 1, 2, 5),
++                   row(0, 0, 1, 1, 1, 5),
++                   row(0, 0, 2, 0, 0, 5));
++
 +        assertRows(execute("SELECT * FROM %s WHERE a = ? AND (c) IN ((?), (?)) AND f = ? ALLOW FILTERING", 0, 1, 2, 5),
 +                   row(0, 0, 1, 1, 1, 5),
 +                   row(0, 0, 2, 0, 0, 5));
 +
++        assertRows(execute("SELECT * FROM %s WHERE a = ? AND b = ? AND (c, d) IN ((?, ?)) AND f = ?", 0, 0, 1, 0, 3),
++                   row(0, 0, 1, 0, 0, 3));
++
 +        assertRows(execute("SELECT * FROM %s WHERE a = ? AND (c, d) IN ((?, ?)) AND f = ? ALLOW FILTERING", 0, 1, 0, 3),
 +                   row(0, 0, 1, 0, 0, 3));
 +
++        assertRows(execute("SELECT * FROM %s WHERE a = ? AND b = ? AND (c) >= (?) AND f = ?", 0, 0, 1, 5),
++                   row(0, 0, 1, 1, 1, 5),
++                   row(0, 0, 2, 0, 0, 5));
++
 +        assertRows(execute("SELECT * FROM %s WHERE a = ? AND (c) >= (?) AND f = ? ALLOW FILTERING", 0, 1, 5),
 +                   row(0, 0, 1, 1, 1, 5),
 +                   row(0, 0, 2, 0, 0, 5));
 +
++        assertRows(execute("SELECT * FROM %s WHERE a = ? AND b = ? AND (c, d) >= (?, ?) AND f = ?", 0, 0, 1, 1, 5),
++                   row(0, 0, 1, 1, 1, 5),
++                   row(0, 0, 2, 0, 0, 5));
++
 +        assertRows(execute("SELECT * FROM %s WHERE a = ? AND (c, d) >= (?, ?) AND f = ? ALLOW FILTERING", 0, 1, 1, 5),
 +                   row(0, 0, 1, 1, 1, 5),
 +                   row(0, 0, 2, 0, 0, 5));
 +    }
 +
 +    /**
 +     * Check select on tuple relations with mixed ASC | DESC clustering, see CASSANDRA-7281
 +     * migrated from cql_tests.py:TestCQL.tuple_query_mixed_order_columns_test to tuple_query_mixed_order_columns_test9
 +     */
 +    @Ignore // CASSANDRA-7281 not yet delivered
 +    public void testMixedOrderClustering1() throws Throwable
 +    {
 +        createTableForMixedOrderClusteringTest("DESC", "ASC", "DESC", "ASC");
 +
 +        assertRows(execute("SELECT * FROM %s WHERE a=0 AND (b, c, d, e) > (0, 1, 1, 0)"),
 +                   row(0, 2, 0, 0, 0),
 +                   row(0, 1, 0, 0, 0),
 +                   row(0, 0, 1, 2, -1),
 +                   row(0, 0, 1, 1, 1),
 +                   row(0, 0, 2, 1, -3),
 +                   row(0, 0, 2, 0, 3));
 +    }
 +
 +    @Ignore // CASSANDRA-7281 not yet delivered
 +    public void testMixedOrderClustering2() throws Throwable
 +    {
 +        createTableForMixedOrderClusteringTest("DESC", "DESC", "DESC", "ASC");
 +
 +        assertRows(execute("SELECT * FROM %s WHERE a=0 AND (b, c, d, e) > (0, 1, 1, 0)"),
 +                   row(0, 2, 0, 0, 0),
 +                   row(0, 1, 0, 0, 0),
 +                   row(0, 0, 2, 1, -3),
 +                   row(0, 0, 2, 0, 3),
 +                   row(0, 0, 1, 2, -1),
 +                   row(0, 0, 1, 1, 1));
 +    }
 +
 +    @Ignore // CASSANDRA-7281 not yet delivered
 +    public void testMixedOrderClustering3() throws Throwable
 +    {
 +        createTableForMixedOrderClusteringTest("ASC", "DESC", "DESC", "ASC");
 +
 +        assertRows(execute("SELECT * FROM %s WHERE a=0 AND (b, c, d, e) > (0, 1, 1, 0)"),
 +                   row(0, 0, 2, 1, -3),
 +                   row(0, 0, 2, 0, 3),
 +                   row(0, 0, 1, 2, -1),
 +                   row(0, 0, 1, 1, 1),
 +                   row(0, 1, 0, 0, 0),
 +                   row(0, 2, 0, 0, 0));
 +    }
 +
 +    @Ignore // CASSANDRA-7281 not yet delivered
 +    public void testMixedOrderClustering4() throws Throwable
 +    {
 +        createTableForMixedOrderClusteringTest("DESC", "ASC", "ASC", "DESC");
 +
 +        assertRows(execute("SELECT * FROM %s WHERE a=0 AND (b, c, d, e) > (0, 1, 1, 0)"),
 +                   row(0, 2, 0, 0, 0),
 +                   row(0, 1, 0, 0, 0),
 +                   row(0, 0, 1, 1, 1),
 +                   row(0, 0, 1, 2, -1),
 +                   row(0, 0, 2, 0, 3),
 +                   row(0, 0, 2, 1, -3));
 +    }
 +
 +    @Ignore // CASSANDRA-7281 not yet delivered
 +    public void testMixedOrderClustering5() throws Throwable
 +    {
 +        createTableForMixedOrderClusteringTest("DESC", "DESC", "DESC", "DESC");
 +
 +        assertRows(execute("SELECT * FROM %s WHERE a=0 AND (b, c, d, e) > (0, 1, 1, 0)"),
 +                   row(0, 2, 0, 0, 0),
 +                   row(0, 1, 0, 0, 0),
 +                   row(0, 0, 2, 1, -3),
 +                   row(0, 0, 2, 0, 3),
 +                   row(0, 0, 1, 2, -1),
 +                   row(0, 0, 1, 1, 1));
 +    }
 +
 +    @Ignore // CASSANDRA-7281 not yet delivered
 +    public void testMixedOrderClustering6() throws Throwable
 +    {
 +        createTableForMixedOrderClusteringTest("ASC", "ASC", "ASC", "ASC");
 +
 +        assertRows(execute("SELECT * FROM %s WHERE a=0 AND (b, c, d, e) > (0, 1, 1, 0)"),
 +                   row(0, 0, 1, 1, 1),
 +                   row(0, 0, 1, 2, -1),
 +                   row(0, 0, 2, 0, 3),
 +                   row(0, 0, 2, 1, -3),
 +                   row(0, 1, 0, 0, 0),
 +                   row(0, 2, 0, 0, 0));
 +    }
 +
 +    @Ignore // CASSANDRA-7281 not yet delivered
 +    public void testMixedOrderClustering7() throws Throwable
 +    {
 +        createTableForMixedOrderClusteringTest("DESC", "ASC", "DESC", "ASC");
 +
 +        assertRows(execute("SELECT * FROM %s WHERE a=0 AND (b, c, d, e) <= (0, 1, 1, 0)"),
 +                   row(0, 0, 0, 0, 0),
 +                   row(0, 0, 1, 1, -1),
 +                   row(0, 0, 1, 1, 0),
 +                   row(0, 0, 1, 0, 2),
 +                   row(0, -1, 2, 2, 2));
 +    }
 +
 +    @Ignore // CASSANDRA-7281 not yet delivered
 +    public void testMixedOrderClustering8() throws Throwable
 +    {
 +        createTableForMixedOrderClusteringTest("ASC", "DESC", "DESC", "ASC");
 +
 +        assertRows(execute("SELECT * FROM %s WHERE a=0 AND (b, c, d, e) <= (0, 1, 1, 0)"),
 +                   row(0, -1, 2, 2, 2),
 +                   row(0, 0, 1, 1, -1),
 +                   row(0, 0, 1, 1, 0),
 +                   row(0, 0, 1, 0, 2),
 +                   row(0, 0, 0, 0, 0));
 +    }
 +
 +    @Ignore // CASSANDRA-7281 not yet delivered
 +    public void testMixedOrderClustering9() throws Throwable
 +    {
 +        createTableForMixedOrderClusteringTest("DESC", "ASC", "DESC", "DESC");
 +
 +        assertRows(execute("SELECT * FROM %s WHERE a=0 AND (b, c, d, e) <= (0, 1, 1, 0)"),
 +                   row(0, 0, 0, 0, 0),
 +                   row(0, 0, 1, 1, 0),
 +                   row(0, 0, 1, 1, -1),
 +                   row(0, 0, 1, 0, 2),
 +                   row(0, -1, 2, 2, 2));
 +    }
 +
 +    private void createTableForMixedOrderClusteringTest(String ... formats) throws Throwable
 +    {
 +        assertEquals(4, formats.length);
 +
 +        String clustering = String.format("WITH CLUSTERING ORDER BY (b %s, c %s, d %s, e %s)", (Object[])formats);
 +        createTable("CREATE TABLE %s (a int, b int, c int, d int , e int, PRIMARY KEY (a, b, c, d, e) ) " + clustering);
 +
 +        execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, 2, 0, 0, 0)");
 +        execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, 1, 0, 0, 0)");
 +        execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, 0, 0, 0, 0)");
 +        execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, 0, 1, 2, -1)");
 +        execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, 0, 1, 1, -1)");
 +        execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, 0, 1, 1, 0)");
 +        execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, 0, 1, 1, 1)");
 +        execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, 0, 1, 0, 2)");
 +        execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, 0, 2, 1, -3)");
 +        execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, 0, 2, 0, 3)");
 +        execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, -1, 2, 2, 2)");
 +    }
 +
 +    /**
 +     * Check select on tuple relations, see CASSANDRA-8613
 +     * migrated from cql_tests.py:TestCQL.simple_tuple_query_test()
 +     */
 +    @Test
 +    public void testSimpleTupleQuery() throws Throwable
 +    {
 +        createTable("create table %s (a int, b int, c int, d int , e int, PRIMARY KEY (a, b, c, d, e))");
 +
 +        execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, 2, 0, 0, 0)");
 +        execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, 1, 0, 0, 0)");
 +        execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, 0, 0, 0, 0)");
 +        execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, 0, 1, 1, 1)");
 +        execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, 0, 2, 2, 2)");
 +        execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, 0, 3, 3, 3)");
 +        execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, 0, 1, 1, 1)");
 +
 +        assertRows(execute("SELECT * FROM %s WHERE b=0 AND (c, d, e) > (1, 1, 1) ALLOW FILTERING"),
 +                   row(0, 0, 2, 2, 2),
 +                   row(0, 0, 3, 3, 3));
 +    }
 + }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/2c585813/test/unit/org/apache/cassandra/cql3/validation/operations/SelectSingleColumnRelationTest.java
----------------------------------------------------------------------
diff --cc test/unit/org/apache/cassandra/cql3/validation/operations/SelectSingleColumnRelationTest.java
index e950e7a,0000000..05bb88b
mode 100644,000000..100644
--- a/test/unit/org/apache/cassandra/cql3/validation/operations/SelectSingleColumnRelationTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/operations/SelectSingleColumnRelationTest.java
@@@ -1,109 -1,0 +1,116 @@@
 +/*
 + * Licensed to the Apache Software Foundation (ASF) under one
 + * or more contributor license agreements.  See the NOTICE file
 + * distributed with this work for additional information
 + * regarding copyright ownership.  The ASF licenses this file
 + * to you under the Apache License, Version 2.0 (the
 + * "License"); you may not use this file except in compliance
 + * with the License.  You may obtain a copy of the License at
 + *
 + *     http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +package org.apache.cassandra.cql3.validation.operations;
 +
 +import org.junit.Test;
 +
 +import java.util.ArrayList;
 +import java.util.List;
 +
 +import org.apache.cassandra.cql3.CQLTester;
 +
 +public class SelectSingleColumnRelationTest extends CQLTester
 +{
 +    @Test
 +    public void testInvalidCollectionEqualityRelation() throws Throwable
 +    {
 +        createTable("CREATE TABLE %s (a int PRIMARY KEY, b set<int>, c list<int>, d map<int, int>)");
 +        createIndex("CREATE INDEX ON %s (b)");
 +        createIndex("CREATE INDEX ON %s (c)");
 +        createIndex("CREATE INDEX ON %s (d)");
 +
 +        assertInvalid("SELECT * FROM %s WHERE a = 0 AND b=?", set(0));
 +        assertInvalid("SELECT * FROM %s WHERE a = 0 AND c=?", list(0));
 +        assertInvalid("SELECT * FROM %s WHERE a = 0 AND d=?", map(0, 0));
 +    }
 +
 +    @Test
 +    public void testInvalidCollectionNonEQRelation() throws Throwable
 +    {
 +        createTable("CREATE TABLE %s (a int PRIMARY KEY, b set<int>, c int)");
 +        createIndex("CREATE INDEX ON %s (c)");
 +        execute("INSERT INTO %s (a, b, c) VALUES (0, {0}, 0)");
 +
 +        // non-EQ operators
 +        assertInvalid("SELECT * FROM %s WHERE c = 0 AND b > ?", set(0));
 +        assertInvalid("SELECT * FROM %s WHERE c = 0 AND b >= ?", set(0));
 +        assertInvalid("SELECT * FROM %s WHERE c = 0 AND b < ?", set(0));
 +        assertInvalid("SELECT * FROM %s WHERE c = 0 AND b <= ?", set(0));
 +        assertInvalid("SELECT * FROM %s WHERE c = 0 AND b IN (?)", set(0));
 +    }
 +
 +    @Test
 +    public void testLargeClusteringINValues() throws Throwable
 +    {
 +        createTable("CREATE TABLE %s (k int, c int, v int, PRIMARY KEY (k, c))");
 +        execute("INSERT INTO %s (k, c, v) VALUES (0, 0, 0)");
 +        List<Integer> inValues = new ArrayList<>(10000);
 +        for (int i = 0; i < 10000; i++)
 +            inValues.add(i);
 +        assertRows(execute("SELECT * FROM %s WHERE k=? AND c IN ?", 0, inValues),
 +                row(0, 0, 0)
 +        );
 +    }
 +
 +    @Test
 +    public void testMultiplePartitionKeyWithIndex() throws Throwable
 +    {
 +        createTable("CREATE TABLE %s (a int, b int, c int, d int, e int, f int, PRIMARY KEY ((a, b), c, d, e))");
 +        createIndex("CREATE INDEX ON %s (c)");
 +        createIndex("CREATE INDEX ON %s (f)");
 +
 +        execute("INSERT INTO %s (a, b, c, d, e, f) VALUES (?, ?, ?, ?, ?, ?)", 0, 0, 0, 0, 0, 0);
 +        execute("INSERT INTO %s (a, b, c, d, e, f) VALUES (?, ?, ?, ?, ?, ?)", 0, 0, 0, 1, 0, 1);
 +        execute("INSERT INTO %s (a, b, c, d, e, f) VALUES (?, ?, ?, ?, ?, ?)", 0, 0, 0, 1, 1, 2);
 +
 +        execute("INSERT INTO %s (a, b, c, d, e, f) VALUES (?, ?, ?, ?, ?, ?)", 0, 0, 1, 0, 0, 3);
 +        execute("INSERT INTO %s (a, b, c, d, e, f) VALUES (?, ?, ?, ?, ?, ?)", 0, 0, 1, 1, 0, 4);
 +        execute("INSERT INTO %s (a, b, c, d, e, f) VALUES (?, ?, ?, ?, ?, ?)", 0, 0, 1, 1, 1, 5);
 +
 +        execute("INSERT INTO %s (a, b, c, d, e, f) VALUES (?, ?, ?, ?, ?, ?)", 0, 0, 2, 0, 0, 5);
 +
 +        assertRows(execute("SELECT * FROM %s WHERE a = ? AND c = ? ALLOW FILTERING", 0, 1),
 +                   row(0, 0, 1, 0, 0, 3),
 +                   row(0, 0, 1, 1, 0, 4),
 +                   row(0, 0, 1, 1, 1, 5));
 +
 +        assertRows(execute("SELECT * FROM %s WHERE a = ? AND c = ? AND d = ? ALLOW FILTERING", 0, 1, 1),
 +                   row(0, 0, 1, 1, 0, 4),
 +                   row(0, 0, 1, 1, 1, 5));
 +
 +        assertInvalidMessage("Partition key part b must be restricted since preceding part is",
 +                             "SELECT * FROM %s WHERE a = ? AND c >= ? ALLOW FILTERING", 0, 1);
 +
++        assertRows(execute("SELECT * FROM %s WHERE a = ? AND b = ? AND c >= ? AND f = ?", 0, 0, 1, 5),
++                   row(0, 0, 1, 1, 1, 5),
++                   row(0, 0, 2, 0, 0, 5));
++
 +        assertRows(execute("SELECT * FROM %s WHERE a = ? AND c >= ? AND f = ? ALLOW FILTERING", 0, 1, 5),
 +                   row(0, 0, 1, 1, 1, 5),
 +                   row(0, 0, 2, 0, 0, 5));
 +
++        assertRows(execute("SELECT * FROM %s WHERE a = ? AND b = ? AND c = ? AND d >= ? AND f = ?", 0, 0, 1, 1, 5),
++                   row(0, 0, 1, 1, 1, 5));
++
 +        assertRows(execute("SELECT * FROM %s WHERE a = ? AND c = ? AND d >= ? AND f = ? ALLOW FILTERING", 0, 1, 1, 5),
 +                   row(0, 0, 1, 1, 1, 5));
 +
 +        assertInvalidMessage("Cannot execute this query as it might involve data filtering and thus may have unpredictable performance. If you want to execute this query despite the performance unpredictability, use ALLOW FILTERING",
 +                             "SELECT * FROM %s WHERE a = ? AND d >= ? AND f = ?", 0, 1, 5);
 +    }
 +}