This is an automated email from the ASF dual-hosted git repository.
adelapena pushed a commit to branch cassandra-4.0
in repository https://gitbox.apache.org/repos/asf/cassandra.git
The following commit(s) were added to refs/heads/cassandra-4.0 by this push:
new 2873c91269 Split ReadRepairQueryTypesTest to avoid JUnit timeouts
2873c91269 is described below
commit 2873c9126979e21a8089e9a18d96af802745dbc2
Author: Andrés de la Peña <[email protected]>
AuthorDate: Wed Apr 13 12:09:17 2022 +0100
Split ReadRepairQueryTypesTest to avoid JUnit timeouts
patch by Andrés de la Peña; reviewed by Caleb Rackliffe for CASSANDRA-17543
---
.../test/ReadRepairCollectionQueriesTest.java | 236 ++++
.../distributed/test/ReadRepairInQueriesTest.java | 247 ++++
.../test/ReadRepairPointQueriesTest.java | 79 ++
.../distributed/test/ReadRepairQueryTester.java | 280 +++++
.../distributed/test/ReadRepairQueryTypesTest.java | 1192 --------------------
.../test/ReadRepairRangeQueriesTest.java | 261 +++++
.../test/ReadRepairSliceQueriesTest.java | 145 +++
.../test/ReadRepairUnrestrictedQueriesTest.java | 116 ++
8 files changed, 1364 insertions(+), 1192 deletions(-)
diff --git
a/test/distributed/org/apache/cassandra/distributed/test/ReadRepairCollectionQueriesTest.java
b/test/distributed/org/apache/cassandra/distributed/test/ReadRepairCollectionQueriesTest.java
new file mode 100644
index 0000000000..6149ffc93f
--- /dev/null
+++
b/test/distributed/org/apache/cassandra/distributed/test/ReadRepairCollectionQueriesTest.java
@@ -0,0 +1,236 @@
+/*
+ * 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.distributed.test;
+
+import org.junit.Test;
+
+import static org.apache.cassandra.distributed.shared.AssertUtils.row;
+
+/**
+ * {@link ReadRepairQueryTester} for queries on collections.
+ */
+public class ReadRepairCollectionQueriesTest extends ReadRepairQueryTester
+{
+ /**
+ * Test unrestricted queries with frozen tuples.
+ */
+ @Test
+ public void testTuple()
+ {
+ tester("")
+ .createTable("CREATE TABLE %s (k int PRIMARY KEY, a tuple<int,int>, b
tuple<int,int>)")
+ .mutate("INSERT INTO %s (k, a, b) VALUES (0, (1, 2), (3, 4))")
+ .queryColumns("a", 1, 1,
+ rows(row(tuple(1, 2))),
+ rows(row(0, tuple(1, 2), tuple(3, 4))),
+ rows(row(0, tuple(1, 2), null)))
+ .deleteColumn("DELETE a FROM %s WHERE k=0", "b", 0, 1,
+ rows(row(tuple(3, 4))),
+ rows(row(0, null, tuple(3, 4))),
+ rows(row(0, tuple(1, 2), tuple(3, 4))))
+ .deleteRows("DELETE FROM %s WHERE k=0", 1,
+ rows(),
+ rows(row(0, null, tuple(3, 4))))
+ .tearDown();
+ }
+
+ /**
+ * Test unrestricted queries with frozen sets.
+ */
+ @Test
+ public void testFrozenSet()
+ {
+ tester("")
+ .createTable("CREATE TABLE %s (k int PRIMARY KEY, a frozen<set<int>>,
b frozen<set<int>>)")
+ .mutate("INSERT INTO %s (k, a, b) VALUES (0, {1, 2}, {3, 4})")
+ .queryColumns("a[1]", 1, 1,
+ rows(row(1)),
+ rows(row(0, set(1, 2), set(3, 4))),
+ rows(row(0, set(1, 2), null)))
+ .deleteColumn("DELETE a FROM %s WHERE k=0", "b[4]", 0, 1,
+ rows(row(4)),
+ rows(row(0, null, set(3, 4))),
+ rows(row(0, set(1, 2), set(3, 4))))
+ .deleteRows("DELETE FROM %s WHERE k=0", 1,
+ rows(),
+ rows(row(0, null, set(3, 4))))
+ .tearDown();
+ }
+
+ /**
+ * Test unrestricted queries with frozen lists.
+ */
+ @Test
+ public void testFrozenList()
+ {
+ tester("")
+ .createTable("CREATE TABLE %s (k int PRIMARY KEY, a frozen<list<int>>,
b frozen<list<int>>)")
+ .mutate("INSERT INTO %s (k, a, b) VALUES (0, [1, 2], [3, 4])")
+ .queryColumns("a", 1, 1,
+ rows(row(list(1, 2))),
+ rows(row(0, list(1, 2), list(3, 4))),
+ rows(row(0, list(1, 2), null)))
+ .deleteColumn("DELETE a FROM %s WHERE k=0", "b", 0, 1,
+ rows(row(list(3, 4))),
+ rows(row(0, null, list(3, 4))),
+ rows(row(0, list(1, 2), list(3, 4))))
+ .deleteRows("DELETE FROM %s WHERE k=0", 1,
+ rows(),
+ rows(row(0, null, list(3, 4))))
+ .tearDown();
+ }
+
+ /**
+ * Test unrestricted queries with frozen maps.
+ */
+ @Test
+ public void testFrozenMap()
+ {
+ tester("")
+ .createTable("CREATE TABLE %s (k int PRIMARY KEY, a
frozen<map<int,int>>, b frozen<map<int,int>>)")
+ .mutate("INSERT INTO %s (k, a, b) VALUES (0, {1:10, 2:20}, {3:30,
4:40})")
+ .queryColumns("a[2]", 1, 1,
+ rows(row(20)),
+ rows(row(0, map(1, 10, 2, 20), map(3, 30, 4, 40))),
+ rows(row(0, map(1, 10, 2, 20), null)))
+ .deleteColumn("DELETE a FROM %s WHERE k=0", "b[4]", 0, 1,
+ rows(row(40)),
+ rows(row(0, null, map(3, 30, 4, 40))),
+ rows(row(0, map(1, 10, 2, 20), map(3, 30, 4, 40))))
+ .deleteRows("DELETE FROM %s WHERE k=0", 1,
+ rows(),
+ rows(row(0, null, map(3, 30, 4, 40))))
+ .tearDown();
+ }
+
+ /**
+ * Test unrestricted queries with frozen user-defined types.
+ */
+ @Test
+ public void testFrozentuple()
+ {
+ tester("")
+ .createTable("CREATE TABLE %s (k int PRIMARY KEY, a frozen<udt>, b
frozen<udt>)")
+ .mutate("INSERT INTO %s (k, a, b) VALUES (0, {x:1, y:2}, {x:3, y:4})")
+ .queryColumns("a.x", 1, 1,
+ rows(row(1)),
+ rows(row(0, tuple(1, 2), tuple(3, 4))),
+ rows(row(0, tuple(1, 2), null)))
+ .deleteColumn("DELETE a FROM %s WHERE k=0", "b.y", 0, 1,
+ rows(row(4)),
+ rows(row(0, null, tuple(3, 4))),
+ rows(row(0, tuple(1, 2), tuple(3, 4))))
+ .deleteRows("DELETE FROM %s WHERE k=0", 1,
+ rows(),
+ rows(row(0, null, tuple(3, 4))))
+ .tearDown();
+ }
+
+ /**
+ * Test unrestricted queries with non-frozen sets.
+ */
+ @Test
+ public void testNonFrozenSet()
+ {
+ tester("")
+ .createTable("CREATE TABLE %s (k int PRIMARY KEY, a set<int>, b
set<int>, c int)")
+ .mutate("INSERT INTO %s (k, a, b, c) VALUES (0, {1, 2}, {3, 4}, 10)")
+ .queryColumns("a[1]", 1, 1,
+ rows(row(1)),
+ rows(row(0, set(1, 2), set(3, 4), 10)),
+ rows(row(0, set(1), null, null)))
+ .deleteColumn("UPDATE %s SET a=a-{2} WHERE k=0", "b[4]", 0, 1,
+ rows(row(4)),
+ rows(row(0, set(1), set(3, 4), 10)),
+ rows(row(0, set(1, 2), set(3, 4), 10)))
+ .deleteRows("DELETE FROM %s WHERE k=0", 1,
+ rows(),
+ rows(row(0, set(1), set(3, 4), 10)))
+ .tearDown();
+ }
+
+ /**
+ * Test unrestricted queries with non-frozen lists.
+ */
+ @Test
+ public void testNonFrozenList()
+ {
+ tester("")
+ .createTable("CREATE TABLE %s (k int PRIMARY KEY, a list<int>, b
list<int>, c int)")
+ .mutate("INSERT INTO %s (k, a, b, c) VALUES (0, [1, 2], [3, 4], 10)")
+ .queryColumns("a", 1, 1,
+ rows(row(list(1, 2))),
+ rows(row(0, list(1, 2), list(3, 4), 10)),
+ rows(row(0, list(1, 2), null, null)))
+ .deleteColumn("DELETE a[1] FROM %s WHERE k=0", "b", 0, 1,
+ rows(row(list(3, 4))),
+ rows(row(0, list(1), list(3, 4), 10)),
+ rows(row(0, list(1, 2), list(3, 4), 10)))
+ .deleteRows("DELETE FROM %s WHERE k=0", 1,
+ rows(),
+ rows(row(0, list(1), list(3, 4), 10)))
+ .tearDown();
+ }
+
+ /**
+ * Test unrestricted queries with non-frozen maps.
+ */
+ @Test
+ public void testNonFrozenMap()
+ {
+ tester("")
+ .createTable("CREATE TABLE %s (k int PRIMARY KEY, a map<int,int>, b
map<int,int>, c int)")
+ .mutate("INSERT INTO %s (k, a, b, c) VALUES (0, {1:10, 2:20}, {3:30,
4:40}, 10)")
+ .queryColumns("a[2]", 1, 1,
+ rows(row(20)),
+ rows(row(0, map(1, 10, 2, 20), map(3, 30, 4, 40), 10)),
+ rows(row(0, map(2, 20), null, null)))
+ .deleteColumn("DELETE a[1] FROM %s WHERE k=0", "b[4]", 0, 1,
+ rows(row(40)),
+ rows(row(0, map(2, 20), map(3, 30, 4, 40), 10)),
+ rows(row(0, map(1, 10, 2, 20), map(3, 30, 4, 40), 10)))
+ .deleteRows("DELETE FROM %s WHERE k=0", 1,
+ rows(),
+ rows(row(0, map(2, 20), map(3, 30, 4, 40), 10)))
+ .tearDown();
+ }
+
+ /**
+ * Test unrestricted queries with non-frozen user-defined types.
+ */
+ @Test
+ public void testNonFrozentuple()
+ {
+ tester("")
+ .createTable("CREATE TABLE %s (k int PRIMARY KEY, a udt, b udt, c
int)")
+ .mutate("INSERT INTO %s (k, a, b, c) VALUES (0, {x:1, y:2}, {x:3,
y:4}, 10)")
+ .queryColumns("a.x", 1, 1,
+ rows(row(1)),
+ rows(row(0, tuple(1, 2), tuple(3, 4), 10)),
+ rows(row(0, tuple(1, 2), null, null)))
+ .deleteColumn("DELETE a.x FROM %s WHERE k=0", "b.y", 0, 1,
+ rows(row(4)),
+ rows(row(0, tuple(null, 2), tuple(3, 4), 10)),
+ rows(row(0, tuple(1, 2), tuple(3, 4), 10)))
+ .deleteRows("DELETE FROM %s WHERE k=0", 1,
+ rows(),
+ rows(row(0, tuple(null, 2), tuple(3, 4), 10)))
+ .tearDown();
+ }
+}
diff --git
a/test/distributed/org/apache/cassandra/distributed/test/ReadRepairInQueriesTest.java
b/test/distributed/org/apache/cassandra/distributed/test/ReadRepairInQueriesTest.java
new file mode 100644
index 0000000000..0e34d1821c
--- /dev/null
+++
b/test/distributed/org/apache/cassandra/distributed/test/ReadRepairInQueriesTest.java
@@ -0,0 +1,247 @@
+/*
+ * 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.distributed.test;
+
+import org.junit.Test;
+
+import static org.apache.cassandra.distributed.shared.AssertUtils.row;
+
+/**
+ * {@link ReadRepairQueryTester} for queries using {@code IN} restrictions.
+ */
+public class ReadRepairInQueriesTest extends ReadRepairQueryTester
+{
+ /**
+ * Test queries with an IN restriction on a table without clustering
columns.
+ */
+ @Test
+ public void testInQueryOnSkinnyTable()
+ {
+ tester("WHERE k IN (1, 3)")
+ .createTable("CREATE TABLE %s (k int PRIMARY KEY, a int, b int)")
+ .mutate("INSERT INTO %s (k, a, b) VALUES (1, 10, 100)",
+ "INSERT INTO %s (k, a, b) VALUES (2, 20, 200)",
+ "INSERT INTO %s (k, a, b) VALUES (3, 30, 300)")
+ .queryColumns("a", 2, 2,
+ rows(row(10), row(30)),
+ rows(row(1, 10, 100), row(3, 30, 300)),
+ rows(row(1, 10, null), row(3, 30, null)))
+ .deleteColumn("DELETE a FROM %s WHERE k=1", "b", 0, 1,
+ rows(row(100), row(300)),
+ rows(row(1, null, 100), row(3, 30, 300)),
+ rows(row(1, 10, 100), row(3, 30, 300)))
+ .deleteRows("DELETE FROM %s WHERE k=3", 1,
+ rows(row(1, null, 100)),
+ rows(row(1, null, 100), row(3, 30, 300)))
+ .tearDown(1,
+ rows(row(1, null, 100), row(2, 20, 200)),
+ rows(row(1, null, 100)));
+ }
+
+ /**
+ * Test queries with an IN restriction on a table with clustering columns.
+ */
+ @Test
+ public void testInQueryOnWideTable()
+ {
+ tester("WHERE k IN (1, 3)")
+ .createTable("CREATE TABLE %s (k int, c int, a int, b int, PRIMARY
KEY(k, c))")
+ .mutate("INSERT INTO %s (k, c, a, b) VALUES (1, 10, 100, 1000)",
+ "INSERT INTO %s (k, c, a, b) VALUES (2, 20, 200, 2000)",
+ "INSERT INTO %s (k, c, a, b) VALUES (3, 30, 300, 3000)")
+ .queryColumns("a", 2, 2,
+ rows(row(100), row(300)),
+ rows(row(1, 10, 100, 1000), row(3, 30, 300, 3000)),
+ rows(row(1, 10, 100, null), row(3, 30, 300, null)))
+ .deleteColumn("DELETE a FROM %s WHERE k=1 AND c=10", "b", 0, 1,
+ rows(row(1000), row(3000)),
+ rows(row(1, 10, null, 1000), row(3, 30, 300, 3000)),
+ rows(row(1, 10, 100, 1000), row(3, 30, 300, 3000)))
+ .deleteRows("DELETE FROM %s WHERE k=3", 1,
+ rows(row(1, 10, null, 1000)),
+ rows(row(1, 10, null, 1000), row(3, 30, 300, 3000)))
+ .tearDown(1,
+ rows(row(1, 10, null, 1000), row(2, 20, 200, 2000)),
+ rows(row(1, 10, null, 1000)));
+ }
+
+ /**
+ * Test queries with an IN restriction and a limit on a table without
clustering columns.
+ */
+ @Test
+ public void testInQueryWithLimitOnSkinnyTable()
+ {
+ tester("WHERE k IN (1, 3) LIMIT 1")
+ .createTable("CREATE TABLE %s (k int PRIMARY KEY, a int, b int)")
+ .mutate("INSERT INTO %s (k, a, b) VALUES (1, 10, 100)",
+ "INSERT INTO %s (k, a, b) VALUES (2, 20, 200)",
+ "INSERT INTO %s (k, a, b) VALUES (3, 30, 300)")
+ .queryColumns("a", 1, 1,
+ rows(row(10)),
+ rows(row(1, 10, 100)),
+ rows(row(1, 10, null)))
+ .deleteColumn("DELETE a FROM %s WHERE k=1", "b", 0, 1,
+ rows(row(100)),
+ rows(row(1, null, 100)),
+ rows(row(1, 10, 100)))
+ .deleteRows("DELETE FROM %s WHERE k=1", 2,
+ rows(row(3, 30, 300)),
+ rows(row(1, null, 100)))
+ .tearDown(1,
+ rows(row(2, 20, 200), row(3, 30, 300)),
+ rows(row(3, 30, 300)));
+ }
+
+ /**
+ * Test queries with an IN restriction and a limit on a table with
clustering columns.
+ */
+ @Test
+ public void testInQueryWithLimitOnWideTable()
+ {
+ tester("WHERE k IN (1, 3) LIMIT 1")
+ .createTable("CREATE TABLE %s (k int, c int, a int, b int, PRIMARY
KEY(k, c))")
+ .mutate("INSERT INTO %s (k, c, a, b) VALUES (1, 10, 100, 1000)",
+ "INSERT INTO %s (k, c, a, b) VALUES (2, 20, 200, 2000)",
+ "INSERT INTO %s (k, c, a, b) VALUES (3, 30, 300, 3000)")
+ .queryColumns("a", 1, 1,
+ rows(row(100)),
+ rows(row(1, 10, 100, 1000)),
+ rows(row(1, 10, 100, null)))
+ .deleteColumn("DELETE a FROM %s WHERE k=1 AND c=10", "b", 0, 1,
+ rows(row(1000)),
+ rows(row(1, 10, null, 1000)),
+ rows(row(1, 10, 100, 1000)))
+ .deleteRows("DELETE FROM %s WHERE k=1", 2,
+ rows(row(3, 30, 300, 3000)),
+ rows(row(1, 10, null, 1000)))
+ .tearDown(1,
+ rows(row(2, 20, 200, 2000), row(3, 30, 300, 3000)),
+ rows(row(3, 30, 300, 3000)));
+ }
+
+ /**
+ * Test queries with an IN restriction and a row filter on one of the
selected columns without clustering columns.
+ */
+ @Test
+ public void testInQueryWithFilterOnSelectedColumnOnSkinnyTable()
+ {
+ tester("WHERE k IN (1, 3) AND a=10 ALLOW FILTERING")
+ .createTable("CREATE TABLE %s (k int PRIMARY KEY, a int, b int)")
+ .mutate("INSERT INTO %s (k, a, b) VALUES (1, 10, 100)",
+ "INSERT INTO %s (k, a, b) VALUES (2, 10, 200)",
+ "INSERT INTO %s (k, a, b) VALUES (3, 10, 300)",
+ "INSERT INTO %s (k, a, b) VALUES (4, 40, 400)")
+ .queryColumns("a", 2, 2,
+ rows(row(10), row(10)),
+ rows(row(1, 10, 100), row(3, 10, 300)),
+ rows(row(1, 10, null), row(3, 10, null)))
+ .deleteColumn("DELETE b FROM %s WHERE k=1", "a", 0, 1,
+ rows(row(10), row(10)),
+ rows(row(1, 10, null), row(3, 10, 300)),
+ rows(row(1, 10, 100), row(3, 10, 300)))
+ .deleteRows("DELETE FROM %s WHERE k=1", 1,
+ rows(row(3, 10, 300)),
+ rows(row(1, 10, null), row(3, 10, 300)))
+ .tearDown(2,
+ rows(row(2, 10, 200), row(4, 40, 400), row(3, 10, 300)),
+ rows(row(3, 10, 300)));
+ }
+
+ /**
+ * Test queries with an IN restriction and a row filter on one of the
selected columns with clustering columns.
+ */
+ @Test
+ public void testInQueryWithFilterOnSelectedColumnOnWideTable()
+ {
+ tester("WHERE k IN (1, 3) AND a=100 ALLOW FILTERING")
+ .createTable("CREATE TABLE %s (k int, c int, a int, b int, PRIMARY
KEY(k, c))")
+ .mutate("INSERT INTO %s (k, c, a, b) VALUES (1, 10, 100, 1000)",
+ "INSERT INTO %s (k, c, a, b) VALUES (2, 20, 100, 2000)",
+ "INSERT INTO %s (k, c, a, b) VALUES (3, 30, 100, 3000)",
+ "INSERT INTO %s (k, c, a, b) VALUES (4, 40, 400, 4000)")
+ .queryColumns("a", 2, 2,
+ rows(row(100), row(100)),
+ rows(row(1, 10, 100, 1000), row(3, 30, 100, 3000)),
+ rows(row(1, 10, 100, null), row(3, 30, 100, null)))
+ .deleteColumn("DELETE b FROM %s WHERE k=1 AND c=10", "a", 0, 1,
+ rows(row(100), row(100)),
+ rows(row(1, 10, 100, null), row(3, 30, 100, 3000)),
+ rows(row(1, 10, 100, 1000), row(3, 30, 100, 3000)))
+ .deleteRows("DELETE FROM %s WHERE k=1", 1,
+ rows(row(3, 30, 100, 3000)),
+ rows(row(1, 10, 100, null), row(3, 30, 100, 3000)))
+ .tearDown(2,
+ rows(row(2, 20, 100, 2000), row(4, 40, 400, 4000), row(3,
30, 100, 3000)),
+ rows(row(3, 30, 100, 3000)));
+ }
+
+ /**
+ * Test queries with an IN restriction and a row filter on unselected
columns without clustering columns.
+ */
+ @Test
+ public void testInQueryWithFilterOnUnselectedColumnOnSkinnyTable()
+ {
+ tester("WHERE k IN (1, 3) AND b=100 ALLOW FILTERING")
+ .createTable("CREATE TABLE %s (k int PRIMARY KEY, a int, b int)")
+ .mutate("INSERT INTO %s (k, a, b) VALUES (1, 10, 100)",
+ "INSERT INTO %s (k, a, b) VALUES (2, 20, 100)",
+ "INSERT INTO %s (k, a, b) VALUES (3, 30, 100)")
+ .queryColumns("a", 2, 0,
+ rows(row(10), row(30)),
+ rows(row(1, 10, 100), row(3, 30, 100)),
+ rows(row(1, 10, 100), row(3, 30, 100))) // the filtered
column is repaired even if it isn't selected
+ .deleteColumn("DELETE a FROM %s WHERE k=1", "b", 0, 1,
+ rows(row(100), row(100)),
+ rows(row(1, null, 100), row(3, 30, 100)),
+ rows(row(1, 10, 100), row(3, 30, 100)))
+ .deleteRows("DELETE FROM %s WHERE k=1", 1,
+ rows(row(3, 30, 100)),
+ rows(row(1, null, 100), row(3, 30, 100)))
+ .tearDown(1,
+ rows(row(2, 20, 100), row(3, 30, 100)),
+ rows(row(3, 30, 100)));
+ }
+
+ /**
+ * Test queries with an IN restriction and a row filter on unselected
columns with clustering columns.
+ */
+ @Test
+ public void testInQueryWithFilterOnUnselectedColumnOnWideTable()
+ {
+ tester("WHERE k IN (1, 3) AND b=1000 ALLOW FILTERING")
+ .createTable("CREATE TABLE %s (k int, c int, a int, b int, PRIMARY
KEY(k, c))")
+ .mutate("INSERT INTO %s (k, c, a, b) VALUES (1, 10, 100, 1000)",
+ "INSERT INTO %s (k, c, a, b) VALUES (2, 20, 200, 2000)",
+ "INSERT INTO %s (k, c, a, b) VALUES (3, 30, 300, 3000)")
+ .queryColumns("a", 1, 0,
+ rows(row(100)),
+ rows(row(1, 10, 100, 1000)),
+ rows(row(1, 10, 100, 1000))) // the filtered column is
repaired even if it isn't selected
+ .deleteColumn("DELETE a FROM %s WHERE k=1 AND c=10", "b", 0, 1,
+ rows(row(1000)),
+ rows(row(1, 10, null, 1000)),
+ rows(row(1, 10, 100, 1000)))
+ .deleteRows("DELETE FROM %s WHERE k=1", 1,
+ rows(),
+ rows(row(1, 10, null, 1000)))
+ .tearDown(2,
+ rows(row(2, 20, 200, 2000), row(3, 30, 300, 3000)),
+ rows());
+ }
+}
diff --git
a/test/distributed/org/apache/cassandra/distributed/test/ReadRepairPointQueriesTest.java
b/test/distributed/org/apache/cassandra/distributed/test/ReadRepairPointQueriesTest.java
new file mode 100644
index 0000000000..a226d390d9
--- /dev/null
+++
b/test/distributed/org/apache/cassandra/distributed/test/ReadRepairPointQueriesTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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.distributed.test;
+
+import org.junit.Test;
+
+import static org.apache.cassandra.distributed.shared.AssertUtils.row;
+
+/**
+ * {@link ReadRepairQueryTester} for queries with a restriction on the primary
key.
+ */
+public class ReadRepairPointQueriesTest extends ReadRepairQueryTester
+{
+ /**
+ * Test queries selecting a specific row from a table without clustering
columns.
+ */
+ @Test
+ public void testPointQueryOnSkinnyTable()
+ {
+ tester("WHERE k=1")
+ .createTable("CREATE TABLE %s (k int PRIMARY KEY, a int, b int)")
+ .mutate("INSERT INTO %s (k, a, b) VALUES (1, 2, 3)")
+ .queryColumns("a", 1, 1,
+ rows(row(2)),
+ rows(row(1, 2, 3)),
+ rows(row(1, 2, null)))
+ .deleteColumn("DELETE a FROM %s WHERE k=1", "b", 0, 1,
+ rows(row(3)),
+ rows(row(1, null, 3)),
+ rows(row(1, 2, 3)))
+ .deleteRows("DELETE FROM %s WHERE k=1", 1,
+ rows(),
+ rows(row(1, null, 3)))
+ .tearDown();
+ }
+
+ /**
+ * Test queries selecting a specific row from a table with clustering
columns.
+ */
+ @Test
+ public void testPointQueryOnWideTable()
+ {
+ tester("WHERE k=0 AND c=2")
+ .createTable("CREATE TABLE %s (k int, c int, a int, b int, PRIMARY
KEY(k, c))")
+ .mutate("INSERT INTO %s (k, c, a, b) VALUES (0, 1, 10, 100)",
+ "INSERT INTO %s (k, c, a, b) VALUES (0, 2, 20, 200)",
+ "INSERT INTO %s (k, c, a, b) VALUES (0, 3, 30, 300)")
+ .queryColumns("a", 1, 1,
+ rows(row(20)),
+ rows(row(0, 2, 20, 200)),
+ rows(row(0, 2, 20, null)))
+ .deleteColumn("DELETE a FROM %s WHERE k=0 AND c=2", "b", 0, 1,
+ rows(row(200)),
+ rows(row(0, 2, null, 200)),
+ rows(row(0, 2, 20, 200)))
+ .deleteRows("DELETE FROM %s WHERE k=0 AND c=2", 1,
+ rows(),
+ rows(row(0, 2, null, 200)))
+ .tearDown(paging ? 2 : 1,
+ rows(row(0, 1, 10, 100), row(0, 3, 30, 300)),
+ rows());
+ }
+}
diff --git
a/test/distributed/org/apache/cassandra/distributed/test/ReadRepairQueryTester.java
b/test/distributed/org/apache/cassandra/distributed/test/ReadRepairQueryTester.java
new file mode 100644
index 0000000000..10bf05021b
--- /dev/null
+++
b/test/distributed/org/apache/cassandra/distributed/test/ReadRepairQueryTester.java
@@ -0,0 +1,280 @@
+/*
+ * 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.distributed.test;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import org.apache.cassandra.distributed.Cluster;
+import org.apache.cassandra.service.reads.repair.ReadRepairStrategy;
+
+import static java.util.concurrent.TimeUnit.MINUTES;
+import static org.apache.cassandra.distributed.shared.AssertUtils.assertEquals;
+import static org.apache.cassandra.distributed.shared.AssertUtils.assertRows;
+import static
org.apache.cassandra.service.reads.repair.ReadRepairStrategy.NONE;
+
+/**
+ * Base class for tests around read repair functionality with different query
types and schemas.
+ * <p>
+ * Each test verifies that its tested query triggers read repair propagating
mismatched rows/columns and row/column
+ * deletions. They also verify that the selected rows and columns are
propagated through read repair on missmatch,
+ * and that unselected rows/columns are not repaired.
+ * <p>
+ * The tests are parameterized for:
+ * <ul>
+ * <li><Both {@code NONE} and {@code BLOCKING} read repair stratregies/li>
+ * <li>Data to be repaired residing on the query coordinator or a
replica</li>
+ * <li>Data to be repaired residing on memtables or flushed to
sstables</li>
+ * </ul>
+ * <p>
+ * All derived tests follow a similar pattern:
+ * <ul>
+ * <li>Create a keyspace with RF=2 and a table</li>
+ * <li>Insert some data in only one of the nodes</li>
+ * <li>Run the tested read query selecting a subset of the inserted
columns with CL=ALL</li>
+ * <li>Verify that the previous read has triggered read repair propagating
only the queried columns</li>
+ * <li>Run the tested read query again but this time selecting all the
columns</li>
+ * <li>Verify that the previous read has triggered read repair propagating
the rest of the queried rows</li>
+ * <li>Delete one of the involved columns in just one node</li>
+ * <li>Run the tested read query again but this time selecting a column
different to the deleted one</li>
+ * <li>Verify that the previous read hasn't propagated the column
deletion</li>
+ * <li>Run the tested read query again selecting all the columns</li>
+ * <li>Verify that the previous read has triggered read repair propagating
the column deletion</li>
+ * <li>Delete one of the involved rows in just one node</li>
+ * <li>Run the tested read query again selecting all the columns</li>
+ * <li>Verify that the previous read has triggered read repair propagating
the row deletions</li>
+ * <li>Verify the final status of each node and drop the table</li>
+ * </ul>
+ */
+@RunWith(Parameterized.class)
+public abstract class ReadRepairQueryTester extends TestBaseImpl
+{
+ private static final int NUM_NODES = 2;
+
+ /**
+ * The read repair strategy to be used
+ */
+ @Parameterized.Parameter
+ public ReadRepairStrategy strategy;
+
+ /**
+ * The node to be used as coordinator
+ */
+ @Parameterized.Parameter(1)
+ public int coordinator;
+
+ /**
+ * Whether to flush data after mutations
+ */
+ @Parameterized.Parameter(2)
+ public boolean flush;
+
+ /**
+ * Whether paging is used for the distributed queries
+ */
+ @Parameterized.Parameter(3)
+ public boolean paging;
+
+ @Parameterized.Parameters(name = "{index}: strategy={0} coordinator={1}
flush={2} paging={3}")
+ public static Collection<Object[]> data()
+ {
+ List<Object[]> result = new ArrayList<>();
+ for (int coordinator = 1; coordinator <= NUM_NODES; coordinator++)
+ for (boolean flush : BOOLEANS)
+ for (boolean paging : BOOLEANS)
+ result.add(new Object[]{ ReadRepairStrategy.BLOCKING,
coordinator, flush, paging });
+ result.add(new Object[]{ ReadRepairStrategy.NONE, 1, false, false });
+ return result;
+ }
+
+ private static Cluster cluster;
+
+ @BeforeClass
+ public static void setupCluster() throws IOException
+ {
+ cluster = init(Cluster.build(NUM_NODES)
+ .withConfig(config ->
config.set("read_request_timeout_in_ms", MINUTES.toMillis(1))
+
.set("write_request_timeout_in_ms", MINUTES.toMillis(1)))
+ .start());
+ cluster.schemaChange(withKeyspace("CREATE TYPE %s.udt (x int, y
int)"));
+ }
+
+ @AfterClass
+ public static void teardownCluster()
+ {
+ if (cluster != null)
+ cluster.close();
+ }
+
+ protected Tester tester(String restriction)
+ {
+ return new Tester(restriction, cluster, strategy, coordinator, flush,
paging);
+ }
+
+ protected static class Tester extends ReadRepairTester<Tester>
+ {
+ private final String restriction; // the tested CQL query WHERE
restriction
+ private final String allColumnsQuery; // a SELECT * query for the
table using the tested restriction
+
+ Tester(String restriction, Cluster cluster, ReadRepairStrategy
strategy, int coordinator, boolean flush, boolean paging)
+ {
+ super(cluster, strategy, coordinator, flush, paging, false);
+ this.restriction = restriction;
+
+ allColumnsQuery = String.format("SELECT * FROM %s %s",
qualifiedTableName, restriction);
+ }
+
+ @Override
+ Tester self()
+ {
+ return this;
+ }
+
+ /**
+ * Runs the tested query with CL=ALL selectig only the specified
columns and verifies that it returns the
+ * specified rows. Then, it runs the query again selecting all the
columns, and verifies that the first query
+ * execution only propagated the selected columns, and that the second
execution propagated everything.
+ *
+ * @param columns the selected columns
+ * @param columnsQueryRepairedRows the expected number of repaired
rows when querying only the selected columns
+ * @param rowsQueryRepairedRows the expected number of repaired
rows when querying all the columns
+ * @param columnsQueryResults the rows returned by the query for
a subset of columns
+ * @param node1Rows the rows in the first node, which
is the one with the most updated data
+ * @param node2Rows the rows in the second node, which
is the one meant to receive the RR writes
+ */
+ Tester queryColumns(String columns,
+ long columnsQueryRepairedRows,
+ long rowsQueryRepairedRows,
+ Object[][] columnsQueryResults,
+ Object[][] node1Rows,
+ Object[][] node2Rows)
+ {
+ // query only the selected columns with CL=ALL to trigger partial
read repair on that column
+ String columnsQuery = String.format("SELECT %s FROM %s %s",
columns, qualifiedTableName, restriction);
+ assertRowsDistributed(columnsQuery, columnsQueryRepairedRows,
columnsQueryResults);
+
+ // query entire rows to repair the rest of the columns, that might
trigger new repairs for those columns
+ return verifyQuery(allColumnsQuery, rowsQueryRepairedRows,
node1Rows, node2Rows);
+ }
+
+ /**
+ * Executes the specified column deletion on just one node. Then it
runs the tested query with CL=ALL selectig
+ * only the specified columns (which are expected to be different to
the deleted one) and verifies that it
+ * returns the specified rows. Then it runs the tested query again,
this time selecting all the columns, to
+ * verify that the previous query didn't propagate the column deletion.
+ *
+ * @param columnDeletion the deletion query for a first node
+ * @param columns a subset of the table columns for
the first distributed query
+ * @param columnsQueryRepairedRows the expected number of repaired
rows when querying only the selected columns
+ * @param rowsQueryRepairedRows the expected number of repaired
rows when querying all the columns
+ * @param columnsQueryResults the rows returned by the query for
a subset of columns
+ * @param node1Rows the rows in the first node, which
is the one with the most updated data
+ * @param node2Rows the rows in the second node, which
is the one meant to receive the RR writes
+ */
+ Tester deleteColumn(String columnDeletion,
+ String columns,
+ long columnsQueryRepairedRows,
+ long rowsQueryRepairedRows,
+ Object[][] columnsQueryResults,
+ Object[][] node1Rows,
+ Object[][] node2Rows)
+ {
+ assert restriction != null;
+
+ // execute the column deletion on just one node
+ mutate(1, columnDeletion);
+
+ // verify the columns read with CL=ALL, in most cases this won't
propagate the previous column deletion if
+ // the deleted and read columns don't overlap
+ return queryColumns(columns,
+ columnsQueryRepairedRows,
+ rowsQueryRepairedRows,
+ columnsQueryResults,
+ node1Rows,
+ node2Rows);
+ }
+
+ /**
+ * Executes the specified row deletion on just one node and verifies
the tested query, to ensure that the tested
+ * query propagates the row deletion.
+ */
+ Tester deleteRows(String rowDeletion, long repairedRows, Object[][]
node1Rows, Object[][] node2Rows)
+ {
+ mutate(1, rowDeletion);
+ return verifyQuery(allColumnsQuery, repairedRows, node1Rows,
node2Rows);
+ }
+
+ Tester mutate(String... queries)
+ {
+ return mutate(1, queries);
+ }
+
+ private Tester verifyQuery(String query, long expectedRepairedRows,
Object[][] node1Rows, Object[][] node2Rows)
+ {
+ // verify the per-replica status before running the query
distributedly
+ assertRows(cluster.get(1).executeInternal(query), node1Rows);
+ assertRows(cluster.get(2).executeInternal(query), strategy == NONE
? EMPTY_ROWS : node2Rows);
+
+ // now, run the query with CL=ALL to reconcile and repair the
replicas
+ assertRowsDistributed(query, expectedRepairedRows, node1Rows);
+
+ // run the query locally again to verify that the distributed
query has repaired everything
+ assertRows(cluster.get(1).executeInternal(query), node1Rows);
+ assertRows(cluster.get(2).executeInternal(query), strategy == NONE
? EMPTY_ROWS : node1Rows);
+
+ return this;
+ }
+
+ /**
+ * Verifies that the replicas are empty and drop the table.
+ */
+ void tearDown()
+ {
+ tearDown(0, rows(), rows());
+ }
+
+ /**
+ * Verifies the final status of the nodes with an unrestricted query,
to ensure that the main tested query
+ * hasn't triggered any unexpected repairs. Then, it verifies that the
node that hasn't been used as coordinator
+ * hasn't triggered any unexpected repairs. Finally, it drops the
table.
+ */
+ void tearDown(long repairedRows, Object[][] node1Rows, Object[][]
node2Rows)
+ {
+ verifyQuery("SELECT * FROM " + qualifiedTableName, repairedRows,
node1Rows, node2Rows);
+ for (int n = 1; n <= cluster.size(); n++)
+ {
+ if (n == coordinator)
+ continue;
+
+ long requests = readRepairRequestsCount(n);
+ String message = String.format("No read repair requests were
expected in not-coordinator nodes, " +
+ "but found %d requests in node
%d", requests, n);
+ assertEquals(message, 0, requests);
+ }
+ schemaChange("DROP TABLE " + qualifiedTableName);
+ }
+ }
+}
diff --git
a/test/distributed/org/apache/cassandra/distributed/test/ReadRepairQueryTypesTest.java
b/test/distributed/org/apache/cassandra/distributed/test/ReadRepairQueryTypesTest.java
deleted file mode 100644
index b79e0c4a3a..0000000000
---
a/test/distributed/org/apache/cassandra/distributed/test/ReadRepairQueryTypesTest.java
+++ /dev/null
@@ -1,1192 +0,0 @@
-/*
- * 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.distributed.test;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import org.apache.cassandra.distributed.Cluster;
-import org.apache.cassandra.service.reads.repair.ReadRepairStrategy;
-
-import static java.util.concurrent.TimeUnit.MINUTES;
-import static org.apache.cassandra.distributed.shared.AssertUtils.assertEquals;
-import static org.apache.cassandra.distributed.shared.AssertUtils.assertRows;
-import static org.apache.cassandra.distributed.shared.AssertUtils.row;
-import static
org.apache.cassandra.service.reads.repair.ReadRepairStrategy.NONE;
-
-/**
- * Tests basic read repair functionality with different types of query types
and schemas.
- * <p>
- * Each test verifies that its tested query triggers read repair propagating
mismatched rows/columns and row/column
- * deletions. They also verify that the selected rows and columns are
propagated through read repair on missmatch,
- * and that unselected rows/columns are not repaired.
- * <p>
- * The tests are parameterized for:
- * <ul>
- * <li><Both {@code NONE} and {@code BLOCKING} read repair stratregies/li>
- * <li>Data to be repaired residing on the query coordinator or a
replica</li>
- * <li>Data to be repaired residing on memtables or flushed to
sstables</li>
- * </ul>
- * <p>
- * All the included tests have a similar behaviour:
- * <ul>
- * <li>Create a keyspace with RF=2 and a table</li>
- * <li>Insert some data in only one of the nodes</li>
- * <li>Run the tested read query selecting a subset of the inserted
columns with CL=ALL</li>
- * <li>Verify that the previous read has triggered read repair propagating
only the queried columns</li>
- * <li>Run the tested read query again but this time selecting all the
columns</li>
- * <li>Verify that the previous read has triggered read repair propagating
the rest of the queried rows</li>
- * <li>Delete one of the involved columns in just one node</li>
- * <li>Run the tested read query again but this time selecting a column
different to the deleted one</li>
- * <li>Verify that the previous read hasn't propagated the column
deletion</li>
- * <li>Run the tested read query again selecting all the columns</li>
- * <li>Verify that the previous read has triggered read repair propagating
the column deletion</li>
- * <li>Delete one of the involved rows in just one node</li>
- * <li>Run the tested read query again selecting all the columns</li>
- * <li>Verify that the previous read has triggered read repair propagating
the row deletions</li>
- * <li>Verify the final status of each node and drop the table</li>
- * </ul>
- */
-@RunWith(Parameterized.class)
-public class ReadRepairQueryTypesTest extends TestBaseImpl
-{
- private static final int NUM_NODES = 2;
-
- /**
- * The read repair strategy to be used
- */
- @Parameterized.Parameter
- public ReadRepairStrategy strategy;
-
- /**
- * The node to be used as coordinator
- */
- @Parameterized.Parameter(1)
- public int coordinator;
-
- /**
- * Whether to flush data after mutations
- */
- @Parameterized.Parameter(2)
- public boolean flush;
-
- /**
- * Whether paging is used for the distributed queries
- */
- @Parameterized.Parameter(3)
- public boolean paging;
-
- @Parameterized.Parameters(name = "{index}: strategy={0} coordinator={1}
flush={2} paging={3}")
- public static Collection<Object[]> data()
- {
- List<Object[]> result = new ArrayList<>();
- for (int coordinator = 1; coordinator <= NUM_NODES; coordinator++)
- for (boolean flush : BOOLEANS)
- for (boolean paging : BOOLEANS)
- result.add(new Object[]{ ReadRepairStrategy.BLOCKING,
coordinator, flush, paging });
- result.add(new Object[]{ ReadRepairStrategy.NONE, 1, false, false });
- return result;
- }
-
- private static Cluster cluster;
-
- @BeforeClass
- public static void setupCluster() throws IOException
- {
- cluster = init(Cluster.build(NUM_NODES)
- .withConfig(config ->
config.set("read_request_timeout_in_ms", MINUTES.toMillis(1))
-
.set("write_request_timeout_in_ms", MINUTES.toMillis(1)))
- .start());
- cluster.schemaChange(withKeyspace("CREATE TYPE %s.udt (x int, y
int)"));
- }
-
- @AfterClass
- public static void teardownCluster()
- {
- if (cluster != null)
- cluster.close();
- }
-
- /**
- * Test queries without restrictions on a table without clustering columns.
- */
- @Test
- public void testUnrestrictedQueryOnSkinnyTable()
- {
- tester("")
- .createTable("CREATE TABLE %s (k int PRIMARY KEY, a int, b int)")
- .mutate("INSERT INTO %s (k, a, b) VALUES (1, 10, 100)",
- "INSERT INTO %s (k, a, b) VALUES (2, 20, 200)")
- .queryColumns("a", 2, 2,
- rows(row(10), row(20)),
- rows(row(1, 10, 100), row(2, 20, 200)),
- rows(row(1, 10, null), row(2, 20, null)))
- .deleteColumn("DELETE a FROM %s WHERE k=1", "b", 0, 1,
- rows(row(100), row(200)),
- rows(row(1, null, 100), row(2, 20, 200)),
- rows(row(1, 10, 100), row(2, 20, 200)))
- .deleteRows("DELETE FROM %s WHERE k=1", 1,
- rows(row(2, 20, 200)),
- rows(row(1, null, 100), row(2, 20, 200)))
- .tearDown(0,
- rows(rows(row(2, 20, 200))),
- rows(rows(row(2, 20, 200))));
- }
-
- /**
- * Test queries without restrictions on a table with clustering columns.
- */
- @Test
- public void testUnrestrictedQueryOnWideTable()
- {
- tester("")
- .createTable("CREATE TABLE %s (k int, c int, a int, b int, PRIMARY
KEY(k, c))")
- .mutate("INSERT INTO %s (k, c, a, b) VALUES (1, 10, 100, 1000)",
- "INSERT INTO %s (k, c, a, b) VALUES (1, 20, 200, 2000)",
- "INSERT INTO %s (k, c, a, b) VALUES (2, 30, 300, 3000)")
- .queryColumns("a", paging ? 3 : 2, paging ? 3 : 2,
- rows(row(100), row(200), row(300)),
- rows(row(1, 10, 100, 1000), row(1, 20, 200, 2000),
row(2, 30, 300, 3000)),
- rows(row(1, 10, 100, null), row(1, 20, 200, null),
row(2, 30, 300, null)))
- .deleteColumn("DELETE a FROM %s WHERE k=1 AND c=20", "b", 0, 1,
- rows(row(1000), row(2000), row(3000)),
- rows(row(1, 10, 100, 1000), row(1, 20, null, 2000),
row(2, 30, 300, 3000)),
- rows(row(1, 10, 100, 1000), row(1, 20, 200, 2000),
row(2, 30, 300, 3000)))
- .deleteRows("DELETE FROM %s WHERE k=1 AND c=20", 1,
- rows(row(1, 10, 100, 1000), row(2, 30, 300, 3000)),
- rows(row(1, 10, 100, 1000), row(1, 20, null, 2000), row(2,
30, 300, 3000)))
- .deleteRows("DELETE FROM %s WHERE k=1", 1,
- rows(row(2, 30, 300, 3000)),
- rows(row(1, 10, 100, 1000), row(2, 30, 300, 3000)))
- .tearDown(0,
- rows(row(2, 30, 300, 3000)),
- rows(row(2, 30, 300, 3000)));
- }
-
- /**
- * Test range queries on a table with static columns.
- */
- @Test
- public void testUnrestrictedQueryWithStaticColumns()
- {
- tester("")
- .createTable("CREATE TABLE %s (k int, s1 int static, s2 int static, c
int, PRIMARY KEY(k, c))")
- .mutate("INSERT INTO %s (k, s1, s2) VALUES (1, 10, 100)",
- "INSERT INTO %s (k, c) VALUES (1, 1)",
- "INSERT INTO %s (k, c) VALUES (1, 2)",
- "INSERT INTO %s (k, s1, s2) VALUES (2, 10, 100)")
- .queryColumns("s1", paging ? 3 : 2, 2,
- rows(row(10), row(10), row(10)),
- rows(row(1, 1, 10, 100), row(1, 2, 10, 100), row(2,
null, 10, 100)),
- rows(row(1, 1, 10, null), row(1, 2, 10, null), row(2,
null, 10, null)))
- .deleteColumn("DELETE s1 FROM %s WHERE k=1", "s2", 0, 1,
- rows(row(100), row(100), row(100)),
- rows(row(1, 1, null, 100), row(1, 2, null, 100), row(2,
null, 10, 100)),
- rows(row(1, 1, 10, 100), row(1, 2, 10, 100), row(2,
null, 10, 100)))
- .deleteRows("DELETE FROM %s WHERE k=1 AND c=1", 1,
- rows(row(1, 2, null, 100), row(2, null, 10, 100)),
- rows(row(1, 1, null, 100), row(1, 2, null, 100), row(2,
null, 10, 100)))
- .deleteRows("DELETE FROM %s WHERE k=1", 1,
- rows(row(2, null, 10, 100)),
- rows(row(1, 2, null, 100), row(2, null, 10, 100)))
- .tearDown(0,
- rows(row(2, null, 10, 100)),
- rows(row(2, null, 10, 100)));
- }
-
- /**
- * Test queries selecting a specific row from a table without clustering
columns.
- */
- @Test
- public void testPointQueryOnSkinnyTable()
- {
- tester("WHERE k=1")
- .createTable("CREATE TABLE %s (k int PRIMARY KEY, a int, b int)")
- .mutate("INSERT INTO %s (k, a, b) VALUES (1, 2, 3)")
- .queryColumns("a", 1, 1,
- rows(row(2)),
- rows(row(1, 2, 3)),
- rows(row(1, 2, null)))
- .deleteColumn("DELETE a FROM %s WHERE k=1", "b", 0, 1,
- rows(row(3)),
- rows(row(1, null, 3)),
- rows(row(1, 2, 3)))
- .deleteRows("DELETE FROM %s WHERE k=1", 1,
- rows(),
- rows(row(1, null, 3)))
- .tearDown();
- }
-
- /**
- * Test queries selecting a specific row from a table with clustering
columns.
- */
- @Test
- public void testPointQueryOnWideTable()
- {
- tester("WHERE k=0 AND c=2")
- .createTable("CREATE TABLE %s (k int, c int, a int, b int, PRIMARY
KEY(k, c))")
- .mutate("INSERT INTO %s (k, c, a, b) VALUES (0, 1, 10, 100)",
- "INSERT INTO %s (k, c, a, b) VALUES (0, 2, 20, 200)",
- "INSERT INTO %s (k, c, a, b) VALUES (0, 3, 30, 300)")
- .queryColumns("a", 1, 1,
- rows(row(20)),
- rows(row(0, 2, 20, 200)),
- rows(row(0, 2, 20, null)))
- .deleteColumn("DELETE a FROM %s WHERE k=0 AND c=2", "b", 0, 1,
- rows(row(200)),
- rows(row(0, 2, null, 200)),
- rows(row(0, 2, 20, 200)))
- .deleteRows("DELETE FROM %s WHERE k=0 AND c=2", 1,
- rows(),
- rows(row(0, 2, null, 200)))
- .tearDown(paging ? 2 : 1,
- rows(row(0, 1, 10, 100), row(0, 3, 30, 300)),
- rows());
- }
-
- /**
- * Test range queries on a table without clustering columns.
- */
- @Test
- public void testRangeQueryOnSkinnyTable()
- {
- tester("WHERE token(k) >= token(2)")
- .createTable("CREATE TABLE %s (k int PRIMARY KEY, a int, b int)")
- .mutate("INSERT INTO %s (k, a, b) VALUES (1, 10, 100)",
- "INSERT INTO %s (k, a, b) VALUES (2, 20, 200)",
- "INSERT INTO %s (k, a, b) VALUES (3, 30, 300)")
- .queryColumns("a", 2, 2,
- rows(row(20), row(30)),
- rows(row(2, 20, 200), row(3, 30, 300)),
- rows(row(2, 20, null), row(3, 30, null)))
- .deleteColumn("DELETE a FROM %s WHERE k=2", "b", 0, 1,
- rows(row(200), row(300)),
- rows(row(2, null, 200), row(3, 30, 300)),
- rows(row(2, 20, 200), row(3, 30, 300)))
- .deleteRows("DELETE FROM %s WHERE k=3", 1,
- rows(row(2, null, 200)),
- rows(row(2, null, 200), row(3, 30, 300)))
- .tearDown(1,
- rows(row(1, 10, 100), row(2, null, 200)),
- rows(row(2, null, 200)));
- }
-
- /**
- * Test range queries on a table with clustering columns.
- */
- @Test
- public void testRangeQueryOnWideTable()
- {
- tester("WHERE token(k) >= token(2)")
- .createTable("CREATE TABLE %s (k int, c int, a int, b int, PRIMARY
KEY(k, c))")
- .mutate("INSERT INTO %s (k, c, a, b) VALUES (1, 10, 100, 1000)",
- "INSERT INTO %s (k, c, a, b) VALUES (2, 20, 200, 2000)",
- "INSERT INTO %s (k, c, a, b) VALUES (2, 21, 201, 2001)",
- "INSERT INTO %s (k, c, a, b) VALUES (3, 30, 300, 3000)")
- .queryColumns("a",
- paging ? 3 : 2,
- paging ? 3 : 2,
- rows(row(200), row(201), row(300)),
- rows(row(2, 20, 200, 2000), row(2, 21, 201, 2001),
row(3, 30, 300, 3000)),
- rows(row(2, 20, 200, null), row(2, 21, 201, null),
row(3, 30, 300, null)))
- .deleteColumn("DELETE a FROM %s WHERE k=2 AND c=21", "b", 0, 1,
- rows(row(2000), row(2001), row(3000)),
- rows(row(2, 20, 200, 2000), row(2, 21, null, 2001),
row(3, 30, 300, 3000)),
- rows(row(2, 20, 200, 2000), row(2, 21, 201, 2001),
row(3, 30, 300, 3000)))
- .deleteRows("DELETE FROM %s WHERE k=2 AND c=21", 1,
- rows(row(2, 20, 200, 2000), row(3, 30, 300, 3000)),
- rows(row(2, 20, 200, 2000), row(2, 21, null, 2001), row(3,
30, 300, 3000)))
- .deleteRows("DELETE FROM %s WHERE k=2", 1,
- rows(row(3, 30, 300, 3000)),
- rows(row(2, 20, 200, 2000), row(3, 30, 300, 3000)))
- .tearDown(1,
- rows(row(1, 10, 100, 1000), row(3, 30, 300, 3000)),
- rows(row(3, 30, 300, 3000)));
- }
-
- /**
- * Test range queries without restrictions but with a limit on a table
without clustering columns.
- */
- @Test
- public void testRangeQueryWithLimitOnSkinnyTable()
- {
- tester("WHERE token(k) >= token(1) LIMIT 2")
- .createTable("CREATE TABLE %s (k int PRIMARY KEY, a int, b int)")
- .mutate("INSERT INTO %s (k, a, b) VALUES (1, 10, 100)",
- "INSERT INTO %s (k, a, b) VALUES (2, 20, 200)",
- "INSERT INTO %s (k, a, b) VALUES (3, 30, 300)")
- .queryColumns("a", 2, 2,
- rows(row(10), row(20)),
- rows(row(1, 10, 100), row(2, 20, 200)),
- rows(row(1, 10, null), row(2, 20, null)))
- .deleteColumn("DELETE a FROM %s WHERE k=2", "b", 0, 1,
- rows(row(100), row(200)),
- rows(row(1, 10, 100), row(2, null, 200)),
- rows(row(1, 10, 100), row(2, 20, 200)))
- .deleteRows("DELETE FROM %s WHERE k=1", 2,
- rows(row(2, null, 200), row(3, 30, 300)),
- rows(row(1, 10, 100), row(2, null, 200)))
- .tearDown(0,
- rows(row(2, null, 200), row(3, 30, 300)),
- rows(row(2, null, 200), row(3, 30, 300)));
- }
-
- /**
- * Test range queries without restrictions but with a limit on a table
with clustering columns.
- */
- @Test
- public void testRangeQueryWithLimitOnWideTable()
- {
- tester("WHERE token(k) >= token(1) LIMIT 2")
- .createTable("CREATE TABLE %s (k int, c int, a int, b int, PRIMARY
KEY(k, c))")
- .mutate("INSERT INTO %s (k, c, a, b) VALUES (1, 10, 100, 1000)",
- "INSERT INTO %s (k, c, a, b) VALUES (2, 20, 200, 2000)",
- "INSERT INTO %s (k, c, a, b) VALUES (2, 21, 201, 2001)",
- "INSERT INTO %s (k, c, a, b) VALUES (3, 30, 300, 3000)")
- .queryColumns("a", 2, 2,
- rows(row(100), row(200)),
- rows(row(1, 10, 100, 1000), row(2, 20, 200, 2000)),
- rows(row(1, 10, 100, null), row(2, 20, 200, null)))
- .deleteColumn("DELETE a FROM %s WHERE k=2 AND c=20", "b", 0, 1,
- rows(row(1000), row(2000)),
- rows(row(1, 10, 100, 1000), row(2, 20, null, 2000)),
- rows(row(1, 10, 100, 1000), row(2, 20, 200, 2000)))
- .deleteRows("DELETE FROM %s WHERE k=2 AND c=20", 1,
- rows(row(1, 10, 100, 1000), row(2, 21, 201, 2001)),
- rows(row(1, 10, 100, 1000), row(2, 20, null, 2000)))
- .deleteRows("DELETE FROM %s WHERE k=2", 2,
- rows(row(1, 10, 100, 1000), row(3, 30, 300, 3000)),
- rows(row(1, 10, 100, 1000), row(2, 21, 201, 2001)))
- .tearDown(0,
- rows(row(1, 10, 100, 1000), row(3, 30, 300, 3000)),
- rows(row(1, 10, 100, 1000), row(3, 30, 300, 3000)));
- }
-
- /**
- * Test range queries using filtering on a selected column on a table
without clustering columns.
- */
- @Test
- public void testRangeQueryWithFilterOnSelectedColumnOnSkinnyTable()
- {
- tester("WHERE a=2 ALLOW FILTERING")
- .createTable("CREATE TABLE %s (k int PRIMARY KEY, a int, b int)")
- .mutate("INSERT INTO %s (k, a, b) VALUES (1, 2, 3)",
- "INSERT INTO %s (k, a, b) VALUES (10, 20, 30)")
- .queryColumns("a", 1, 1,
- rows(row(2)),
- rows(row(1, 2, 3)),
- rows(row(1, 2, null)))
- .deleteColumn("DELETE b FROM %s WHERE k=1", "a", 0, 1,
- rows(row(2)),
- rows(row(1, 2, null)),
- rows(row(1, 2, 3)))
- .deleteRows("DELETE FROM %s WHERE k=1", 1,
- rows(),
- rows(row(1, 2, null)))
- .tearDown(1,
- rows(row(10, 20, 30)),
- rows());
- }
-
- /**
- * Test range queries using filtering on an selected column on a table
with clustering columns.
- */
- @Test
- public void testRangeQueryWithFilterOnSelectedColumnOnWideTable()
- {
- tester("WHERE a=1 ALLOW FILTERING")
- .createTable("CREATE TABLE %s (k int, c int, a int, b int, PRIMARY
KEY(k, c))")
- .mutate("INSERT INTO %s (k, c, a, b) VALUES (1, 1, 1, 1)",
- "INSERT INTO %s (k, c, a, b) VALUES (1, 2, 2, 2)",
- "INSERT INTO %s (k, c, a, b) VALUES (2, 1, 1, 1)",
- "INSERT INTO %s (k, c, a, b) VALUES (2, 2, 2, 2)")
- .queryColumns("a", 2, 2,
- rows(row(1), row(1)),
- rows(row(1, 1, 1, 1), row(2, 1, 1, 1)),
- rows(row(1, 1, 1, null), row(2, 1, 1, null)))
- .deleteColumn("DELETE b FROM %s WHERE k=1 AND c=1", "a", 0, 1,
- rows(row(1), row(1)),
- rows(row(1, 1, 1, null), row(2, 1, 1, 1)),
- rows(row(1, 1, 1, 1), row(2, 1, 1, 1)))
- .deleteRows("DELETE FROM %s WHERE k=1 AND c=1", 1,
- rows(row(2, 1, 1, 1)),
- rows(row(1, 1, 1, null), row(2, 1, 1, 1)))
- .deleteRows("DELETE FROM %s WHERE k=2", 1,
- rows(),
- rows(row(2, 1, 1, 1)))
- .tearDown(1,
- rows(row(1, 2, 2, 2)),
- rows());
- }
-
- /**
- * Test range queries using filtering on an unselected column on a table
without clustering columns.
- */
- @Test
- public void testRangeQueryWithFilterOnUnselectedColumnOnSkinnyTable()
- {
- tester("WHERE b=3 ALLOW FILTERING")
- .createTable("CREATE TABLE %s (k int PRIMARY KEY, a int, b int)")
- .mutate("INSERT INTO %s (k, a, b) VALUES (1, 2, 3)",
- "INSERT INTO %s (k, a, b) VALUES (10, 20, 30)")
- .queryColumns("a", 1, 0,
- rows(row(2)),
- rows(row(1, 2, 3)),
- rows(row(1, 2, 3))) // the filtered column is repaired
even if it isn't selected
- .deleteColumn("DELETE a FROM %s WHERE k=1", "b", 0, 1,
- rows(row(3)),
- rows(row(1, null, 3)),
- rows(row(1, 2, 3)))
- .deleteRows("DELETE FROM %s WHERE k=1", 1,
- rows(),
- rows(row(1, null, 3)))
- .tearDown(1,
- rows(row(10, 20, 30)),
- rows());
- }
-
- /**
- * Test range queries using filtering on an unselected column on a table
with clustering columns.
- */
- @Test
- public void testRangeQueryWithFilterOnUnselectedColumnOnWideTable()
- {
- tester("WHERE b=2 ALLOW FILTERING")
- .createTable("CREATE TABLE %s (k int, c int, a int, b int, PRIMARY
KEY(k, c))")
- .mutate("INSERT INTO %s (k, c, a, b) VALUES (1, 1, 1, 1)",
- "INSERT INTO %s (k, c, a, b) VALUES (1, 2, 2, 2)",
- "INSERT INTO %s (k, c, a, b) VALUES (2, 1, 1, 1)",
- "INSERT INTO %s (k, c, a, b) VALUES (2, 2, 2, 2)")
- .queryColumns("a", 2, 0,
- rows(row(2), row(2)),
- rows(row(1, 2, 2, 2), row(2, 2, 2, 2)),
- rows(row(1, 2, 2, 2), row(2, 2, 2, 2))) // the filtered
column is repaired even if it isn't selected
- .deleteColumn("DELETE a FROM %s WHERE k=1 AND c=2", "b", 0, 1,
- rows(row(2), row(2)),
- rows(row(1, 2, null, 2), row(2, 2, 2, 2)),
- rows(row(1, 2, 2, 2), row(2, 2, 2, 2)))
- .deleteRows("DELETE FROM %s WHERE k=2 AND c=2", 1,
- rows(row(1, 2, null, 2)),
- rows(row(1, 2, null, 2), row(2, 2, 2, 2)))
- .deleteRows("DELETE FROM %s WHERE k=1", 1,
- rows(),
- rows(row(1, 2, null, 2)))
- .tearDown(1,
- rows(row(2, 1, 1, 1)),
- rows());
- }
-
- /**
- * Test slice queries without additional restrictions.
- */
- @Test
- public void testSliceQuery()
- {
- tester("WHERE k=0 AND c>1 AND c<4")
- .createTable("CREATE TABLE %s (k int, c int, a int, b int, PRIMARY
KEY(k, c))")
- .mutate("INSERT INTO %s (k, c, a, b) VALUES (0, 1, 10, 100)",
- "INSERT INTO %s (k, c, a, b) VALUES (0, 2, 20, 200)",
- "INSERT INTO %s (k, c, a, b) VALUES (0, 3, 30, 300)",
- "INSERT INTO %s (k, c, a, b) VALUES (0, 4, 40, 400)")
- .queryColumns("a", paging ? 2 : 1, paging ? 2 : 1,
- rows(row(20), row(30)),
- rows(row(0, 2, 20, 200), row(0, 3, 30, 300)),
- rows(row(0, 2, 20, null), row(0, 3, 30, null)))
- .deleteColumn("DELETE a FROM %s WHERE k=0 AND c=2", "b", 0, 1,
- rows(row(200), row(300)),
- rows(row(0, 2, null, 200), row(0, 3, 30, 300)),
- rows(row(0, 2, 20, 200), row(0, 3, 30, 300)))
- .deleteRows("DELETE FROM %s WHERE k=0 AND c=3", 1,
- rows(row(0, 2, null, 200)),
- rows(row(0, 2, null, 200), row(0, 3, 30, 300)))
- .deleteRows("DELETE FROM %s WHERE k=0", 1,
- rows(),
- rows(row(0, 2, null, 200)))
- .tearDown();
- }
-
- /**
- * Test slice queries using filtering.
- */
- @Test
- public void testSliceQueryWithFilter()
- {
- tester("WHERE k=0 AND a>10 AND a<40 ALLOW FILTERING")
- .createTable("CREATE TABLE %s (k int, c int, a int, b int, PRIMARY
KEY(k, c))")
- .mutate("INSERT INTO %s (k, c, a, b) VALUES (0, 1, 10, 100)",
- "INSERT INTO %s (k, c, a, b) VALUES (0, 2, 20, 200)",
- "INSERT INTO %s (k, c, a, b) VALUES (0, 3, 30, 300)",
- "INSERT INTO %s (k, c, a, b) VALUES (0, 4, 40, 400)")
- .queryColumns("a", paging ? 2 : 1, paging ? 2 : 1,
- rows(row(20), row(30)),
- rows(row(0, 2, 20, 200), row(0, 3, 30, 300)),
- rows(row(0, 2, 20, null), row(0, 3, 30, null)))
- .deleteColumn("DELETE b FROM %s WHERE k=0 AND c=2", "a", 0, 1,
- rows(row(20), row(30)),
- rows(row(0, 2, 20, null), row(0, 3, 30, 300)),
- rows(row(0, 2, 20, 200), row(0, 3, 30, 300)))
- .deleteRows("DELETE FROM %s WHERE k=0 AND c=3", 1,
- rows(row(0, 2, 20, null)),
- rows(row(0, 2, 20, null), row(0, 3, 30, 300)))
- .deleteRows("DELETE FROM %s WHERE k=0", 1,
- rows(),
- rows(row(0, 2, 20, null)))
- .tearDown();
- }
-
- /**
- * Test slice queries without restrictions but with a limit.
- */
- @Test
- public void testSliceQueryWithLimit()
- {
- tester("WHERE k=0 AND c>1 LIMIT 2")
- .createTable("CREATE TABLE %s (k int, c int, a int, b int, PRIMARY
KEY(k, c))")
- .mutate("INSERT INTO %s (k, c, a, b) VALUES (0, 1, 10, 100)",
- "INSERT INTO %s (k, c, a, b) VALUES (0, 2, 20, 200)",
- "INSERT INTO %s (k, c, a, b) VALUES (0, 3, 30, 300)",
- "INSERT INTO %s (k, c, a, b) VALUES (0, 4, 40, 400)")
- .queryColumns("a", paging ? 2 : 1, paging ? 2 : 1,
- rows(row(20), row(30)),
- rows(row(0, 2, 20, 200), row(0, 3, 30, 300)),
- rows(row(0, 2, 20, null), row(0, 3, 30, null)))
- .deleteColumn("DELETE b FROM %s WHERE k=0 AND c=2", "a", 0, 1,
- rows(row(20), row(30)),
- rows(row(0, 2, 20, null), row(0, 3, 30, 300)),
- rows(row(0, 2, 20, 200), row(0, 3, 30, 300)))
- .deleteRows("DELETE FROM %s WHERE k=0 AND c=3", 1,
- rows(row(0, 2, 20, null), row(0, 4, 40, 400)),
- rows(row(0, 2, 20, null), row(0, 3, 30, 300)))
- .deleteRows("DELETE FROM %s WHERE k=0", 1,
- rows(),
- rows(row(0, 2, 20, null), row(0, 4, 40, 400)))
- .tearDown();
- }
-
- /**
- * Test slice queries on a table with static columns.
- */
- @Test
- public void testSliceQueryWithStaticColumns()
- {
- tester("WHERE k=0 AND c>1")
- .createTable("CREATE TABLE %s (k int, s1 int static, s2 int static, c
int, PRIMARY KEY(k, c))")
- .mutate("INSERT INTO %s (k, s1, s2) VALUES (0, 10, 100)",
- "INSERT INTO %s (k, c) VALUES (0, 1)",
- "INSERT INTO %s (k, c) VALUES (0, 2)",
- "INSERT INTO %s (k, c) VALUES (0, 3)")
- .queryColumns("s1,c", paging ? 2 : 1, 1,
- rows(row(10, 2), row(10, 3)),
- rows(row(0, 2, 10, 100), row(0, 3, 10, 100)),
- rows(row(0, 2, 10, null), row(0, 3, 10, null)))
- .deleteColumn("DELETE s1 FROM %s WHERE k=0", "s2,c", 0, 1,
- rows(row(100, 2), row(100, 3)),
- rows(row(0, 2, null, 100), row(0, 3, null, 100)),
- rows(row(0, 2, 10, 100), row(0, 3, 10, 100)))
- .deleteRows("DELETE FROM %s WHERE k=0 AND c=3", 1,
- rows(row(0, 2, null, 100)),
- rows(row(0, 2, null, 100), row(0, 3, null, 100)))
- .deleteRows("DELETE FROM %s WHERE k=0", 1,
- rows(),
- rows(row(0, 2, null, 100)))
- .tearDown();
- }
-
- /**
- * Test queries with an IN restriction on a table without clustering
columns.
- */
- @Test
- public void testInQueryOnSkinnyTable()
- {
- tester("WHERE k IN (1, 3)")
- .createTable("CREATE TABLE %s (k int PRIMARY KEY, a int, b int)")
- .mutate("INSERT INTO %s (k, a, b) VALUES (1, 10, 100)",
- "INSERT INTO %s (k, a, b) VALUES (2, 20, 200)",
- "INSERT INTO %s (k, a, b) VALUES (3, 30, 300)")
- .queryColumns("a", 2, 2,
- rows(row(10), row(30)),
- rows(row(1, 10, 100), row(3, 30, 300)),
- rows(row(1, 10, null), row(3, 30, null)))
- .deleteColumn("DELETE a FROM %s WHERE k=1", "b", 0, 1,
- rows(row(100), row(300)),
- rows(row(1, null, 100), row(3, 30, 300)),
- rows(row(1, 10, 100), row(3, 30, 300)))
- .deleteRows("DELETE FROM %s WHERE k=3", 1,
- rows(row(1, null, 100)),
- rows(row(1, null, 100), row(3, 30, 300)))
- .tearDown(1,
- rows(row(1, null, 100), row(2, 20, 200)),
- rows(row(1, null, 100)));
- }
-
- /**
- * Test queries with an IN restriction on a table with clustering columns.
- */
- @Test
- public void testInQueryOnWideTable()
- {
- tester("WHERE k IN (1, 3)")
- .createTable("CREATE TABLE %s (k int, c int, a int, b int, PRIMARY
KEY(k, c))")
- .mutate("INSERT INTO %s (k, c, a, b) VALUES (1, 10, 100, 1000)",
- "INSERT INTO %s (k, c, a, b) VALUES (2, 20, 200, 2000)",
- "INSERT INTO %s (k, c, a, b) VALUES (3, 30, 300, 3000)")
- .queryColumns("a", 2, 2,
- rows(row(100), row(300)),
- rows(row(1, 10, 100, 1000), row(3, 30, 300, 3000)),
- rows(row(1, 10, 100, null), row(3, 30, 300, null)))
- .deleteColumn("DELETE a FROM %s WHERE k=1 AND c=10", "b", 0, 1,
- rows(row(1000), row(3000)),
- rows(row(1, 10, null, 1000), row(3, 30, 300, 3000)),
- rows(row(1, 10, 100, 1000), row(3, 30, 300, 3000)))
- .deleteRows("DELETE FROM %s WHERE k=3", 1,
- rows(row(1, 10, null, 1000)),
- rows(row(1, 10, null, 1000), row(3, 30, 300, 3000)))
- .tearDown(1,
- rows(row(1, 10, null, 1000), row(2, 20, 200, 2000)),
- rows(row(1, 10, null, 1000)));
- }
-
- /**
- * Test queries with an IN restriction and a limit on a table without
clustering columns.
- */
- @Test
- public void testInQueryWithLimitOnSkinnyTable()
- {
- tester("WHERE k IN (1, 3) LIMIT 1")
- .createTable("CREATE TABLE %s (k int PRIMARY KEY, a int, b int)")
- .mutate("INSERT INTO %s (k, a, b) VALUES (1, 10, 100)",
- "INSERT INTO %s (k, a, b) VALUES (2, 20, 200)",
- "INSERT INTO %s (k, a, b) VALUES (3, 30, 300)")
- .queryColumns("a", 1, 1,
- rows(row(10)),
- rows(row(1, 10, 100)),
- rows(row(1, 10, null)))
- .deleteColumn("DELETE a FROM %s WHERE k=1", "b", 0, 1,
- rows(row(100)),
- rows(row(1, null, 100)),
- rows(row(1, 10, 100)))
- .deleteRows("DELETE FROM %s WHERE k=1", 2,
- rows(row(3, 30, 300)),
- rows(row(1, null, 100)))
- .tearDown(1,
- rows(row(2, 20, 200), row(3, 30, 300)),
- rows(row(3, 30, 300)));
- }
-
- /**
- * Test queries with an IN restriction and a limit on a table with
clustering columns.
- */
- @Test
- public void testInQueryWithLimitOnWideTable()
- {
- tester("WHERE k IN (1, 3) LIMIT 1")
- .createTable("CREATE TABLE %s (k int, c int, a int, b int, PRIMARY
KEY(k, c))")
- .mutate("INSERT INTO %s (k, c, a, b) VALUES (1, 10, 100, 1000)",
- "INSERT INTO %s (k, c, a, b) VALUES (2, 20, 200, 2000)",
- "INSERT INTO %s (k, c, a, b) VALUES (3, 30, 300, 3000)")
- .queryColumns("a", 1, 1,
- rows(row(100)),
- rows(row(1, 10, 100, 1000)),
- rows(row(1, 10, 100, null)))
- .deleteColumn("DELETE a FROM %s WHERE k=1 AND c=10", "b", 0, 1,
- rows(row(1000)),
- rows(row(1, 10, null, 1000)),
- rows(row(1, 10, 100, 1000)))
- .deleteRows("DELETE FROM %s WHERE k=1", 2,
- rows(row(3, 30, 300, 3000)),
- rows(row(1, 10, null, 1000)))
- .tearDown(1,
- rows(row(2, 20, 200, 2000), row(3, 30, 300, 3000)),
- rows(row(3, 30, 300, 3000)));
- }
-
- /**
- * Test queries with an IN restriction and a row filter on one of the
selected columns without clustering columns.
- */
- @Test
- public void testInQueryWithFilterOnSelectedColumnOnSkinnyTable()
- {
- tester("WHERE k IN (1, 3) AND a=10 ALLOW FILTERING")
- .createTable("CREATE TABLE %s (k int PRIMARY KEY, a int, b int)")
- .mutate("INSERT INTO %s (k, a, b) VALUES (1, 10, 100)",
- "INSERT INTO %s (k, a, b) VALUES (2, 10, 200)",
- "INSERT INTO %s (k, a, b) VALUES (3, 10, 300)",
- "INSERT INTO %s (k, a, b) VALUES (4, 40, 400)")
- .queryColumns("a", 2, 2,
- rows(row(10), row(10)),
- rows(row(1, 10, 100), row(3, 10, 300)),
- rows(row(1, 10, null), row(3, 10, null)))
- .deleteColumn("DELETE b FROM %s WHERE k=1", "a", 0, 1,
- rows(row(10), row(10)),
- rows(row(1, 10, null), row(3, 10, 300)),
- rows(row(1, 10, 100), row(3, 10, 300)))
- .deleteRows("DELETE FROM %s WHERE k=1", 1,
- rows(row(3, 10, 300)),
- rows(row(1, 10, null), row(3, 10, 300)))
- .tearDown(2,
- rows(row(2, 10, 200), row(4, 40, 400), row(3, 10, 300)),
- rows(row(3, 10, 300)));
- }
-
- /**
- * Test queries with an IN restriction and a row filter on one of the
selected columns with clustering columns.
- */
- @Test
- public void testInQueryWithFilterOnSelectedColumnOnWideTable()
- {
- tester("WHERE k IN (1, 3) AND a=100 ALLOW FILTERING")
- .createTable("CREATE TABLE %s (k int, c int, a int, b int, PRIMARY
KEY(k, c))")
- .mutate("INSERT INTO %s (k, c, a, b) VALUES (1, 10, 100, 1000)",
- "INSERT INTO %s (k, c, a, b) VALUES (2, 20, 100, 2000)",
- "INSERT INTO %s (k, c, a, b) VALUES (3, 30, 100, 3000)",
- "INSERT INTO %s (k, c, a, b) VALUES (4, 40, 400, 4000)")
- .queryColumns("a", 2, 2,
- rows(row(100), row(100)),
- rows(row(1, 10, 100, 1000), row(3, 30, 100, 3000)),
- rows(row(1, 10, 100, null), row(3, 30, 100, null)))
- .deleteColumn("DELETE b FROM %s WHERE k=1 AND c=10", "a", 0, 1,
- rows(row(100), row(100)),
- rows(row(1, 10, 100, null), row(3, 30, 100, 3000)),
- rows(row(1, 10, 100, 1000), row(3, 30, 100, 3000)))
- .deleteRows("DELETE FROM %s WHERE k=1", 1,
- rows(row(3, 30, 100, 3000)),
- rows(row(1, 10, 100, null), row(3, 30, 100, 3000)))
- .tearDown(2,
- rows(row(2, 20, 100, 2000), row(4, 40, 400, 4000), row(3,
30, 100, 3000)),
- rows(row(3, 30, 100, 3000)));
- }
-
- /**
- * Test queries with an IN restriction and a row filter on unselected
columns without clustering columns.
- */
- @Test
- public void testInQueryWithFilterOnUnselectedColumnOnSkinnyTable()
- {
- tester("WHERE k IN (1, 3) AND b=100 ALLOW FILTERING")
- .createTable("CREATE TABLE %s (k int PRIMARY KEY, a int, b int)")
- .mutate("INSERT INTO %s (k, a, b) VALUES (1, 10, 100)",
- "INSERT INTO %s (k, a, b) VALUES (2, 20, 100)",
- "INSERT INTO %s (k, a, b) VALUES (3, 30, 100)")
- .queryColumns("a", 2, 0,
- rows(row(10), row(30)),
- rows(row(1, 10, 100), row(3, 30, 100)),
- rows(row(1, 10, 100), row(3, 30, 100))) // the filtered
column is repaired even if it isn't selected
- .deleteColumn("DELETE a FROM %s WHERE k=1", "b", 0, 1,
- rows(row(100), row(100)),
- rows(row(1, null, 100), row(3, 30, 100)),
- rows(row(1, 10, 100), row(3, 30, 100)))
- .deleteRows("DELETE FROM %s WHERE k=1", 1,
- rows(row(3, 30, 100)),
- rows(row(1, null, 100), row(3, 30, 100)))
- .tearDown(1,
- rows(row(2, 20, 100), row(3, 30, 100)),
- rows(row(3, 30, 100)));
- }
-
- /**
- * Test queries with an IN restriction and a row filter on unselected
columns with clustering columns.
- */
- @Test
- public void testInQueryWithFilterOnUnselectedColumnOnWideTable()
- {
- tester("WHERE k IN (1, 3) AND b=1000 ALLOW FILTERING")
- .createTable("CREATE TABLE %s (k int, c int, a int, b int, PRIMARY
KEY(k, c))")
- .mutate("INSERT INTO %s (k, c, a, b) VALUES (1, 10, 100, 1000)",
- "INSERT INTO %s (k, c, a, b) VALUES (2, 20, 200, 2000)",
- "INSERT INTO %s (k, c, a, b) VALUES (3, 30, 300, 3000)")
- .queryColumns("a", 1, 0,
- rows(row(100)),
- rows(row(1, 10, 100, 1000)),
- rows(row(1, 10, 100, 1000))) // the filtered column is
repaired even if it isn't selected
- .deleteColumn("DELETE a FROM %s WHERE k=1 AND c=10", "b", 0, 1,
- rows(row(1000)),
- rows(row(1, 10, null, 1000)),
- rows(row(1, 10, 100, 1000)))
- .deleteRows("DELETE FROM %s WHERE k=1", 1,
- rows(),
- rows(row(1, 10, null, 1000)))
- .tearDown(2,
- rows(row(2, 20, 200, 2000), row(3, 30, 300, 3000)),
- rows());
- }
-
- /**
- * Test unrestricted queries with frozen tuples.
- */
- @Test
- public void testTuple()
- {
- tester("")
- .createTable("CREATE TABLE %s (k int PRIMARY KEY, a tuple<int,int>, b
tuple<int,int>)")
- .mutate("INSERT INTO %s (k, a, b) VALUES (0, (1, 2), (3, 4))")
- .queryColumns("a", 1, 1,
- rows(row(tuple(1, 2))),
- rows(row(0, tuple(1, 2), tuple(3, 4))),
- rows(row(0, tuple(1, 2), null)))
- .deleteColumn("DELETE a FROM %s WHERE k=0", "b", 0, 1,
- rows(row(tuple(3, 4))),
- rows(row(0, null, tuple(3, 4))),
- rows(row(0, tuple(1, 2), tuple(3, 4))))
- .deleteRows("DELETE FROM %s WHERE k=0", 1,
- rows(),
- rows(row(0, null, tuple(3, 4))))
- .tearDown();
- }
-
- /**
- * Test unrestricted queries with frozen sets.
- */
- @Test
- public void testFrozenSet()
- {
- tester("")
- .createTable("CREATE TABLE %s (k int PRIMARY KEY, a frozen<set<int>>,
b frozen<set<int>>)")
- .mutate("INSERT INTO %s (k, a, b) VALUES (0, {1, 2}, {3, 4})")
- .queryColumns("a[1]", 1, 1,
- rows(row(1)),
- rows(row(0, set(1, 2), set(3, 4))),
- rows(row(0, set(1, 2), null)))
- .deleteColumn("DELETE a FROM %s WHERE k=0", "b[4]", 0, 1,
- rows(row(4)),
- rows(row(0, null, set(3, 4))),
- rows(row(0, set(1, 2), set(3, 4))))
- .deleteRows("DELETE FROM %s WHERE k=0", 1,
- rows(),
- rows(row(0, null, set(3, 4))))
- .tearDown();
- }
-
- /**
- * Test unrestricted queries with frozen lists.
- */
- @Test
- public void testFrozenList()
- {
- tester("")
- .createTable("CREATE TABLE %s (k int PRIMARY KEY, a frozen<list<int>>,
b frozen<list<int>>)")
- .mutate("INSERT INTO %s (k, a, b) VALUES (0, [1, 2], [3, 4])")
- .queryColumns("a", 1, 1,
- rows(row(list(1, 2))),
- rows(row(0, list(1, 2), list(3, 4))),
- rows(row(0, list(1, 2), null)))
- .deleteColumn("DELETE a FROM %s WHERE k=0", "b", 0, 1,
- rows(row(list(3, 4))),
- rows(row(0, null, list(3, 4))),
- rows(row(0, list(1, 2), list(3, 4))))
- .deleteRows("DELETE FROM %s WHERE k=0", 1,
- rows(),
- rows(row(0, null, list(3, 4))))
- .tearDown();
- }
-
- /**
- * Test unrestricted queries with frozen maps.
- */
- @Test
- public void testFrozenMap()
- {
- tester("")
- .createTable("CREATE TABLE %s (k int PRIMARY KEY, a
frozen<map<int,int>>, b frozen<map<int,int>>)")
- .mutate("INSERT INTO %s (k, a, b) VALUES (0, {1:10, 2:20}, {3:30,
4:40})")
- .queryColumns("a[2]", 1, 1,
- rows(row(20)),
- rows(row(0, map(1, 10, 2, 20), map(3, 30, 4, 40))),
- rows(row(0, map(1, 10, 2, 20), null)))
- .deleteColumn("DELETE a FROM %s WHERE k=0", "b[4]", 0, 1,
- rows(row(40)),
- rows(row(0, null, map(3, 30, 4, 40))),
- rows(row(0, map(1, 10, 2, 20), map(3, 30, 4, 40))))
- .deleteRows("DELETE FROM %s WHERE k=0", 1,
- rows(),
- rows(row(0, null, map(3, 30, 4, 40))))
- .tearDown();
- }
-
- /**
- * Test unrestricted queries with frozen user-defined types.
- */
- @Test
- public void testFrozentuple()
- {
- tester("")
- .createTable("CREATE TABLE %s (k int PRIMARY KEY, a frozen<udt>, b
frozen<udt>)")
- .mutate("INSERT INTO %s (k, a, b) VALUES (0, {x:1, y:2}, {x:3, y:4})")
- .queryColumns("a.x", 1, 1,
- rows(row(1)),
- rows(row(0, tuple(1, 2), tuple(3, 4))),
- rows(row(0, tuple(1, 2), null)))
- .deleteColumn("DELETE a FROM %s WHERE k=0", "b.y", 0, 1,
- rows(row(4)),
- rows(row(0, null, tuple(3, 4))),
- rows(row(0, tuple(1, 2), tuple(3, 4))))
- .deleteRows("DELETE FROM %s WHERE k=0", 1,
- rows(),
- rows(row(0, null, tuple(3, 4))))
- .tearDown();
- }
-
- /**
- * Test unrestricted queries with non-frozen sets.
- */
- @Test
- public void testNonFrozenSet()
- {
- tester("")
- .createTable("CREATE TABLE %s (k int PRIMARY KEY, a set<int>, b
set<int>, c int)")
- .mutate("INSERT INTO %s (k, a, b, c) VALUES (0, {1, 2}, {3, 4}, 10)")
- .queryColumns("a[1]", 1, 1,
- rows(row(1)),
- rows(row(0, set(1, 2), set(3, 4), 10)),
- rows(row(0, set(1), null, null)))
- .deleteColumn("UPDATE %s SET a=a-{2} WHERE k=0", "b[4]", 0, 1,
- rows(row(4)),
- rows(row(0, set(1), set(3, 4), 10)),
- rows(row(0, set(1, 2), set(3, 4), 10)))
- .deleteRows("DELETE FROM %s WHERE k=0", 1,
- rows(),
- rows(row(0, set(1), set(3, 4), 10)))
- .tearDown();
- }
-
- /**
- * Test unrestricted queries with non-frozen lists.
- */
- @Test
- public void testNonFrozenList()
- {
- tester("")
- .createTable("CREATE TABLE %s (k int PRIMARY KEY, a list<int>, b
list<int>, c int)")
- .mutate("INSERT INTO %s (k, a, b, c) VALUES (0, [1, 2], [3, 4], 10)")
- .queryColumns("a", 1, 1,
- rows(row(list(1, 2))),
- rows(row(0, list(1, 2), list(3, 4), 10)),
- rows(row(0, list(1, 2), null, null)))
- .deleteColumn("DELETE a[1] FROM %s WHERE k=0", "b", 0, 1,
- rows(row(list(3, 4))),
- rows(row(0, list(1), list(3, 4), 10)),
- rows(row(0, list(1, 2), list(3, 4), 10)))
- .deleteRows("DELETE FROM %s WHERE k=0", 1,
- rows(),
- rows(row(0, list(1), list(3, 4), 10)))
- .tearDown();
- }
-
- /**
- * Test unrestricted queries with non-frozen maps.
- */
- @Test
- public void testNonFrozenMap()
- {
- tester("")
- .createTable("CREATE TABLE %s (k int PRIMARY KEY, a map<int,int>, b
map<int,int>, c int)")
- .mutate("INSERT INTO %s (k, a, b, c) VALUES (0, {1:10, 2:20}, {3:30,
4:40}, 10)")
- .queryColumns("a[2]", 1, 1,
- rows(row(20)),
- rows(row(0, map(1, 10, 2, 20), map(3, 30, 4, 40), 10)),
- rows(row(0, map(2, 20), null, null)))
- .deleteColumn("DELETE a[1] FROM %s WHERE k=0", "b[4]", 0, 1,
- rows(row(40)),
- rows(row(0, map(2, 20), map(3, 30, 4, 40), 10)),
- rows(row(0, map(1, 10, 2, 20), map(3, 30, 4, 40), 10)))
- .deleteRows("DELETE FROM %s WHERE k=0", 1,
- rows(),
- rows(row(0, map(2, 20), map(3, 30, 4, 40), 10)))
- .tearDown();
- }
-
- /**
- * Test unrestricted queries with non-frozen user-defined types.
- */
- @Test
- public void testNonFrozentuple()
- {
- tester("")
- .createTable("CREATE TABLE %s (k int PRIMARY KEY, a udt, b udt, c
int)")
- .mutate("INSERT INTO %s (k, a, b, c) VALUES (0, {x:1, y:2}, {x:3,
y:4}, 10)")
- .queryColumns("a.x", 1, 1,
- rows(row(1)),
- rows(row(0, tuple(1, 2), tuple(3, 4), 10)),
- rows(row(0, tuple(1, 2), null, null)))
- .deleteColumn("DELETE a.x FROM %s WHERE k=0", "b.y", 0, 1,
- rows(row(4)),
- rows(row(0, tuple(null, 2), tuple(3, 4), 10)),
- rows(row(0, tuple(1, 2), tuple(3, 4), 10)))
- .deleteRows("DELETE FROM %s WHERE k=0", 1,
- rows(),
- rows(row(0, tuple(null, 2), tuple(3, 4), 10)))
- .tearDown();
- }
-
- private Tester tester(String restriction)
- {
- return new Tester(restriction, cluster, strategy, coordinator, flush,
paging);
- }
-
- private static class Tester extends ReadRepairTester<Tester>
- {
- private final String restriction; // the tested CQL query WHERE
restriction
- private final String allColumnsQuery; // a SELECT * query for the
table using the tested restriction
-
- Tester(String restriction, Cluster cluster, ReadRepairStrategy
strategy, int coordinator, boolean flush, boolean paging)
- {
- super(cluster, strategy, coordinator, flush, paging, false);
- this.restriction = restriction;
-
- allColumnsQuery = String.format("SELECT * FROM %s %s",
qualifiedTableName, restriction);
- }
-
- @Override
- Tester self()
- {
- return this;
- }
-
- /**
- * Runs the tested query with CL=ALL selectig only the specified
columns and verifies that it returns the
- * specified rows. Then, it runs the query again selecting all the
columns, and verifies that the first query
- * execution only propagated the selected columns, and that the second
execution propagated everything.
- *
- * @param columns the selected columns
- * @param columnsQueryRepairedRows the expected number of repaired
rows when querying only the selected columns
- * @param rowsQueryRepairedRows the expected number of repaired
rows when querying all the columns
- * @param columnsQueryResults the rows returned by the query for
a subset of columns
- * @param node1Rows the rows in the first node, which
is the one with the most updated data
- * @param node2Rows the rows in the second node, which
is the one meant to receive the RR writes
- */
- Tester queryColumns(String columns,
- long columnsQueryRepairedRows,
- long rowsQueryRepairedRows,
- Object[][] columnsQueryResults,
- Object[][] node1Rows,
- Object[][] node2Rows)
- {
- // query only the selected columns with CL=ALL to trigger partial
read repair on that column
- String columnsQuery = String.format("SELECT %s FROM %s %s",
columns, qualifiedTableName, restriction);
- assertRowsDistributed(columnsQuery, columnsQueryRepairedRows,
columnsQueryResults);
-
- // query entire rows to repair the rest of the columns, that might
trigger new repairs for those columns
- return verifyQuery(allColumnsQuery, rowsQueryRepairedRows,
node1Rows, node2Rows);
- }
-
- /**
- * Executes the specified column deletion on just one node. Then it
runs the tested query with CL=ALL selectig
- * only the specified columns (which are expected to be different to
the deleted one) and verifies that it
- * returns the specified rows. Then it runs the tested query again,
this time selecting all the columns, to
- * verify that the previous query didn't propagate the column deletion.
- *
- * @param columnDeletion the deletion query for a first node
- * @param columns a subset of the table columns for
the first distributed query
- * @param columnsQueryRepairedRows the expected number of repaired
rows when querying only the selected columns
- * @param rowsQueryRepairedRows the expected number of repaired
rows when querying all the columns
- * @param columnsQueryResults the rows returned by the query for
a subset of columns
- * @param node1Rows the rows in the first node, which
is the one with the most updated data
- * @param node2Rows the rows in the second node, which
is the one meant to receive the RR writes
- */
- Tester deleteColumn(String columnDeletion,
- String columns,
- long columnsQueryRepairedRows,
- long rowsQueryRepairedRows,
- Object[][] columnsQueryResults,
- Object[][] node1Rows,
- Object[][] node2Rows)
- {
- assert restriction != null;
-
- // execute the column deletion on just one node
- mutate(1, columnDeletion);
-
- // verify the columns read with CL=ALL, in most cases this won't
propagate the previous column deletion if
- // the deleted and read columns don't overlap
- return queryColumns(columns,
- columnsQueryRepairedRows,
- rowsQueryRepairedRows,
- columnsQueryResults,
- node1Rows,
- node2Rows);
- }
-
- /**
- * Executes the specified row deletion on just one node and verifies
the tested query, to ensure that the tested
- * query propagates the row deletion.
- */
- Tester deleteRows(String rowDeletion, long repairedRows, Object[][]
node1Rows, Object[][] node2Rows)
- {
- mutate(1, rowDeletion);
- return verifyQuery(allColumnsQuery, repairedRows, node1Rows,
node2Rows);
- }
-
- private Tester mutate(String... queries)
- {
- return mutate(1, queries);
- }
-
- private Tester verifyQuery(String query, long expectedRepairedRows,
Object[][] node1Rows, Object[][] node2Rows)
- {
- // verify the per-replica status before running the query
distributedly
- assertRows(cluster.get(1).executeInternal(query), node1Rows);
- assertRows(cluster.get(2).executeInternal(query), strategy == NONE
? EMPTY_ROWS : node2Rows);
-
- // now, run the query with CL=ALL to reconcile and repair the
replicas
- assertRowsDistributed(query, expectedRepairedRows, node1Rows);
-
- // run the query locally again to verify that the distributed
query has repaired everything
- assertRows(cluster.get(1).executeInternal(query), node1Rows);
- assertRows(cluster.get(2).executeInternal(query), strategy == NONE
? EMPTY_ROWS : node1Rows);
-
- return this;
- }
-
- /**
- * Verifies that the replicas are empty and drop the table.
- */
- void tearDown()
- {
- tearDown(0, rows(), rows());
- }
-
- /**
- * Verifies the final status of the nodes with an unrestricted query,
to ensure that the main tested query
- * hasn't triggered any unexpected repairs. Then, it verifies that the
node that hasn't been used as coordinator
- * hasn't triggered any unexpected repairs. Finally, it drops the
table.
- */
- void tearDown(long repairedRows, Object[][] node1Rows, Object[][]
node2Rows)
- {
- verifyQuery("SELECT * FROM " + qualifiedTableName, repairedRows,
node1Rows, node2Rows);
- for (int n = 1; n <= cluster.size(); n++)
- {
- if (n == coordinator)
- continue;
-
- long requests = readRepairRequestsCount(n);
- String message = String.format("No read repair requests were
expected in not-coordinator nodes, " +
- "but found %d requests in node
%d", requests, n);
- assertEquals(message, 0, requests);
- }
- schemaChange("DROP TABLE " + qualifiedTableName);
- }
- }
-}
\ No newline at end of file
diff --git
a/test/distributed/org/apache/cassandra/distributed/test/ReadRepairRangeQueriesTest.java
b/test/distributed/org/apache/cassandra/distributed/test/ReadRepairRangeQueriesTest.java
new file mode 100644
index 0000000000..f9abb4505d
--- /dev/null
+++
b/test/distributed/org/apache/cassandra/distributed/test/ReadRepairRangeQueriesTest.java
@@ -0,0 +1,261 @@
+/*
+ * 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.distributed.test;
+
+import org.junit.Test;
+
+import static org.apache.cassandra.distributed.shared.AssertUtils.row;
+
+/**
+ * {@link ReadRepairQueryTester} for range queries.
+ */
+public class ReadRepairRangeQueriesTest extends ReadRepairQueryTester
+{
+ /**
+ * Test range queries on a table without clustering columns.
+ */
+ @Test
+ public void testRangeQueryOnSkinnyTable()
+ {
+ tester("WHERE token(k) >= token(2)")
+ .createTable("CREATE TABLE %s (k int PRIMARY KEY, a int, b int)")
+ .mutate("INSERT INTO %s (k, a, b) VALUES (1, 10, 100)",
+ "INSERT INTO %s (k, a, b) VALUES (2, 20, 200)",
+ "INSERT INTO %s (k, a, b) VALUES (3, 30, 300)")
+ .queryColumns("a", 2, 2,
+ rows(row(20), row(30)),
+ rows(row(2, 20, 200), row(3, 30, 300)),
+ rows(row(2, 20, null), row(3, 30, null)))
+ .deleteColumn("DELETE a FROM %s WHERE k=2", "b", 0, 1,
+ rows(row(200), row(300)),
+ rows(row(2, null, 200), row(3, 30, 300)),
+ rows(row(2, 20, 200), row(3, 30, 300)))
+ .deleteRows("DELETE FROM %s WHERE k=3", 1,
+ rows(row(2, null, 200)),
+ rows(row(2, null, 200), row(3, 30, 300)))
+ .tearDown(1,
+ rows(row(1, 10, 100), row(2, null, 200)),
+ rows(row(2, null, 200)));
+ }
+
+ /**
+ * Test range queries on a table with clustering columns.
+ */
+ @Test
+ public void testRangeQueryOnWideTable()
+ {
+ tester("WHERE token(k) >= token(2)")
+ .createTable("CREATE TABLE %s (k int, c int, a int, b int, PRIMARY
KEY(k, c))")
+ .mutate("INSERT INTO %s (k, c, a, b) VALUES (1, 10, 100, 1000)",
+ "INSERT INTO %s (k, c, a, b) VALUES (2, 20, 200, 2000)",
+ "INSERT INTO %s (k, c, a, b) VALUES (2, 21, 201, 2001)",
+ "INSERT INTO %s (k, c, a, b) VALUES (3, 30, 300, 3000)")
+ .queryColumns("a",
+ paging ? 3 : 2,
+ paging ? 3 : 2,
+ rows(row(200), row(201), row(300)),
+ rows(row(2, 20, 200, 2000), row(2, 21, 201, 2001),
row(3, 30, 300, 3000)),
+ rows(row(2, 20, 200, null), row(2, 21, 201, null),
row(3, 30, 300, null)))
+ .deleteColumn("DELETE a FROM %s WHERE k=2 AND c=21", "b", 0, 1,
+ rows(row(2000), row(2001), row(3000)),
+ rows(row(2, 20, 200, 2000), row(2, 21, null, 2001),
row(3, 30, 300, 3000)),
+ rows(row(2, 20, 200, 2000), row(2, 21, 201, 2001),
row(3, 30, 300, 3000)))
+ .deleteRows("DELETE FROM %s WHERE k=2 AND c=21", 1,
+ rows(row(2, 20, 200, 2000), row(3, 30, 300, 3000)),
+ rows(row(2, 20, 200, 2000), row(2, 21, null, 2001), row(3,
30, 300, 3000)))
+ .deleteRows("DELETE FROM %s WHERE k=2", 1,
+ rows(row(3, 30, 300, 3000)),
+ rows(row(2, 20, 200, 2000), row(3, 30, 300, 3000)))
+ .tearDown(1,
+ rows(row(1, 10, 100, 1000), row(3, 30, 300, 3000)),
+ rows(row(3, 30, 300, 3000)));
+ }
+
+ /**
+ * Test range queries without restrictions but with a limit on a table
without clustering columns.
+ */
+ @Test
+ public void testRangeQueryWithLimitOnSkinnyTable()
+ {
+ tester("WHERE token(k) >= token(1) LIMIT 2")
+ .createTable("CREATE TABLE %s (k int PRIMARY KEY, a int, b int)")
+ .mutate("INSERT INTO %s (k, a, b) VALUES (1, 10, 100)",
+ "INSERT INTO %s (k, a, b) VALUES (2, 20, 200)",
+ "INSERT INTO %s (k, a, b) VALUES (3, 30, 300)")
+ .queryColumns("a", 2, 2,
+ rows(row(10), row(20)),
+ rows(row(1, 10, 100), row(2, 20, 200)),
+ rows(row(1, 10, null), row(2, 20, null)))
+ .deleteColumn("DELETE a FROM %s WHERE k=2", "b", 0, 1,
+ rows(row(100), row(200)),
+ rows(row(1, 10, 100), row(2, null, 200)),
+ rows(row(1, 10, 100), row(2, 20, 200)))
+ .deleteRows("DELETE FROM %s WHERE k=1", 2,
+ rows(row(2, null, 200), row(3, 30, 300)),
+ rows(row(1, 10, 100), row(2, null, 200)))
+ .tearDown(0,
+ rows(row(2, null, 200), row(3, 30, 300)),
+ rows(row(2, null, 200), row(3, 30, 300)));
+ }
+
+ /**
+ * Test range queries without restrictions but with a limit on a table
with clustering columns.
+ */
+ @Test
+ public void testRangeQueryWithLimitOnWideTable()
+ {
+ tester("WHERE token(k) >= token(1) LIMIT 2")
+ .createTable("CREATE TABLE %s (k int, c int, a int, b int, PRIMARY
KEY(k, c))")
+ .mutate("INSERT INTO %s (k, c, a, b) VALUES (1, 10, 100, 1000)",
+ "INSERT INTO %s (k, c, a, b) VALUES (2, 20, 200, 2000)",
+ "INSERT INTO %s (k, c, a, b) VALUES (2, 21, 201, 2001)",
+ "INSERT INTO %s (k, c, a, b) VALUES (3, 30, 300, 3000)")
+ .queryColumns("a", 2, 2,
+ rows(row(100), row(200)),
+ rows(row(1, 10, 100, 1000), row(2, 20, 200, 2000)),
+ rows(row(1, 10, 100, null), row(2, 20, 200, null)))
+ .deleteColumn("DELETE a FROM %s WHERE k=2 AND c=20", "b", 0, 1,
+ rows(row(1000), row(2000)),
+ rows(row(1, 10, 100, 1000), row(2, 20, null, 2000)),
+ rows(row(1, 10, 100, 1000), row(2, 20, 200, 2000)))
+ .deleteRows("DELETE FROM %s WHERE k=2 AND c=20", 1,
+ rows(row(1, 10, 100, 1000), row(2, 21, 201, 2001)),
+ rows(row(1, 10, 100, 1000), row(2, 20, null, 2000)))
+ .deleteRows("DELETE FROM %s WHERE k=2", 2,
+ rows(row(1, 10, 100, 1000), row(3, 30, 300, 3000)),
+ rows(row(1, 10, 100, 1000), row(2, 21, 201, 2001)))
+ .tearDown(0,
+ rows(row(1, 10, 100, 1000), row(3, 30, 300, 3000)),
+ rows(row(1, 10, 100, 1000), row(3, 30, 300, 3000)));
+ }
+
+ /**
+ * Test range queries using filtering on a selected column on a table
without clustering columns.
+ */
+ @Test
+ public void testRangeQueryWithFilterOnSelectedColumnOnSkinnyTable()
+ {
+ tester("WHERE a=2 ALLOW FILTERING")
+ .createTable("CREATE TABLE %s (k int PRIMARY KEY, a int, b int)")
+ .mutate("INSERT INTO %s (k, a, b) VALUES (1, 2, 3)",
+ "INSERT INTO %s (k, a, b) VALUES (10, 20, 30)")
+ .queryColumns("a", 1, 1,
+ rows(row(2)),
+ rows(row(1, 2, 3)),
+ rows(row(1, 2, null)))
+ .deleteColumn("DELETE b FROM %s WHERE k=1", "a", 0, 1,
+ rows(row(2)),
+ rows(row(1, 2, null)),
+ rows(row(1, 2, 3)))
+ .deleteRows("DELETE FROM %s WHERE k=1", 1,
+ rows(),
+ rows(row(1, 2, null)))
+ .tearDown(1,
+ rows(row(10, 20, 30)),
+ rows());
+ }
+
+ /**
+ * Test range queries using filtering on an selected column on a table
with clustering columns.
+ */
+ @Test
+ public void testRangeQueryWithFilterOnSelectedColumnOnWideTable()
+ {
+ tester("WHERE a=1 ALLOW FILTERING")
+ .createTable("CREATE TABLE %s (k int, c int, a int, b int, PRIMARY
KEY(k, c))")
+ .mutate("INSERT INTO %s (k, c, a, b) VALUES (1, 1, 1, 1)",
+ "INSERT INTO %s (k, c, a, b) VALUES (1, 2, 2, 2)",
+ "INSERT INTO %s (k, c, a, b) VALUES (2, 1, 1, 1)",
+ "INSERT INTO %s (k, c, a, b) VALUES (2, 2, 2, 2)")
+ .queryColumns("a", 2, 2,
+ rows(row(1), row(1)),
+ rows(row(1, 1, 1, 1), row(2, 1, 1, 1)),
+ rows(row(1, 1, 1, null), row(2, 1, 1, null)))
+ .deleteColumn("DELETE b FROM %s WHERE k=1 AND c=1", "a", 0, 1,
+ rows(row(1), row(1)),
+ rows(row(1, 1, 1, null), row(2, 1, 1, 1)),
+ rows(row(1, 1, 1, 1), row(2, 1, 1, 1)))
+ .deleteRows("DELETE FROM %s WHERE k=1 AND c=1", 1,
+ rows(row(2, 1, 1, 1)),
+ rows(row(1, 1, 1, null), row(2, 1, 1, 1)))
+ .deleteRows("DELETE FROM %s WHERE k=2", 1,
+ rows(),
+ rows(row(2, 1, 1, 1)))
+ .tearDown(1,
+ rows(row(1, 2, 2, 2)),
+ rows());
+ }
+
+ /**
+ * Test range queries using filtering on an unselected column on a table
without clustering columns.
+ */
+ @Test
+ public void testRangeQueryWithFilterOnUnselectedColumnOnSkinnyTable()
+ {
+ tester("WHERE b=3 ALLOW FILTERING")
+ .createTable("CREATE TABLE %s (k int PRIMARY KEY, a int, b int)")
+ .mutate("INSERT INTO %s (k, a, b) VALUES (1, 2, 3)",
+ "INSERT INTO %s (k, a, b) VALUES (10, 20, 30)")
+ .queryColumns("a", 1, 0,
+ rows(row(2)),
+ rows(row(1, 2, 3)),
+ rows(row(1, 2, 3))) // the filtered column is repaired
even if it isn't selected
+ .deleteColumn("DELETE a FROM %s WHERE k=1", "b", 0, 1,
+ rows(row(3)),
+ rows(row(1, null, 3)),
+ rows(row(1, 2, 3)))
+ .deleteRows("DELETE FROM %s WHERE k=1", 1,
+ rows(),
+ rows(row(1, null, 3)))
+ .tearDown(1,
+ rows(row(10, 20, 30)),
+ rows());
+ }
+
+ /**
+ * Test range queries using filtering on an unselected column on a table
with clustering columns.
+ */
+ @Test
+ public void testRangeQueryWithFilterOnUnselectedColumnOnWideTable()
+ {
+ tester("WHERE b=2 ALLOW FILTERING")
+ .createTable("CREATE TABLE %s (k int, c int, a int, b int, PRIMARY
KEY(k, c))")
+ .mutate("INSERT INTO %s (k, c, a, b) VALUES (1, 1, 1, 1)",
+ "INSERT INTO %s (k, c, a, b) VALUES (1, 2, 2, 2)",
+ "INSERT INTO %s (k, c, a, b) VALUES (2, 1, 1, 1)",
+ "INSERT INTO %s (k, c, a, b) VALUES (2, 2, 2, 2)")
+ .queryColumns("a", 2, 0,
+ rows(row(2), row(2)),
+ rows(row(1, 2, 2, 2), row(2, 2, 2, 2)),
+ rows(row(1, 2, 2, 2), row(2, 2, 2, 2))) // the filtered
column is repaired even if it isn't selected
+ .deleteColumn("DELETE a FROM %s WHERE k=1 AND c=2", "b", 0, 1,
+ rows(row(2), row(2)),
+ rows(row(1, 2, null, 2), row(2, 2, 2, 2)),
+ rows(row(1, 2, 2, 2), row(2, 2, 2, 2)))
+ .deleteRows("DELETE FROM %s WHERE k=2 AND c=2", 1,
+ rows(row(1, 2, null, 2)),
+ rows(row(1, 2, null, 2), row(2, 2, 2, 2)))
+ .deleteRows("DELETE FROM %s WHERE k=1", 1,
+ rows(),
+ rows(row(1, 2, null, 2)))
+ .tearDown(1,
+ rows(row(2, 1, 1, 1)),
+ rows());
+ }
+}
diff --git
a/test/distributed/org/apache/cassandra/distributed/test/ReadRepairSliceQueriesTest.java
b/test/distributed/org/apache/cassandra/distributed/test/ReadRepairSliceQueriesTest.java
new file mode 100644
index 0000000000..62f3702d50
--- /dev/null
+++
b/test/distributed/org/apache/cassandra/distributed/test/ReadRepairSliceQueriesTest.java
@@ -0,0 +1,145 @@
+/*
+ * 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.distributed.test;
+
+import org.junit.Test;
+
+import static org.apache.cassandra.distributed.shared.AssertUtils.row;
+
+/**
+ * {@link ReadRepairQueryTester} for slice queries.
+ */
+public class ReadRepairSliceQueriesTest extends ReadRepairQueryTester
+{
+ /**
+ * Test slice queries without additional restrictions.
+ */
+ @Test
+ public void testSliceQuery()
+ {
+ tester("WHERE k=0 AND c>1 AND c<4")
+ .createTable("CREATE TABLE %s (k int, c int, a int, b int, PRIMARY
KEY(k, c))")
+ .mutate("INSERT INTO %s (k, c, a, b) VALUES (0, 1, 10, 100)",
+ "INSERT INTO %s (k, c, a, b) VALUES (0, 2, 20, 200)",
+ "INSERT INTO %s (k, c, a, b) VALUES (0, 3, 30, 300)",
+ "INSERT INTO %s (k, c, a, b) VALUES (0, 4, 40, 400)")
+ .queryColumns("a", paging ? 2 : 1, paging ? 2 : 1,
+ rows(row(20), row(30)),
+ rows(row(0, 2, 20, 200), row(0, 3, 30, 300)),
+ rows(row(0, 2, 20, null), row(0, 3, 30, null)))
+ .deleteColumn("DELETE a FROM %s WHERE k=0 AND c=2", "b", 0, 1,
+ rows(row(200), row(300)),
+ rows(row(0, 2, null, 200), row(0, 3, 30, 300)),
+ rows(row(0, 2, 20, 200), row(0, 3, 30, 300)))
+ .deleteRows("DELETE FROM %s WHERE k=0 AND c=3", 1,
+ rows(row(0, 2, null, 200)),
+ rows(row(0, 2, null, 200), row(0, 3, 30, 300)))
+ .deleteRows("DELETE FROM %s WHERE k=0", 1,
+ rows(),
+ rows(row(0, 2, null, 200)))
+ .tearDown();
+ }
+
+ /**
+ * Test slice queries using filtering.
+ */
+ @Test
+ public void testSliceQueryWithFilter()
+ {
+ tester("WHERE k=0 AND a>10 AND a<40 ALLOW FILTERING")
+ .createTable("CREATE TABLE %s (k int, c int, a int, b int, PRIMARY
KEY(k, c))")
+ .mutate("INSERT INTO %s (k, c, a, b) VALUES (0, 1, 10, 100)",
+ "INSERT INTO %s (k, c, a, b) VALUES (0, 2, 20, 200)",
+ "INSERT INTO %s (k, c, a, b) VALUES (0, 3, 30, 300)",
+ "INSERT INTO %s (k, c, a, b) VALUES (0, 4, 40, 400)")
+ .queryColumns("a", paging ? 2 : 1, paging ? 2 : 1,
+ rows(row(20), row(30)),
+ rows(row(0, 2, 20, 200), row(0, 3, 30, 300)),
+ rows(row(0, 2, 20, null), row(0, 3, 30, null)))
+ .deleteColumn("DELETE b FROM %s WHERE k=0 AND c=2", "a", 0, 1,
+ rows(row(20), row(30)),
+ rows(row(0, 2, 20, null), row(0, 3, 30, 300)),
+ rows(row(0, 2, 20, 200), row(0, 3, 30, 300)))
+ .deleteRows("DELETE FROM %s WHERE k=0 AND c=3", 1,
+ rows(row(0, 2, 20, null)),
+ rows(row(0, 2, 20, null), row(0, 3, 30, 300)))
+ .deleteRows("DELETE FROM %s WHERE k=0", 1,
+ rows(),
+ rows(row(0, 2, 20, null)))
+ .tearDown();
+ }
+
+ /**
+ * Test slice queries without restrictions but with a limit.
+ */
+ @Test
+ public void testSliceQueryWithLimit()
+ {
+ tester("WHERE k=0 AND c>1 LIMIT 2")
+ .createTable("CREATE TABLE %s (k int, c int, a int, b int, PRIMARY
KEY(k, c))")
+ .mutate("INSERT INTO %s (k, c, a, b) VALUES (0, 1, 10, 100)",
+ "INSERT INTO %s (k, c, a, b) VALUES (0, 2, 20, 200)",
+ "INSERT INTO %s (k, c, a, b) VALUES (0, 3, 30, 300)",
+ "INSERT INTO %s (k, c, a, b) VALUES (0, 4, 40, 400)")
+ .queryColumns("a", paging ? 2 : 1, paging ? 2 : 1,
+ rows(row(20), row(30)),
+ rows(row(0, 2, 20, 200), row(0, 3, 30, 300)),
+ rows(row(0, 2, 20, null), row(0, 3, 30, null)))
+ .deleteColumn("DELETE b FROM %s WHERE k=0 AND c=2", "a", 0, 1,
+ rows(row(20), row(30)),
+ rows(row(0, 2, 20, null), row(0, 3, 30, 300)),
+ rows(row(0, 2, 20, 200), row(0, 3, 30, 300)))
+ .deleteRows("DELETE FROM %s WHERE k=0 AND c=3", 1,
+ rows(row(0, 2, 20, null), row(0, 4, 40, 400)),
+ rows(row(0, 2, 20, null), row(0, 3, 30, 300)))
+ .deleteRows("DELETE FROM %s WHERE k=0", 1,
+ rows(),
+ rows(row(0, 2, 20, null), row(0, 4, 40, 400)))
+ .tearDown();
+ }
+
+ /**
+ * Test slice queries on a table with static columns.
+ */
+ @Test
+ public void testSliceQueryWithStaticColumns()
+ {
+ tester("WHERE k=0 AND c>1")
+ .createTable("CREATE TABLE %s (k int, s1 int static, s2 int static, c
int, PRIMARY KEY(k, c))")
+ .mutate("INSERT INTO %s (k, s1, s2) VALUES (0, 10, 100)",
+ "INSERT INTO %s (k, c) VALUES (0, 1)",
+ "INSERT INTO %s (k, c) VALUES (0, 2)",
+ "INSERT INTO %s (k, c) VALUES (0, 3)")
+ .queryColumns("s1,c", paging ? 2 : 1, 1,
+ rows(row(10, 2), row(10, 3)),
+ rows(row(0, 2, 10, 100), row(0, 3, 10, 100)),
+ rows(row(0, 2, 10, null), row(0, 3, 10, null)))
+ .deleteColumn("DELETE s1 FROM %s WHERE k=0", "s2,c", 0, 1,
+ rows(row(100, 2), row(100, 3)),
+ rows(row(0, 2, null, 100), row(0, 3, null, 100)),
+ rows(row(0, 2, 10, 100), row(0, 3, 10, 100)))
+ .deleteRows("DELETE FROM %s WHERE k=0 AND c=3", 1,
+ rows(row(0, 2, null, 100)),
+ rows(row(0, 2, null, 100), row(0, 3, null, 100)))
+ .deleteRows("DELETE FROM %s WHERE k=0", 1,
+ rows(),
+ rows(row(0, 2, null, 100)))
+ .tearDown();
+ }
+}
diff --git
a/test/distributed/org/apache/cassandra/distributed/test/ReadRepairUnrestrictedQueriesTest.java
b/test/distributed/org/apache/cassandra/distributed/test/ReadRepairUnrestrictedQueriesTest.java
new file mode 100644
index 0000000000..69d4148eb9
--- /dev/null
+++
b/test/distributed/org/apache/cassandra/distributed/test/ReadRepairUnrestrictedQueriesTest.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.cassandra.distributed.test;
+
+import org.junit.Test;
+
+import static org.apache.cassandra.distributed.shared.AssertUtils.row;
+
+/**
+ * {@link ReadRepairQueryTester} for unrestricted queries.
+ */
+public class ReadRepairUnrestrictedQueriesTest extends ReadRepairQueryTester
+{
+ /**
+ * Test queries without restrictions on a table without clustering columns.
+ */
+ @Test
+ public void testUnrestrictedQueryOnSkinnyTable()
+ {
+ tester("")
+ .createTable("CREATE TABLE %s (k int PRIMARY KEY, a int, b int)")
+ .mutate("INSERT INTO %s (k, a, b) VALUES (1, 10, 100)",
+ "INSERT INTO %s (k, a, b) VALUES (2, 20, 200)")
+ .queryColumns("a", 2, 2,
+ rows(row(10), row(20)),
+ rows(row(1, 10, 100), row(2, 20, 200)),
+ rows(row(1, 10, null), row(2, 20, null)))
+ .deleteColumn("DELETE a FROM %s WHERE k=1", "b", 0, 1,
+ rows(row(100), row(200)),
+ rows(row(1, null, 100), row(2, 20, 200)),
+ rows(row(1, 10, 100), row(2, 20, 200)))
+ .deleteRows("DELETE FROM %s WHERE k=1", 1,
+ rows(row(2, 20, 200)),
+ rows(row(1, null, 100), row(2, 20, 200)))
+ .tearDown(0,
+ rows(rows(row(2, 20, 200))),
+ rows(rows(row(2, 20, 200))));
+ }
+
+ /**
+ * Test queries without restrictions on a table with clustering columns.
+ */
+ @Test
+ public void testUnrestrictedQueryOnWideTable()
+ {
+ tester("")
+ .createTable("CREATE TABLE %s (k int, c int, a int, b int, PRIMARY
KEY(k, c))")
+ .mutate("INSERT INTO %s (k, c, a, b) VALUES (1, 10, 100, 1000)",
+ "INSERT INTO %s (k, c, a, b) VALUES (1, 20, 200, 2000)",
+ "INSERT INTO %s (k, c, a, b) VALUES (2, 30, 300, 3000)")
+ .queryColumns("a", paging ? 3 : 2, paging ? 3 : 2,
+ rows(row(100), row(200), row(300)),
+ rows(row(1, 10, 100, 1000), row(1, 20, 200, 2000),
row(2, 30, 300, 3000)),
+ rows(row(1, 10, 100, null), row(1, 20, 200, null),
row(2, 30, 300, null)))
+ .deleteColumn("DELETE a FROM %s WHERE k=1 AND c=20", "b", 0, 1,
+ rows(row(1000), row(2000), row(3000)),
+ rows(row(1, 10, 100, 1000), row(1, 20, null, 2000),
row(2, 30, 300, 3000)),
+ rows(row(1, 10, 100, 1000), row(1, 20, 200, 2000),
row(2, 30, 300, 3000)))
+ .deleteRows("DELETE FROM %s WHERE k=1 AND c=20", 1,
+ rows(row(1, 10, 100, 1000), row(2, 30, 300, 3000)),
+ rows(row(1, 10, 100, 1000), row(1, 20, null, 2000), row(2,
30, 300, 3000)))
+ .deleteRows("DELETE FROM %s WHERE k=1", 1,
+ rows(row(2, 30, 300, 3000)),
+ rows(row(1, 10, 100, 1000), row(2, 30, 300, 3000)))
+ .tearDown(0,
+ rows(row(2, 30, 300, 3000)),
+ rows(row(2, 30, 300, 3000)));
+ }
+
+ /**
+ * Test range queries on a table with static columns.
+ */
+ @Test
+ public void testUnrestrictedQueryWithStaticColumns()
+ {
+ tester("")
+ .createTable("CREATE TABLE %s (k int, s1 int static, s2 int static, c
int, PRIMARY KEY(k, c))")
+ .mutate("INSERT INTO %s (k, s1, s2) VALUES (1, 10, 100)",
+ "INSERT INTO %s (k, c) VALUES (1, 1)",
+ "INSERT INTO %s (k, c) VALUES (1, 2)",
+ "INSERT INTO %s (k, s1, s2) VALUES (2, 10, 100)")
+ .queryColumns("s1", paging ? 3 : 2, 2,
+ rows(row(10), row(10), row(10)),
+ rows(row(1, 1, 10, 100), row(1, 2, 10, 100), row(2,
null, 10, 100)),
+ rows(row(1, 1, 10, null), row(1, 2, 10, null), row(2,
null, 10, null)))
+ .deleteColumn("DELETE s1 FROM %s WHERE k=1", "s2", 0, 1,
+ rows(row(100), row(100), row(100)),
+ rows(row(1, 1, null, 100), row(1, 2, null, 100), row(2,
null, 10, 100)),
+ rows(row(1, 1, 10, 100), row(1, 2, 10, 100), row(2,
null, 10, 100)))
+ .deleteRows("DELETE FROM %s WHERE k=1 AND c=1", 1,
+ rows(row(1, 2, null, 100), row(2, null, 10, 100)),
+ rows(row(1, 1, null, 100), row(1, 2, null, 100), row(2,
null, 10, 100)))
+ .deleteRows("DELETE FROM %s WHERE k=1", 1,
+ rows(row(2, null, 10, 100)),
+ rows(row(1, 2, null, 100), row(2, null, 10, 100)))
+ .tearDown(0,
+ rows(row(2, null, 10, 100)),
+ rows(row(2, null, 10, 100)));
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]