You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by bl...@apache.org on 2016/02/11 10:49:52 UTC
[1/6] cassandra git commit: Fix SELECT on tuple relations for mixed
ASC/DESC clustering order
Repository: cassandra
Updated Branches:
refs/heads/trunk ebd6c23df -> b0448e66b
http://git-wip-us.apache.org/repos/asf/cassandra/blob/90fc8969/test/unit/org/apache/cassandra/cql3/validation/operations/SelectMultiColumnRelationTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/operations/SelectMultiColumnRelationTest.java b/test/unit/org/apache/cassandra/cql3/validation/operations/SelectMultiColumnRelationTest.java
index b3232d5..b8a1d50 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/operations/SelectMultiColumnRelationTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/operations/SelectMultiColumnRelationTest.java
@@ -792,8 +792,10 @@ public class SelectMultiColumnRelationTest extends CQLTester
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));
+ assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b, c) > (?, ?)", 0, 1, 0),
+ row(0,1, 1, 1),
+ row(0, 1, 1, 0)
+ );
}
}
@@ -990,6 +992,859 @@ public class SelectMultiColumnRelationTest extends CQLTester
"SELECT * from %s WHERE (i, j) IN ? ALLOW FILTERING", unset());
}
+ @Test
+ public void testMixedOrderColumns1() throws Throwable
+ {
+ createTable("CREATE TABLE %s (a int, b int, c int, d int, e int, PRIMARY KEY (a, b, c, d, e)) " +
+ "WITH CLUSTERING ORDER BY (b DESC, c ASC, d DESC, e ASC)");
+
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 2, 0, -1, 0);
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 2, 0, -1, 1);
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 2, 0, 1, 1);
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 1, -1, 0, 0);
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 1, -1, 1, 1);
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 1, -1, 1, 0);
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 1, 0, 1, -1);
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 1, 0, 1, 1);
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 1, 0, 0, -1);
+ 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, 0, 0, 1);
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 1, 0, -1, -1);
+ 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, 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, 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, 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, -1, 0, -1, 0);
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, -1, 0, 0, 0);
+ assertRows(execute(
+ "SELECT * FROM %s" +
+ " WHERE a = ? " +
+ "AND (b,c,d,e)<=(?,?,?,?) " +
+ "AND (b)>(?)", 0, 2, 0, 1, 1, -1),
+
+ row( 0, 2, 0, 1, 1),
+ row( 0, 2, 0, -1, 0),
+ row( 0, 2, 0, -1, 1),
+ row( 0, 1, -1, 1, 0),
+ row( 0, 1, -1, 1, 1),
+ row( 0, 1, -1, 0, 0),
+ row( 0, 1, 0, 1, -1),
+ row( 0, 1, 0, 1, 1),
+ row( 0, 1, 0, 0, -1),
+ row( 0, 1, 0, 0, 0),
+ row( 0, 1, 0, 0, 1),
+ row( 0, 1, 0, -1, -1),
+ row( 0, 1, 1, 0, -1),
+ row( 0, 1, 1, 0, 0),
+ row( 0, 1, 1, 0, 1),
+ row( 0, 1, 1, -1, 0),
+ row( 0, 0, 0, 0, 0)
+ );
+
+
+
+ assertRows(execute(
+ "SELECT * FROM %s" +
+ " WHERE a = ? " +
+ "AND (b,c,d,e)<=(?,?,?,?) " +
+ "AND (b)>=(?)", 0, 2, 0, 1, 1, -1),
+
+ row( 0, 2, 0, 1, 1),
+ row( 0, 2, 0, -1, 0),
+ row( 0, 2, 0, -1, 1),
+ row( 0, 1, -1, 1, 0),
+ row( 0, 1, -1, 1, 1),
+ row( 0, 1, -1, 0, 0),
+ row( 0, 1, 0, 1, -1),
+ row( 0, 1, 0, 1, 1),
+ row( 0, 1, 0, 0, -1),
+ row( 0, 1, 0, 0, 0),
+ row( 0, 1, 0, 0, 1),
+ row( 0, 1, 0, -1, -1),
+ row( 0, 1, 1, 0, -1),
+ row( 0, 1, 1, 0, 0),
+ row( 0, 1, 1, 0, 1),
+ row( 0, 1, 1, -1, 0),
+ row( 0, 0, 0, 0, 0),
+ row( 0, -1, 0, 0, 0),
+ row( 0, -1, 0, -1, 0)
+ );
+
+ assertRows(execute(
+ "SELECT * FROM %s" +
+ " WHERE a = ? " +
+ "AND (b,c,d)>=(?,?,?)"+
+ "AND (b,c,d,e)<(?,?,?,?) ", 0, 1, 1,0,1, 1, 0,1),
+ row( 0, 1, 1, 0, -1),
+ row( 0, 1, 1, 0, 0)
+
+ );
+
+ assertRows(execute(
+ "SELECT * FROM %s" +
+ " WHERE a = ? " +
+ "AND (b,c,d,e)>(?,?,?,?)"+
+ "AND (b,c,d)<=(?,?,?) ", 0, -1, 0,-1,-1, 2, 0,-1),
+
+ row( 0, 2, 0, -1, 0),
+ row( 0, 2, 0, -1, 1),
+ row( 0, 1, -1, 1, 0),
+ row( 0, 1, -1, 1, 1),
+ row( 0, 1, -1, 0, 0),
+ row( 0, 1, 0, 1, -1),
+ row( 0, 1, 0, 1, 1),
+ row( 0, 1, 0, 0, -1),
+ row( 0, 1, 0, 0, 0),
+ row( 0, 1, 0, 0, 1),
+ row( 0, 1, 0, -1, -1),
+ row( 0, 1, 1, 0, -1),
+ row( 0, 1, 1, 0, 0),
+ row( 0, 1, 1, 0, 1),
+ row( 0, 1, 1, -1, 0),
+ row( 0, 0, 0, 0, 0),
+ row( 0, -1, 0, 0, 0),
+ row( 0, -1, 0, -1, 0)
+ );
+
+ assertRows(execute(
+ "SELECT * FROM %s" +
+ " WHERE a = ? " +
+ "AND (b,c,d,e) < (?,?,?,?) " +
+ "AND (b,c,d,e)>(?,?,?,?)", 0, 1, 0, 0, 0, 1, 0,-1,-1),
+ row(0, 1, 0, 0, -1)
+ );
+
+ assertRows(execute(
+ "SELECT * FROM %s" +
+ " WHERE a = ? " +
+ "AND (b,c,d,e) <= (?,?,?,?) " +
+ "AND (b,c,d,e)>(?,?,?,?)", 0, 1, 0, 0, 0, 1, 0,-1,-1),
+ row(0, 1, 0, 0, -1),
+ row(0, 1, 0, 0, 0)
+ );
+
+ assertRows(execute(
+ "SELECT * FROM %s" +
+ " WHERE a = ? " +
+ "AND (b)<(?) " +
+ "AND (b,c,d,e)>(?,?,?,?)", 0, 2, -1, 0,-1,-1),
+
+ row( 0, 1, -1, 1, 0),
+ row( 0, 1, -1, 1, 1),
+ row( 0, 1, -1, 0, 0),
+ row( 0, 1, 0, 1, -1),
+ row( 0, 1, 0, 1, 1),
+ row( 0, 1, 0, 0, -1),
+ row( 0, 1, 0, 0, 0),
+ row( 0, 1, 0, 0, 1),
+ row( 0, 1, 0, -1, -1),
+ row( 0, 1, 1, 0, -1),
+ row( 0, 1, 1, 0, 0),
+ row( 0, 1, 1, 0, 1),
+ row( 0, 1, 1, -1, 0),
+ row( 0, 0, 0, 0, 0),
+ row( 0, -1, 0, 0, 0),
+ row( 0, -1, 0, -1, 0)
+
+ );
+
+
+
+ assertRows(execute(
+ "SELECT * FROM %s" +
+ " WHERE a = ? " +
+ "AND (b)<(?) " +
+ "AND (b)>(?)", 0, 2, -1),
+
+ row( 0, 1, -1, 1, 0),
+ row( 0, 1, -1, 1, 1),
+ row( 0, 1, -1, 0, 0),
+ row( 0, 1, 0, 1, -1),
+ row( 0, 1, 0, 1, 1),
+ row( 0, 1, 0, 0, -1),
+ row( 0, 1, 0, 0, 0),
+ row( 0, 1, 0, 0, 1),
+ row( 0, 1, 0, -1, -1),
+ row( 0, 1, 1, 0, -1),
+ row( 0, 1, 1, 0, 0),
+ row( 0, 1, 1, 0, 1),
+ row( 0, 1, 1, -1, 0),
+ row( 0, 0, 0, 0, 0)
+
+ );
+
+ assertRows(execute(
+ "SELECT * FROM %s" +
+ " WHERE a = ? " +
+ "AND (b)<(?) " +
+ "AND (b)>=(?)", 0, 2, -1),
+
+ row( 0, 1, -1, 1, 0),
+ row( 0, 1, -1, 1, 1),
+ row( 0, 1, -1, 0, 0),
+ row( 0, 1, 0, 1, -1),
+ row( 0, 1, 0, 1, 1),
+ row( 0, 1, 0, 0, -1),
+ row( 0, 1, 0, 0, 0),
+ row( 0, 1, 0, 0, 1),
+ row( 0, 1, 0, -1, -1),
+ row( 0, 1, 1, 0, -1),
+ row( 0, 1, 1, 0, 0),
+ row( 0, 1, 1, 0, 1),
+ row( 0, 1, 1, -1, 0),
+ row( 0, 0, 0, 0, 0),
+ row( 0, -1, 0, 0, 0),
+ row( 0, -1, 0, -1, 0)
+ );
+
+ assertRows(execute(
+ "SELECT * FROM %s" +
+ " WHERE a = ? " +
+ "AND (b,c,d,e)<=(?,?,?,?) " +
+ "AND (b,c,d,e)>(?,?,?,?)", 0, 2, 0, 1, 1, -1, 0,-1,-1),
+
+ row( 0, 2, 0, 1, 1),
+ row( 0, 2, 0, -1, 0),
+ row( 0, 2, 0, -1, 1),
+ row( 0, 1, -1, 1, 0),
+ row( 0, 1, -1, 1, 1),
+ row( 0, 1, -1, 0, 0),
+ row( 0, 1, 0, 1, -1),
+ row( 0, 1, 0, 1, 1),
+ row( 0, 1, 0, 0, -1),
+ row( 0, 1, 0, 0, 0),
+ row( 0, 1, 0, 0, 1),
+ row( 0, 1, 0, -1, -1),
+ row( 0, 1, 1, 0, -1),
+ row( 0, 1, 1, 0, 0),
+ row( 0, 1, 1, 0, 1),
+ row( 0, 1, 1, -1, 0),
+ row( 0, 0, 0, 0, 0),
+ row( 0, -1, 0, 0, 0),
+ row( 0, -1, 0, -1, 0)
+ );
+
+ assertRows(execute(
+ "SELECT * FROM %s" +
+ " WHERE a = ? " +
+ "AND (b,c)<=(?,?) " +
+ "AND (b,c,d,e)>(?,?,?,?)", 0, 2, 0, -1, 0,-1,-1),
+
+ row( 0, 2, 0, 1, 1),
+ row( 0, 2, 0, -1, 0),
+ row( 0, 2, 0, -1, 1),
+ row( 0, 1, -1, 1, 0),
+ row( 0, 1, -1, 1, 1),
+ row( 0, 1, -1, 0, 0),
+ row( 0, 1, 0, 1, -1),
+ row( 0, 1, 0, 1, 1),
+ row( 0, 1, 0, 0, -1),
+ row( 0, 1, 0, 0, 0),
+ row( 0, 1, 0, 0, 1),
+ row( 0, 1, 0, -1, -1),
+ row( 0, 1, 1, 0, -1),
+ row( 0, 1, 1, 0, 0),
+ row( 0, 1, 1, 0, 1),
+ row( 0, 1, 1, -1, 0),
+ row( 0, 0, 0, 0, 0),
+ row( 0, -1, 0, 0, 0),
+ row( 0, -1, 0, -1, 0)
+ );
+
+ assertRows(execute(
+ "SELECT * FROM %s" +
+ " WHERE a = ? " +
+ "AND (b,c,d)<=(?,?,?) " +
+ "AND (b,c,d,e)>(?,?,?,?)", 0, 2, 0,-1, -1, 0,-1,-1),
+
+ row( 0, 2, 0, -1, 0),
+ row( 0, 2, 0, -1, 1),
+ row( 0, 1, -1, 1, 0),
+ row( 0, 1, -1, 1, 1),
+ row( 0, 1, -1, 0, 0),
+ row( 0, 1, 0, 1, -1),
+ row( 0, 1, 0, 1, 1),
+ row( 0, 1, 0, 0, -1),
+ row( 0, 1, 0, 0, 0),
+ row( 0, 1, 0, 0, 1),
+ row( 0, 1, 0, -1, -1),
+ row( 0, 1, 1, 0, -1),
+ row( 0, 1, 1, 0, 0),
+ row( 0, 1, 1, 0, 1),
+ row( 0, 1, 1, -1, 0),
+ row( 0, 0, 0, 0, 0),
+ row( 0, -1, 0, 0, 0),
+ row( 0, -1, 0, -1, 0)
+ );
+
+ assertRows(execute(
+ "SELECT * FROM %s" +
+ " WHERE a = ? " +
+ "AND (b,c,d,e)>(?,?,?,?)"+
+ "AND (b,c,d)<=(?,?,?) ", 0, -1, 0,-1,-1, 2, 0,-1),
+
+ row( 0, 2, 0, -1, 0),
+ row( 0, 2, 0, -1, 1),
+ row( 0, 1, -1, 1, 0),
+ row( 0, 1, -1, 1, 1),
+ row( 0, 1, -1, 0, 0),
+ row( 0, 1, 0, 1, -1),
+ row( 0, 1, 0, 1, 1),
+ row( 0, 1, 0, 0, -1),
+ row( 0, 1, 0, 0, 0),
+ row( 0, 1, 0, 0, 1),
+ row( 0, 1, 0, -1, -1),
+ row( 0, 1, 1, 0, -1),
+ row( 0, 1, 1, 0, 0),
+ row( 0, 1, 1, 0, 1),
+ row( 0, 1, 1, -1, 0),
+ row( 0, 0, 0, 0, 0),
+ row( 0, -1, 0, 0, 0),
+ row( 0, -1, 0, -1, 0)
+ );
+
+ assertRows(execute(
+ "SELECT * FROM %s" +
+ " WHERE a = ? " +
+ "AND (b,c,d)>=(?,?,?)"+
+ "AND (b,c,d,e)<(?,?,?,?) ", 0, 1, 1,0,1, 1, 0,1),
+ row( 0, 1, 1, 0, -1),
+ row( 0, 1, 1, 0, 0)
+ );
+ assertRows(execute(
+ "SELECT * FROM %s" +
+ " WHERE a = ? " +
+ "AND (b,c,d,e)<(?,?,?,?) "+
+ "AND (b,c,d)>=(?,?,?)", 0, 1, 1,0,1,1, 1, 0),
+ row( 0, 1, 1, 0, -1),
+ row( 0, 1, 1, 0, 0)
+
+ );
+
+ assertRows(execute(
+ "SELECT * FROM %s" +
+ " WHERE a = ? " +
+ "AND (b,c)<(?,?) " +
+ "AND (b,c,d,e)>(?,?,?,?)", 0, 2, 0, -1, 0,-1,-1),
+ row( 0, 1, -1, 1, 0),
+ row( 0, 1, -1, 1, 1),
+ row( 0, 1, -1, 0, 0),
+ row( 0, 1, 0, 1, -1),
+ row( 0, 1, 0, 1, 1),
+ row( 0, 1, 0, 0, -1),
+ row( 0, 1, 0, 0, 0),
+ row( 0, 1, 0, 0, 1),
+ row( 0, 1, 0, -1, -1),
+ row( 0, 1, 1, 0, -1),
+ row( 0, 1, 1, 0, 0),
+ row( 0, 1, 1, 0, 1),
+ row( 0, 1, 1, -1, 0),
+ row( 0, 0, 0, 0, 0),
+ row( 0, -1, 0, 0, 0),
+ row( 0, -1, 0, -1, 0)
+ );
+
+ assertRows(execute(
+ "SELECT * FROM %s" +
+ " WHERE a = ? " +
+ "AND (b,c)<(?,?) " +
+ "AND (b,c,d,e)>(?,?,?,?)", 0, 2, 0, -1, 0,-1,-1),
+ row( 0, 1, -1, 1, 0),
+ row( 0, 1, -1, 1, 1),
+ row( 0, 1, -1, 0, 0),
+ row( 0, 1, 0, 1, -1),
+ row( 0, 1, 0, 1, 1),
+ row( 0, 1, 0, 0, -1),
+ row( 0, 1, 0, 0, 0),
+ row( 0, 1, 0, 0, 1),
+ row( 0, 1, 0, -1, -1),
+ row( 0, 1, 1, 0, -1),
+ row( 0, 1, 1, 0, 0),
+ row( 0, 1, 1, 0, 1),
+ row( 0, 1, 1, -1, 0),
+ row( 0, 0, 0, 0, 0),
+ row( 0, -1, 0, 0, 0),
+ row( 0, -1, 0, -1, 0)
+ );
+
+ assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b,c,d,e) <= (?,?,?,?)", 0, 1, 0, 0, 0),
+ row(0, 1, -1, 1, 0),
+ row(0, 1, -1, 1, 1),
+ row(0, 1, -1, 0, 0),
+ row(0, 1, 0, 0, -1),
+ row(0, 1, 0, 0, 0),
+ row(0, 1, 0, -1, -1),
+ row(0, 0, 0, 0, 0),
+ row(0, -1, 0, 0, 0),
+ row(0, -1, 0, -1, 0)
+ );
+
+ assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b,c,d,e) > (?,?,?,?)", 0, 1, 0, 0, 0),
+ row(0, 2, 0, 1, 1),
+ row(0, 2, 0, -1, 0),
+ row(0, 2, 0, -1, 1),
+ row(0, 1, 0, 1, -1),
+ row(0, 1, 0, 1, 1),
+ row(0, 1, 0, 0, 1),
+ row(0, 1, 1, 0, -1),
+ row(0, 1, 1, 0, 0),
+ row(0, 1, 1, 0, 1),
+ row(0, 1, 1, -1, 0)
+ );
+
+ assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b,c,d,e) >= (?,?,?,?)", 0, 1, 0, 0, 0),
+ row( 0, 2, 0, 1, 1),
+ row(0, 2, 0, -1, 0),
+ row(0, 2, 0, -1, 1),
+ row(0, 1, 0, 1, -1),
+ row(0, 1, 0, 1, 1),
+ row(0, 1, 0, 0, 0),
+ row(0, 1, 0, 0, 1),
+ row(0, 1, 1, 0, -1),
+ row(0, 1, 1, 0, 0),
+ row(0, 1, 1, 0, 1),
+ row(0, 1, 1, -1, 0)
+ );
+
+ assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b,c,d) >= (?,?,?)", 0, 1, 0, 0),
+ row( 0, 2, 0, 1, 1),
+ row(0, 2, 0, -1, 0),
+ row(0, 2, 0, -1, 1),
+ row(0, 1, 0, 1, -1),
+ row(0, 1, 0, 1, 1),
+ row(0, 1, 0, 0, -1),
+ row(0, 1, 0, 0, 0),
+ row(0, 1, 0, 0, 1),
+ row(0, 1, 1, 0, -1),
+ row(0, 1, 1, 0, 0),
+ row(0, 1, 1, 0, 1),
+ row(0, 1, 1, -1, 0)
+ );
+
+ assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b,c,d) > (?,?,?)", 0, 1, 0, 0),
+ row(0, 2, 0, 1, 1),
+ row(0, 2, 0, -1, 0),
+ row(0, 2, 0, -1, 1),
+ row(0, 1, 0, 1, -1),
+ row(0, 1, 0, 1, 1),
+ row(0, 1, 1, 0, -1),
+ row(0, 1, 1, 0, 0),
+ row(0, 1, 1, 0, 1),
+ row(0, 1, 1, -1, 0)
+ );
+
+ }
+
+ @Test
+ public void testMixedOrderColumns2() throws Throwable
+ {
+ createTable("CREATE TABLE %s (a int, b int, c int, d int, e int, PRIMARY KEY (a, b, c, d, e)) " +
+ "WITH CLUSTERING ORDER BY (b DESC, c ASC, d ASC, e ASC)");
+
+ // b and d are reversed in the clustering order
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 2, 0, -1, 0);
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 2, 0, -1, 1);
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 1, -1, 0, 0);
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 1, -1, 1, 0);
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 1, -1, 1, 1);
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 1, 0, 1, -1);
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 1, 0, 1, 1);
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 1, 0, 0, -1);
+ 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, 0, 0, 1);
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 1, 0, -1, -1);
+ 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, 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, 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, 0);
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 0, 0, 0, 0);
+
+ assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b,c,d,e) <= (?,?,?,?)", 0, 1, 0, 0, 0),
+ row(0, 1, -1, 0, 0),
+ row(0, 1, -1, 1, 0),
+ row(0, 1, -1, 1, 1),
+ row(0, 1, 0, -1, -1),
+ row(0, 1, 0, 0, -1),
+ row(0, 1, 0, 0, 0),
+ row(0, 0, 0, 0, 0)
+ );
+
+ assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b,c,d,e) > (?,?,?,?)", 0, 1, 0, 0, 0),
+ row(0, 2, 0, -1, 0),
+ row(0, 2, 0, -1, 1),
+ row(0, 1, 0, 0, 1),
+ row(0, 1, 0, 1, -1),
+ row(0, 1, 0, 1, 1),
+ row(0, 1, 1, -1, 0),
+ row(0, 1, 1, 0, -1),
+ row(0, 1, 1, 0, 0),
+ row(0, 1, 1, 0, 1)
+ );
+ assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b,c,d,e) >= (?,?,?,?)", 0, 1, 0, 0, 0),
+ row(0, 2, 0, -1, 0),
+ row(0, 2, 0, -1, 1),
+ row(0, 1, 0, 0, 0),
+ row(0, 1, 0, 0, 1),
+ row(0, 1, 0, 1, -1),
+ row(0, 1, 0, 1, 1),
+ row(0, 1, 1, -1, 0),
+ row(0, 1, 1, 0, -1),
+ row(0, 1, 1, 0, 0),
+ row(0, 1, 1, 0, 1)
+ );
+ }
+
+ @Test
+ public void testMixedOrderColumns3() throws Throwable
+ {
+ createTable("create table %s (a int, b int, c int, PRIMARY KEY (a, b, c)) WITH CLUSTERING ORDER BY (b DESC, c ASC)");
+
+ execute("INSERT INTO %s (a, b, c) VALUES (?,?,?);", 0, 2, 3);
+ execute("INSERT INTO %s (a, b, c) VALUES (?,?,?);", 0, 2, 4);
+ execute("INSERT INTO %s (a, b, c) VALUES (?,?,?);", 0, 4, 4);
+ execute("INSERT INTO %s (a, b, c) VALUES (?,?,?);", 0, 3, 4);
+ execute("INSERT INTO %s (a, b, c) VALUES (?,?,?);", 0, 4, 5);
+ execute("INSERT INTO %s (a, b, c) VALUES (?,?,?);", 0, 4, 6);
+
+
+ assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b,c)>=(?,?) AND (b,c)<(?,?) ALLOW FILTERING", 0, 2, 3, 4, 5),
+ row(0, 4, 4), row(0, 3, 4), row(0, 2, 3), row(0, 2, 4)
+ );
+ assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b,c)>=(?,?) AND (b,c)<=(?,?) ALLOW FILTERING", 0, 2, 3, 4, 5),
+ row(0, 4, 4), row(0, 4, 5), row(0, 3, 4), row(0, 2, 3), row(0, 2, 4)
+ );
+ assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b,c)<(?,?) ALLOW FILTERING", 0, 4, 5),
+ row(0, 4, 4),row(0, 3, 4),row(0, 2, 3),row(0, 2, 4)
+ );
+
+ assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b,c)>(?,?) ALLOW FILTERING", 0, 4, 5),
+ row(0, 4, 6)
+ );
+
+ assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b)<(?) and (b)>(?) ALLOW FILTERING", 0, 4, 2),
+ row(0, 3, 4)
+ );
+ }
+
+ @Test
+ public void testMixedOrderColumns4() throws Throwable
+ {
+ createTable("CREATE TABLE %s (a int, b int, c int, d int, e int, PRIMARY KEY (a, b, c, d, e)) " +
+ "WITH CLUSTERING ORDER BY (b ASC, c DESC, d DESC, e ASC)");
+
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 2, 0, -1, 0);
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 2, 0, -1, 1);
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 2, 0, 1, 1);
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 2, -1, 1, 1);
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 2, -3, 1, 1);
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 1, -1, 0, 0);
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 1, -1, 1, 1);
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 1, -1, 1, 0);
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 1, 0, 1, -1);
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 1, 0, 1, 1);
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 1, 0, 0, -1);
+ 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, 0, 0, 1);
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, 1, 0, -1, -1);
+ 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, 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, 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, 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, -1, 0, -1, 0);
+ execute("INSERT INTO %s (a, b, c, d, e) VALUES (?, ?, ?, ?, ?)", 0, -1, 0, 0, 0);
+
+ assertRows(execute(
+ "SELECT * FROM %s" +
+ " WHERE a = ? " +
+ "AND (b,c,d,e)<(?,?,?,?) " +
+ "AND (b,c,d,e)>(?,?,?,?)", 0, 2, 0, 1, 1, -1, 0, -1, -1),
+
+ row(0, -1, 0, 0, 0),
+ row(0, -1, 0, -1, 0),
+ row(0, 0, 0, 0, 0),
+ row(0, 1, 1, 0, -1),
+ row(0, 1, 1, 0, 0),
+ row(0, 1, 1, 0, 1),
+ row(0, 1, 1, -1, 0),
+ row(0, 1, 0, 1, -1),
+ row(0, 1, 0, 1, 1),
+ row(0, 1, 0, 0, -1),
+ row(0, 1, 0, 0, 0),
+ row(0, 1, 0, 0, 1),
+ row(0, 1, 0, -1, -1),
+ row(0, 1, -1, 1, 0),
+ row(0, 1, -1, 1, 1),
+ row(0, 1, -1, 0, 0),
+ row(0, 2, 0, -1, 0),
+ row(0, 2, 0, -1, 1),
+ row(0, 2, -1, 1, 1),
+ row(0, 2, -3, 1, 1)
+
+ );
+
+
+ assertRows(execute(
+ "SELECT * FROM %s" +
+ " WHERE a = ? " +
+ "AND (b,c,d,e) < (?,?,?,?) " +
+ "AND (b,c,d,e)>(?,?,?,?)", 0, 1, 0, 0, 0, 1, 0, -1, -1),
+ row(0, 1, 0, 0, -1)
+ );
+
+ assertRows(execute(
+ "SELECT * FROM %s" +
+ " WHERE a = ? " +
+ "AND (b,c,d,e) <= (?,?,?,?) " +
+ "AND (b,c,d,e)>(?,?,?,?)", 0, 1, 0, 0, 0, 1, 0,-1,-1),
+ row(0, 1, 0, 0, -1),
+ row(0, 1, 0, 0, 0)
+ );
+
+
+ assertRows(execute(
+ "SELECT * FROM %s" +
+ " WHERE a = ? " +
+ "AND (b,c,d,e)<=(?,?,?,?) " +
+ "AND (b,c,d,e)>(?,?,?,?)", 0, 2, 0, 1, 1, -1, 0,-1,-1),
+
+ row( 0, -1, 0, 0, 0),
+ row( 0, -1, 0, -1, 0),
+ row(0, 0, 0, 0, 0),
+ row( 0, 1, 1, 0, -1),
+ row( 0, 1, 1, 0, 0),
+ row( 0, 1, 1, 0, 1),
+ row( 0, 1, 1, -1, 0),
+ row( 0, 1, 0, 1, -1),
+ row( 0, 1, 0, 1, 1),
+ row( 0, 1, 0, 0, -1),
+ row( 0, 1, 0, 0, 0),
+ row( 0, 1, 0, 0, 1),
+ row( 0, 1, 0, -1, -1),
+ row( 0, 1, -1, 1, 0),
+ row( 0, 1, -1, 1, 1),
+ row( 0, 1, -1, 0, 0),
+ row( 0, 2, 0, 1, 1),
+ row( 0, 2, 0, -1, 0),
+ row( 0, 2, 0, -1, 1),
+ row( 0, 2, -1, 1, 1),
+ row( 0, 2, -3, 1, 1)
+ );
+
+ assertRows(execute(
+ "SELECT * FROM %s" +
+ " WHERE a = ? " +
+ "AND (b,c)<=(?,?) " +
+ "AND (b,c,d,e)>(?,?,?,?)", 0, 2, 0, -1, 0,-1,-1),
+
+ row( 0, -1, 0, 0, 0),
+ row(0, -1, 0, -1, 0),
+ row( 0, 0, 0, 0, 0),
+ row( 0, 1, 1, 0, -1),
+ row( 0, 1, 1, 0, 0),
+ row( 0, 1, 1, 0, 1),
+ row( 0, 1, 1, -1, 0),
+ row( 0, 1, 0, 1, -1),
+ row( 0, 1, 0, 1, 1),
+ row( 0, 1, 0, 0, -1),
+ row( 0, 1, 0, 0, 0),
+ row( 0, 1, 0, 0, 1),
+ row( 0, 1, 0, -1, -1),
+ row( 0, 1, -1, 1, 0),
+ row( 0, 1, -1, 1, 1),
+ row( 0, 1, -1, 0, 0),
+ row( 0, 2, 0, 1, 1),
+ row( 0, 2, 0, -1, 0),
+ row( 0, 2, 0, -1, 1),
+ row( 0, 2, -1, 1, 1),
+ row( 0, 2, -3, 1, 1)
+ );
+
+ assertRows(execute(
+ "SELECT * FROM %s" +
+ " WHERE a = ? " +
+ "AND (b,c)<(?,?) " +
+ "AND (b,c,d,e)>(?,?,?,?)", 0, 2, 0, -1, 0, -1, -1),
+ row( 0, -1, 0, 0, 0),
+ row( 0, -1, 0, -1, 0),
+ row( 0, 0, 0, 0, 0),
+ row( 0, 1, 1, 0, -1),
+ row( 0, 1, 1, 0, 0),
+ row( 0, 1, 1, 0, 1),
+ row( 0, 1, 1, -1, 0),
+ row( 0, 1, 0, 1, -1),
+ row( 0, 1, 0, 1, 1),
+ row( 0, 1, 0, 0, -1),
+ row( 0, 1, 0, 0, 0),
+ row( 0, 1, 0, 0, 1),
+ row( 0, 1, 0, -1, -1),
+ row( 0, 1, -1, 1, 0),
+ row( 0, 1, -1, 1, 1),
+ row( 0, 1, -1, 0, 0),
+ row( 0, 2, -1, 1, 1),
+ row(0, 2, -3, 1, 1)
+ );
+
+ assertRows(execute(
+ "SELECT * FROM %s" +
+ " WHERE a = ? " +
+ "AND (b,c,d,e)<=(?,?,?,?) " +
+ "AND (b)>=(?)", 0, 2, 0, 1, 1, -1),
+
+ row( 0, -1, 0, 0, 0),
+ row( 0, -1, 0, -1, 0),
+ row( 0, 0, 0, 0, 0),
+ row( 0, 1, 1, 0, -1),
+ row(0, 1, 1, 0, 0),
+ row( 0, 1, 1, 0, 1),
+ row( 0, 1, 1, -1, 0),
+ row( 0, 1, 0, 1, -1),
+ row( 0, 1, 0, 1, 1),
+ row( 0, 1, 0, 0, -1),
+ row( 0, 1, 0, 0, 0),
+ row( 0, 1, 0, 0, 1),
+ row( 0, 1, 0, -1, -1),
+ row( 0, 1, -1, 1, 0),
+ row( 0, 1, -1, 1, 1),
+ row( 0, 1, -1, 0, 0),
+ row( 0, 2, 0, 1, 1),
+ row( 0, 2, 0, -1, 0),
+ row( 0, 2, 0, -1, 1),
+ row( 0, 2, -1, 1, 1),
+ row( 0, 2, -3, 1, 1)
+ );
+
+ assertRows(execute(
+ "SELECT * FROM %s" +
+ " WHERE a = ? " +
+ "AND (b,c,d,e)<=(?,?,?,?) " +
+ "AND (b)>(?)", 0, 2, 0, 1, 1, -1),
+
+ row( 0, 0, 0, 0, 0),
+ row( 0, 1, 1, 0, -1),
+ row( 0, 1, 1, 0, 0),
+ row( 0, 1, 1, 0, 1),
+ row( 0, 1, 1, -1, 0),
+ row( 0, 1, 0, 1, -1),
+ row( 0, 1, 0, 1, 1),
+ row( 0, 1, 0, 0, -1),
+ row( 0, 1, 0, 0, 0),
+ row( 0, 1, 0, 0, 1),
+ row( 0, 1, 0, -1, -1),
+ row( 0, 1, -1, 1, 0),
+ row( 0, 1, -1, 1, 1),
+ row( 0, 1, -1, 0, 0),
+ row( 0, 2, 0, 1, 1),
+ row( 0, 2, 0, -1, 0),
+ row( 0, 2, 0, -1, 1),
+ row( 0, 2, -1, 1, 1),
+ row( 0, 2, -3, 1, 1)
+ );
+
+ assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b,c,d,e) <= (?,?,?,?)", 0, 1, 0, 0, 0),
+ row(0, -1, 0, 0, 0),
+ row(0, -1, 0, -1, 0),
+ row(0, 0, 0, 0, 0),
+ row(0, 1, 0, 0, -1),
+ row(0, 1, 0, 0, 0),
+ row(0, 1, 0, -1, -1),
+ row(0, 1, -1, 1, 0),
+ row(0, 1, -1, 1, 1),
+ row(0, 1, -1, 0, 0)
+ );
+
+ assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b,c,d,e) > (?,?,?,?)", 0, 1, 0, 0, 0),
+ row(0, 1, 1, 0, -1),
+ row(0, 1, 1, 0, 0),
+ row(0, 1, 1, 0, 1),
+ row(0, 1, 1, -1, 0),
+ row(0, 1, 0, 1, -1),
+ row(0, 1, 0, 1, 1),
+ row(0, 1, 0, 0, 1),
+ row(0, 2, 0, 1, 1),
+ row(0, 2, 0, -1, 0),
+ row(0, 2, 0, -1, 1),
+ row( 0, 2, -1, 1, 1),
+ row( 0, 2, -3, 1, 1)
+
+ );
+
+ assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b,c,d,e) >= (?,?,?,?)", 0, 1, 0, 0, 0),
+ row(0, 1, 1, 0, -1),
+ row(0, 1, 1, 0, 0),
+ row(0, 1, 1, 0, 1),
+ row(0, 1, 1, -1, 0),
+ row(0, 1, 0, 1, -1),
+ row(0, 1, 0, 1, 1),
+ row(0, 1, 0, 0, 0),
+ row(0, 1, 0, 0, 1),
+ row(0, 2, 0, 1, 1),
+ row(0, 2, 0, -1, 0),
+ row(0, 2, 0, -1, 1),
+ row( 0, 2, -1, 1, 1),
+ row( 0, 2, -3, 1, 1)
+ );
+
+ assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b,c,d) >= (?,?,?)", 0, 1, 0, 0),
+ row(0, 1, 1, 0, -1),
+ row(0, 1, 1, 0, 0),
+ row(0, 1, 1, 0, 1),
+ row(0, 1, 1, -1, 0),
+ row(0, 1, 0, 1, -1),
+ row(0, 1, 0, 1, 1),
+ row(0, 1, 0, 0, -1),
+ row(0, 1, 0, 0, 0),
+ row(0, 1, 0, 0, 1),
+ row(0, 2, 0, 1, 1),
+ row(0, 2, 0, -1, 0),
+ row(0, 2, 0, -1, 1),
+ row( 0, 2, -1, 1, 1),
+ row( 0, 2, -3, 1, 1)
+ );
+
+ assertRows(execute("SELECT * FROM %s WHERE a = ? AND (b,c,d) > (?,?,?)", 0, 1, 0, 0),
+ row(0, 1, 1, 0, -1),
+ row(0, 1, 1, 0, 0),
+ row(0, 1, 1, 0, 1),
+ row(0, 1, 1, -1, 0),
+ row(0, 1, 0, 1, -1),
+ row(0, 1, 0, 1, 1),
+ row(0, 2, 0, 1, 1),
+ row(0, 2, 0, -1, 0),
+ row(0, 2, 0, -1, 1),
+ row( 0, 2, -1, 1, 1),
+ row( 0, 2, -3, 1, 1)
+ );
+
+ assertRows(execute(
+ "SELECT * FROM %s" +
+ " WHERE a = ? " +
+ "AND (b) < (?) ", 0, 0),
+ row(0, -1, 0, 0, 0), row(0, -1, 0, -1, 0)
+ );
+ assertRows(execute(
+ "SELECT * FROM %s" +
+ " WHERE a = ? " +
+ "AND (b) <= (?) ", 0,-1),
+ row(0, -1, 0, 0, 0), row(0, -1, 0, -1, 0)
+ );
+ assertRows(execute(
+ "SELECT * FROM %s" +
+ " WHERE a = ? " +
+ "AND (b,c,d,e) < (?,?,?,?) and (b,c,d,e) > (?,?,?,?) ", 0, 2, 0, 0, 0, 2, -2, 0, 0),
+ row(0, 2, 0, -1, 0),
+ row(0, 2, 0, -1, 1),
+ row(0, 2, -1, 1, 1)
+ );
+ }
+
/**
* Check select on tuple relations, see CASSANDRA-8613
* migrated from cql_tests.py:TestCQL.simple_tuple_query_test()
[6/6] cassandra git commit: Merge branch cassandra-3.0 into trunk
Posted by bl...@apache.org.
Merge branch cassandra-3.0 into trunk
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/b0448e66
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/b0448e66
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/b0448e66
Branch: refs/heads/trunk
Commit: b0448e66b567bb8dc80acb1cb9c66bbf8b5f461c
Parents: ebd6c23 1aa97e3
Author: Benjamin Lerer <b....@gmail.com>
Authored: Thu Feb 11 10:44:30 2016 +0100
Committer: Benjamin Lerer <b....@gmail.com>
Committed: Thu Feb 11 10:48:28 2016 +0100
----------------------------------------------------------------------
CHANGES.txt | 1 +
.../cql3/restrictions/AbstractRestriction.java | 14 +
.../ForwardingPrimaryKeyRestrictions.java | 3 +-
.../restrictions/MultiColumnRestriction.java | 76 +-
.../restrictions/PrimaryKeyRestrictionSet.java | 34 +-
.../cql3/restrictions/Restriction.java | 4 +-
.../cql3/restrictions/RestrictionSet.java | 4 +-
.../restrictions/SingleColumnRestriction.java | 9 +-
.../cql3/restrictions/TokenRestriction.java | 2 +-
.../org/apache/cassandra/db/MultiCBuilder.java | 90 +-
.../PrimaryKeyRestrictionSetTest.java | 1174 +++++++++++++++---
.../SelectMultiColumnRelationTest.java | 859 ++++++++++++-
12 files changed, 2059 insertions(+), 211 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/b0448e66/CHANGES.txt
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/b0448e66/src/java/org/apache/cassandra/cql3/restrictions/AbstractRestriction.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/b0448e66/src/java/org/apache/cassandra/cql3/restrictions/ForwardingPrimaryKeyRestrictions.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/b0448e66/src/java/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSet.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSet.java
index d24799a,8121858..978ebbc
--- a/src/java/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSet.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSet.java
@@@ -163,20 -175,6 +163,30 @@@ final class PrimaryKeyRestrictionSet ex
return new PrimaryKeyRestrictionSet(this, restriction);
}
+ // Whether any of the underlying restriction is an IN
+ private boolean hasIN()
+ {
+ if (isIN())
+ return true;
+
+ for (Restriction restriction : restrictions)
+ {
+ if (restriction.isIN())
+ return true;
+ }
+ return false;
+ }
+
++ private boolean hasMultiColumnSlice()
++ {
++ for (Restriction restriction : restrictions)
++ {
++ if (restriction.isMultiColumn() && restriction.isSlice())
++ return true;
++ }
++ return false;
++ }
++
@Override
public NavigableSet<Clustering> valuesAsClustering(QueryOptions options) throws InvalidRequestException
{
@@@ -204,7 -202,7 +214,7 @@@
@Override
public NavigableSet<Slice.Bound> boundsAsClustering(Bound bound, QueryOptions options) throws InvalidRequestException
{
- MultiCBuilder builder = MultiCBuilder.create(comparator, hasIN());
- MultiCBuilder builder = MultiCBuilder.create(comparator);
++ MultiCBuilder builder = MultiCBuilder.create(comparator, hasIN() || hasMultiColumnSlice());
int keyPosition = 0;
for (Restriction r : restrictions)
{
http://git-wip-us.apache.org/repos/asf/cassandra/blob/b0448e66/src/java/org/apache/cassandra/cql3/restrictions/Restriction.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/b0448e66/src/java/org/apache/cassandra/cql3/restrictions/RestrictionSet.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/b0448e66/src/java/org/apache/cassandra/cql3/restrictions/SingleColumnRestriction.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/b0448e66/src/java/org/apache/cassandra/db/MultiCBuilder.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/db/MultiCBuilder.java
index 7a4eef0,7c77ab0..f03e674
--- a/src/java/org/apache/cassandra/db/MultiCBuilder.java
+++ b/src/java/org/apache/cassandra/db/MultiCBuilder.java
@@@ -18,8 -18,11 +18,13 @@@
package org.apache.cassandra.db;
import java.nio.ByteBuffer;
- import java.util.*;
+ import java.util.ArrayList;
++import java.util.Arrays;
+ import java.util.List;
+ import java.util.NavigableSet;
+ import org.apache.cassandra.config.ColumnDefinition;
++import org.apache.cassandra.db.Slice.Bound;
import org.apache.cassandra.utils.ByteBufferUtil;
import org.apache.cassandra.utils.btree.BTreeSet;
@@@ -159,260 -257,123 +164,333 @@@ public abstract class MultiCBuilde
*
* @return the clusterings
*/
- public NavigableSet<Clustering> build()
- {
- built = true;
-
- if (hasMissingElements)
- return BTreeSet.empty(comparator);
-
- CBuilder builder = CBuilder.create(comparator);
-
- if (elementsList.isEmpty())
- return BTreeSet.of(builder.comparator(), builder.build());
-
- BTreeSet.Builder<Clustering> set = BTreeSet.builder(builder.comparator());
- for (int i = 0, m = elementsList.size(); i < m; i++)
- {
- List<ByteBuffer> elements = elementsList.get(i);
- set.add(builder.buildWith(elements));
- }
- return set.build();
- }
+ public abstract NavigableSet<Clustering> build();
/**
- * Builds the <code>clusterings</code> with the specified EOC.
+ * Builds the <code>Slice.Bound</code>s for slice restrictions.
*
- * @return the clusterings
+ * @param isStart specify if the bound is a start one
+ * @param isInclusive specify if the bound is inclusive or not
+ * @param isOtherBoundInclusive specify if the other bound is inclusive or not
+ * @param columnDefs the columns of the slice restriction
+ * @return the <code>Slice.Bound</code>s
+ */
- public NavigableSet<Slice.Bound> buildBoundForSlice(boolean isStart,
- boolean isInclusive,
- boolean isOtherBoundInclusive,
- List<ColumnDefinition> columnDefs)
++ public abstract NavigableSet<Slice.Bound> buildBoundForSlice(boolean isStart,
++ boolean isInclusive,
++ boolean isOtherBoundInclusive,
++ List<ColumnDefinition> columnDefs);
++
++ /**
++ * Builds the <code>Slice.Bound</code>s
++ *
++ * @param isStart specify if the bound is a start one
++ * @param isInclusive specify if the bound is inclusive or not
++ * @return the <code>Slice.Bound</code>s
+ */
+ public abstract NavigableSet<Slice.Bound> buildBound(boolean isStart, boolean isInclusive);
+
+ /**
+ * Checks if some elements can still be added to the clusterings.
+ *
+ * @return <code>true</code> if it is possible to add more elements to the clusterings, <code>false</code> otherwise.
+ */
+ public boolean hasRemaining()
{
- built = true;
+ return remainingCount() > 0;
+ }
- if (hasMissingElements)
- return BTreeSet.empty(comparator);
+ /**
+ * Specialization of MultiCBuilder when we know only one clustering/bound is created.
+ */
+ private static class OneClusteringBuilder extends MultiCBuilder
+ {
+ /**
+ * The elements of the clusterings
+ */
+ private final ByteBuffer[] elements;
- CBuilder builder = CBuilder.create(comparator);
+ public OneClusteringBuilder(ClusteringComparator comparator)
+ {
+ super(comparator);
+ this.elements = new ByteBuffer[comparator.size()];
+ }
- if (elementsList.isEmpty())
- return BTreeSet.of(comparator, builder.buildBound(isStart, isInclusive));
+ public MultiCBuilder addElementToAll(ByteBuffer value)
+ {
+ checkUpdateable();
- // Use a TreeSet to sort and eliminate duplicates
- BTreeSet.Builder<Slice.Bound> set = BTreeSet.builder(comparator);
+ if (value == null)
+ containsNull = true;
+ if (value == ByteBufferUtil.UNSET_BYTE_BUFFER)
+ containsUnset = true;
- // The first column of the slice might not be the first clustering column (e.g. clustering_0 = ? AND (clustering_1, clustering_2) >= (?, ?)
- int offset = columnDefs.get(0).position();
+ elements[size++] = value;
+ return this;
+ }
- for (int i = 0, m = elementsList.size(); i < m; i++)
+ public MultiCBuilder addEachElementToAll(List<ByteBuffer> values)
{
- List<ByteBuffer> elements = elementsList.get(i);
-
- // Handle the no bound case
- if (elements.size() == offset)
+ if (values.isEmpty())
{
- set.add(builder.buildBoundWith(elements, isStart, true));
- continue;
+ hasMissingElements = true;
+ return this;
}
- // In the case of mixed order columns, we will have some extra slices where the columns change directions.
- // For example: if we have clustering_0 DESC and clustering_1 ASC a slice like (clustering_0, clustering_1) > (1, 2)
- // will produce 2 slices: [BOTTOM, 1) and (1.2, 1]
- // So, the END bound will return 2 bounds with the same values 1
- ColumnDefinition lastColumn = columnDefs.get(columnDefs.size() - 1);
- if (elements.size() <= lastColumn.position() && i < m - 1 && elements.equals(elementsList.get(i + 1)))
+ assert values.size() == 1;
+
+ return addElementToAll(values.get(0));
+ }
+
+ public MultiCBuilder addAllElementsToAll(List<List<ByteBuffer>> values)
+ {
+ if (values.isEmpty())
{
- set.add(builder.buildBoundWith(elements, isStart, false));
- set.add(builder.buildBoundWith(elementsList.get(i++), isStart, true));
- continue;
+ hasMissingElements = true;
+ return this;
}
- // Handle the normal bounds
- ColumnDefinition column = columnDefs.get(elements.size() - 1 - offset);
- set.add(builder.buildBoundWith(elements, isStart, column.isReversedType() ? isOtherBoundInclusive : isInclusive));
+ assert values.size() == 1;
+ return addEachElementToAll(values.get(0));
}
- return set.build();
- }
- public NavigableSet<Slice.Bound> buildBound(boolean isStart, boolean isInclusive)
- {
- built = true;
-
- if (hasMissingElements)
- return BTreeSet.empty(comparator);
+ public NavigableSet<Clustering> build()
+ {
+ built = true;
- CBuilder builder = CBuilder.create(comparator);
+ if (hasMissingElements)
+ return BTreeSet.empty(comparator);
- if (elementsList.isEmpty())
- return BTreeSet.of(comparator, builder.buildBound(isStart, isInclusive));
+ return BTreeSet.of(comparator, size == 0 ? Clustering.EMPTY : Clustering.make(elements));
+ }
- // Use a TreeSet to sort and eliminate duplicates
- BTreeSet.Builder<Slice.Bound> set = BTreeSet.builder(comparator);
++ @Override
++ public NavigableSet<Bound> buildBoundForSlice(boolean isStart,
++ boolean isInclusive,
++ boolean isOtherBoundInclusive,
++ List<ColumnDefinition> columnDefs)
++ {
++ return buildBound(isStart, columnDefs.get(0).isReversedType() ? isOtherBoundInclusive : isInclusive);
++ }
+
- for (int i = 0, m = elementsList.size(); i < m; i++)
+ public NavigableSet<Slice.Bound> buildBound(boolean isStart, boolean isInclusive)
{
- List<ByteBuffer> elements = elementsList.get(i);
- set.add(builder.buildBoundWith(elements, isStart, isInclusive));
+ built = true;
+
+ if (hasMissingElements)
+ return BTreeSet.empty(comparator);
+
+ if (size == 0)
+ return BTreeSet.of(comparator, isStart ? Slice.Bound.BOTTOM : Slice.Bound.TOP);
+
+ ByteBuffer[] newValues = size == elements.length
+ ? elements
+ : Arrays.copyOf(elements, size);
+
+ return BTreeSet.of(comparator, Slice.Bound.create(Slice.Bound.boundKind(isStart, isInclusive), newValues));
}
- return set.build();
}
/**
- * Checks if some elements can still be added to the clusterings.
- *
- * @return <code>true</code> if it is possible to add more elements to the clusterings, <code>false</code> otherwise.
+ * MultiCBuilder implementation actually supporting the creation of multiple clustering/bound.
*/
- public boolean hasRemaining()
+ private static class MultiClusteringBuilder extends MultiCBuilder
{
- return remainingCount() > 0;
- }
+ /**
+ * The elements of the clusterings
+ */
+ private final List<List<ByteBuffer>> elementsList = new ArrayList<>();
- private void checkUpdateable()
- {
- if (!hasRemaining() || built)
- throw new IllegalStateException("this builder cannot be updated anymore");
+ public MultiClusteringBuilder(ClusteringComparator comparator)
+ {
+ super(comparator);
+ }
+
+ public MultiCBuilder addElementToAll(ByteBuffer value)
+ {
+ checkUpdateable();
+
+ if (elementsList.isEmpty())
+ elementsList.add(new ArrayList<ByteBuffer>());
+
+ if (value == null)
+ containsNull = true;
+ else if (value == ByteBufferUtil.UNSET_BYTE_BUFFER)
+ containsUnset = true;
+
+ for (int i = 0, m = elementsList.size(); i < m; i++)
+ elementsList.get(i).add(value);
+
+ size++;
+ return this;
+ }
+
+ public MultiCBuilder addEachElementToAll(List<ByteBuffer> values)
+ {
+ checkUpdateable();
+
+ if (elementsList.isEmpty())
+ elementsList.add(new ArrayList<ByteBuffer>());
+
+ if (values.isEmpty())
+ {
+ hasMissingElements = true;
+ }
+ else
+ {
+ for (int i = 0, m = elementsList.size(); i < m; i++)
+ {
+ List<ByteBuffer> oldComposite = elementsList.remove(0);
+
+ for (int j = 0, n = values.size(); j < n; j++)
+ {
+ List<ByteBuffer> newComposite = new ArrayList<>(oldComposite);
+ elementsList.add(newComposite);
+
+ ByteBuffer value = values.get(j);
+
+ if (value == null)
+ containsNull = true;
+ if (value == ByteBufferUtil.UNSET_BYTE_BUFFER)
+ containsUnset = true;
+
+ newComposite.add(values.get(j));
+ }
+ }
+ }
+ size++;
+ return this;
+ }
+
+ public MultiCBuilder addAllElementsToAll(List<List<ByteBuffer>> values)
+ {
+ checkUpdateable();
+
+ if (elementsList.isEmpty())
+ elementsList.add(new ArrayList<ByteBuffer>());
+
+ if (values.isEmpty())
+ {
+ hasMissingElements = true;
+ }
+ else
+ {
+ for (int i = 0, m = elementsList.size(); i < m; i++)
+ {
+ List<ByteBuffer> oldComposite = elementsList.remove(0);
+
+ for (int j = 0, n = values.size(); j < n; j++)
+ {
+ List<ByteBuffer> newComposite = new ArrayList<>(oldComposite);
+ elementsList.add(newComposite);
+
+ List<ByteBuffer> value = values.get(j);
+
- if (value.isEmpty())
- hasMissingElements = true;
-
+ if (value.contains(null))
+ containsNull = true;
+ if (value.contains(ByteBufferUtil.UNSET_BYTE_BUFFER))
+ containsUnset = true;
+
+ newComposite.addAll(value);
+ }
+ }
+ size += values.get(0).size();
+ }
+ return this;
+ }
+
+ public NavigableSet<Clustering> build()
+ {
+ built = true;
+
+ if (hasMissingElements)
+ return BTreeSet.empty(comparator);
+
+ CBuilder builder = CBuilder.create(comparator);
+
+ if (elementsList.isEmpty())
+ return BTreeSet.of(builder.comparator(), builder.build());
+
+ BTreeSet.Builder<Clustering> set = BTreeSet.builder(builder.comparator());
+ for (int i = 0, m = elementsList.size(); i < m; i++)
+ {
+ List<ByteBuffer> elements = elementsList.get(i);
+ set.add(builder.buildWith(elements));
+ }
+ return set.build();
+ }
+
++ public NavigableSet<Slice.Bound> buildBoundForSlice(boolean isStart,
++ boolean isInclusive,
++ boolean isOtherBoundInclusive,
++ List<ColumnDefinition> columnDefs)
++ {
++ built = true;
++
++ if (hasMissingElements)
++ return BTreeSet.empty(comparator);
++
++ CBuilder builder = CBuilder.create(comparator);
++
++ if (elementsList.isEmpty())
++ return BTreeSet.of(comparator, builder.buildBound(isStart, isInclusive));
++
++ // Use a TreeSet to sort and eliminate duplicates
++ BTreeSet.Builder<Slice.Bound> set = BTreeSet.builder(comparator);
++
++ // The first column of the slice might not be the first clustering column (e.g. clustering_0 = ? AND (clustering_1, clustering_2) >= (?, ?)
++ int offset = columnDefs.get(0).position();
++
++ for (int i = 0, m = elementsList.size(); i < m; i++)
++ {
++ List<ByteBuffer> elements = elementsList.get(i);
++
++ // Handle the no bound case
++ if (elements.size() == offset)
++ {
++ set.add(builder.buildBoundWith(elements, isStart, true));
++ continue;
++ }
++
++ // In the case of mixed order columns, we will have some extra slices where the columns change directions.
++ // For example: if we have clustering_0 DESC and clustering_1 ASC a slice like (clustering_0, clustering_1) > (1, 2)
++ // will produce 2 slices: [BOTTOM, 1) and (1.2, 1]
++ // So, the END bound will return 2 bounds with the same values 1
++ ColumnDefinition lastColumn = columnDefs.get(columnDefs.size() - 1);
++ if (elements.size() <= lastColumn.position() && i < m - 1 && elements.equals(elementsList.get(i + 1)))
++ {
++ set.add(builder.buildBoundWith(elements, isStart, false));
++ set.add(builder.buildBoundWith(elementsList.get(i++), isStart, true));
++ continue;
++ }
++
++ // Handle the normal bounds
++ ColumnDefinition column = columnDefs.get(elements.size() - 1 - offset);
++ set.add(builder.buildBoundWith(elements, isStart, column.isReversedType() ? isOtherBoundInclusive : isInclusive));
++ }
++ return set.build();
++ }
++
+ public NavigableSet<Slice.Bound> buildBound(boolean isStart, boolean isInclusive)
+ {
+ built = true;
+
+ if (hasMissingElements)
+ return BTreeSet.empty(comparator);
+
+ CBuilder builder = CBuilder.create(comparator);
+
+ if (elementsList.isEmpty())
+ return BTreeSet.of(comparator, builder.buildBound(isStart, isInclusive));
+
+ // Use a TreeSet to sort and eliminate duplicates
+ BTreeSet.Builder<Slice.Bound> set = BTreeSet.builder(comparator);
+
+ for (int i = 0, m = elementsList.size(); i < m; i++)
+ {
+ List<ByteBuffer> elements = elementsList.get(i);
+ set.add(builder.buildBoundWith(elements, isStart, isInclusive));
+ }
+ return set.build();
+ }
}
}
[2/6] cassandra git commit: Fix SELECT on tuple relations for mixed
ASC/DESC clustering order
Posted by bl...@apache.org.
http://git-wip-us.apache.org/repos/asf/cassandra/blob/90fc8969/test/unit/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSetTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSetTest.java b/test/unit/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSetTest.java
index 05d6e98..1deeb9e 100644
--- a/test/unit/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSetTest.java
+++ b/test/unit/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSetTest.java
@@ -31,11 +31,10 @@ import org.apache.cassandra.cql3.statements.Bound;
import org.apache.cassandra.db.ColumnFamilyType;
import org.apache.cassandra.db.composites.Composite;
import org.apache.cassandra.db.composites.Composite.EOC;
-import org.apache.cassandra.db.composites.Composites;
import org.apache.cassandra.db.composites.CompoundSparseCellNameType;
import org.apache.cassandra.db.marshal.AbstractType;
import org.apache.cassandra.db.marshal.Int32Type;
-import org.apache.cassandra.exceptions.InvalidRequestException;
+import org.apache.cassandra.db.marshal.ReversedType;
import org.apache.cassandra.utils.ByteBufferUtil;
import static java.util.Arrays.asList;
@@ -45,9 +44,9 @@ import static org.junit.Assert.assertTrue;
public class PrimaryKeyRestrictionSetTest
{
@Test
- public void testBoundsAsCompositesWithNoRestrictions() throws InvalidRequestException
+ public void testBoundsAsCompositesWithNoRestrictions()
{
- CFMetaData cfMetaData = newCFMetaData(1);
+ CFMetaData cfMetaData = newCFMetaData(Sort.ASC);
PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
@@ -64,9 +63,9 @@ public class PrimaryKeyRestrictionSetTest
* Test 'clustering_0 = 1' with only one clustering column
*/
@Test
- public void testBoundsAsCompositesWithOneEqRestrictionsAndOneClusteringColumn() throws InvalidRequestException
+ public void testBoundsAsCompositesWithOneEqRestrictionsAndOneClusteringColumn()
{
- CFMetaData cfMetaData = newCFMetaData(1);
+ CFMetaData cfMetaData = newCFMetaData(Sort.ASC);
ByteBuffer clustering_0 = ByteBufferUtil.bytes(1);
Restriction eq = newSingleEq(cfMetaData, 0, clustering_0);
@@ -87,9 +86,9 @@ public class PrimaryKeyRestrictionSetTest
* Test 'clustering_1 = 1' with 2 clustering columns
*/
@Test
- public void testBoundsAsCompositesWithOneEqRestrictionsAndTwoClusteringColumns() throws InvalidRequestException
+ public void testBoundsAsCompositesWithOneEqRestrictionsAndTwoClusteringColumns()
{
- CFMetaData cfMetaData = newCFMetaData(2);
+ CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC);
ByteBuffer clustering_0 = ByteBufferUtil.bytes(1);
Restriction eq = newSingleEq(cfMetaData, 0, clustering_0);
@@ -110,13 +109,13 @@ public class PrimaryKeyRestrictionSetTest
* Test 'clustering_0 IN (1, 2, 3)' with only one clustering column
*/
@Test
- public void testBoundsAsCompositesWithOneInRestrictionsAndOneClusteringColumn() throws InvalidRequestException
+ public void testBoundsAsCompositesWithOneInRestrictionsAndOneClusteringColumn()
{
ByteBuffer value1 = ByteBufferUtil.bytes(1);
ByteBuffer value2 = ByteBufferUtil.bytes(2);
ByteBuffer value3 = ByteBufferUtil.bytes(3);
- CFMetaData cfMetaData = newCFMetaData(2);
+ CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC);
Restriction in = newSingleIN(cfMetaData, 0, value1, value2, value3);
@@ -140,9 +139,9 @@ public class PrimaryKeyRestrictionSetTest
* Test slice restriction (e.g 'clustering_0 > 1') with only one clustering column
*/
@Test
- public void testBoundsAsCompositesWithSliceRestrictionsAndOneClusteringColumn() throws InvalidRequestException
+ public void testBoundsAsCompositesWithSliceRestrictionsAndOneClusteringColumn()
{
- CFMetaData cfMetaData = newCFMetaData(1);
+ CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC);
ByteBuffer value1 = ByteBufferUtil.bytes(1);
ByteBuffer value2 = ByteBufferUtil.bytes(2);
@@ -223,12 +222,98 @@ public class PrimaryKeyRestrictionSetTest
}
/**
+ * Test slice restriction (e.g 'clustering_0 > 1') with only one descending clustering column
+ */
+ @Test
+ public void testBoundsAsCompositesWithSliceRestrictionsAndOneDescendingClusteringColumn()
+ {
+ CFMetaData cfMetaData = newCFMetaData(Sort.DESC, Sort.DESC);
+
+ ByteBuffer value1 = ByteBufferUtil.bytes(1);
+ ByteBuffer value2 = ByteBufferUtil.bytes(2);
+
+ Restriction slice = newSingleSlice(cfMetaData, 0, Bound.START, false, value1);
+ PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice);
+
+ List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertEmptyComposite(bounds.get(0));
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.START);
+
+ slice = newSingleSlice(cfMetaData, 0, Bound.START, true, value1);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertEmptyComposite(bounds.get(0));
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.END);
+
+ slice = newSingleSlice(cfMetaData, 0, Bound.END, true, value1);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.NONE);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertEmptyComposite(bounds.get(0));
+
+ slice = newSingleSlice(cfMetaData, 0, Bound.END, false, value1);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.END);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertEmptyComposite(bounds.get(0));
+
+ slice = newSingleSlice(cfMetaData, 0, Bound.START, false, value1);
+ Restriction slice2 = newSingleSlice(cfMetaData, 0, Bound.END, false, value2);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value2, EOC.END);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.START);
+
+ slice = newSingleSlice(cfMetaData, 0, Bound.START, true, value1);
+ slice2 = newSingleSlice(cfMetaData, 0, Bound.END, true, value2);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value2, EOC.NONE);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.END);
+ }
+
+ /**
* Test 'clustering_0 = 1 AND clustering_1 IN (1, 2, 3)'
*/
@Test
- public void testBoundsAsCompositesWithEqAndInRestrictions() throws InvalidRequestException
+ public void testBoundsAsCompositesWithEqAndInRestrictions()
{
- CFMetaData cfMetaData = newCFMetaData(2);
+ CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC);
ByteBuffer value1 = ByteBufferUtil.bytes(1);
ByteBuffer value2 = ByteBufferUtil.bytes(2);
@@ -255,9 +340,9 @@ public class PrimaryKeyRestrictionSetTest
* Test equal and slice restrictions (e.g 'clustering_0 = 0 clustering_1 > 1')
*/
@Test
- public void testBoundsAsCompositesWithEqAndSliceRestrictions() throws InvalidRequestException
+ public void testBoundsAsCompositesWithEqAndSliceRestrictions()
{
- CFMetaData cfMetaData = newCFMetaData(2);
+ CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC);
ByteBuffer value1 = ByteBufferUtil.bytes(1);
ByteBuffer value2 = ByteBufferUtil.bytes(2);
@@ -286,218 +371,909 @@ public class PrimaryKeyRestrictionSetTest
assertComposite(bounds.get(0), value3, value1, EOC.NONE);
bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value3, EOC.END);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value3, EOC.END);
+
+ slice = newSingleSlice(cfMetaData, 1, Bound.END, true, value1);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(eq).mergeWith(slice);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value3, EOC.START);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value3, value1, EOC.END);
+
+ slice = newSingleSlice(cfMetaData, 1, Bound.END, false, value1);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(eq).mergeWith(slice);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value3, EOC.START);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value3, value1, EOC.START);
+
+ slice = newSingleSlice(cfMetaData, 1, Bound.START, false, value1);
+ Restriction slice2 = newSingleSlice(cfMetaData, 1, Bound.END, false, value2);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(eq).mergeWith(slice).mergeWith(slice2);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value3, value1, EOC.END);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value3, value2, EOC.START);
+
+ slice = newSingleSlice(cfMetaData, 1, Bound.START, true, value1);
+ slice2 = newSingleSlice(cfMetaData, 1, Bound.END, true, value2);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(eq).mergeWith(slice).mergeWith(slice2);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value3, value1, EOC.NONE);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value3, value2, EOC.END);
+ }
+
+ /**
+ * Test '(clustering_0, clustering_1) = (1, 2)' with two clustering column
+ */
+ @Test
+ public void testBoundsAsCompositesWithMultiEqRestrictions()
+ {
+ CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC);
+
+ ByteBuffer value1 = ByteBufferUtil.bytes(1);
+ ByteBuffer value2 = ByteBufferUtil.bytes(2);
+ Restriction eq = newMultiEq(cfMetaData, 0, value1, value2);
+ PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(eq);
+
+ List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.START);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.END);
+ }
+
+ /**
+ * Test '(clustering_0, clustering_1) IN ((1, 2), (2, 3))' with two clustering column
+ */
+ @Test
+ public void testBoundsAsCompositesWithMultiInRestrictions()
+ {
+ CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC);
+
+ ByteBuffer value1 = ByteBufferUtil.bytes(1);
+ ByteBuffer value2 = ByteBufferUtil.bytes(2);
+ ByteBuffer value3 = ByteBufferUtil.bytes(3);
+ Restriction in = newMultiIN(cfMetaData, 0, asList(value1, value2), asList(value2, value3));
+ PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(in);
+
+ List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.START);
+ assertComposite(bounds.get(1), value2, value3, EOC.START);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.END);
+ assertComposite(bounds.get(1), value2, value3, EOC.END);
+ }
+
+ /**
+ * Test multi-column slice restrictions (e.g '(clustering_0) > (1)') with only one clustering column
+ */
+ @Test
+ public void testBoundsAsCompositesWithMultiSliceRestrictionsWithOneClusteringColumn()
+ {
+ CFMetaData cfMetaData = newCFMetaData(Sort.ASC);
+
+ ByteBuffer value1 = ByteBufferUtil.bytes(1);
+ ByteBuffer value2 = ByteBufferUtil.bytes(2);
+
+ Restriction slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1);
+ PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice);
+
+ List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.END);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertEmptyComposite(bounds.get(0));
+
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.NONE);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertEmptyComposite(bounds.get(0));
+
+ slice = newMultiSlice(cfMetaData, 0, Bound.END, true, value1);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertEmptyComposite(bounds.get(0));
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.END);
+
+ slice = newMultiSlice(cfMetaData, 0, Bound.END, false, value1);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertEmptyComposite(bounds.get(0));
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.START);
+
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1);
+ Restriction slice2 = newMultiSlice(cfMetaData, 0, Bound.END, false, value2);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.END);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value2, EOC.START);
+
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1);
+ slice2 = newMultiSlice(cfMetaData, 0, Bound.END, true, value2);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.NONE);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value2, EOC.END);
+ }
+
+ /**
+ * Test multi-column slice restrictions (e.g '(clustering_0) > (1)') with only one clustering column in reverse
+ * order
+ */
+ @Test
+ public void testBoundsAsCompositesWithMultiSliceRestrictionsWithOneDescendingClusteringColumn()
+ {
+ CFMetaData cfMetaData = newCFMetaData(Sort.DESC);
+
+ ByteBuffer value1 = ByteBufferUtil.bytes(1);
+ ByteBuffer value2 = ByteBufferUtil.bytes(2);
+
+ Restriction slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1);
+ PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice);
+
+ List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertEmptyComposite(bounds.get(0));
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.START);
+
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertEmptyComposite(bounds.get(0));
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.END);
+
+ slice = newMultiSlice(cfMetaData, 0, Bound.END, true, value1);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.NONE);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertEmptyComposite(bounds.get(0));
+
+ slice = newMultiSlice(cfMetaData, 0, Bound.END, false, value1);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.END);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertEmptyComposite(bounds.get(0));
+
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1);
+ Restriction slice2 = newMultiSlice(cfMetaData, 0, Bound.END, false, value2);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value2, EOC.END);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.START);
+
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1);
+ slice2 = newMultiSlice(cfMetaData, 0, Bound.END, true, value2);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value2, EOC.NONE);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.END);
+ }
+
+ /**
+ * Test multi-column slice restrictions (e.g '(clustering_0, clustering_1) > (1, 2)')
+ */
+ @Test
+ public void testBoundsAsCompositesWithMultiSliceRestrictionsWithTwoClusteringColumn()
+ {
+ CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC);
+
+ ByteBuffer value1 = ByteBufferUtil.bytes(1);
+ ByteBuffer value2 = ByteBufferUtil.bytes(2);
+
+ // (clustering_0, clustering1) > (1, 2)
+ Restriction slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2);
+ PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice);
+
+ List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.END);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertEmptyComposite(bounds.get(0));
+
+ // (clustering_0, clustering1) >= (1, 2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.NONE);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertEmptyComposite(bounds.get(0));
+
+ // (clustering_0, clustering1) <= (1, 2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.END, true, value1, value2);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertEmptyComposite(bounds.get(0));
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.END);
+
+ // (clustering_0, clustering1) < (1, 2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.END, false, value1, value2);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertEmptyComposite(bounds.get(0));
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.START);
+
+ // (clustering_0, clustering1) > (1, 2) AND (clustering_0) < (2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2);
+ Restriction slice2 = newMultiSlice(cfMetaData, 0, Bound.END, false, value2);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.END);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value2, EOC.START);
+
+ // (clustering_0, clustering1) >= (1, 2) AND (clustering_0, clustering1) <= (2, 1)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2);
+ slice2 = newMultiSlice(cfMetaData, 0, Bound.END, true, value2, value1);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.NONE);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value2, value1, EOC.END);
+ }
+
+ /**
+ * Test multi-column slice restrictions with 2 descending clustering columns (e.g '(clustering_0, clustering_1) > (1, 2)')
+ */
+ @Test
+ public void testBoundsAsCompositesWithMultiSliceRestrictionsWithTwoDescendingClusteringColumns()
+ {
+ CFMetaData cfMetaData = newCFMetaData(Sort.DESC, Sort.DESC);
+
+ ByteBuffer value1 = ByteBufferUtil.bytes(1);
+ ByteBuffer value2 = ByteBufferUtil.bytes(2);
+
+ // (clustering_0, clustering1) > (1, 2)
+ Restriction slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2);
+ PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice);
+
+ List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertEmptyComposite(bounds.get(0));
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.START);
+
+ // (clustering_0, clustering1) >= (1, 2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertEmptyComposite(bounds.get(0));
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.END);
+
+ // (clustering_0, clustering1) <= (1, 2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.END, true, value1, value2);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.NONE);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertEmptyComposite(bounds.get(0));
+
+ // (clustering_0, clustering1) < (1, 2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.END, false, value1, value2);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.END);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertEmptyComposite(bounds.get(0));
+
+
+ // (clustering_0, clustering1) > (1, 2) AND (clustering_0) < (2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2);
+ Restriction slice2 = newMultiSlice(cfMetaData, 0, Bound.END, false, value2);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value2, EOC.END);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.START);
+
+ // (clustering_0, clustering1) >= (1, 2) AND (clustering_0, clustering1) <= (2, 1)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2);
+ slice2 = newMultiSlice(cfMetaData, 0, Bound.END, true, value2, value1);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value2, value1, EOC.NONE);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.END);
+ }
+
+ /**
+ * Test multi-column slice restrictions with 1 descending clustering column and 1 ascending
+ * (e.g '(clustering_0, clustering_1) > (1, 2)')
+ */
+ @Test
+ public void testBoundsAsCompositesWithMultiSliceRestrictionsWithOneDescendingAndOneAscendingClusteringColumns()
+ {
+ CFMetaData cfMetaData = newCFMetaData(Sort.DESC, Sort.ASC);
+
+ ByteBuffer value1 = ByteBufferUtil.bytes(1);
+ ByteBuffer value2 = ByteBufferUtil.bytes(2);
+
+ // (clustering_0, clustering1) > (1, 2)
+ Restriction slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2);
+ PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice);
+
+ List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
+ assertEmptyComposite(bounds.get(0));
+ assertComposite(bounds.get(1), value1, value2, EOC.END);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.START);
+ assertComposite(bounds.get(1), value1, EOC.END);
+
+ // (clustering_0, clustering1) >= (1, 2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
+ assertEmptyComposite(bounds.get(0));
+ assertComposite(bounds.get(1), value1, value2, EOC.NONE);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.START);
+ assertComposite(bounds.get(1), value1, EOC.END);
+
+ // (clustering_0, clustering1) <= (1, 2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.END, true, value1, value2);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.START);
+ assertComposite(bounds.get(1), value1, EOC.END);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.END);
+ assertEmptyComposite(bounds.get(1));
+
+ // (clustering_0, clustering1) < (1, 2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.END, false, value1, value2);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.START);
+ assertComposite(bounds.get(1), value1, EOC.END);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.START);
+ assertEmptyComposite(bounds.get(1));
+
+ // (clustering_0, clustering1) > (1, 2) AND (clustering_0) < (2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2);
+ Restriction slice2 = newMultiSlice(cfMetaData, 0, Bound.END, false, value2);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
+ assertComposite(bounds.get(0), value2, EOC.END);
+ assertComposite(bounds.get(1), value1, value2, EOC.END);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.START);
+ assertComposite(bounds.get(1), value1, EOC.END);
+
+ // (clustering_0) > (1) AND (clustering_0, clustering1) < (2, 1)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1);
+ slice2 = newMultiSlice(cfMetaData, 0, Bound.END, false, value2, value1);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
+ assertComposite(bounds.get(0), value2, EOC.START);
+ assertComposite(bounds.get(1), value2, EOC.END);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
+ assertComposite(bounds.get(0), value2, value1, EOC.START);
+ assertComposite(bounds.get(1), value1, EOC.START);
+
+ // (clustering_0, clustering1) >= (1, 2) AND (clustering_0, clustering1) <= (2, 1)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2);
+ slice2 = newMultiSlice(cfMetaData, 0, Bound.END, true, value2, value1);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(3, bounds.size());
+ assertComposite(bounds.get(0), value2, EOC.START);
+ assertComposite(bounds.get(1), value2, EOC.END);
+ assertComposite(bounds.get(2), value1, value2, EOC.NONE);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(3, bounds.size());
+ assertComposite(bounds.get(0), value2, value1, EOC.END);
+ assertComposite(bounds.get(1), value1, EOC.START);
+ assertComposite(bounds.get(2), value1, EOC.END);
+ }
+
+ /**
+ * Test multi-column slice restrictions with 1 descending clustering column and 1 ascending
+ * (e.g '(clustering_0, clustering_1) > (1, 2)')
+ */
+ @Test
+ public void testBoundsAsCompositesWithMultiSliceRestrictionsWithOneAscendingAndOneDescendingClusteringColumns()
+ {
+ CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.DESC);
+
+ ByteBuffer value1 = ByteBufferUtil.bytes(1);
+ ByteBuffer value2 = ByteBufferUtil.bytes(2);
+
+ // (clustering_0, clustering1) > (1, 2)
+ Restriction slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2);
+ PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice);
+
+ List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.START);
+ assertComposite(bounds.get(1), value1, EOC.END);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.START);
+ assertEmptyComposite(bounds.get(1));
+
+ // (clustering_0, clustering1) >= (1, 2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.START);
+ assertComposite(bounds.get(1), value1, EOC.END);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.END);
+ assertEmptyComposite(bounds.get(1));
- slice = newSingleSlice(cfMetaData, 1, Bound.END, true, value1);
+ // (clustering_0, clustering1) <= (1, 2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.END, true, value1, value2);
restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
- restrictions = restrictions.mergeWith(eq).mergeWith(slice);
+ restrictions = restrictions.mergeWith(slice);
bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value3, EOC.START);
+ assertEquals(2, bounds.size());
+ assertEmptyComposite(bounds.get(0));
+ assertComposite(bounds.get(1), value1, value2, EOC.NONE);
bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value3, value1, EOC.END);
+ assertEquals(2, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.START);
+ assertComposite(bounds.get(1), value1, EOC.END);
- slice = newSingleSlice(cfMetaData, 1, Bound.END, false, value1);
+ // (clustering_0, clustering1) < (1, 2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.END, false, value1, value2);
restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
- restrictions = restrictions.mergeWith(eq).mergeWith(slice);
+ restrictions = restrictions.mergeWith(slice);
bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value3, EOC.START);
+ assertEquals(2, bounds.size());
+ assertEmptyComposite(bounds.get(0));
+ assertComposite(bounds.get(1), value1, value2, EOC.END);
bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value3, value1, EOC.START);
+ assertEquals(2, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.START);
+ assertComposite(bounds.get(1), value1, EOC.END);
- slice = newSingleSlice(cfMetaData, 1, Bound.START, false, value1);
- Restriction slice2 = newSingleSlice(cfMetaData, 1, Bound.END, false, value2);
+ // (clustering_0, clustering1) > (1, 2) AND (clustering_0) < (2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2);
+ Restriction slice2 = newMultiSlice(cfMetaData, 0, Bound.END, false, value2);
restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
- restrictions = restrictions.mergeWith(eq).mergeWith(slice).mergeWith(slice2);
+ restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value3, value1, EOC.END);
+ assertEquals(2, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.START);
+ assertComposite(bounds.get(1), value1, EOC.END);
bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value3, value2, EOC.START);
+ assertEquals(2, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.START);
+ assertComposite(bounds.get(1), value2, EOC.START);
- slice = newSingleSlice(cfMetaData, 1, Bound.START, true, value1);
- slice2 = newSingleSlice(cfMetaData, 1, Bound.END, true, value2);
+ // (clustering_0, clustering1) >= (1, 2) AND (clustering_0, clustering1) <= (2, 1)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2);
+ slice2 = newMultiSlice(cfMetaData, 0, Bound.END, true, value2, value1);
restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
- restrictions = restrictions.mergeWith(eq).mergeWith(slice).mergeWith(slice2);
+ restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value3, value1, EOC.NONE);
+ assertEquals(3, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.START);
+ assertComposite(bounds.get(1), value1, EOC.END);
+ assertComposite(bounds.get(2), value2, value1, EOC.NONE);
bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value3, value2, EOC.END);
+ assertEquals(3, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.END);
+ assertComposite(bounds.get(1), value2, EOC.START);
+ assertComposite(bounds.get(2), value2, EOC.END);
}
/**
- * Test '(clustering_0, clustering_1) = (1, 2)' with two clustering column
+ * Test multi-column slice restrictions with 2 ascending clustering column and 2 descending
+ * (e.g '(clustering_0, clustering1, clustering_3, clustering4) > (1, 2, 3, 4)')
*/
@Test
- public void testBoundsAsCompositesWithMultiEqRestrictions() throws InvalidRequestException
+ public void testBoundsAsCompositesWithMultiSliceRestrictionsWithTwoAscendingAndTwoDescendingClusteringColumns()
{
- CFMetaData cfMetaData = newCFMetaData(2);
+ CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC, Sort.DESC, Sort.DESC);
ByteBuffer value1 = ByteBufferUtil.bytes(1);
ByteBuffer value2 = ByteBufferUtil.bytes(2);
- Restriction eq = newMultiEq(cfMetaData, 0, value1, value2);
+ ByteBuffer value3 = ByteBufferUtil.bytes(3);
+ ByteBuffer value4 = ByteBufferUtil.bytes(4);
+
+ // (clustering_0, clustering1, clustering_2, clustering_3) > (1, 2, 3, 4)
+ Restriction slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2, value3, value4);
PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
- restrictions = restrictions.mergeWith(eq);
+ restrictions = restrictions.mergeWith(slice);
List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
+ assertEquals(2, bounds.size());
assertComposite(bounds.get(0), value1, value2, EOC.START);
+ assertComposite(bounds.get(1), value1, value2, EOC.END);
bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.END);
- }
-
- /**
- * Test '(clustering_0, clustering_1) IN ((1, 2), (2, 3))' with two clustering column
- */
- @Test
- public void testBoundsAsCompositesWithMultiInRestrictions() throws InvalidRequestException
- {
- CFMetaData cfMetaData = newCFMetaData(2);
+ assertEquals(2, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, value3, value4, EOC.START);
+ assertEmptyComposite(bounds.get(1));
- ByteBuffer value1 = ByteBufferUtil.bytes(1);
- ByteBuffer value2 = ByteBufferUtil.bytes(2);
- ByteBuffer value3 = ByteBufferUtil.bytes(3);
- Restriction in = newMultiIN(cfMetaData, 0, asList(value1, value2), asList(value2, value3));
- PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
- restrictions = restrictions.mergeWith(in);
+ // clustering_0 = 1 AND (clustering_1, clustering_2, clustering_3) > (2, 3, 4)
+ Restriction eq = newSingleEq(cfMetaData, 0, value1);
+ slice = newMultiSlice(cfMetaData, 1, Bound.START, false, value2, value3, value4);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice);
+ restrictions = restrictions.mergeWith(eq);
- List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
assertEquals(2, bounds.size());
assertComposite(bounds.get(0), value1, value2, EOC.START);
- assertComposite(bounds.get(1), value2, value3, EOC.START);
+ assertComposite(bounds.get(1), value1, value2, EOC.END);
bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
assertEquals(2, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.END);
- assertComposite(bounds.get(1), value2, value3, EOC.END);
- }
+ assertComposite(bounds.get(0), value1, value2, value3, value4, EOC.START);
+ assertComposite(bounds.get(1), value1, EOC.END);
- /**
- * Test multi-column slice restrictions (e.g '(clustering_0) > (1)') with only one clustering column
- */
- @Test
- public void testBoundsAsCompositesWithMultiSliceRestrictionsWithOneClusteringColumn() throws InvalidRequestException
- {
- CFMetaData cfMetaData = newCFMetaData(1);
+ // clustering_0 = 1 AND (clustering_1, clustering_2, clustering_3) > (2, 3, 4)
+ Restriction in = newSingleIN(cfMetaData, 0, value1, value2);
+ slice = newMultiSlice(cfMetaData, 1, Bound.START, false, value2, value3, value4);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice);
+ restrictions = restrictions.mergeWith(in);
- ByteBuffer value1 = ByteBufferUtil.bytes(1);
- ByteBuffer value2 = ByteBufferUtil.bytes(2);
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(4, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.START);
+ assertComposite(bounds.get(1), value1, value2, EOC.END);
+ assertComposite(bounds.get(2), value2, value2, EOC.START);
+ assertComposite(bounds.get(3), value2, value2, EOC.END);
- Restriction slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1);
- PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(4, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, value3, value4, EOC.START);
+ assertComposite(bounds.get(1), value1, EOC.END);
+ assertComposite(bounds.get(2), value2, value2, value3, value4, EOC.START);
+ assertComposite(bounds.get(3), value2, EOC.END);
+
+ // (clustering_0, clustering1) >= (1, 2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
restrictions = restrictions.mergeWith(slice);
- List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.END);
+ assertComposite(bounds.get(0), value1, value2, EOC.NONE);
bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
assertEquals(1, bounds.size());
assertEmptyComposite(bounds.get(0));
- slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1);
+ // (clustering_0, clustering1, clustering_2, clustering_3) >= (1, 2, 3, 4)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2, value3, value4);
restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
restrictions = restrictions.mergeWith(slice);
bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.NONE);
+ assertEquals(2, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.START);
+ assertComposite(bounds.get(1), value1, value2, EOC.END);
bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertEmptyComposite(bounds.get(0));
+ assertEquals(2, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, value3, value4, EOC.END);
+ assertEmptyComposite(bounds.get(1));
- slice = newMultiSlice(cfMetaData, 0, Bound.END, true, value1);
+ // (clustering_0, clustering1, clustering_2, clustering_3) <= (1, 2, 3, 4)
+ slice = newMultiSlice(cfMetaData, 0, Bound.END, true, value1, value2, value3, value4);
restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
restrictions = restrictions.mergeWith(slice);
bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
+ assertEquals(2, bounds.size());
assertEmptyComposite(bounds.get(0));
+ assertComposite(bounds.get(1), value1, value2, value3, value4, EOC.NONE);
bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.END);
+ assertEquals(2, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.START);
+ assertComposite(bounds.get(1), value1, value2, EOC.END);
- slice = newMultiSlice(cfMetaData, 0, Bound.END, false, value1);
+ // (clustering_0, clustering1, clustering_2, clustering_3) < (1, 2, 3, 4)
+ slice = newMultiSlice(cfMetaData, 0, Bound.END, false, value1, value2, value3, value4);
restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
restrictions = restrictions.mergeWith(slice);
bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
+ assertEquals(2, bounds.size());
assertEmptyComposite(bounds.get(0));
+ assertComposite(bounds.get(1), value1, value2, value3, value4, EOC.END);
bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.START);
+ assertEquals(2, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.START);
+ assertComposite(bounds.get(1), value1, value2, EOC.END);
- slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1);
- Restriction slice2 = newMultiSlice(cfMetaData, 0, Bound.END, false, value2);
+ // (clustering_0, clustering1, clustering_2, clustering_3) > (1, 2, 3, 4) AND (clustering_0, clustering_1) < (2, 3)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2, value3, value4);
+ Restriction slice2 = newMultiSlice(cfMetaData, 0, Bound.END, false, value2, value3);
restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.END);
+ assertEquals(2, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.START);
+ assertComposite(bounds.get(1), value1, value2, EOC.END);
bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value2, EOC.START);
+ assertEquals(2, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, value3, value4, EOC.START);
+ assertComposite(bounds.get(1), value2, value3, EOC.START);
- slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1);
- slice2 = newMultiSlice(cfMetaData, 0, Bound.END, true, value2);
+ // (clustering_0, clustering1, clustering_2, clustering_3) >= (1, 2, 3, 4) AND (clustering_0, clustering1, clustering_2, clustering_3) <= (4, 3, 2, 1)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2, value3, value4);
+ slice2 = newMultiSlice(cfMetaData, 0, Bound.END, true, value4, value3, value2, value1);
restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.NONE);
+ assertEquals(3, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.START);
+ assertComposite(bounds.get(1), value1, value2, EOC.END);
+ assertComposite(bounds.get(2), value4, value3, value2, value1, EOC.NONE);
bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value2, EOC.END);
+ assertEquals(3, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, value3, value4, EOC.END);
+ assertComposite(bounds.get(1), value4, value3, EOC.START);
+ assertComposite(bounds.get(2), value4, value3, EOC.END);
}
/**
- * Test multi-column slice restrictions (e.g '(clustering_0, clustering_1) > (1, 2)')
+ * Test multi-column slice restrictions with ascending, descending, ascending and descending columns
+ * (e.g '(clustering_0, clustering1, clustering_3, clustering4) > (1, 2, 3, 4)')
*/
@Test
- public void testBoundsAsCompositesWithMultiSliceRestrictionsWithTwoClusteringColumn() throws InvalidRequestException
+ public void testBoundsAsCompositesWithMultiSliceRestrictionsMixingAscendingDescendingClusteringColumns()
{
- CFMetaData cfMetaData = newCFMetaData(2);
+ CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.DESC, Sort.ASC, Sort.DESC);
ByteBuffer value1 = ByteBufferUtil.bytes(1);
ByteBuffer value2 = ByteBufferUtil.bytes(2);
+ ByteBuffer value3 = ByteBufferUtil.bytes(3);
+ ByteBuffer value4 = ByteBufferUtil.bytes(4);
- // (clustering_0, clustering1) > (1, 2)
- Restriction slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2);
+ // (clustering_0, clustering1, clustering_2, clustering_3) > (1, 2, 3, 4)
+ Restriction slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2, value3, value4);
PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
restrictions = restrictions.mergeWith(slice);
List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.END);
+ assertEquals(4, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.START);
+ assertComposite(bounds.get(1), value1, value2, value3, EOC.START);
+ assertComposite(bounds.get(2), value1, value2, value3, EOC.END);
+ assertComposite(bounds.get(3), value1, EOC.END);
+
bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertEmptyComposite(bounds.get(0));
+ assertEquals(4, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.START);
+ assertComposite(bounds.get(1), value1, value2, value3, value4, EOC.START);
+ assertComposite(bounds.get(2), value1, value2, EOC.END);
+ assertEmptyComposite(bounds.get(3));
+
+ // clustering_0 = 1 AND (clustering_1, clustering_2, clustering_3) > (2, 3, 4)
+ Restriction eq = newSingleEq(cfMetaData, 0, value1);
+ slice = newMultiSlice(cfMetaData, 1, Bound.START, false, value2, value3, value4);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice);
+ restrictions = restrictions.mergeWith(eq);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(3, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.START);
+ assertComposite(bounds.get(1), value1, value2, value3, EOC.START);
+ assertComposite(bounds.get(2), value1, value2, value3, EOC.END);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(3, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.START);
+ assertComposite(bounds.get(1), value1, value2, value3, value4, EOC.START);
+ assertComposite(bounds.get(2), value1, value2, EOC.END);
// (clustering_0, clustering1) >= (1, 2)
slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2);
@@ -505,75 +1281,129 @@ public class PrimaryKeyRestrictionSetTest
restrictions = restrictions.mergeWith(slice);
bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.NONE);
+ assertEquals(2, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.START);
+ assertComposite(bounds.get(1), value1, EOC.END);
bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertEmptyComposite(bounds.get(0));
+ assertEquals(2, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.END);
+ assertEmptyComposite(bounds.get(1));
- // (clustering_0, clustering1) <= (1, 2)
- slice = newMultiSlice(cfMetaData, 0, Bound.END, true, value1, value2);
+ // (clustering_0, clustering1, clustering_2, clustering_3) >= (1, 2, 3, 4)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2, value3, value4);
restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
restrictions = restrictions.mergeWith(slice);
bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
+ assertEquals(4, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.START);
+ assertComposite(bounds.get(1), value1, value2, value3, EOC.START);
+ assertComposite(bounds.get(2), value1, value2, value3, EOC.END);
+ assertComposite(bounds.get(3), value1, EOC.END);
+
+ bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(4, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.START);
+ assertComposite(bounds.get(1), value1, value2, value3, value4, EOC.END);
+ assertComposite(bounds.get(2), value1, value2, EOC.END);
+ assertEmptyComposite(bounds.get(3));
+
+
+ // (clustering_0, clustering1, clustering_2, clustering_3) <= (1, 2, 3, 4)
+ slice = newMultiSlice(cfMetaData, 0, Bound.END, true, value1, value2, value3, value4);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = restrictions.mergeWith(slice);
+
+ bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(4, bounds.size());
assertEmptyComposite(bounds.get(0));
+ assertComposite(bounds.get(1), value1, value2, EOC.START);
+ assertComposite(bounds.get(2), value1, value2, value3, value4, EOC.NONE);
+ assertComposite(bounds.get(3), value1, value2, EOC.END);
bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.END);
+ assertEquals(4, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.START);
+ assertComposite(bounds.get(1), value1, value2, value3, EOC.START);
+ assertComposite(bounds.get(2), value1, value2, value3, EOC.END);
+ assertComposite(bounds.get(3), value1, EOC.END);
- // (clustering_0, clustering1) < (1, 2)
- slice = newMultiSlice(cfMetaData, 0, Bound.END, false, value1, value2);
+ // (clustering_0, clustering1, clustering_2, clustering_3) < (1, 2, 3, 4)
+ slice = newMultiSlice(cfMetaData, 0, Bound.END, false, value1, value2, value3, value4);
restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
restrictions = restrictions.mergeWith(slice);
bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
+ assertEquals(4, bounds.size());
assertEmptyComposite(bounds.get(0));
+ assertComposite(bounds.get(1), value1, value2, EOC.START);
+ assertComposite(bounds.get(2), value1, value2, value3, value4, EOC.END);
+ assertComposite(bounds.get(3), value1, value2, EOC.END);
bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.START);
+ assertEquals(4, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.START);
+ assertComposite(bounds.get(1), value1, value2, value3, EOC.START);
+ assertComposite(bounds.get(2), value1, value2, value3, EOC.END);
+ assertComposite(bounds.get(3), value1, EOC.END);
- // (clustering_0, clustering1) > (1, 2) AND (clustering_0) < (2)
- slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2);
- Restriction slice2 = newMultiSlice(cfMetaData, 0, Bound.END, false, value2);
+ // (clustering_0, clustering1, clustering_2, clustering_3) > (1, 2, 3, 4) AND (clustering_0, clustering_1) < (2, 3)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2, value3, value4);
+ Restriction slice2 = newMultiSlice(cfMetaData, 0, Bound.END, false, value2, value3);
restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.END);
+ assertEquals(5, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.START);
+ assertComposite(bounds.get(1), value1, value2, value3, EOC.START);
+ assertComposite(bounds.get(2), value1, value2, value3, EOC.END);
+ assertComposite(bounds.get(3), value1, EOC.END);
+ assertComposite(bounds.get(4), value2, value3, EOC.END);
bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value2, EOC.START);
-
- // (clustering_0, clustering1) >= (1, 2) AND (clustering_0, clustering1) <= (2, 1)
- slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2);
- slice2 = newMultiSlice(cfMetaData, 0, Bound.END, true, value2, value1);
+ assertEquals(5, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.START);
+ assertComposite(bounds.get(1), value1, value2, value3, value4, EOC.START);
+ assertComposite(bounds.get(2), value1, value2, EOC.END);
+ assertComposite(bounds.get(3), value2, EOC.START);
+ assertComposite(bounds.get(4), value2, EOC.END);
+
+ // (clustering_0, clustering1, clustering_2, clustering_3) >= (1, 2, 3, 4) AND (clustering_0, clustering1, clustering_2, clustering_3) <= (4, 3, 2, 1)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2, value3, value4);
+ slice2 = newMultiSlice(cfMetaData, 0, Bound.END, true, value4, value3, value2, value1);
restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.NONE);
+ assertEquals(7, bounds.size());
+ assertComposite(bounds.get(0), value1, EOC.START);
+ assertComposite(bounds.get(1), value1, value2, value3, EOC.START);
+ assertComposite(bounds.get(2), value1, value2, value3, EOC.END);
+ assertComposite(bounds.get(3), value1, EOC.END);
+ assertComposite(bounds.get(4), value4, value3, EOC.START);
+ assertComposite(bounds.get(5), value4, value3, value2, value1, EOC.NONE);
+ assertComposite(bounds.get(6), value4, value3, EOC.END);
bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value2, value1, EOC.END);
+ assertEquals(7, bounds.size());
+ assertComposite(bounds.get(0), value1, value2, EOC.START);
+ assertComposite(bounds.get(1), value1, value2, value3, value4, EOC.END);
+ assertComposite(bounds.get(2), value1, value2, EOC.END);
+ assertComposite(bounds.get(3), value4, EOC.START);
+ assertComposite(bounds.get(4), value4, value3, value2, EOC.START);
+ assertComposite(bounds.get(5), value4, value3, value2, EOC.END);
+ assertComposite(bounds.get(6), value4, EOC.END);
}
/**
* Test mixing single and multi equals restrictions (e.g. clustering_0 = 1 AND (clustering_1, clustering_2) = (2, 3))
*/
@Test
- public void testBoundsAsCompositesWithSingleEqAndMultiEqRestrictions() throws InvalidRequestException
+ public void testBoundsAsCompositesWithSingleEqAndMultiEqRestrictions()
{
- CFMetaData cfMetaData = newCFMetaData(4);
+ CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC, Sort.ASC, Sort.ASC);
ByteBuffer value1 = ByteBufferUtil.bytes(1);
ByteBuffer value2 = ByteBufferUtil.bytes(2);
@@ -643,9 +1473,9 @@ public class PrimaryKeyRestrictionSetTest
* Test clustering_0 = 1 AND (clustering_1, clustering_2) IN ((2, 3), (4, 5))
*/
@Test
- public void testBoundsAsCompositesWithSingleEqAndMultiINRestrictions() throws InvalidRequestException
+ public void testBoundsAsCompositesWithSingleEqAndMultiINRestrictions()
{
- CFMetaData cfMetaData = newCFMetaData(4);
+ CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC, Sort.ASC, Sort.ASC);
ByteBuffer value1 = ByteBufferUtil.bytes(1);
ByteBuffer value2 = ByteBufferUtil.bytes(2);
@@ -706,9 +1536,9 @@ public class PrimaryKeyRestrictionSetTest
* (e.g. clustering_0 = 1 AND (clustering_1, clustering_2) > (2, 3))
*/
@Test
- public void testBoundsAsCompositesWithSingleEqAndSliceRestrictions() throws InvalidRequestException
+ public void testBoundsAsCompositesWithSingleEqAndSliceRestrictions()
{
- CFMetaData cfMetaData = newCFMetaData(3);
+ CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC, Sort.ASC);
ByteBuffer value1 = ByteBufferUtil.bytes(1);
ByteBuffer value2 = ByteBufferUtil.bytes(2);
@@ -766,9 +1596,9 @@ public class PrimaryKeyRestrictionSetTest
* (e.g. clustering_0 = 1 AND (clustering_1, clustering_2) > (2, 3))
*/
@Test
- public void testBoundsAsCompositesWithMultiEqAndSingleSliceRestrictions() throws InvalidRequestException
+ public void testBoundsAsCompositesWithMultiEqAndSingleSliceRestrictions()
{
- CFMetaData cfMetaData = newCFMetaData(3);
+ CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC, Sort.ASC);
ByteBuffer value1 = ByteBufferUtil.bytes(1);
ByteBuffer value2 = ByteBufferUtil.bytes(2);
@@ -790,9 +1620,9 @@ public class PrimaryKeyRestrictionSetTest
}
@Test
- public void testBoundsAsCompositesWithSeveralMultiColumnRestrictions() throws InvalidRequestException
+ public void testBoundsAsCompositesWithSeveralMultiColumnRestrictions()
{
- CFMetaData cfMetaData = newCFMetaData(4);
+ CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC, Sort.ASC, Sort.ASC);
ByteBuffer value1 = ByteBufferUtil.bytes(1);
ByteBuffer value2 = ByteBufferUtil.bytes(2);
@@ -852,7 +1682,7 @@ public class PrimaryKeyRestrictionSetTest
*/
private static void assertEmptyComposite(Composite composite)
{
- assertEquals(Composites.EMPTY, composite);
+ assertTrue(composite.isEmpty());
}
/**
@@ -947,20 +1777,20 @@ public class PrimaryKeyRestrictionSetTest
* @param numberOfClusteringColumns the number of clustering column
* @return a new <code>CFMetaData</code> instance
*/
- private static CFMetaData newCFMetaData(int numberOfClusteringColumns)
+ private static CFMetaData newCFMetaData(Sort... sorts)
{
List<AbstractType<?>> types = new ArrayList<>();
- for (int i = 0; i < numberOfClusteringColumns; i++)
- types.add(Int32Type.instance);
+ for (Sort sort : sorts)
+ types.add(sort == Sort.ASC ? Int32Type.instance : ReversedType.getInstance(Int32Type.instance));
CompoundSparseCellNameType cType = new CompoundSparseCellNameType(types);
CFMetaData cfMetaData = new CFMetaData("keyspace", "test", ColumnFamilyType.Standard, cType);
- for (int i = 0; i < numberOfClusteringColumns; i++)
+ for (int i = 0; i < sorts.length; i++)
{
ByteBuffer name = ByteBufferUtil.bytes("clustering_" + i);
- ColumnDefinition columnDef = ColumnDefinition.clusteringKeyDef(cfMetaData, name, Int32Type.instance, i);
+ ColumnDefinition columnDef = ColumnDefinition.clusteringKeyDef(cfMetaData, name, types.get(i), i);
cfMetaData.addColumnDefinition(columnDef);
}
cfMetaData.rebuild();
@@ -1117,4 +1947,10 @@ public class PrimaryKeyRestrictionSetTest
terms.add(toTerm(value));
return terms;
}
+
+ private static enum Sort
+ {
+ ASC,
+ DESC;
+ }
}
[5/6] cassandra git commit: Merge branch cassandra-2.2 into
cassandra-3.0
Posted by bl...@apache.org.
Merge branch cassandra-2.2 into cassandra-3.0
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/1aa97e30
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/1aa97e30
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/1aa97e30
Branch: refs/heads/trunk
Commit: 1aa97e30ca075ad3c350d1b49aee94dffc62db19
Parents: 62f94b7 90fc896
Author: Benjamin Lerer <b....@gmail.com>
Authored: Thu Feb 11 10:40:50 2016 +0100
Committer: Benjamin Lerer <b....@gmail.com>
Committed: Thu Feb 11 10:42:17 2016 +0100
----------------------------------------------------------------------
CHANGES.txt | 1 +
.../cql3/restrictions/AbstractRestriction.java | 14 +
.../ForwardingPrimaryKeyRestrictions.java | 3 +-
.../restrictions/MultiColumnRestriction.java | 76 +-
.../restrictions/PrimaryKeyRestrictionSet.java | 22 +-
.../cql3/restrictions/Restriction.java | 4 +-
.../cql3/restrictions/RestrictionSet.java | 4 +-
.../restrictions/SingleColumnRestriction.java | 9 +-
.../cql3/restrictions/TokenRestriction.java | 2 +-
.../org/apache/cassandra/db/MultiCBuilder.java | 67 +-
.../PrimaryKeyRestrictionSetTest.java | 1174 +++++++++++++++---
.../SelectMultiColumnRelationTest.java | 859 ++++++++++++-
12 files changed, 2025 insertions(+), 210 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/1aa97e30/CHANGES.txt
----------------------------------------------------------------------
diff --cc CHANGES.txt
index 188cdd6,5674b9d..bca5fcd
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@@ -1,12 -1,5 +1,13 @@@
-2.2.6
+3.0.4
+ * AssertionError when listing sstable files on inconsistent disk state (CASSANDRA-11156)
+ * Fix wrong rack counting and invalid conditions check for TokenAllocation
+ (CASSANDRA-11139)
+ * Avoid creating empty hint files (CASSANDRA-11090)
+ * Fix leak detection strong reference loop using weak reference (CASSANDRA-11120)
+ * Configurie BatchlogManager to stop delayed tasks on shutdown (CASSANDRA-11062)
+ * Hadoop integration is incompatible with Cassandra Driver 3.0.0 (CASSANDRA-11001)
+Merged from 2.2.6:
+ * Fix SELECT on tuple relations for mixed ASC/DESC clustering order (CASSANDRA-7281)
* (cqlsh) Support utf-8/cp65001 encoding on Windows (CASSANDRA-11030)
* Fix paging on DISTINCT queries repeats result when first row in partition changes (CASSANDRA-10010)
Merged from 2.1:
http://git-wip-us.apache.org/repos/asf/cassandra/blob/1aa97e30/src/java/org/apache/cassandra/cql3/restrictions/AbstractRestriction.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/restrictions/AbstractRestriction.java
index 023c2ac,dac7203..df04331
--- a/src/java/org/apache/cassandra/cql3/restrictions/AbstractRestriction.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/AbstractRestriction.java
@@@ -17,10 -17,19 +17,12 @@@
*/
package org.apache.cassandra.cql3.restrictions;
-import java.nio.ByteBuffer;
-
-import org.apache.cassandra.config.ColumnDefinition;
-
-import org.apache.cassandra.cql3.ColumnSpecification;
import org.apache.cassandra.cql3.QueryOptions;
import org.apache.cassandra.cql3.statements.Bound;
-import org.apache.cassandra.db.composites.CompositesBuilder;
-import org.apache.cassandra.exceptions.InvalidRequestException;
-import static org.apache.cassandra.cql3.statements.RequestValidations.checkBindValueSet;
-import static org.apache.cassandra.cql3.statements.RequestValidations.checkFalse;
-import static org.apache.cassandra.cql3.statements.RequestValidations.checkNotNull;
+import org.apache.cassandra.db.MultiCBuilder;
+
++import org.apache.cassandra.config.ColumnDefinition;
+
/**
* Base class for <code>Restriction</code>s
*/
@@@ -85,4 -88,26 +87,16 @@@ abstract class AbstractRestriction imp
{
return true;
}
+
- protected static ByteBuffer validateIndexedValue(ColumnSpecification columnSpec,
- ByteBuffer value)
- throws InvalidRequestException
- {
- checkNotNull(value, "Unsupported null value for indexed column %s", columnSpec.name);
- checkBindValueSet(value, "Unsupported unset value for indexed column %s", columnSpec.name);
- checkFalse(value.remaining() > 0xFFFF, "Index expression values may not be larger than 64K");
- return value;
- }
-
+ /**
+ * Reverses the specified bound if the column type is a reversed one.
+ *
+ * @param columnDefinition the column definition
+ * @param bound the bound
+ * @return the bound reversed if the column type was a reversed one or the original bound
+ */
+ protected static Bound reverseBoundIfNeeded(ColumnDefinition columnDefinition, Bound bound)
+ {
+ return columnDefinition.isReversedType() ? bound.reverse() : bound;
+ }
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/1aa97e30/src/java/org/apache/cassandra/cql3/restrictions/ForwardingPrimaryKeyRestrictions.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/restrictions/ForwardingPrimaryKeyRestrictions.java
index 18e7105,71855a0..723ebc3
--- a/src/java/org/apache/cassandra/cql3/restrictions/ForwardingPrimaryKeyRestrictions.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/ForwardingPrimaryKeyRestrictions.java
@@@ -18,9 -18,7 +18,8 @@@
package org.apache.cassandra.cql3.restrictions;
import java.nio.ByteBuffer;
- import java.util.Collection;
import java.util.List;
+import java.util.NavigableSet;
import org.apache.cassandra.config.ColumnDefinition;
import org.apache.cassandra.cql3.QueryOptions;
http://git-wip-us.apache.org/repos/asf/cassandra/blob/1aa97e30/src/java/org/apache/cassandra/cql3/restrictions/MultiColumnRestriction.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/restrictions/MultiColumnRestriction.java
index 069a01b,96e6f2b..ec02d06
--- a/src/java/org/apache/cassandra/cql3/restrictions/MultiColumnRestriction.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/MultiColumnRestriction.java
@@@ -357,16 -357,64 +357,64 @@@ public abstract class MultiColumnRestri
}
@Override
- public CompositesBuilder appendBoundTo(CompositesBuilder builder, Bound bound, QueryOptions options)
+ public MultiCBuilder appendBoundTo(MultiCBuilder builder, Bound bound, QueryOptions options)
{
- List<ByteBuffer> vals = componentBounds(bound, options);
+ boolean reversed = getFirstColumn().isReversedType();
- for (int i = 0, m = vals.size(); i < m; i++)
+ EnumMap<Bound, List<ByteBuffer>> componentBounds = new EnumMap<Bound, List<ByteBuffer>>(Bound.class);
+ componentBounds.put(Bound.START, componentBounds(Bound.START, options));
+ componentBounds.put(Bound.END, componentBounds(Bound.END, options));
+
+ List<List<ByteBuffer>> toAdd = new ArrayList<>();
+ List<ByteBuffer> values = new ArrayList<>();
+
+ for (int i = 0, m = columnDefs.size(); i < m; i++)
{
- ByteBuffer v = checkNotNull(vals.get(i), "Invalid null value in condition for column %s", columnDefs.get(i).name);
- builder.addElementToAll(v);
+ ColumnDefinition column = columnDefs.get(i);
+ Bound b = reverseBoundIfNeeded(column, bound);
+
+ // For mixed order columns, we need to create additional slices when 2 columns are in reverse order
+ if (reversed != column.isReversedType())
+ {
+ reversed = column.isReversedType();
+ // As we are switching direction we need to add the current composite
+ toAdd.add(values);
+
+ // The new bound side has no value for this component. just stop
+ if (!hasComponent(b, i, componentBounds))
+ continue;
+
+ // The other side has still some components. We need to end the slice that we have just open.
+ if (hasComponent(b.reverse(), i, componentBounds))
+ toAdd.add(values);
+
+ // We need to rebuild where we are in this bound side
+ values = new ArrayList<ByteBuffer>();
+
+ List<ByteBuffer> vals = componentBounds.get(b);
+
+ int n = Math.min(i, vals.size());
+ for (int j = 0; j < n; j++)
+ {
+ ByteBuffer v = checkNotNull(vals.get(j),
+ "Invalid null value in condition for column %s",
+ columnDefs.get(j).name);
+ values.add(v);
+ }
+ }
+
+ if (!hasComponent(b, i, componentBounds))
+ continue;
+
+ ByteBuffer v = checkNotNull(componentBounds.get(b).get(i), "Invalid null value in condition for column %s", columnDefs.get(i).name);
+ values.add(v);
}
- return builder;
+ toAdd.add(values);
+
+ if (bound.isEnd())
+ Collections.reverse(toAdd);
+
+ return builder.addAllElementsToAll(toAdd);
}
@Override
@@@ -458,60 -506,10 +509,65 @@@
return Collections.singletonList(terminal.get(options.getProtocolVersion()));
}
+
+ private boolean hasComponent(Bound b, int index, EnumMap<Bound, List<ByteBuffer>> componentBounds)
+ {
+ return componentBounds.get(b).size() > index;
+ }
}
+
+ public static class NotNullRestriction extends MultiColumnRestriction
+ {
+ public NotNullRestriction(List<ColumnDefinition> columnDefs)
+ {
+ super(columnDefs);
+ assert columnDefs.size() == 1;
+ }
+
+ @Override
+ public Iterable<Function> getFunctions()
+ {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public boolean isNotNull()
+ {
+ return true;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "IS NOT NULL";
+ }
+
+ @Override
+ public Restriction doMergeWith(Restriction otherRestriction) throws InvalidRequestException
+ {
+ throw invalidRequest("%s cannot be restricted by a relation if it includes an IS NOT NULL clause",
+ getColumnsInCommons(otherRestriction));
+ }
+
+ @Override
+ protected boolean isSupportedBy(Index index)
+ {
+ for(ColumnDefinition column : columnDefs)
+ if (index.supportsExpression(column, Operator.IS_NOT))
+ return true;
+ return false;
+ }
+
+ @Override
+ public MultiCBuilder appendTo(MultiCBuilder builder, QueryOptions options)
+ {
+ throw new UnsupportedOperationException("Cannot use IS NOT NULL restriction for slicing");
+ }
+
+ @Override
+ public final void addRowFilterTo(RowFilter filter, SecondaryIndexManager indexMananger, QueryOptions options) throws InvalidRequestException
+ {
+ throw new UnsupportedOperationException("Secondary indexes do not support IS NOT NULL restrictions");
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/1aa97e30/src/java/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSet.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSet.java
index 107cbd1,936dbd6..8121858
--- a/src/java/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSet.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSet.java
@@@ -216,22 -200,14 +213,17 @@@ final class PrimaryKeyRestrictionSet ex
if (r.isSlice())
{
- if (!r.hasBound(b))
- {
- // There wasn't any non EQ relation on that key, we select all records having the preceding component as prefix.
- // For composites, if there was preceding component and we're computing the end, we must change the last component
- // End-Of-Component, otherwise we would be selecting only one record.
- return builder.buildBound(bound.isStart(), true);
- }
-
- r.appendBoundTo(builder, b, options);
- return builder.buildBound(bound.isStart(), r.isInclusive(b));
+ r.appendBoundTo(builder, bound, options);
- return filterAndSort(setEocs(r, bound, builder.build()));
++ return builder.buildBoundForSlice(bound.isStart(),
++ r.isInclusive(bound),
++ r.isInclusive(bound.reverse()),
++ r.getColumnDefs());
}
- r.appendBoundTo(builder, b, options);
+ r.appendBoundTo(builder, bound, options);
if (builder.hasMissingElements())
- return Collections.emptyList();
+ return BTreeSet.empty(comparator);
keyPosition = r.getLastColumn().position() + 1;
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/1aa97e30/src/java/org/apache/cassandra/cql3/restrictions/Restriction.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/1aa97e30/src/java/org/apache/cassandra/cql3/restrictions/RestrictionSet.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/1aa97e30/src/java/org/apache/cassandra/cql3/restrictions/SingleColumnRestriction.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/restrictions/SingleColumnRestriction.java
index d851253,735a2e2..3a61616
--- a/src/java/org/apache/cassandra/cql3/restrictions/SingleColumnRestriction.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/SingleColumnRestriction.java
@@@ -350,9 -349,14 +350,14 @@@ public abstract class SingleColumnRestr
}
@Override
- public CompositesBuilder appendBoundTo(CompositesBuilder builder, Bound bound, QueryOptions options)
+ public MultiCBuilder appendBoundTo(MultiCBuilder builder, Bound bound, QueryOptions options)
{
- ByteBuffer value = slice.bound(bound).bindAndGet(options);
+ Bound b = reverseBoundIfNeeded(getFirstColumn(), bound);
+
+ if (!hasBound(b))
+ return builder;
+
+ ByteBuffer value = slice.bound(b).bindAndGet(options);
checkBindValueSet(value, "Invalid unset value for column %s", columnDef.name);
return builder.addElementToAll(value);
http://git-wip-us.apache.org/repos/asf/cassandra/blob/1aa97e30/src/java/org/apache/cassandra/cql3/restrictions/TokenRestriction.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/1aa97e30/src/java/org/apache/cassandra/db/MultiCBuilder.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/db/MultiCBuilder.java
index be654fa,0000000..7c77ab0
mode 100644,000000..100644
--- a/src/java/org/apache/cassandra/db/MultiCBuilder.java
+++ b/src/java/org/apache/cassandra/db/MultiCBuilder.java
@@@ -1,324 -1,0 +1,379 @@@
+/*
+ * 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.db;
+
+import java.nio.ByteBuffer;
- import java.util.*;
++import java.util.ArrayList;
++import java.util.List;
++import java.util.NavigableSet;
+
++import org.apache.cassandra.config.ColumnDefinition;
+import org.apache.cassandra.utils.ByteBufferUtil;
+import org.apache.cassandra.utils.btree.BTreeSet;
+
+/**
+ * Builder that allow to build multiple Clustering/Slice.Bound at the same time.
+ */
+public class MultiCBuilder
+{
+ /**
+ * The table comparator.
+ */
+ private final ClusteringComparator comparator;
+
+ /**
+ * The elements of the clusterings
+ */
+ private final List<List<ByteBuffer>> elementsList = new ArrayList<>();
+
+ /**
+ * The number of elements that have been added.
+ */
+ private int size;
+
+ /**
+ * <code>true</code> if the clusterings have been build, <code>false</code> otherwise.
+ */
+ private boolean built;
+
+ /**
+ * <code>true</code> if the clusterings contains some <code>null</code> elements.
+ */
+ private boolean containsNull;
+
+ /**
+ * <code>true</code> if the composites contains some <code>unset</code> elements.
+ */
+ private boolean containsUnset;
+
+ /**
+ * <code>true</code> if some empty collection have been added.
+ */
+ private boolean hasMissingElements;
+
+ private MultiCBuilder(ClusteringComparator comparator)
+ {
+ this.comparator = comparator;
+ }
+
+ /**
+ * Creates a new empty {@code MultiCBuilder}.
+ */
+ public static MultiCBuilder create(ClusteringComparator comparator)
+ {
+ return new MultiCBuilder(comparator);
+ }
+
+ /**
+ * Checks if this builder is empty.
+ *
+ * @return <code>true</code> if this builder is empty, <code>false</code> otherwise.
+ */
+ private boolean isEmpty()
+ {
+ return elementsList.isEmpty();
+ }
+
+ /**
+ * Adds the specified element to all the clusterings.
+ * <p>
+ * If this builder contains 2 clustering: A-B and A-C a call to this method to add D will result in the clusterings:
+ * A-B-D and A-C-D.
+ * </p>
+ *
+ * @param value the value of the next element
+ * @return this <code>MulitCBuilder</code>
+ */
+ public MultiCBuilder addElementToAll(ByteBuffer value)
+ {
+ checkUpdateable();
+
+ if (isEmpty())
+ elementsList.add(new ArrayList<ByteBuffer>());
+
+ for (int i = 0, m = elementsList.size(); i < m; i++)
+ {
+ if (value == null)
+ containsNull = true;
+ if (value == ByteBufferUtil.UNSET_BYTE_BUFFER)
+ containsUnset = true;
+
+ elementsList.get(i).add(value);
+ }
+ size++;
+ return this;
+ }
+
+ /**
+ * Adds individually each of the specified elements to the end of all of the existing clusterings.
+ * <p>
+ * If this builder contains 2 clusterings: A-B and A-C a call to this method to add D and E will result in the 4
+ * clusterings: A-B-D, A-B-E, A-C-D and A-C-E.
+ * </p>
+ *
+ * @param values the elements to add
+ * @return this <code>CompositeBuilder</code>
+ */
+ public MultiCBuilder addEachElementToAll(List<ByteBuffer> values)
+ {
+ checkUpdateable();
+
+ if (isEmpty())
+ elementsList.add(new ArrayList<ByteBuffer>());
+
+ if (values.isEmpty())
+ {
+ hasMissingElements = true;
+ }
+ else
+ {
+ for (int i = 0, m = elementsList.size(); i < m; i++)
+ {
+ List<ByteBuffer> oldComposite = elementsList.remove(0);
+
+ for (int j = 0, n = values.size(); j < n; j++)
+ {
+ List<ByteBuffer> newComposite = new ArrayList<>(oldComposite);
+ elementsList.add(newComposite);
+
+ ByteBuffer value = values.get(j);
+
+ if (value == null)
+ containsNull = true;
+ if (value == ByteBufferUtil.UNSET_BYTE_BUFFER)
+ containsUnset = true;
+
+ newComposite.add(values.get(j));
+ }
+ }
+ }
+ size++;
+ return this;
+ }
+
+ /**
+ * Adds individually each of the specified list of elements to the end of all of the existing composites.
+ * <p>
+ * If this builder contains 2 composites: A-B and A-C a call to this method to add [[D, E], [F, G]] will result in the 4
+ * composites: A-B-D-E, A-B-F-G, A-C-D-E and A-C-F-G.
+ * </p>
+ *
+ * @param values the elements to add
+ * @return this <code>CompositeBuilder</code>
+ */
+ public MultiCBuilder addAllElementsToAll(List<List<ByteBuffer>> values)
+ {
+ checkUpdateable();
+
+ if (isEmpty())
+ elementsList.add(new ArrayList<ByteBuffer>());
+
+ if (values.isEmpty())
+ {
+ hasMissingElements = true;
+ }
+ else
+ {
+ for (int i = 0, m = elementsList.size(); i < m; i++)
+ {
+ List<ByteBuffer> oldComposite = elementsList.remove(0);
+
+ for (int j = 0, n = values.size(); j < n; j++)
+ {
+ List<ByteBuffer> newComposite = new ArrayList<>(oldComposite);
+ elementsList.add(newComposite);
+
+ List<ByteBuffer> value = values.get(j);
+
- if (value.isEmpty())
- hasMissingElements = true;
-
+ if (value.contains(null))
+ containsNull = true;
+ if (value.contains(ByteBufferUtil.UNSET_BYTE_BUFFER))
+ containsUnset = true;
+
+ newComposite.addAll(value);
+ }
+ }
+ size += values.get(0).size();
+ }
+ return this;
+ }
+
+ /**
+ * Returns the number of elements that can be added to the clusterings.
+ *
+ * @return the number of elements that can be added to the clusterings.
+ */
+ public int remainingCount()
+ {
+ return comparator.size() - size;
+ }
+
+ /**
+ * Checks if the clusterings contains null elements.
+ *
+ * @return <code>true</code> if the clusterings contains <code>null</code> elements, <code>false</code> otherwise.
+ */
+ public boolean containsNull()
+ {
+ return containsNull;
+ }
+
+ /**
+ * Checks if the clusterings contains unset elements.
+ *
+ * @return <code>true</code> if the clusterings contains <code>unset</code> elements, <code>false</code> otherwise.
+ */
+ public boolean containsUnset()
+ {
+ return containsUnset;
+ }
+
+ /**
+ * Checks if some empty list of values have been added
+ * @return <code>true</code> if the clusterings have some missing elements, <code>false</code> otherwise.
+ */
+ public boolean hasMissingElements()
+ {
+ return hasMissingElements;
+ }
+
+ /**
+ * Builds the <code>clusterings</code>.
+ *
+ * @return the clusterings
+ */
+ public NavigableSet<Clustering> build()
+ {
+ built = true;
+
+ if (hasMissingElements)
+ return BTreeSet.empty(comparator);
+
+ CBuilder builder = CBuilder.create(comparator);
+
+ if (elementsList.isEmpty())
+ return BTreeSet.of(builder.comparator(), builder.build());
+
+ BTreeSet.Builder<Clustering> set = BTreeSet.builder(builder.comparator());
+ for (int i = 0, m = elementsList.size(); i < m; i++)
+ {
+ List<ByteBuffer> elements = elementsList.get(i);
+ set.add(builder.buildWith(elements));
+ }
+ return set.build();
+ }
+
+ /**
- * Builds the <code>clusterings</code> with the specified EOC.
++ * Builds the <code>Slice.Bound</code>s for slice restrictions.
+ *
- * @return the clusterings
++ * @param isStart specify if the bound is a start one
++ * @param isInclusive specify if the bound is inclusive or not
++ * @param isOtherBoundInclusive specify if the other bound is inclusive or not
++ * @param columnDefs the columns of the slice restriction
++ * @return the <code>Slice.Bound</code>s
+ */
++ public NavigableSet<Slice.Bound> buildBoundForSlice(boolean isStart,
++ boolean isInclusive,
++ boolean isOtherBoundInclusive,
++ List<ColumnDefinition> columnDefs)
++ {
++ built = true;
++
++ if (hasMissingElements)
++ return BTreeSet.empty(comparator);
++
++ CBuilder builder = CBuilder.create(comparator);
++
++ if (elementsList.isEmpty())
++ return BTreeSet.of(comparator, builder.buildBound(isStart, isInclusive));
++
++ // Use a TreeSet to sort and eliminate duplicates
++ BTreeSet.Builder<Slice.Bound> set = BTreeSet.builder(comparator);
++
++ // The first column of the slice might not be the first clustering column (e.g. clustering_0 = ? AND (clustering_1, clustering_2) >= (?, ?)
++ int offset = columnDefs.get(0).position();
++
++ for (int i = 0, m = elementsList.size(); i < m; i++)
++ {
++ List<ByteBuffer> elements = elementsList.get(i);
++
++ // Handle the no bound case
++ if (elements.size() == offset)
++ {
++ set.add(builder.buildBoundWith(elements, isStart, true));
++ continue;
++ }
++
++ // In the case of mixed order columns, we will have some extra slices where the columns change directions.
++ // For example: if we have clustering_0 DESC and clustering_1 ASC a slice like (clustering_0, clustering_1) > (1, 2)
++ // will produce 2 slices: [BOTTOM, 1) and (1.2, 1]
++ // So, the END bound will return 2 bounds with the same values 1
++ ColumnDefinition lastColumn = columnDefs.get(columnDefs.size() - 1);
++ if (elements.size() <= lastColumn.position() && i < m - 1 && elements.equals(elementsList.get(i + 1)))
++ {
++ set.add(builder.buildBoundWith(elements, isStart, false));
++ set.add(builder.buildBoundWith(elementsList.get(i++), isStart, true));
++ continue;
++ }
++
++ // Handle the normal bounds
++ ColumnDefinition column = columnDefs.get(elements.size() - 1 - offset);
++ set.add(builder.buildBoundWith(elements, isStart, column.isReversedType() ? isOtherBoundInclusive : isInclusive));
++ }
++ return set.build();
++ }
++
+ public NavigableSet<Slice.Bound> buildBound(boolean isStart, boolean isInclusive)
+ {
+ built = true;
+
+ if (hasMissingElements)
+ return BTreeSet.empty(comparator);
+
+ CBuilder builder = CBuilder.create(comparator);
+
+ if (elementsList.isEmpty())
+ return BTreeSet.of(comparator, builder.buildBound(isStart, isInclusive));
+
+ // Use a TreeSet to sort and eliminate duplicates
+ BTreeSet.Builder<Slice.Bound> set = BTreeSet.builder(comparator);
+
+ for (int i = 0, m = elementsList.size(); i < m; i++)
+ {
+ List<ByteBuffer> elements = elementsList.get(i);
+ set.add(builder.buildBoundWith(elements, isStart, isInclusive));
+ }
+ return set.build();
+ }
+
+ /**
+ * Checks if some elements can still be added to the clusterings.
+ *
+ * @return <code>true</code> if it is possible to add more elements to the clusterings, <code>false</code> otherwise.
+ */
+ public boolean hasRemaining()
+ {
+ return remainingCount() > 0;
+ }
+
+ private void checkUpdateable()
+ {
+ if (!hasRemaining() || built)
+ throw new IllegalStateException("this builder cannot be updated anymore");
+ }
+}
[4/6] cassandra git commit: Merge branch cassandra-2.2 into
cassandra-3.0
Posted by bl...@apache.org.
http://git-wip-us.apache.org/repos/asf/cassandra/blob/1aa97e30/test/unit/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSetTest.java
----------------------------------------------------------------------
diff --cc test/unit/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSetTest.java
index d738c46,1deeb9e..abbd36b
--- a/test/unit/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSetTest.java
+++ b/test/unit/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSetTest.java
@@@ -28,10 -28,13 +28,11 @@@ import org.apache.cassandra.config.Colu
import org.apache.cassandra.cql3.*;
import org.apache.cassandra.cql3.Term.MultiItemTerminal;
import org.apache.cassandra.cql3.statements.Bound;
-import org.apache.cassandra.db.ColumnFamilyType;
-import org.apache.cassandra.db.composites.Composite;
-import org.apache.cassandra.db.composites.Composite.EOC;
-import org.apache.cassandra.db.composites.CompoundSparseCellNameType;
++
+import org.apache.cassandra.db.*;
import org.apache.cassandra.db.marshal.AbstractType;
import org.apache.cassandra.db.marshal.Int32Type;
- import org.apache.cassandra.exceptions.InvalidRequestException;
+ import org.apache.cassandra.db.marshal.ReversedType;
import org.apache.cassandra.utils.ByteBufferUtil;
import static java.util.Arrays.asList;
@@@ -41,28 -44,28 +42,28 @@@ import static org.junit.Assert.assertTr
public class PrimaryKeyRestrictionSetTest
{
@Test
- public void testboundsAsClusteringWithNoRestrictions() throws InvalidRequestException
- public void testBoundsAsCompositesWithNoRestrictions()
++ public void testBoundsAsClusteringWithNoRestrictions()
{
- CFMetaData cfMetaData = newCFMetaData(1);
+ CFMetaData cfMetaData = newCFMetaData(Sort.ASC);
- PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
- List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ SortedSet<Slice.Bound> bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
assertEquals(1, bounds.size());
- assertEmptyComposite(bounds.get(0));
+ assertEmptyStart(get(bounds, 0));
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
assertEquals(1, bounds.size());
- assertEmptyComposite(bounds.get(0));
+ assertEmptyEnd(get(bounds, 0));
}
/**
* Test 'clustering_0 = 1' with only one clustering column
*/
@Test
- public void testboundsAsClusteringWithOneEqRestrictionsAndOneClusteringColumn() throws InvalidRequestException
- public void testBoundsAsCompositesWithOneEqRestrictionsAndOneClusteringColumn()
++ public void testBoundsAsClusteringWithOneEqRestrictionsAndOneClusteringColumn()
{
- CFMetaData cfMetaData = newCFMetaData(1);
+ CFMetaData cfMetaData = newCFMetaData(Sort.ASC);
ByteBuffer clustering_0 = ByteBufferUtil.bytes(1);
Restriction eq = newSingleEq(cfMetaData, 0, clustering_0);
@@@ -83,9 -86,9 +84,9 @@@
* Test 'clustering_1 = 1' with 2 clustering columns
*/
@Test
- public void testboundsAsClusteringWithOneEqRestrictionsAndTwoClusteringColumns() throws InvalidRequestException
- public void testBoundsAsCompositesWithOneEqRestrictionsAndTwoClusteringColumns()
++ public void testBoundsAsClusteringWithOneEqRestrictionsAndTwoClusteringColumns()
{
- CFMetaData cfMetaData = newCFMetaData(2);
+ CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC);
ByteBuffer clustering_0 = ByteBufferUtil.bytes(1);
Restriction eq = newSingleEq(cfMetaData, 0, clustering_0);
@@@ -106,7 -109,7 +107,7 @@@
* Test 'clustering_0 IN (1, 2, 3)' with only one clustering column
*/
@Test
- public void testboundsAsClusteringWithOneInRestrictionsAndOneClusteringColumn() throws InvalidRequestException
- public void testBoundsAsCompositesWithOneInRestrictionsAndOneClusteringColumn()
++ public void testBoundsAsClusteringWithOneInRestrictionsAndOneClusteringColumn()
{
ByteBuffer value1 = ByteBufferUtil.bytes(1);
ByteBuffer value2 = ByteBufferUtil.bytes(2);
@@@ -136,9 -139,9 +137,9 @@@
* Test slice restriction (e.g 'clustering_0 > 1') with only one clustering column
*/
@Test
- public void testboundsAsClusteringWithSliceRestrictionsAndOneClusteringColumn() throws InvalidRequestException
- public void testBoundsAsCompositesWithSliceRestrictionsAndOneClusteringColumn()
++ public void testBoundsAsClusteringWithSliceRestrictionsAndOneClusteringColumn()
{
- CFMetaData cfMetaData = newCFMetaData(1);
+ CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC);
ByteBuffer value1 = ByteBufferUtil.bytes(1);
ByteBuffer value2 = ByteBufferUtil.bytes(2);
@@@ -219,12 -222,98 +220,98 @@@
}
/**
+ * Test slice restriction (e.g 'clustering_0 > 1') with only one descending clustering column
+ */
+ @Test
- public void testBoundsAsCompositesWithSliceRestrictionsAndOneDescendingClusteringColumn()
++ public void testBoundsAsClusteringWithSliceRestrictionsAndOneDescendingClusteringColumn()
+ {
+ CFMetaData cfMetaData = newCFMetaData(Sort.DESC, Sort.DESC);
+
+ ByteBuffer value1 = ByteBufferUtil.bytes(1);
+ ByteBuffer value2 = ByteBufferUtil.bytes(2);
+
+ Restriction slice = newSingleSlice(cfMetaData, 0, Bound.START, false, value1);
- PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice);
+
- List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ SortedSet<Slice.Bound> bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertEmptyComposite(bounds.get(0));
++ assertEmptyStart(get(bounds, 0));
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.START);
++ assertEndBound(get(bounds, 0), false, value1);
+
+ slice = newSingleSlice(cfMetaData, 0, Bound.START, true, value1);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertEmptyComposite(bounds.get(0));
++ assertEmptyStart(get(bounds, 0));
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.END);
++ assertEndBound(get(bounds, 0), true, value1);
+
+ slice = newSingleSlice(cfMetaData, 0, Bound.END, true, value1);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.NONE);
++ assertStartBound(get(bounds, 0), true, value1);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertEmptyComposite(bounds.get(0));
++ assertEmptyEnd(get(bounds, 0));
+
+ slice = newSingleSlice(cfMetaData, 0, Bound.END, false, value1);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.END);
++ assertStartBound(get(bounds, 0), false, value1);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertEmptyComposite(bounds.get(0));
++ assertEmptyEnd(get(bounds, 0));
+
+ slice = newSingleSlice(cfMetaData, 0, Bound.START, false, value1);
+ Restriction slice2 = newSingleSlice(cfMetaData, 0, Bound.END, false, value2);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value2, EOC.END);
++ assertStartBound(get(bounds, 0), false, value2);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.START);
++ assertEndBound(get(bounds, 0), false, value1);
+
+ slice = newSingleSlice(cfMetaData, 0, Bound.START, true, value1);
+ slice2 = newSingleSlice(cfMetaData, 0, Bound.END, true, value2);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value2, EOC.NONE);
++ assertStartBound(get(bounds, 0), true, value2);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.END);
++ assertEndBound(get(bounds, 0), true, value1);
+ }
+
+ /**
* Test 'clustering_0 = 1 AND clustering_1 IN (1, 2, 3)'
*/
@Test
- public void testboundsAsClusteringWithEqAndInRestrictions() throws InvalidRequestException
- public void testBoundsAsCompositesWithEqAndInRestrictions()
++ public void testBoundsAsClusteringWithEqAndInRestrictions()
{
- CFMetaData cfMetaData = newCFMetaData(2);
+ CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC);
ByteBuffer value1 = ByteBufferUtil.bytes(1);
ByteBuffer value2 = ByteBufferUtil.bytes(2);
@@@ -251,9 -340,9 +338,9 @@@
* Test equal and slice restrictions (e.g 'clustering_0 = 0 clustering_1 > 1')
*/
@Test
- public void testboundsAsClusteringWithEqAndSliceRestrictions() throws InvalidRequestException
- public void testBoundsAsCompositesWithEqAndSliceRestrictions()
++ public void testBoundsAsClusteringWithEqAndSliceRestrictions()
{
- CFMetaData cfMetaData = newCFMetaData(2);
+ CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC);
ByteBuffer value1 = ByteBufferUtil.bytes(1);
ByteBuffer value2 = ByteBufferUtil.bytes(2);
@@@ -262,314 -351,1059 +349,1059 @@@
Restriction eq = newSingleEq(cfMetaData, 0, value3);
Restriction slice = newSingleSlice(cfMetaData, 1, Bound.START, false, value1);
- PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
restrictions = restrictions.mergeWith(eq).mergeWith(slice);
- List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ SortedSet<Slice.Bound> bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value3, value1, EOC.END);
+ assertStartBound(get(bounds, 0), false, value3, value1);
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertEndBound(get(bounds, 0), true, value3);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value3, EOC.END);
++ assertEndBound(get(bounds, 0), true, value3);
+
+ slice = newSingleSlice(cfMetaData, 1, Bound.START, true, value1);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(eq).mergeWith(slice);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value3, value1, EOC.NONE);
++ assertStartBound(get(bounds, 0), true, value3, value1);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value3, EOC.END);
++ assertEndBound(get(bounds, 0), true, value3);
+
+ slice = newSingleSlice(cfMetaData, 1, Bound.END, true, value1);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(eq).mergeWith(slice);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value3, EOC.START);
++ assertStartBound(get(bounds, 0), true, value3);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value3, value1, EOC.END);
++ assertEndBound(get(bounds, 0), true, value3, value1);
+
+ slice = newSingleSlice(cfMetaData, 1, Bound.END, false, value1);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(eq).mergeWith(slice);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value3, EOC.START);
++ assertStartBound(get(bounds, 0), true, value3);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value3, value1, EOC.START);
++ assertEndBound(get(bounds, 0), false, value3, value1);
+
+ slice = newSingleSlice(cfMetaData, 1, Bound.START, false, value1);
+ Restriction slice2 = newSingleSlice(cfMetaData, 1, Bound.END, false, value2);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(eq).mergeWith(slice).mergeWith(slice2);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value3, value1, EOC.END);
++ assertStartBound(get(bounds, 0), false, value3, value1);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value3, value2, EOC.START);
++ assertEndBound(get(bounds, 0), false, value3, value2);
+
+ slice = newSingleSlice(cfMetaData, 1, Bound.START, true, value1);
+ slice2 = newSingleSlice(cfMetaData, 1, Bound.END, true, value2);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(eq).mergeWith(slice).mergeWith(slice2);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value3, value1, EOC.NONE);
++ assertStartBound(get(bounds, 0), true, value3, value1);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value3, value2, EOC.END);
++ assertEndBound(get(bounds, 0), true, value3, value2);
+ }
+
+ /**
+ * Test '(clustering_0, clustering_1) = (1, 2)' with two clustering column
+ */
+ @Test
- public void testBoundsAsCompositesWithMultiEqRestrictions()
++ public void testBoundsAsClusteringWithMultiEqRestrictions()
+ {
+ CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC);
+
+ ByteBuffer value1 = ByteBufferUtil.bytes(1);
+ ByteBuffer value2 = ByteBufferUtil.bytes(2);
+ Restriction eq = newMultiEq(cfMetaData, 0, value1, value2);
- PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(eq);
+
- List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ SortedSet<Slice.Bound> bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.START);
++ assertStartBound(get(bounds, 0), true, value1, value2);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.END);
++ assertEndBound(get(bounds, 0), true, value1, value2);
+ }
+
+ /**
+ * Test '(clustering_0, clustering_1) IN ((1, 2), (2, 3))' with two clustering column
+ */
+ @Test
- public void testBoundsAsCompositesWithMultiInRestrictions()
++ public void testBoundsAsClusteringWithMultiInRestrictions()
+ {
+ CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC);
+
+ ByteBuffer value1 = ByteBufferUtil.bytes(1);
+ ByteBuffer value2 = ByteBufferUtil.bytes(2);
+ ByteBuffer value3 = ByteBufferUtil.bytes(3);
+ Restriction in = newMultiIN(cfMetaData, 0, asList(value1, value2), asList(value2, value3));
- PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(in);
+
- List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ SortedSet<Slice.Bound> bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.START);
- assertComposite(bounds.get(1), value2, value3, EOC.START);
++ assertStartBound(get(bounds, 0), true, value1, value2);
++ assertStartBound(get(bounds, 1), true, value2, value3);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.END);
- assertComposite(bounds.get(1), value2, value3, EOC.END);
++ assertEndBound(get(bounds, 0), true, value1, value2);
++ assertEndBound(get(bounds, 1), true, value2, value3);
+ }
+
+ /**
+ * Test multi-column slice restrictions (e.g '(clustering_0) > (1)') with only one clustering column
+ */
+ @Test
- public void testBoundsAsCompositesWithMultiSliceRestrictionsWithOneClusteringColumn()
++ public void testBoundsAsClusteringWithMultiSliceRestrictionsWithOneClusteringColumn()
+ {
+ CFMetaData cfMetaData = newCFMetaData(Sort.ASC);
+
++
+ ByteBuffer value1 = ByteBufferUtil.bytes(1);
+ ByteBuffer value2 = ByteBufferUtil.bytes(2);
+
+ Restriction slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1);
- PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice);
+
- List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ SortedSet<Slice.Bound> bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.END);
++ assertStartBound(get(bounds, 0), false, value1);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertEmptyComposite(bounds.get(0));
++ assertEmptyEnd(get(bounds, 0));
+
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.NONE);
++ assertStartBound(get(bounds, 0), true, value1);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertEmptyComposite(bounds.get(0));
++ assertEmptyEnd(get(bounds, 0));
+
+ slice = newMultiSlice(cfMetaData, 0, Bound.END, true, value1);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertEmptyComposite(bounds.get(0));
++ assertEmptyStart(get(bounds, 0));
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.END);
++ assertEndBound(get(bounds, 0), true, value1);
+
+ slice = newMultiSlice(cfMetaData, 0, Bound.END, false, value1);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertEmptyComposite(bounds.get(0));
++ assertEmptyStart(get(bounds, 0));
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.START);
++ assertEndBound(get(bounds, 0), false, value1);
+
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1);
+ Restriction slice2 = newMultiSlice(cfMetaData, 0, Bound.END, false, value2);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.END);
++ assertStartBound(get(bounds, 0), false, value1);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value2, EOC.START);
++ assertEndBound(get(bounds, 0), false, value2);
+
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1);
+ slice2 = newMultiSlice(cfMetaData, 0, Bound.END, true, value2);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.NONE);
++ assertStartBound(get(bounds, 0), true, value1);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value2, EOC.END);
++ assertEndBound(get(bounds, 0), true, value2);
+ }
+
+ /**
+ * Test multi-column slice restrictions (e.g '(clustering_0) > (1)') with only one clustering column in reverse
+ * order
+ */
+ @Test
- public void testBoundsAsCompositesWithMultiSliceRestrictionsWithOneDescendingClusteringColumn()
++ public void testBoundsAsClusteringWithMultiSliceRestrictionsWithOneDescendingClusteringColumn()
+ {
+ CFMetaData cfMetaData = newCFMetaData(Sort.DESC);
+
+ ByteBuffer value1 = ByteBufferUtil.bytes(1);
+ ByteBuffer value2 = ByteBufferUtil.bytes(2);
+
+ Restriction slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1);
- PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice);
+
- List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ SortedSet<Slice.Bound> bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertEmptyComposite(bounds.get(0));
++ assertEmptyStart(get(bounds, 0));
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.START);
++ assertEndBound(get(bounds, 0), false, value1);
+
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertEmptyComposite(bounds.get(0));
++ assertEmptyStart(get(bounds, 0));
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.END);
++ assertEndBound(get(bounds, 0), true, value1);
+
+ slice = newMultiSlice(cfMetaData, 0, Bound.END, true, value1);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.NONE);
++ assertStartBound(get(bounds, 0), true, value1);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertEmptyComposite(bounds.get(0));
++ assertEmptyEnd(get(bounds, 0));
+
+ slice = newMultiSlice(cfMetaData, 0, Bound.END, false, value1);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.END);
++ assertStartBound(get(bounds, 0), false, value1);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertEmptyComposite(bounds.get(0));
++ assertEmptyEnd(get(bounds, 0));
+
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1);
+ Restriction slice2 = newMultiSlice(cfMetaData, 0, Bound.END, false, value2);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value2, EOC.END);
++ assertStartBound(get(bounds, 0), false, value2);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.START);
++ assertEndBound(get(bounds, 0), false, value1);
+
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1);
+ slice2 = newMultiSlice(cfMetaData, 0, Bound.END, true, value2);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value2, EOC.NONE);
++ assertStartBound(get(bounds, 0), true, value2);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.END);
++ assertEndBound(get(bounds, 0), true, value1);
+ }
+
+ /**
+ * Test multi-column slice restrictions (e.g '(clustering_0, clustering_1) > (1, 2)')
+ */
+ @Test
- public void testBoundsAsCompositesWithMultiSliceRestrictionsWithTwoClusteringColumn()
++ public void testBoundsAsClusteringWithMultiSliceRestrictionsWithTwoClusteringColumn()
+ {
+ CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC);
+
+ ByteBuffer value1 = ByteBufferUtil.bytes(1);
+ ByteBuffer value2 = ByteBufferUtil.bytes(2);
+
+ // (clustering_0, clustering1) > (1, 2)
+ Restriction slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2);
- PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice);
+
- List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ SortedSet<Slice.Bound> bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.END);
++ assertStartBound(get(bounds, 0), false, value1, value2);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertEmptyComposite(bounds.get(0));
++ assertEmptyEnd(get(bounds, 0));
+
+ // (clustering_0, clustering1) >= (1, 2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.NONE);
++ assertStartBound(get(bounds, 0), true, value1, value2);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertEmptyComposite(bounds.get(0));
++ assertEmptyEnd(get(bounds, 0));
+
+ // (clustering_0, clustering1) <= (1, 2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.END, true, value1, value2);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertEmptyComposite(bounds.get(0));
++ assertEmptyStart(get(bounds, 0));
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.END);
++ assertEndBound(get(bounds, 0), true, value1, value2);
+
+ // (clustering_0, clustering1) < (1, 2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.END, false, value1, value2);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertEmptyComposite(bounds.get(0));
++ assertEmptyStart(get(bounds, 0));
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.START);
++ assertEndBound(get(bounds, 0), false, value1, value2);
+
+ // (clustering_0, clustering1) > (1, 2) AND (clustering_0) < (2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2);
+ Restriction slice2 = newMultiSlice(cfMetaData, 0, Bound.END, false, value2);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.END);
++ assertStartBound(get(bounds, 0), false, value1, value2);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value2, EOC.START);
++ assertEndBound(get(bounds, 0), false, value2);
+
+ // (clustering_0, clustering1) >= (1, 2) AND (clustering_0, clustering1) <= (2, 1)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2);
+ slice2 = newMultiSlice(cfMetaData, 0, Bound.END, true, value2, value1);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.NONE);
++ assertStartBound(get(bounds, 0), true, value1, value2);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value2, value1, EOC.END);
++ assertEndBound(get(bounds, 0), true, value2, value1);
+ }
+
+ /**
+ * Test multi-column slice restrictions with 2 descending clustering columns (e.g '(clustering_0, clustering_1) > (1, 2)')
+ */
+ @Test
- public void testBoundsAsCompositesWithMultiSliceRestrictionsWithTwoDescendingClusteringColumns()
++ public void testBoundsAsClusteringWithMultiSliceRestrictionsWithTwoDescendingClusteringColumns()
+ {
+ CFMetaData cfMetaData = newCFMetaData(Sort.DESC, Sort.DESC);
+
+ ByteBuffer value1 = ByteBufferUtil.bytes(1);
+ ByteBuffer value2 = ByteBufferUtil.bytes(2);
+
+ // (clustering_0, clustering1) > (1, 2)
+ Restriction slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2);
- PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice);
+
- List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ SortedSet<Slice.Bound> bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertEmptyComposite(bounds.get(0));
++ assertEmptyStart(get(bounds, 0));
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.START);
++ assertEndBound(get(bounds, 0), false, value1, value2);
+
+ // (clustering_0, clustering1) >= (1, 2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertEmptyComposite(bounds.get(0));
++ assertEmptyStart(get(bounds, 0));
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.END);
++ assertEndBound(get(bounds, 0), true, value1, value2);
+
+ // (clustering_0, clustering1) <= (1, 2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.END, true, value1, value2);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.NONE);
++ assertStartBound(get(bounds, 0), true, value1, value2);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertEmptyComposite(bounds.get(0));
++ assertEmptyEnd(get(bounds, 0));
+
+ // (clustering_0, clustering1) < (1, 2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.END, false, value1, value2);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.END);
++ assertStartBound(get(bounds, 0), false, value1, value2);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertEmptyComposite(bounds.get(0));
++ assertEmptyEnd(get(bounds, 0));
+
+
+ // (clustering_0, clustering1) > (1, 2) AND (clustering_0) < (2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2);
+ Restriction slice2 = newMultiSlice(cfMetaData, 0, Bound.END, false, value2);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value2, EOC.END);
++ assertStartBound(get(bounds, 0), false, value2);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.START);
++ assertEndBound(get(bounds, 0), false, value1, value2);
+
+ // (clustering_0, clustering1) >= (1, 2) AND (clustering_0, clustering1) <= (2, 1)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2);
+ slice2 = newMultiSlice(cfMetaData, 0, Bound.END, true, value2, value1);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value2, value1, EOC.NONE);
++ assertStartBound(get(bounds, 0), true, value2, value1);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(1, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.END);
++ assertEndBound(get(bounds, 0), true, value1, value2);
+ }
+
+ /**
+ * Test multi-column slice restrictions with 1 descending clustering column and 1 ascending
+ * (e.g '(clustering_0, clustering_1) > (1, 2)')
+ */
+ @Test
- public void testBoundsAsCompositesWithMultiSliceRestrictionsWithOneDescendingAndOneAscendingClusteringColumns()
++ public void testBoundsAsClusteringWithMultiSliceRestrictionsWithOneDescendingAndOneAscendingClusteringColumns()
+ {
+ CFMetaData cfMetaData = newCFMetaData(Sort.DESC, Sort.ASC);
+
+ ByteBuffer value1 = ByteBufferUtil.bytes(1);
+ ByteBuffer value2 = ByteBufferUtil.bytes(2);
+
+ // (clustering_0, clustering1) > (1, 2)
+ Restriction slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2);
- PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice);
+
- List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ SortedSet<Slice.Bound> bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
- assertEmptyComposite(bounds.get(0));
- assertComposite(bounds.get(1), value1, value2, EOC.END);
++ assertEmptyStart(get(bounds, 0));
++ assertStartBound(get(bounds, 1), false, value1, value2);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.START);
- assertComposite(bounds.get(1), value1, EOC.END);
++ assertEndBound(get(bounds, 0), false, value1);
++ assertEndBound(get(bounds, 1), true, value1);
+
+ // (clustering_0, clustering1) >= (1, 2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
- assertEmptyComposite(bounds.get(0));
- assertComposite(bounds.get(1), value1, value2, EOC.NONE);
++ assertEmptyStart(get(bounds, 0));
++ assertStartBound(get(bounds, 1), true, value1, value2);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.START);
- assertComposite(bounds.get(1), value1, EOC.END);
++ assertEndBound(get(bounds, 0), false, value1);
++ assertEndBound(get(bounds, 1), true, value1);
+
+ // (clustering_0, clustering1) <= (1, 2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.END, true, value1, value2);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.START);
- assertComposite(bounds.get(1), value1, EOC.END);
++ assertStartBound(get(bounds, 0), true, value1);
++ assertStartBound(get(bounds, 1), false, value1);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.END);
- assertEmptyComposite(bounds.get(1));
++ assertEndBound(get(bounds, 0), true, value1, value2);
++ assertEmptyEnd(get(bounds, 1));
+
+ // (clustering_0, clustering1) < (1, 2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.END, false, value1, value2);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.START);
- assertComposite(bounds.get(1), value1, EOC.END);
++ assertStartBound(get(bounds, 0), true, value1);
++ assertStartBound(get(bounds, 1), false, value1);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.START);
- assertEmptyComposite(bounds.get(1));
++ assertEndBound(get(bounds, 0), false, value1, value2);
++ assertEmptyEnd(get(bounds, 1));
+
+ // (clustering_0, clustering1) > (1, 2) AND (clustering_0) < (2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2);
+ Restriction slice2 = newMultiSlice(cfMetaData, 0, Bound.END, false, value2);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
- assertComposite(bounds.get(0), value2, EOC.END);
- assertComposite(bounds.get(1), value1, value2, EOC.END);
++ assertStartBound(get(bounds, 0), false, value2);
++ assertStartBound(get(bounds, 1), false, value1, value2);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.START);
- assertComposite(bounds.get(1), value1, EOC.END);
++ assertEndBound(get(bounds, 0), false, value1);
++ assertEndBound(get(bounds, 1), true, value1);
+
+ // (clustering_0) > (1) AND (clustering_0, clustering1) < (2, 1)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1);
+ slice2 = newMultiSlice(cfMetaData, 0, Bound.END, false, value2, value1);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
- assertComposite(bounds.get(0), value2, EOC.START);
- assertComposite(bounds.get(1), value2, EOC.END);
++ assertStartBound(get(bounds, 0), true, value2);
++ assertStartBound(get(bounds, 1), false, value2);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
- assertComposite(bounds.get(0), value2, value1, EOC.START);
- assertComposite(bounds.get(1), value1, EOC.START);
++ assertEndBound(get(bounds, 0), false, value2, value1);
++ assertEndBound(get(bounds, 1), false, value1);
+
+ // (clustering_0, clustering1) >= (1, 2) AND (clustering_0, clustering1) <= (2, 1)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2);
+ slice2 = newMultiSlice(cfMetaData, 0, Bound.END, true, value2, value1);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
+
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(3, bounds.size());
- assertComposite(bounds.get(0), value2, EOC.START);
- assertComposite(bounds.get(1), value2, EOC.END);
- assertComposite(bounds.get(2), value1, value2, EOC.NONE);
++ assertStartBound(get(bounds, 0), true, value2);
++ assertStartBound(get(bounds, 1), false, value2);
++ assertStartBound(get(bounds, 2), true, value1, value2);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(3, bounds.size());
- assertComposite(bounds.get(0), value2, value1, EOC.END);
- assertComposite(bounds.get(1), value1, EOC.START);
- assertComposite(bounds.get(2), value1, EOC.END);
++ assertEndBound(get(bounds, 0), true, value2, value1);
++ assertEndBound(get(bounds, 1), false, value1);
++ assertEndBound(get(bounds, 2), true, value1);
+ }
+
+ /**
+ * Test multi-column slice restrictions with 1 descending clustering column and 1 ascending
+ * (e.g '(clustering_0, clustering_1) > (1, 2)')
+ */
+ @Test
- public void testBoundsAsCompositesWithMultiSliceRestrictionsWithOneAscendingAndOneDescendingClusteringColumns()
++ public void testBoundsAsClusteringWithMultiSliceRestrictionsWithOneAscendingAndOneDescendingClusteringColumns()
+ {
+ CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.DESC);
+
+ ByteBuffer value1 = ByteBufferUtil.bytes(1);
+ ByteBuffer value2 = ByteBufferUtil.bytes(2);
+
+ // (clustering_0, clustering1) > (1, 2)
+ Restriction slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2);
- PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice);
+
- List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ SortedSet<Slice.Bound> bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.START);
- assertComposite(bounds.get(1), value1, EOC.END);
++ assertStartBound(get(bounds, 0), true, value1);
++ assertStartBound(get(bounds, 1), false, value1);
+
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(2, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.START);
- assertEmptyComposite(bounds.get(1));
++ assertEndBound(get(bounds, 0), false, value1, value2);
++ assertEmptyEnd(get(bounds, 1));
- slice = newSingleSlice(cfMetaData, 1, Bound.START, true, value1);
+ // (clustering_0, clustering1) >= (1, 2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
- restrictions = restrictions.mergeWith(eq).mergeWith(slice);
+ restrictions = restrictions.mergeWith(slice);
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertStartBound(get(bounds, 0), true, value3, value1);
+ assertEquals(2, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.START);
- assertComposite(bounds.get(1), value1, EOC.END);
++ assertStartBound(get(bounds, 0), true, value1);
++ assertStartBound(get(bounds, 1), false, value1);
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertEndBound(get(bounds, 0), true, value3);
+ assertEquals(2, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.END);
- assertEmptyComposite(bounds.get(1));
++ assertEndBound(get(bounds, 0), true, value1, value2);
++ assertEmptyEnd(get(bounds, 1));
- slice = newSingleSlice(cfMetaData, 1, Bound.END, true, value1);
+ // (clustering_0, clustering1) <= (1, 2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.END, true, value1, value2);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
- restrictions = restrictions.mergeWith(eq).mergeWith(slice);
+ restrictions = restrictions.mergeWith(slice);
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertStartBound(get(bounds, 0), true, value3);
+ assertEquals(2, bounds.size());
- assertEmptyComposite(bounds.get(0));
- assertComposite(bounds.get(1), value1, value2, EOC.NONE);
++ assertEmptyStart(get(bounds, 0));
++ assertStartBound(get(bounds, 1), true, value1, value2);
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertEndBound(get(bounds, 0), true, value3, value1);
+ assertEquals(2, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.START);
- assertComposite(bounds.get(1), value1, EOC.END);
++ assertEndBound(get(bounds, 0), false, value1);
++ assertEndBound(get(bounds, 1), true, value1);
- slice = newSingleSlice(cfMetaData, 1, Bound.END, false, value1);
+ // (clustering_0, clustering1) < (1, 2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.END, false, value1, value2);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
- restrictions = restrictions.mergeWith(eq).mergeWith(slice);
+ restrictions = restrictions.mergeWith(slice);
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertStartBound(get(bounds, 0), true, value3);
+ assertEquals(2, bounds.size());
- assertEmptyComposite(bounds.get(0));
- assertComposite(bounds.get(1), value1, value2, EOC.END);
++ assertEmptyStart(get(bounds, 0));
++ assertStartBound(get(bounds, 1), false, value1, value2);
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertEndBound(get(bounds, 0), false, value3, value1);
+ assertEquals(2, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.START);
- assertComposite(bounds.get(1), value1, EOC.END);
++ assertEndBound(get(bounds, 0), false, value1);
++ assertEndBound(get(bounds, 1), true, value1);
- slice = newSingleSlice(cfMetaData, 1, Bound.START, false, value1);
- Restriction slice2 = newSingleSlice(cfMetaData, 1, Bound.END, false, value2);
+ // (clustering_0, clustering1) > (1, 2) AND (clustering_0) < (2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2);
+ Restriction slice2 = newMultiSlice(cfMetaData, 0, Bound.END, false, value2);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
- restrictions = restrictions.mergeWith(eq).mergeWith(slice).mergeWith(slice2);
+ restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertStartBound(get(bounds, 0), false, value3, value1);
+ assertEquals(2, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.START);
- assertComposite(bounds.get(1), value1, EOC.END);
++ assertStartBound(get(bounds, 0), true, value1);
++ assertStartBound(get(bounds, 1), false, value1);
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertEndBound(get(bounds, 0), false, value3, value2);
+ assertEquals(2, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.START);
- assertComposite(bounds.get(1), value2, EOC.START);
++ assertEndBound(get(bounds, 0), false, value1, value2);
++ assertEndBound(get(bounds, 1), false, value2);
- slice = newSingleSlice(cfMetaData, 1, Bound.START, true, value1);
- slice2 = newSingleSlice(cfMetaData, 1, Bound.END, true, value2);
+ // (clustering_0, clustering1) >= (1, 2) AND (clustering_0, clustering1) <= (2, 1)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2);
+ slice2 = newMultiSlice(cfMetaData, 0, Bound.END, true, value2, value1);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
- restrictions = restrictions.mergeWith(eq).mergeWith(slice).mergeWith(slice2);
+ restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertStartBound(get(bounds, 0), true, value3, value1);
+ assertEquals(3, bounds.size());
- assertComposite(bounds.get(0), value1, EOC.START);
- assertComposite(bounds.get(1), value1, EOC.END);
- assertComposite(bounds.get(2), value2, value1, EOC.NONE);
++ assertStartBound(get(bounds, 0), true, value1);
++ assertStartBound(get(bounds, 1), false, value1);
++ assertStartBound(get(bounds, 2), true, value2, value1);
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertEndBound(get(bounds, 0), true, value3, value2);
+ assertEquals(3, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.END);
- assertComposite(bounds.get(1), value2, EOC.START);
- assertComposite(bounds.get(2), value2, EOC.END);
++ assertEndBound(get(bounds, 0), true, value1, value2);
++ assertEndBound(get(bounds, 1), false, value2);
++ assertEndBound(get(bounds, 2), true, value2);
}
/**
- * Test '(clustering_0, clustering_1) = (1, 2)' with two clustering column
+ * Test multi-column slice restrictions with 2 ascending clustering column and 2 descending
+ * (e.g '(clustering_0, clustering1, clustering_3, clustering4) > (1, 2, 3, 4)')
*/
@Test
- public void testboundsAsClusteringWithMultiEqRestrictions() throws InvalidRequestException
- public void testBoundsAsCompositesWithMultiSliceRestrictionsWithTwoAscendingAndTwoDescendingClusteringColumns()
++ public void testBoundsAsClusteringWithMultiSliceRestrictionsWithTwoAscendingAndTwoDescendingClusteringColumns()
{
- CFMetaData cfMetaData = newCFMetaData(2);
+ CFMetaData cfMetaData = newCFMetaData(Sort.ASC, Sort.ASC, Sort.DESC, Sort.DESC);
ByteBuffer value1 = ByteBufferUtil.bytes(1);
ByteBuffer value2 = ByteBufferUtil.bytes(2);
- Restriction eq = newMultiEq(cfMetaData, 0, value1, value2);
+ ByteBuffer value3 = ByteBufferUtil.bytes(3);
+ ByteBuffer value4 = ByteBufferUtil.bytes(4);
+
+ // (clustering_0, clustering1, clustering_2, clustering_3) > (1, 2, 3, 4)
+ Restriction slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2, value3, value4);
- PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
- restrictions = restrictions.mergeWith(eq);
+ restrictions = restrictions.mergeWith(slice);
- List<Composite> bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ SortedSet<Slice.Bound> bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
+ assertEquals(2, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.START);
- assertComposite(bounds.get(1), value1, value2, EOC.END);
+ assertStartBound(get(bounds, 0), true, value1, value2);
++ assertStartBound(get(bounds, 1), false, value1, value2);
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertEndBound(get(bounds, 0), true, value1, value2);
- }
-
- /**
- * Test '(clustering_0, clustering_1) IN ((1, 2), (2, 3))' with two clustering column
- */
- @Test
- public void testboundsAsClusteringWithMultiInRestrictions() throws InvalidRequestException
- {
- CFMetaData cfMetaData = newCFMetaData(2);
+ assertEquals(2, bounds.size());
- assertComposite(bounds.get(0), value1, value2, value3, value4, EOC.START);
- assertEmptyComposite(bounds.get(1));
++ assertEndBound(get(bounds, 0), false, value1, value2, value3, value4);
++ assertEmptyEnd(get(bounds, 1));
- ByteBuffer value1 = ByteBufferUtil.bytes(1);
- ByteBuffer value2 = ByteBufferUtil.bytes(2);
- ByteBuffer value3 = ByteBufferUtil.bytes(3);
- Restriction in = newMultiIN(cfMetaData, 0, asList(value1, value2), asList(value2, value3));
- PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
- restrictions = restrictions.mergeWith(in);
+ // clustering_0 = 1 AND (clustering_1, clustering_2, clustering_3) > (2, 3, 4)
+ Restriction eq = newSingleEq(cfMetaData, 0, value1);
+ slice = newMultiSlice(cfMetaData, 1, Bound.START, false, value2, value3, value4);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice);
+ restrictions = restrictions.mergeWith(eq);
- SortedSet<Slice.Bound> bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
assertEquals(2, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.START);
- assertComposite(bounds.get(1), value1, value2, EOC.END);
+ assertStartBound(get(bounds, 0), true, value1, value2);
- assertStartBound(get(bounds, 1), true, value2, value3);
++ assertStartBound(get(bounds, 1), false, value1, value2);
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
assertEquals(2, bounds.size());
- assertEndBound(get(bounds, 0), true, value1, value2);
- assertEndBound(get(bounds, 1), true, value2, value3);
- }
- assertComposite(bounds.get(0), value1, value2, value3, value4, EOC.START);
- assertComposite(bounds.get(1), value1, EOC.END);
++ assertEndBound(get(bounds, 0), false, value1, value2, value3, value4);
++ assertEndBound(get(bounds, 1), true, value1);
- /**
- * Test multi-column slice restrictions (e.g '(clustering_0) > (1)') with only one clustering column
- */
- @Test
- public void testboundsAsClusteringWithMultiSliceRestrictionsWithOneClusteringColumn() throws InvalidRequestException
- {
- CFMetaData cfMetaData = newCFMetaData(1);
- // clustering_0 = 1 AND (clustering_1, clustering_2, clustering_3) > (2, 3, 4)
++ // clustering_0 IN (1, 2) AND (clustering_1, clustering_2, clustering_3) > (2, 3, 4)
+ Restriction in = newSingleIN(cfMetaData, 0, value1, value2);
+ slice = newMultiSlice(cfMetaData, 1, Bound.START, false, value2, value3, value4);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
+ restrictions = restrictions.mergeWith(slice);
+ restrictions = restrictions.mergeWith(in);
- ByteBuffer value1 = ByteBufferUtil.bytes(1);
- ByteBuffer value2 = ByteBufferUtil.bytes(2);
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
+ assertEquals(4, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.START);
- assertComposite(bounds.get(1), value1, value2, EOC.END);
- assertComposite(bounds.get(2), value2, value2, EOC.START);
- assertComposite(bounds.get(3), value2, value2, EOC.END);
++ assertStartBound(get(bounds, 0), true, value1, value2);
++ assertStartBound(get(bounds, 1), false, value1, value2);
++ assertStartBound(get(bounds, 2), true, value2, value2);
++ assertStartBound(get(bounds, 3), false, value2, value2);
- Restriction slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1);
- PrimaryKeyRestrictions restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
+ assertEquals(4, bounds.size());
- assertComposite(bounds.get(0), value1, value2, value3, value4, EOC.START);
- assertComposite(bounds.get(1), value1, EOC.END);
- assertComposite(bounds.get(2), value2, value2, value3, value4, EOC.START);
- assertComposite(bounds.get(3), value2, EOC.END);
++ assertEndBound(get(bounds, 0), false, value1, value2, value3, value4);
++ assertEndBound(get(bounds, 1), true, value1);
++ assertEndBound(get(bounds, 2), false, value2, value2, value3, value4);
++ assertEndBound(get(bounds, 3), true, value2);
+
+ // (clustering_0, clustering1) >= (1, 2)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
++ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
restrictions = restrictions.mergeWith(slice);
- SortedSet<Slice.Bound> bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
++ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
assertEquals(1, bounds.size());
- assertStartBound(get(bounds, 0), false, value1);
- assertComposite(bounds.get(0), value1, value2, EOC.NONE);
++ assertStartBound(get(bounds, 0), true, value1, value2);
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
assertEquals(1, bounds.size());
- assertEmptyComposite(bounds.get(0));
+ assertEmptyEnd(get(bounds, 0));
- slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1);
+ // (clustering_0, clustering1, clustering_2, clustering_3) >= (1, 2, 3, 4)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2, value3, value4);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
restrictions = restrictions.mergeWith(slice);
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertStartBound(get(bounds, 0), true, value1);
+ assertEquals(2, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.START);
- assertComposite(bounds.get(1), value1, value2, EOC.END);
++ assertStartBound(get(bounds, 0), true, value1, value2);
++ assertStartBound(get(bounds, 1), false, value1, value2);
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertEmptyEnd(get(bounds, 0));
+ assertEquals(2, bounds.size());
- assertComposite(bounds.get(0), value1, value2, value3, value4, EOC.END);
- assertEmptyComposite(bounds.get(1));
++ assertEndBound(get(bounds, 0), true, value1, value2, value3, value4);
++ assertEmptyEnd(get(bounds, 1));
- slice = newMultiSlice(cfMetaData, 0, Bound.END, true, value1);
+ // (clustering_0, clustering1, clustering_2, clustering_3) <= (1, 2, 3, 4)
+ slice = newMultiSlice(cfMetaData, 0, Bound.END, true, value1, value2, value3, value4);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
restrictions = restrictions.mergeWith(slice);
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
+ assertEquals(2, bounds.size());
- assertEmptyComposite(bounds.get(0));
- assertComposite(bounds.get(1), value1, value2, value3, value4, EOC.NONE);
+ assertEmptyStart(get(bounds, 0));
++ assertStartBound(get(bounds, 1), true, value1, value2, value3, value4);
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertEndBound(get(bounds, 0), true, value1);
+ assertEquals(2, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.START);
- assertComposite(bounds.get(1), value1, value2, EOC.END);
++ assertEndBound(get(bounds, 0), false, value1, value2);
++ assertEndBound(get(bounds, 1), true, value1, value2);
- slice = newMultiSlice(cfMetaData, 0, Bound.END, false, value1);
+ // (clustering_0, clustering1, clustering_2, clustering_3) < (1, 2, 3, 4)
+ slice = newMultiSlice(cfMetaData, 0, Bound.END, false, value1, value2, value3, value4);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
restrictions = restrictions.mergeWith(slice);
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
+ assertEquals(2, bounds.size());
- assertEmptyComposite(bounds.get(0));
- assertComposite(bounds.get(1), value1, value2, value3, value4, EOC.END);
+ assertEmptyStart(get(bounds, 0));
++ assertStartBound(get(bounds, 1), false, value1, value2, value3, value4);
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertEndBound(get(bounds, 0), false, value1);
+ assertEquals(2, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.START);
- assertComposite(bounds.get(1), value1, value2, EOC.END);
++ assertEndBound(get(bounds, 0), false, value1, value2);
++ assertEndBound(get(bounds, 1), true, value1, value2);
- slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1);
- Restriction slice2 = newMultiSlice(cfMetaData, 0, Bound.END, false, value2);
+ // (clustering_0, clustering1, clustering_2, clustering_3) > (1, 2, 3, 4) AND (clustering_0, clustering_1) < (2, 3)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, false, value1, value2, value3, value4);
+ Restriction slice2 = newMultiSlice(cfMetaData, 0, Bound.END, false, value2, value3);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertStartBound(get(bounds, 0), false, value1);
+ assertEquals(2, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.START);
- assertComposite(bounds.get(1), value1, value2, EOC.END);
++ assertStartBound(get(bounds, 0), true, value1, value2);
++ assertStartBound(get(bounds, 1), false, value1, value2);
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertEndBound(get(bounds, 0), false, value2);
+ assertEquals(2, bounds.size());
- assertComposite(bounds.get(0), value1, value2, value3, value4, EOC.START);
- assertComposite(bounds.get(1), value2, value3, EOC.START);
++ assertEndBound(get(bounds, 0), false, value1, value2, value3, value4);
++ assertEndBound(get(bounds, 1), false, value2, value3);
- slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1);
- slice2 = newMultiSlice(cfMetaData, 0, Bound.END, true, value2);
+ // (clustering_0, clustering1, clustering_2, clustering_3) >= (1, 2, 3, 4) AND (clustering_0, clustering1, clustering_2, clustering_3) <= (4, 3, 2, 1)
+ slice = newMultiSlice(cfMetaData, 0, Bound.START, true, value1, value2, value3, value4);
+ slice2 = newMultiSlice(cfMetaData, 0, Bound.END, true, value4, value3, value2, value1);
- restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator);
+ restrictions = new PrimaryKeyRestrictionSet(cfMetaData.comparator, false);
restrictions = restrictions.mergeWith(slice).mergeWith(slice2);
- bounds = restrictions.boundsAsComposites(Bound.START, QueryOptions.DEFAULT);
+ bounds = restrictions.boundsAsClustering(Bound.START, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertStartBound(get(bounds, 0), true, value1);
+ assertEquals(3, bounds.size());
- assertComposite(bounds.get(0), value1, value2, EOC.START);
- assertComposite(bounds.get(1), value1, value2, EOC.END);
- assertComposite(bounds.get(2), value4, value3, value2, value1, EOC.NONE);
++ assertStartBound(get(bounds, 0), true, value1, value2);
++ assertStartBound(get(bounds, 1), false, value1, value2);
++ assertStartBound(get(bounds, 2), true, value4, value3, value2, value1);
- bounds = restrictions.boundsAsComposites(Bound.END, QueryOptions.DEFAULT);
+ bounds = restrictions.boundsAsClustering(Bound.END, QueryOptions.DEFAULT);
- assertEquals(1, bounds.size());
- assertEndBound(get(bounds, 0), true, value2);
+ assertEquals(3, bounds.size());
- assertComposite(bounds.get(0), value1, value2, value3, value4, EOC.END);
- assertComposite(bounds.get(1), value4, value3, EOC.START);
- assertComposite(bounds.get(2), value4, value3, EOC.END);
++ assertEndBound(get(bounds, 0), true, value1, value2, value3, value4);
++ assertEndBound(get(bounds, 1), false, value4, value3);
++ assertEndBound(get(bounds, 2), true, value4, value3);
}
/**
- * Test multi-column slice restrictions (e.g '(clustering_0, clustering_1) > (1, 2)')
+ * Test multi-column slice restrictions with ascending, descending, ascending and descending columns
+ * (e.g '(clustering_0, clustering1, clustering_3, clustering4) > (1, 2, 3, 4)')
*/
@Test
- public void testboundsAsClusteringWithMultiSliceRestrictionsWithTwo
<TRUNCATED>
[3/6] cassandra git commit: Fix SELECT on tuple relations for mixed
ASC/DESC clustering order
Posted by bl...@apache.org.
Fix SELECT on tuple relations for mixed ASC/DESC clustering order
patch by Marcin Szymaniuk and Benjamin Lerer; reviewed by Sylvain Lebresne for CASSANDRA-7281
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/90fc8969
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/90fc8969
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/90fc8969
Branch: refs/heads/trunk
Commit: 90fc8969a656b183e81496e479db35f321c8a3aa
Parents: 984e174
Author: Marcin Szymaniuk <ma...@gmail.com>
Authored: Wed Feb 10 18:29:54 2016 +0100
Committer: Benjamin Lerer <b....@gmail.com>
Committed: Thu Feb 11 10:28:45 2016 +0100
----------------------------------------------------------------------
CHANGES.txt | 1 +
.../cql3/restrictions/AbstractRestriction.java | 15 +-
.../ForwardingPrimaryKeyRestrictions.java | 3 +-
.../restrictions/MultiColumnRestriction.java | 80 +-
.../restrictions/PrimaryKeyRestrictionSet.java | 95 +-
.../cql3/restrictions/Restriction.java | 3 +-
.../cql3/restrictions/RestrictionSet.java | 4 +-
.../restrictions/SingleColumnRestriction.java | 9 +-
.../cql3/restrictions/TokenRestriction.java | 3 +-
.../cql3/statements/ModificationStatement.java | 19 +-
.../db/composites/CompositesBuilder.java | 20 +-
.../PrimaryKeyRestrictionSetTest.java | 1164 +++++++++++++++---
.../SelectMultiColumnRelationTest.java | 859 ++++++++++++-
13 files changed, 2043 insertions(+), 232 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/90fc8969/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 7565386..5674b9d 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
2.2.6
+ * Fix SELECT on tuple relations for mixed ASC/DESC clustering order (CASSANDRA-7281)
* (cqlsh) Support utf-8/cp65001 encoding on Windows (CASSANDRA-11030)
* Fix paging on DISTINCT queries repeats result when first row in partition changes (CASSANDRA-10010)
Merged from 2.1:
http://git-wip-us.apache.org/repos/asf/cassandra/blob/90fc8969/src/java/org/apache/cassandra/cql3/restrictions/AbstractRestriction.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/restrictions/AbstractRestriction.java b/src/java/org/apache/cassandra/cql3/restrictions/AbstractRestriction.java
index 64c94f4..dac7203 100644
--- a/src/java/org/apache/cassandra/cql3/restrictions/AbstractRestriction.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/AbstractRestriction.java
@@ -19,12 +19,13 @@ package org.apache.cassandra.cql3.restrictions;
import java.nio.ByteBuffer;
+import org.apache.cassandra.config.ColumnDefinition;
+
import org.apache.cassandra.cql3.ColumnSpecification;
import org.apache.cassandra.cql3.QueryOptions;
import org.apache.cassandra.cql3.statements.Bound;
import org.apache.cassandra.db.composites.CompositesBuilder;
import org.apache.cassandra.exceptions.InvalidRequestException;
-
import static org.apache.cassandra.cql3.statements.RequestValidations.checkBindValueSet;
import static org.apache.cassandra.cql3.statements.RequestValidations.checkFalse;
import static org.apache.cassandra.cql3.statements.RequestValidations.checkNotNull;
@@ -97,4 +98,16 @@ abstract class AbstractRestriction implements Restriction
checkFalse(value.remaining() > 0xFFFF, "Index expression values may not be larger than 64K");
return value;
}
+
+ /**
+ * Reverses the specified bound if the column type is a reversed one.
+ *
+ * @param columnDefinition the column definition
+ * @param bound the bound
+ * @return the bound reversed if the column type was a reversed one or the original bound
+ */
+ protected static Bound reverseBoundIfNeeded(ColumnDefinition columnDefinition, Bound bound)
+ {
+ return columnDefinition.isReversedType() ? bound.reverse() : bound;
+ }
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/90fc8969/src/java/org/apache/cassandra/cql3/restrictions/ForwardingPrimaryKeyRestrictions.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/restrictions/ForwardingPrimaryKeyRestrictions.java b/src/java/org/apache/cassandra/cql3/restrictions/ForwardingPrimaryKeyRestrictions.java
index 03c6cbc..71855a0 100644
--- a/src/java/org/apache/cassandra/cql3/restrictions/ForwardingPrimaryKeyRestrictions.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/ForwardingPrimaryKeyRestrictions.java
@@ -18,7 +18,6 @@
package org.apache.cassandra.cql3.restrictions;
import java.nio.ByteBuffer;
-import java.util.Collection;
import java.util.List;
import org.apache.cassandra.config.ColumnDefinition;
@@ -51,7 +50,7 @@ abstract class ForwardingPrimaryKeyRestrictions implements PrimaryKeyRestriction
}
@Override
- public Collection<ColumnDefinition> getColumnDefs()
+ public List<ColumnDefinition> getColumnDefs()
{
return getDelegate().getColumnDefs();
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/90fc8969/src/java/org/apache/cassandra/cql3/restrictions/MultiColumnRestriction.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/restrictions/MultiColumnRestriction.java b/src/java/org/apache/cassandra/cql3/restrictions/MultiColumnRestriction.java
index 84a3952..96e6f2b 100644
--- a/src/java/org/apache/cassandra/cql3/restrictions/MultiColumnRestriction.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/MultiColumnRestriction.java
@@ -20,11 +20,9 @@ package org.apache.cassandra.cql3.restrictions;
import java.nio.ByteBuffer;
import java.util.*;
-import org.apache.cassandra.cql3.Term.Terminal;
-
-import org.apache.cassandra.cql3.Term;
import org.apache.cassandra.config.ColumnDefinition;
import org.apache.cassandra.cql3.*;
+import org.apache.cassandra.cql3.Term.Terminal;
import org.apache.cassandra.cql3.functions.Function;
import org.apache.cassandra.cql3.statements.Bound;
import org.apache.cassandra.db.IndexExpression;
@@ -68,7 +66,7 @@ public abstract class MultiColumnRestriction extends AbstractRestriction
}
@Override
- public Collection<ColumnDefinition> getColumnDefs()
+ public List<ColumnDefinition> getColumnDefs()
{
return columnDefs;
}
@@ -361,14 +359,62 @@ public abstract class MultiColumnRestriction extends AbstractRestriction
@Override
public CompositesBuilder appendBoundTo(CompositesBuilder builder, Bound bound, QueryOptions options)
{
- List<ByteBuffer> vals = componentBounds(bound, options);
+ boolean reversed = getFirstColumn().isReversedType();
+
+ EnumMap<Bound, List<ByteBuffer>> componentBounds = new EnumMap<Bound, List<ByteBuffer>>(Bound.class);
+ componentBounds.put(Bound.START, componentBounds(Bound.START, options));
+ componentBounds.put(Bound.END, componentBounds(Bound.END, options));
- for (int i = 0, m = vals.size(); i < m; i++)
+ List<List<ByteBuffer>> toAdd = new ArrayList<>();
+ List<ByteBuffer> values = new ArrayList<>();
+
+ for (int i = 0, m = columnDefs.size(); i < m; i++)
{
- ByteBuffer v = checkNotNull(vals.get(i), "Invalid null value in condition for column %s", columnDefs.get(i).name);
- builder.addElementToAll(v);
+ ColumnDefinition column = columnDefs.get(i);
+ Bound b = reverseBoundIfNeeded(column, bound);
+
+ // For mixed order columns, we need to create additional slices when 2 columns are in reverse order
+ if (reversed != column.isReversedType())
+ {
+ reversed = column.isReversedType();
+ // As we are switching direction we need to add the current composite
+ toAdd.add(values);
+
+ // The new bound side has no value for this component. just stop
+ if (!hasComponent(b, i, componentBounds))
+ continue;
+
+ // The other side has still some components. We need to end the slice that we have just open.
+ if (hasComponent(b.reverse(), i, componentBounds))
+ toAdd.add(values);
+
+ // We need to rebuild where we are in this bound side
+ values = new ArrayList<ByteBuffer>();
+
+ List<ByteBuffer> vals = componentBounds.get(b);
+
+ int n = Math.min(i, vals.size());
+ for (int j = 0; j < n; j++)
+ {
+ ByteBuffer v = checkNotNull(vals.get(j),
+ "Invalid null value in condition for column %s",
+ columnDefs.get(j).name);
+ values.add(v);
+ }
+ }
+
+ if (!hasComponent(b, i, componentBounds))
+ continue;
+
+ ByteBuffer v = checkNotNull(componentBounds.get(b).get(i), "Invalid null value in condition for column %s", columnDefs.get(i).name);
+ values.add(v);
}
- return builder;
+ toAdd.add(values);
+
+ if (bound.isEnd())
+ Collections.reverse(toAdd);
+
+ return builder.addAllElementsToAll(toAdd);
}
@Override
@@ -378,9 +424,9 @@ public abstract class MultiColumnRestriction extends AbstractRestriction
}
@Override
- public boolean hasBound(Bound b)
+ public boolean hasBound(Bound bound)
{
- return slice.hasBound(b);
+ return slice.hasBound(bound);
}
@Override
@@ -390,9 +436,9 @@ public abstract class MultiColumnRestriction extends AbstractRestriction
}
@Override
- public boolean isInclusive(Bound b)
+ public boolean isInclusive(Bound bound)
{
- return slice.isInclusive(b);
+ return slice.isInclusive(bound);
}
@Override
@@ -448,6 +494,9 @@ public abstract class MultiColumnRestriction extends AbstractRestriction
*/
private List<ByteBuffer> componentBounds(Bound b, QueryOptions options) throws InvalidRequestException
{
+ if (!slice.hasBound(b))
+ return Collections.emptyList();
+
Terminal terminal = slice.bound(b).bind(options);
if (terminal instanceof Tuples.Value)
@@ -457,5 +506,10 @@ public abstract class MultiColumnRestriction extends AbstractRestriction
return Collections.singletonList(terminal.get(options.getProtocolVersion()));
}
+
+ private boolean hasComponent(Bound b, int index, EnumMap<Bound, List<ByteBuffer>> componentBounds)
+ {
+ return componentBounds.get(b).size() > index;
+ }
}
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/90fc8969/src/java/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSet.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSet.java b/src/java/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSet.java
index 3a20f6a..936dbd6 100644
--- a/src/java/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSet.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSet.java
@@ -18,10 +18,9 @@
package org.apache.cassandra.cql3.restrictions;
import java.nio.ByteBuffer;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
+import java.util.*;
+import org.apache.cassandra.db.composites.Composite;
import org.apache.cassandra.config.ColumnDefinition;
import org.apache.cassandra.cql3.QueryOptions;
import org.apache.cassandra.cql3.functions.Function;
@@ -31,7 +30,6 @@ import org.apache.cassandra.db.composites.*;
import org.apache.cassandra.db.composites.Composite.EOC;
import org.apache.cassandra.db.index.SecondaryIndexManager;
import org.apache.cassandra.exceptions.InvalidRequestException;
-
import static org.apache.cassandra.cql3.statements.RequestValidations.checkFalse;
import static org.apache.cassandra.cql3.statements.RequestValidations.invalidRequest;
@@ -163,7 +161,7 @@ final class PrimaryKeyRestrictionSet extends AbstractPrimaryKeyRestrictions
@Override
public List<Composite> valuesAsComposites(QueryOptions options) throws InvalidRequestException
{
- return appendTo(new CompositesBuilder(ctype), options).build();
+ return filterAndSort(appendTo(new CompositesBuilder(ctype), options).build());
}
@Override
@@ -197,29 +195,16 @@ final class PrimaryKeyRestrictionSet extends AbstractPrimaryKeyRestrictions
{
ColumnDefinition def = r.getFirstColumn();
- // In a restriction, we always have Bound.START < Bound.END for the "base" comparator.
- // So if we're doing a reverse slice, we must inverse the bounds when giving them as start and end of the slice filter.
- // But if the actual comparator itself is reversed, we must inversed the bounds too.
- Bound b = !def.isReversedType() ? bound : bound.reverse();
if (keyPosition != def.position() || r.isContains())
break;
if (r.isSlice())
{
- if (!r.hasBound(b))
- {
- // There wasn't any non EQ relation on that key, we select all records having the preceding component as prefix.
- // For composites, if there was preceding component and we're computing the end, we must change the last component
- // End-Of-Component, otherwise we would be selecting only one record.
- return builder.buildWithEOC(bound.isEnd() ? EOC.END : EOC.START);
- }
-
- r.appendBoundTo(builder, b, options);
- Composite.EOC eoc = eocFor(r, bound, b);
- return builder.buildWithEOC(eoc);
+ r.appendBoundTo(builder, bound, options);
+ return filterAndSort(setEocs(r, bound, builder.build()));
}
- r.appendBoundTo(builder, b, options);
+ r.appendBoundTo(builder, bound, options);
if (builder.hasMissingElements())
return Collections.emptyList();
@@ -233,7 +218,71 @@ final class PrimaryKeyRestrictionSet extends AbstractPrimaryKeyRestrictions
// case using the eoc would be bad, since for the random partitioner we have no guarantee that
// prefix.end() will sort after prefix (see #5240).
EOC eoc = !builder.hasRemaining() ? EOC.NONE : (bound.isEnd() ? EOC.END : EOC.START);
- return builder.buildWithEOC(eoc);
+ return filterAndSort(builder.buildWithEOC(eoc));
+ }
+
+ /**
+ * Removes duplicates and sort the specified composites.
+ *
+ * @param composites the composites to filter and sort
+ * @return the composites sorted and without duplicates
+ */
+ private List<Composite> filterAndSort(List<Composite> composites)
+ {
+ if (composites.size() <= 1)
+ return composites;
+
+ TreeSet<Composite> set = new TreeSet<Composite>(ctype);
+ set.addAll(composites);
+ return new ArrayList<>(set);
+ }
+
+ /**
+ * Sets EOCs for the composites returned by the specified slice restriction for the given bound.
+ *
+ * @param r the slice restriction
+ * @param bound the bound
+ * @param composites the composites
+ * @return the composites with their EOCs properly set
+ */
+ private List<Composite> setEocs(Restriction r, Bound bound, List<Composite> composites)
+ {
+ List<Composite> list = new ArrayList<>(composites.size());
+
+ // The first column of the slice might not be the first clustering column (e.g. clustering_0 = ? AND (clustering_1, clustering_2) >= (?, ?)
+ int offset = r.getFirstColumn().position();
+
+ for (int i = 0, m = composites.size(); i < m; i++)
+ {
+ Composite composite = composites.get(i);
+
+ // Handle the no bound case
+ if (composite.size() == offset)
+ {
+ list.add(composite.withEOC(bound.isEnd() ? EOC.END : EOC.START));
+ continue;
+ }
+
+ // In the case of mixed order columns, we will have some extra slices where the columns change directions.
+ // For example: if we have clustering_0 DESC and clustering_1 ASC a slice like (clustering_0, clustering_1) > (1, 2)
+ // will produce 2 slices: [EMPTY, 1.START] and [1.2.END, 1.END]
+ // So, the END bound will return 2 composite with the same values 1
+ if (composite.size() <= r.getLastColumn().position() && i < m - 1 && composite.equals(composites.get(i + 1)))
+ {
+ list.add(composite.withEOC(EOC.START));
+ list.add(composites.get(i++).withEOC(EOC.END));
+ continue;
+ }
+
+ // Handle the normal bounds
+ ColumnDefinition column = r.getColumnDefs().get(composite.size() - 1 - offset);
+ Bound b = reverseBoundIfNeeded(column, bound);
+
+ Composite.EOC eoc = eocFor(r, bound, b);
+ list.add(composite.withEOC(eoc));
+ }
+
+ return list;
}
@Override
@@ -307,7 +356,7 @@ final class PrimaryKeyRestrictionSet extends AbstractPrimaryKeyRestrictions
}
@Override
- public Collection<ColumnDefinition> getColumnDefs()
+ public List<ColumnDefinition> getColumnDefs()
{
return restrictions.getColumnDefs();
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/90fc8969/src/java/org/apache/cassandra/cql3/restrictions/Restriction.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/restrictions/Restriction.java b/src/java/org/apache/cassandra/cql3/restrictions/Restriction.java
index c115a3b..f0ea6a7 100644
--- a/src/java/org/apache/cassandra/cql3/restrictions/Restriction.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/Restriction.java
@@ -17,7 +17,6 @@
*/
package org.apache.cassandra.cql3.restrictions;
-import java.util.Collection;
import java.util.List;
import org.apache.cassandra.config.ColumnDefinition;
@@ -60,7 +59,7 @@ public interface Restriction
* Returns the column definitions in position order.
* @return the column definitions in position order.
*/
- public Collection<ColumnDefinition> getColumnDefs();
+ public List<ColumnDefinition> getColumnDefs();
/**
* Return an Iterable over all of the functions (both native and user-defined) used by any component
http://git-wip-us.apache.org/repos/asf/cassandra/blob/90fc8969/src/java/org/apache/cassandra/cql3/restrictions/RestrictionSet.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/restrictions/RestrictionSet.java b/src/java/org/apache/cassandra/cql3/restrictions/RestrictionSet.java
index 6bf7666..676ed13 100644
--- a/src/java/org/apache/cassandra/cql3/restrictions/RestrictionSet.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/RestrictionSet.java
@@ -75,9 +75,9 @@ final class RestrictionSet implements Restrictions, Iterable<Restriction>
}
@Override
- public final Set<ColumnDefinition> getColumnDefs()
+ public final List<ColumnDefinition> getColumnDefs()
{
- return restrictions.keySet();
+ return new ArrayList<>(restrictions.keySet());
}
@Override
http://git-wip-us.apache.org/repos/asf/cassandra/blob/90fc8969/src/java/org/apache/cassandra/cql3/restrictions/SingleColumnRestriction.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/restrictions/SingleColumnRestriction.java b/src/java/org/apache/cassandra/cql3/restrictions/SingleColumnRestriction.java
index afa0419..735a2e2 100644
--- a/src/java/org/apache/cassandra/cql3/restrictions/SingleColumnRestriction.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/SingleColumnRestriction.java
@@ -52,7 +52,7 @@ public abstract class SingleColumnRestriction extends AbstractRestriction
}
@Override
- public Collection<ColumnDefinition> getColumnDefs()
+ public List<ColumnDefinition> getColumnDefs()
{
return Collections.singletonList(columnDef);
}
@@ -351,7 +351,12 @@ public abstract class SingleColumnRestriction extends AbstractRestriction
@Override
public CompositesBuilder appendBoundTo(CompositesBuilder builder, Bound bound, QueryOptions options)
{
- ByteBuffer value = slice.bound(bound).bindAndGet(options);
+ Bound b = reverseBoundIfNeeded(getFirstColumn(), bound);
+
+ if (!hasBound(b))
+ return builder;
+
+ ByteBuffer value = slice.bound(b).bindAndGet(options);
checkBindValueSet(value, "Invalid unset value for column %s", columnDef.name);
return builder.addElementToAll(value);
http://git-wip-us.apache.org/repos/asf/cassandra/blob/90fc8969/src/java/org/apache/cassandra/cql3/restrictions/TokenRestriction.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/restrictions/TokenRestriction.java b/src/java/org/apache/cassandra/cql3/restrictions/TokenRestriction.java
index f8cd0dc..3cd3304 100644
--- a/src/java/org/apache/cassandra/cql3/restrictions/TokenRestriction.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/TokenRestriction.java
@@ -18,7 +18,6 @@
package org.apache.cassandra.cql3.restrictions;
import java.nio.ByteBuffer;
-import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -67,7 +66,7 @@ public abstract class TokenRestriction extends AbstractPrimaryKeyRestrictions
}
@Override
- public Collection<ColumnDefinition> getColumnDefs()
+ public List<ColumnDefinition> getColumnDefs()
{
return columnDefs;
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/90fc8969/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
index 8b594dd..fbdfc0c 100644
--- a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
@@ -48,7 +48,6 @@ import org.apache.cassandra.transport.messages.ResultMessage;
import org.apache.cassandra.triggers.TriggerExecutor;
import org.apache.cassandra.utils.Pair;
import org.apache.cassandra.utils.UUIDGen;
-
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.invalidRequest;
@@ -310,7 +309,7 @@ public abstract class ModificationStatement implements CQLStatement
r.appendTo(keyBuilder, options);
}
- return Lists.transform(keyBuilder.build(), new com.google.common.base.Function<Composite, ByteBuffer>()
+ return Lists.transform(filterAndSort(keyBuilder.build()), new com.google.common.base.Function<Composite, ByteBuffer>()
{
@Override
public ByteBuffer apply(Composite composite)
@@ -404,6 +403,22 @@ public abstract class ModificationStatement implements CQLStatement
return builder.build().get(0); // We only allow IN for row keys so far
}
+ /**
+ * Removes duplicates and sort the specified composites.
+ *
+ * @param composites the composites to filter and sort
+ * @return the composites sorted and without duplicates
+ */
+ private List<Composite> filterAndSort(List<Composite> composites)
+ {
+ if (composites.size() <= 1)
+ return composites;
+
+ TreeSet<Composite> set = new TreeSet<Composite>(cfm.getKeyValidatorAsCType());
+ set.addAll(composites);
+ return new ArrayList<>(set);
+ }
+
protected ColumnDefinition getFirstEmptyKey()
{
for (ColumnDefinition def : cfm.clusteringColumns())
http://git-wip-us.apache.org/repos/asf/cassandra/blob/90fc8969/src/java/org/apache/cassandra/db/composites/CompositesBuilder.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/composites/CompositesBuilder.java b/src/java/org/apache/cassandra/db/composites/CompositesBuilder.java
index 25a510f..9a4da9e 100644
--- a/src/java/org/apache/cassandra/db/composites/CompositesBuilder.java
+++ b/src/java/org/apache/cassandra/db/composites/CompositesBuilder.java
@@ -181,9 +181,6 @@ public final class CompositesBuilder
List<ByteBuffer> value = values.get(j);
- if (value.isEmpty())
- hasMissingElements = true;
-
if (value.contains(null))
containsNull = true;
if (value.contains(ByteBufferUtil.UNSET_BYTE_BUFFER))
@@ -283,26 +280,15 @@ public final class CompositesBuilder
if (elementsList.isEmpty())
return singletonList(builder.build().withEOC(eoc));
- // Use a Set to sort if needed and eliminate duplicates
- Set<Composite> set = newSet();
+ List<Composite> list = new ArrayList<>();
for (int i = 0, m = elementsList.size(); i < m; i++)
{
List<ByteBuffer> elements = elementsList.get(i);
- set.add(builder.buildWith(elements).withEOC(eoc));
+ list.add(builder.buildWith(elements).withEOC(eoc));
}
- return new ArrayList<>(set);
- }
-
- /**
- * Returns a new <code>Set</code> instance that will be used to eliminate duplicates and sort the results.
- *
- * @return a new <code>Set</code> instance.
- */
- private Set<Composite> newSet()
- {
- return new TreeSet<>(ctype);
+ return list;
}
private void checkUpdateable()