Merge branch cassandra-2.2 into cassandra-3.0
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/da94781a Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/da94781a Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/da94781a Branch: refs/heads/trunk Commit: da94781a2c20394c1fc4f3d488a694ddad45228f Parents: 6bd402d 9a5aef0 Author: Benjamin Lerer <b.le...@gmail.com> Authored: Mon Dec 12 13:26:35 2016 +0100 Committer: Benjamin Lerer <b.le...@gmail.com> Committed: Mon Dec 12 13:46:24 2016 +0100 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../operations/InsertUpdateIfConditionTest.java | 126 +++++++++++-------- 2 files changed, 76 insertions(+), 51 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/da94781a/CHANGES.txt ---------------------------------------------------------------------- diff --cc CHANGES.txt index 266849a,134a37d..bbd47c1 --- a/CHANGES.txt +++ b/CHANGES.txt @@@ -1,14 -1,5 +1,15 @@@ -2.2.9 +3.0.11 + * Set RPC_READY to false when draining or if a node is marked as shutdown (CASSANDRA-12781) + * CQL often queries static columns unnecessarily (CASSANDRA-12768) + * Make sure sstables only get committed when it's safe to discard commit log records (CASSANDRA-12956) + * Reject default_time_to_live option when creating or altering MVs (CASSANDRA-12868) + * Nodetool should use a more sane max heap size (CASSANDRA-12739) + * LocalToken ensures token values are cloned on heap (CASSANDRA-12651) + * AnticompactionRequestSerializer serializedSize is incorrect (CASSANDRA-12934) + * Prevent reloading of logback.xml from UDF sandbox (CASSANDRA-12535) + * Reenable HeapPool (CASSANDRA-12900) +Merged from 2.2: + * Test bind parameters and unset parameters in InsertUpdateIfConditionTest (CASSANDRA-12980) * Do not specify local address on outgoing connection when listen_on_broadcast_address is set (CASSANDRA-12673) * Use saved tokens when setting local tokens on StorageService.joinRing (CASSANDRA-12935) * cqlsh: fix DESC TYPES errors (CASSANDRA-12914) http://git-wip-us.apache.org/repos/asf/cassandra/blob/da94781a/test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionTest.java ---------------------------------------------------------------------- diff --cc test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionTest.java index ec81cf2,4a209e6..f1dc9a2 --- a/test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionTest.java +++ b/test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionTest.java @@@ -23,11 -23,8 +23,10 @@@ import org.junit.Test import org.apache.cassandra.cql3.CQLTester; import org.apache.cassandra.exceptions.InvalidRequestException; import org.apache.cassandra.exceptions.SyntaxException; +import org.apache.cassandra.schema.SchemaKeyspace; +import static java.lang.String.format; import static org.junit.Assert.assertEquals; - import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; public class InsertUpdateIfConditionTest extends CQLTester @@@ -111,13 -111,8 +113,13 @@@ // Shouldn't apply assertRows(execute("UPDATE %s SET v1 = 3, v2 = 'bar' WHERE k = 0 IF EXISTS"), row(false)); - // Shouldn't apply + // Should apply + assertEmpty(execute("SELECT * FROM %s WHERE k = 0")); - assertRows(execute("DELETE FROM %s WHERE k = 0 IF v1 IN (null)"), row(true)); + assertRows(execute("DELETE FROM %s WHERE k = 0 IF v1 IN (?)", (Integer) null), row(true)); + + createTable(" CREATE TABLE %s (k int, c int, v1 text, PRIMARY KEY(k, c))"); + assertInvalidMessage("IN on the clustering key columns is not supported with conditional updates", + "UPDATE %s SET v1 = 'A' WHERE k = 0 AND c IN (1, 2) IF EXISTS"); } /** @@@ -194,58 -191,33 +209,61 @@@ assertRows(execute("DELETE FROM %s WHERE k='k' AND i=0 IF EXISTS"), row(false)); // CASSANDRA-6430 - assertInvalidMessage("DELETE statements must restrict all PRIMARY KEY columns with equality relations in order to use IF conditions, but column 'i' is not restricted", + assertInvalidMessage("DELETE statements must restrict all PRIMARY KEY columns with equality relations in order to delete non static columns", "DELETE FROM %s WHERE k = 'k' IF EXISTS"); - assertInvalidMessage("DELETE statements must restrict all PRIMARY KEY columns with equality relations in order to use IF conditions, but column 'i' is not restricted", + assertInvalidMessage("DELETE statements must restrict all PRIMARY KEY columns with equality relations in order to delete non static columns", - "DELETE FROM %s WHERE k = 'k' IF v = 'foo'"); + "DELETE FROM %s WHERE k = 'k' IF v = ?", "foo"); - assertInvalidMessage("DELETE statements must restrict all PRIMARY KEY columns with equality relations in order to use IF conditions, but column 'k' is not restricted", + assertInvalidMessage("Some partition key parts are missing: k", "DELETE FROM %s WHERE i = 0 IF EXISTS"); + assertInvalidMessage("Invalid INTEGER constant (0) for \"k\" of type text", "DELETE FROM %s WHERE k = 0 AND i > 0 IF EXISTS"); - - assertInvalidMessage("Invalid operator > for PRIMARY KEY part i", + assertInvalidMessage("Invalid INTEGER constant (0) for \"k\" of type text", + "DELETE FROM %s WHERE k = 0 AND i > 0 IF v = 'foo'"); + assertInvalidMessage("DELETE statements must restrict all PRIMARY KEY columns with equality relations in order to delete non static columns", "DELETE FROM %s WHERE k = 'k' AND i > 0 IF EXISTS"); - assertInvalidMessage("Invalid operator > for PRIMARY KEY part i", - "DELETE FROM %s WHERE k = 'k' AND i > 0 IF v = ?", "foo"); + assertInvalidMessage("DELETE statements must restrict all PRIMARY KEY columns with equality relations in order to delete non static columns", + "DELETE FROM %s WHERE k = 'k' AND i > 0 IF v = 'foo'"); + assertInvalidMessage("IN on the clustering key columns is not supported with conditional deletions", + "DELETE FROM %s WHERE k = 'k' AND i IN (0, 1) IF v = 'foo'"); + assertInvalidMessage("IN on the clustering key columns is not supported with conditional deletions", + "DELETE FROM %s WHERE k = 'k' AND i IN (0, 1) IF EXISTS"); + assertInvalidMessage("Invalid 'unset' value in condition", + "DELETE FROM %s WHERE k = 'k' AND i = 0 IF v = ?", unset()); + createTable("CREATE TABLE %s(k int, s int static, i int, v text, PRIMARY KEY(k, i))"); execute("INSERT INTO %s (k, s, i, v) VALUES ( 1, 1, 2, '1')"); - assertRows(execute("DELETE v FROM %s WHERE k = 1 AND i = 2 IF s != 1"), row(false, 1)); - assertRows(execute("DELETE v FROM %s WHERE k = 1 AND i = 2 IF s = 1"), row(true)); + assertRows(execute("DELETE v FROM %s WHERE k = 1 AND i = 2 IF s != ?", 1), row(false, 1)); + assertRows(execute("DELETE v FROM %s WHERE k = 1 AND i = 2 IF s = ?", 1), row(true)); assertRows(execute("SELECT * FROM %s WHERE k = 1 AND i = 2"), row(1, 2, 1, null)); - assertRows(execute("DELETE FROM %s WHERE k = 1 AND i = 2 IF s != 1"), row(false, 1)); - assertRows(execute("DELETE FROM %s WHERE k = 1 AND i = 2 IF s = 1"), row(true)); + assertRows(execute("DELETE FROM %s WHERE k = 1 AND i = 2 IF s != ?", 1), row(false, 1)); + assertRows(execute("DELETE FROM %s WHERE k = 1 AND i = 2 IF s = ?", 1), row(true)); assertEmpty(execute("SELECT * FROM %s WHERE k = 1 AND i = 2")); assertRows(execute("SELECT * FROM %s WHERE k = 1"), row(1, null, 1, null)); + + createTable("CREATE TABLE %s (k int, i int, v1 int, v2 int, s int static, PRIMARY KEY (k, i))"); + execute("INSERT INTO %s (k, i, v1, v2, s) VALUES (?, ?, ?, ?, ?)", + 1, 1, 1, 1, 1); + assertRows(execute("DELETE v1 FROM %s WHERE k = 1 AND i = 1 IF EXISTS"), + row(true)); + assertRows(execute("DELETE v2 FROM %s WHERE k = 1 AND i = 1 IF EXISTS"), + row(true)); + assertRows(execute("DELETE FROM %s WHERE k = 1 AND i = 1 IF EXISTS"), + row(true)); + assertRows(execute("select * from %s"), + row(1, null, 1, null, null)); + assertRows(execute("DELETE v1 FROM %s WHERE k = 1 AND i = 1 IF EXISTS"), + row(false)); + assertRows(execute("DELETE v1 FROM %s WHERE k = 1 AND i = 1 IF s = 5"), + row(false, 1)); + assertRows(execute("DELETE v1 FROM %s WHERE k = 1 AND i = 1 IF v1 = 1 AND v2 = 1"), + row(false)); + assertRows(execute("DELETE v1 FROM %s WHERE k = 1 AND i = 1 IF v1 = 1 AND v2 = 1 AND s = 1"), + row(false, null, null, 1)); + assertRows(execute("DELETE v1 FROM %s WHERE k = 1 AND i = 5 IF s = 1"), + row(true)); } /** @@@ -266,19 -238,15 +284,19 @@@ execute("INSERT INTO %s(id, version) VALUES (0, 0)"); - assertRows(execute("UPDATE %s SET v='foo', version=1 WHERE id=0 AND k='k1' IF version = 0"), row(true)); + assertRows(execute("UPDATE %s SET v='foo', version=1 WHERE id=0 AND k='k1' IF version = ?", 0), row(true)); assertRows(execute("SELECT * FROM %s"), row(0, "k1", 1, "foo")); - assertRows(execute("UPDATE %s SET v='bar', version=1 WHERE id=0 AND k='k2' IF version = 0"), row(false, 1)); + assertRows(execute("UPDATE %s SET v='bar', version=1 WHERE id=0 AND k='k2' IF version = ?", 0), row(false, 1)); assertRows(execute("SELECT * FROM %s"), row(0, "k1", 1, "foo")); - assertRows(execute("UPDATE %s SET v='bar', version=2 WHERE id=0 AND k='k2' IF version = 1"), row(true)); + assertRows(execute("UPDATE %s SET v='bar', version=2 WHERE id=0 AND k='k2' IF version = ?", 1), row(true)); assertRows(execute("SELECT * FROM %s"), row(0, "k1", 2, "foo"), row(0, "k2", 2, "bar")); + // Batch output is slightly different from non-batch CAS, since a full PK is included to disambiguate + // cases when conditions span across multiple rows. + assertRows(execute("UPDATE %1$s SET version=3 WHERE id=0 IF version=1; "), + row(false, 2)); // Testing batches assertRows(execute("BEGIN BATCH " + "UPDATE %1$s SET v='foobar' WHERE id=0 AND k='k1'; " + @@@ -1095,147 -1047,66 +1119,147 @@@ { createTable("CREATE TABLE %s (a int, b int, s int static, d text, PRIMARY KEY (a, b))"); - // pre-populate, leave out static column - for (int i = 1; i <= 5; i++) - execute("INSERT INTO %s (a, b) VALUES (?, ?)", i, i); + assertRows(execute("UPDATE %s SET s = 1 WHERE a = 1 IF s = NULL"), + row(true)); + assertRows(execute("SELECT a, s, d FROM %s WHERE a = 1"), + row(1, 1, null)); - conditionalUpdatesWithNonExistingOrNullValues(); + assertRows(execute("UPDATE %s SET s = 2 WHERE a = 2 IF s IN (10,20,NULL)"), + row(true)); + assertRows(execute("SELECT a, s, d FROM %s WHERE a = 2"), + row(2, 2, null)); + + assertRows(execute("UPDATE %s SET s = 4 WHERE a = 4 IF s != 4"), + row(true)); + assertRows(execute("SELECT a, s, d FROM %s WHERE a = 4"), + row(4, 4, null)); // rejected: IN doesn't contain null - assertRows(execute("UPDATE %s SET s = 3 WHERE a = 3 IF s IN (10,20,30)"), - assertRows(execute("UPDATE %s SET s = 30 WHERE a = 3 IF s IN ?", list(10,20,30)), ++ assertRows(execute("UPDATE %s SET s = 3 WHERE a = 3 IF s IN ?", list(10,20,30)), row(false)); - assertRows(execute("SELECT * FROM %s WHERE a = 3"), - row(3, 3, null, null)); + assertEmpty(execute("SELECT a, s, d FROM %s WHERE a = 3")); // rejected: comparing number with NULL always returns false - for (String operator: new String[] { ">", "<", ">=", "<=", "="}) + for (String operator : new String[]{ ">", "<", ">=", "<=", "=" }) { - assertRows(execute("UPDATE %s SET s = 50 WHERE a = 5 IF s " + operator + " 3"), + assertRows(execute("UPDATE %s SET s = 50 WHERE a = 5 IF s " + operator + " ?", 3), row(false)); - assertRows(execute("SELECT * FROM %s WHERE a = 5"), - row(5, 5, null, null)); + assertEmpty(execute("SELECT * FROM %s WHERE a = 5")); } - } @Test - public void testConditionalUpdatesWithNonExistingValues() throws Throwable + public void testConditionalUpdatesWithNullValues() throws Throwable { - createTable("CREATE TABLE %s (a int, b int, s int static, d text, PRIMARY KEY (a, b))"); + createTable("CREATE TABLE %s (a int, b int, s int static, d int, PRIMARY KEY (a, b))"); - conditionalUpdatesWithNonExistingOrNullValues(); + // pre-populate, leave out static column + for (int i = 1; i <= 5; i++) + { + execute("INSERT INTO %s (a, b) VALUES (?, ?)", i, 1); + execute("INSERT INTO %s (a, b) VALUES (?, ?)", i, 2); + } + + assertRows(execute("UPDATE %s SET s = 100 WHERE a = 1 IF s = NULL"), + row(true)); + assertRows(execute("SELECT a, b, s, d FROM %s WHERE a = 1"), + row(1, 1, 100, null), + row(1, 2, 100, null)); + + assertRows(execute("UPDATE %s SET s = 200 WHERE a = 2 IF s IN (10,20,NULL)"), + row(true)); + assertRows(execute("SELECT a, b, s, d FROM %s WHERE a = 2"), + row(2, 1, 200, null), + row(2, 2, 200, null)); // rejected: IN doesn't contain null - assertRows(execute("UPDATE %s SET s = 30 WHERE a = 3 IF s IN (10,20,30)"), - assertRows(execute("UPDATE %s SET s = 3 WHERE a = 3 IF s IN ?", list(10,20,30)), - row(false)); - assertEmpty(execute("SELECT a, s, d FROM %s WHERE a = 3")); ++ assertRows(execute("UPDATE %s SET s = 30 WHERE a = 3 IF s IN ?", list(10,20,30)), + row(false, null)); + assertRows(execute("SELECT * FROM %s WHERE a = 3"), + row(3, 1, null, null), + row(3, 2, null, null)); + + assertRows(execute("UPDATE %s SET s = 400 WHERE a = 4 IF s IN (10,20,NULL)"), + row(true)); + assertRows(execute("SELECT * FROM %s WHERE a = 4"), + row(4, 1, 400, null), + row(4, 2, 400, null)); // rejected: comparing number with NULL always returns false - for (String operator : new String[]{ ">", "<", ">=", "<=", "=" }) + for (String operator: new String[] { ">", "<", ">=", "<=", "="}) { - assertRows(execute("UPDATE %s SET s = 50 WHERE a = 5 IF s " + operator + " ?", 3), - row(false)); - assertEmpty(execute("SELECT * FROM %s WHERE a = 5")); + assertRows(execute("UPDATE %s SET s = 50 WHERE a = 5 IF s " + operator + " 3"), + row(false, null)); + assertRows(execute("SELECT * FROM %s WHERE a = 5"), + row(5, 1, null, null), + row(5, 2, null, null)); } + + assertRows(execute("UPDATE %s SET s = 500 WHERE a = 5 IF s != 5"), + row(true)); + assertRows(execute("SELECT a, b, s, d FROM %s WHERE a = 5"), + row(5, 1, 500, null), + row(5, 2, 500, null)); + + // Similar test, although with two static columns to test limits + createTable("CREATE TABLE %s (a int, b int, s1 int static, s2 int static, d int, PRIMARY KEY (a, b))"); + + for (int i = 1; i <= 5; i++) + for (int j = 0; j < 5; j++) + execute("INSERT INTO %s (a, b, d) VALUES (?, ?, ?)", i, j, i + j); + + assertRows(execute("UPDATE %s SET s2 = 100 WHERE a = 1 IF s1 = NULL"), + row(true)); + + execute("INSERT INTO %s (a, b, s1) VALUES (?, ?, ?)", 2, 2, 2); + assertRows(execute("UPDATE %s SET s1 = 100 WHERE a = 2 IF s2 = NULL"), + row(true)); + + execute("INSERT INTO %s (a, b, s1) VALUES (?, ?, ?)", 2, 2, 2); + assertRows(execute("UPDATE %s SET s1 = 100 WHERE a = 2 IF s2 = NULL"), + row(true)); } - private void conditionalUpdatesWithNonExistingOrNullValues() throws Throwable + @Test + public void testStaticsWithMultipleConditions() throws Throwable { - assertRows(execute("UPDATE %s SET s = 1 WHERE a = 1 IF s = ?", (Integer) null), - row(true)); - assertRows(execute("SELECT a, s, d FROM %s WHERE a = 1"), - row(1, 1, null)); + createTable("CREATE TABLE %s (a int, b int, s1 int static, s2 int static, d int, PRIMARY KEY (a, b))"); - assertRows(execute("UPDATE %s SET s = 2 WHERE a = 2 IF s IN (?, ?, ?)", 10,20,null), + for (int i = 1; i <= 5; i++) + { + execute("INSERT INTO %s (a, b, d) VALUES (?, ?, ?)", i, 1, 5); + execute("INSERT INTO %s (a, b, d) VALUES (?, ?, ?)", i, 2, 6); + } + + assertRows(execute("BEGIN BATCH\n" + + "UPDATE %1$s SET s2 = 102 WHERE a = 1 IF s1 = null;\n" + + "UPDATE %1$s SET s1 = 101 WHERE a = 1 IF s2 = null;\n" + + "APPLY BATCH"), row(true)); - assertRows(execute("SELECT a, s, d FROM %s WHERE a = 2"), - row(2, 2, null)); + assertRows(execute("SELECT * FROM %s WHERE a = 1"), + row(1, 1, 101, 102, 5), + row(1, 2, 101, 102, 6)); - assertRows(execute("UPDATE %s SET s = 4 WHERE a = 4 IF s != ?", 4 ), + + assertRows(execute("BEGIN BATCH\n" + + "UPDATE %1$s SET s2 = 202 WHERE a = 2 IF s1 = null;\n" + + "UPDATE %1$s SET s1 = 201 WHERE a = 2 IF s2 = null;\n" + + "UPDATE %1$s SET d = 203 WHERE a = 2 AND b = 1 IF d = 5;\n" + + "UPDATE %1$s SET d = 204 WHERE a = 2 AND b = 2 IF d = 6;\n" + + "APPLY BATCH"), row(true)); - assertRows(execute("SELECT a, s, d FROM %s WHERE a = 4"), - row(4, 4, null)); + + assertRows(execute("SELECT * FROM %s WHERE a = 2"), + row(2, 1, 201, 202, 203), + row(2, 2, 201, 202, 204)); + + assertRows(execute("BEGIN BATCH\n" + + "UPDATE %1$s SET s2 = 202 WHERE a = 20 IF s1 = null;\n" + + "UPDATE %1$s SET s1 = 201 WHERE a = 20 IF s2 = null;\n" + + "UPDATE %1$s SET d = 203 WHERE a = 20 AND b = 1 IF d = 5;\n" + + "UPDATE %1$s SET d = 204 WHERE a = 20 AND b = 2 IF d = 6;\n" + + "APPLY BATCH"), + row(false)); } @Test