Update tests Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/006ebf64 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/006ebf64 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/006ebf64
Branch: refs/heads/12060-3.0-v2 Commit: 006ebf641db1bdf096b49320cf6f1247c4ef58f1 Parents: 94e1d56 Author: Alex Petrov <[email protected]> Authored: Thu Aug 11 09:12:19 2016 +0200 Committer: Alex Petrov <[email protected]> Committed: Wed Aug 17 15:30:21 2016 +0200 ---------------------------------------------------------------------- .../operations/InsertUpdateIfConditionTest.java | 287 +++++++++++++------ 1 file changed, 196 insertions(+), 91 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/006ebf64/test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionTest.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionTest.java b/test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionTest.java index a1ee4f8..e4fcccc 100644 --- a/test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionTest.java +++ b/test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionTest.java @@ -111,8 +111,9 @@ public class InsertUpdateIfConditionTest extends CQLTester // Shouldn't apply assertRows(execute("UPDATE %s SET v1 = 3, v2 = 'bar' WHERE k = 0 IF EXISTS"), row(false)); - // Should apply - assertRows(execute("DELETE FROM %s WHERE k = 0 IF v1 IN (null)"), row(true)); + // Shouldn't apply + assertEmpty(execute("SELECT * FROM %s WHERE k = 0")); + assertRows(execute("DELETE FROM %s WHERE k = 0 IF v1 IN (null)"), row(false)); 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", @@ -254,7 +255,7 @@ public class InsertUpdateIfConditionTest extends CQLTester "UPDATE %1$s SET v='barfoo' WHERE id=0 AND k='k2'; " + "UPDATE %1$s SET version=3 WHERE id=0 IF version=1; " + "APPLY BATCH "), - row(false, 0, null, 2)); + row(false, 0, "k1", 2)); assertRows(execute("BEGIN BATCH " + "UPDATE %1$s SET v = 'foobar' WHERE id = 0 AND k = 'k1'; " + @@ -489,8 +490,10 @@ public class InsertUpdateIfConditionTest extends CQLTester createTable("CREATE TABLE %s (partition text, key text, owner text, PRIMARY KEY (partition, key) ) WITH COMPACT STORAGE"); execute("INSERT INTO %s (partition, key, owner) VALUES ('a', 'b', null)"); - assertRows(execute("UPDATE %s SET owner='z' WHERE partition='a' AND key='b' IF owner=null"), row(true)); + assertEmpty(execute("SELECT * FROM %s")); + assertRows(execute("UPDATE %s SET owner='z' WHERE partition='a' AND key='b' IF owner=null"), row(false)); // CASSANDRA-12426 + execute("INSERT INTO %s (partition, key, owner) VALUES ('a', 'b', 'z')"); assertRows(execute("UPDATE %s SET owner='b' WHERE partition='a' AND key='b' IF owner='a'"), row(false, "z")); assertRows(execute("UPDATE %s SET owner='b' WHERE partition='a' AND key='b' IF owner='z'"), row(true)); @@ -1038,47 +1041,138 @@ public class InsertUpdateIfConditionTest extends CQLTester assertRows(execute("SELECT * FROM %s WHERE a = 6"), row(6, 6, 6, "a")); + execute("INSERT INTO %s (a, b, s, d) values (7, 7, 100, 'a')"); + assertRows(execute("UPDATE %s SET s = 7 WHERE a = 7 IF s = 101"), + row(false, 100)); + assertRows(execute("SELECT * FROM %s WHERE a = 7"), + row(7, 7, 100, "a")); + // pre-existing row with null in the static column execute("INSERT INTO %s (a, b, d) values (7, 7, 'a')"); assertRows(execute("UPDATE %s SET s = 7 WHERE a = 7 IF s = NULL"), - row(true)); + row(false, 100)); assertRows(execute("SELECT * FROM %s WHERE a = 7"), - row(7, 7, 7, "a")); + row(7, 7, 100, "a")); - // deleting row before CAS + // deleting row before CAS makes it effectively non-existing execute("DELETE FROM %s WHERE a = 8;"); assertRows(execute("UPDATE %s SET s = 8 WHERE a = 8 IF s = NULL"), - row(true)); - assertRows(execute("SELECT * FROM %s WHERE a = 8"), - row(8, null, 8, null)); + row(false)); + assertRows(execute("SELECT * FROM %s WHERE a = 8")); } @Test 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))"); // pre-populate, leave out static column for (int i = 1; i <= 5; i++) - execute("INSERT INTO %s (a, b) VALUES (?, ?)", i, i); + { + execute("INSERT INTO %s (a, b) VALUES (?, ?)", i, 1); + execute("INSERT INTO %s (a, b) VALUES (?, ?)", i, 2); + } - conditionalUpdatesWithNonExistingOrNullValues(); + 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)"), - row(false)); + row(false, null)); assertRows(execute("SELECT * FROM %s WHERE a = 3"), - row(3, 3, null, null)); + 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)); + + assertRows(execute("UPDATE %s SET s = 500 WHERE a = 500 IF s != 5"), + row(false)); + assertRows(execute("SELECT a, b, s, d FROM %s WHERE a = 5"), + row(5, 1, null, null), + row(5, 2, null, null)); // rejected: comparing number with NULL always returns false for (String operator: new String[] { ">", "<", ">=", "<=", "="}) { assertRows(execute("UPDATE %s SET s = 50 WHERE a = 5 IF s " + operator + " 3"), - row(false)); + row(false, null)); assertRows(execute("SELECT * FROM %s WHERE a = 5"), - row(5, 5, null, null)); + row(5, 1, null, null), + row(5, 2, null, 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)); + } + + @Test + public void testStaticsWithMultipleConditions() throws Throwable + { + 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++) + { + 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 * FROM %s WHERE a = 1"), + row(1, 1, 101, 102, 5), + row(1, 2, 101, 102, 6)); + + + 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 * 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 @@ -1086,7 +1180,19 @@ public class InsertUpdateIfConditionTest extends CQLTester { createTable("CREATE TABLE %s (a int, b int, s int static, d text, PRIMARY KEY (a, b))"); - conditionalUpdatesWithNonExistingOrNullValues(); + // "s = NULL" means "the container of x exists but x itself is null", if container does not + // exist, LWT should not be applied + assertRows(execute("UPDATE %s SET s = 1 WHERE a = 1 IF s = NULL"), + row(false)); + assertEmpty(execute("SELECT a, s, d FROM %s WHERE a = 1")); + + assertRows(execute("UPDATE %s SET s = 2 WHERE a = 2 IF s IN (10,20,NULL)"), + row(false)); + assertEmpty(execute("SELECT a, s, d FROM %s WHERE a = 2")); + + assertRows(execute("UPDATE %s SET s = 4 WHERE a = 4 IF s != 4"), + row(false)); + assertEmpty(execute("SELECT a, s, d FROM %s WHERE a = 4")); // rejected: IN doesn't contain null assertRows(execute("UPDATE %s SET s = 3 WHERE a = 3 IF s IN (10,20,30)"), @@ -1102,24 +1208,6 @@ public class InsertUpdateIfConditionTest extends CQLTester } } - private void conditionalUpdatesWithNonExistingOrNullValues() throws Throwable - { - 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)); - - 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)); - } - @Test public void testConditionalUpdatesWithNullValuesWithBatch() throws Throwable { @@ -1129,7 +1217,14 @@ public class InsertUpdateIfConditionTest extends CQLTester for (int i = 1; i <= 6; i++) execute("INSERT INTO %s (a, b) VALUES (?, ?)", i, i); - testConditionalUpdatesWithNonExistingOrNullValuesWithBatch(); + // applied: null is indistiguishable from empty value, lwt condition is executed before INSERT + assertRows(execute("BEGIN BATCH\n" + + "INSERT INTO %1$s (a, b, d) values (2, 2, 'a');\n" + + "UPDATE %1$s SET s = 2 WHERE a = 2 IF s = null;\n" + + "APPLY BATCH"), + row(true)); + assertRows(execute("SELECT * FROM %s WHERE a = 2"), + row(2, 2, 2, "a")); // rejected: comparing number with null value always returns false for (String operator: new String[] { ">", "<", ">=", "<=", "="}) @@ -1138,20 +1233,45 @@ public class InsertUpdateIfConditionTest extends CQLTester + "INSERT INTO %1$s (a, b, s, d) values (3, 3, 40, 'a');\n" + "UPDATE %1$s SET s = 30 WHERE a = 3 IF s " + operator + " 5;\n" + "APPLY BATCH"), - row(false)); + row(false, 3, 3, null)); assertRows(execute("SELECT * FROM %s WHERE a = 3"), row(3, 3, null, null)); } + // applied: lwt condition is executed before INSERT, update is applied after it + assertRows(execute("BEGIN BATCH\n" + + "INSERT INTO %1$s (a, b, s, d) values (4, 4, 4, 'a');\n" + + "UPDATE %1$s SET s = 5 WHERE a = 4 IF s = null;\n" + + "APPLY BATCH"), + row(true)); + assertRows(execute("SELECT * FROM %s WHERE a = 4"), + row(4, 4, 5, "a")); + + assertRows(execute("BEGIN BATCH\n" + + "INSERT INTO %1$s (a, b, s, d) values (5, 5, 5, 'a');\n" + + "UPDATE %1$s SET s = 6 WHERE a = 5 IF s IN (1,2,null);\n" + + "APPLY BATCH"), + row(true)); + assertRows(execute("SELECT * FROM %s WHERE a = 5"), + row(5, 5, 6, "a")); + // rejected: IN doesn't contain null assertRows(execute("BEGIN BATCH\n" + "INSERT INTO %1$s (a, b, s, d) values (6, 6, 70, 'a');\n" + "UPDATE %1$s SET s = 60 WHERE a = 6 IF s IN (1,2,3);\n" + "APPLY BATCH"), - row(false)); + row(false, 6, 6, null)); assertRows(execute("SELECT * FROM %s WHERE a = 6"), row(6, 6, null, null)); + // "s != 7" means "container exists and the value within that container is not equal to 7" + assertRows(execute("BEGIN BATCH\n" + + "INSERT INTO %1$s (a, b, s, d) values (7, 7, 7, 'a');\n" + + "UPDATE %1$s SET s = 8 WHERE a = 7 IF s != 7;\n" + + "APPLY BATCH"), + row(false)); + assertEmpty(execute("SELECT * FROM %s WHERE a = 7")); + } @Test @@ -1159,63 +1279,53 @@ public class InsertUpdateIfConditionTest extends CQLTester { createTable("CREATE TABLE %s (a int, b int, s int static, d text, PRIMARY KEY (a, b))"); - testConditionalUpdatesWithNonExistingOrNullValuesWithBatch(); - - // rejected: comparing number with non-existing value always returns false - for (String operator: new String[] { ">", "<", ">=", "<=", "="}) - { - assertRows(execute("BEGIN BATCH\n" - + "INSERT INTO %1$s (a, b, s, d) values (3, 3, 3, 'a');\n" - + "UPDATE %1$s SET s = 3 WHERE a = 3 IF s " + operator + " 5;\n" - + "APPLY BATCH"), - row(false)); - assertEmpty(execute("SELECT * FROM %s WHERE a = 3")); - } - - // rejected: IN doesn't contain null - assertRows(execute("BEGIN BATCH\n" - + "INSERT INTO %1$s (a, b, s, d) values (6, 6, 6, 'a');\n" - + "UPDATE %1$s SET s = 7 WHERE a = 6 IF s IN (1,2,3);\n" - + "APPLY BATCH"), - row(false)); - assertEmpty(execute("SELECT * FROM %s WHERE a = 6")); - } - - private void testConditionalUpdatesWithNonExistingOrNullValuesWithBatch() throws Throwable - { - // applied: null is indistiguishable from empty value, lwt condition is executed before INSERT assertRows(execute("BEGIN BATCH\n" + "INSERT INTO %1$s (a, b, d) values (2, 2, 'a');\n" + "UPDATE %1$s SET s = 2 WHERE a = 2 IF s = null;\n" + "APPLY BATCH"), - row(true)); - assertRows(execute("SELECT * FROM %s WHERE a = 2"), - row(2, 2, 2, "a")); + row(false)); + assertEmpty(execute("SELECT * FROM %s WHERE a = 2")); // applied: lwt condition is executed before INSERT, update is applied after it assertRows(execute("BEGIN BATCH\n" + "INSERT INTO %1$s (a, b, s, d) values (4, 4, 4, 'a');\n" + "UPDATE %1$s SET s = 5 WHERE a = 4 IF s = null;\n" + "APPLY BATCH"), - row(true)); - assertRows(execute("SELECT * FROM %s WHERE a = 4"), - row(4, 4, 5, "a")); + row(false)); + assertEmpty(execute("SELECT * FROM %s WHERE a = 4")); assertRows(execute("BEGIN BATCH\n" + "INSERT INTO %1$s (a, b, s, d) values (5, 5, 5, 'a');\n" + "UPDATE %1$s SET s = 6 WHERE a = 5 IF s IN (1,2,null);\n" + "APPLY BATCH"), - row(true)); - assertRows(execute("SELECT * FROM %s WHERE a = 5"), - row(5, 5, 6, "a")); + row(false)); + assertEmpty(execute("SELECT * FROM %s WHERE a = 5")); assertRows(execute("BEGIN BATCH\n" + "INSERT INTO %1$s (a, b, s, d) values (7, 7, 7, 'a');\n" + "UPDATE %1$s SET s = 8 WHERE a = 7 IF s != 7;\n" + "APPLY BATCH"), - row(true)); - assertRows(execute("SELECT * FROM %s WHERE a = 7"), - row(7, 7, 8, "a")); + row(false)); + assertRows(execute("SELECT * FROM %s WHERE a = 7")); + + // rejected: comparing number with non-existing value always returns false + for (String operator: new String[] { ">", "<", ">=", "<=", "="}) + { + assertRows(execute("BEGIN BATCH\n" + + "INSERT INTO %1$s (a, b, s, d) values (3, 3, 3, 'a');\n" + + "UPDATE %1$s SET s = 3 WHERE a = 3 IF s " + operator + " 5;\n" + + "APPLY BATCH"), + row(false)); + assertEmpty(execute("SELECT * FROM %s WHERE a = 3")); + } + + // rejected: IN doesn't contain null + assertRows(execute("BEGIN BATCH\n" + + "INSERT INTO %1$s (a, b, s, d) values (6, 6, 6, 'a');\n" + + "UPDATE %1$s SET s = 7 WHERE a = 6 IF s IN (1,2,3);\n" + + "APPLY BATCH"), + row(false)); + assertEmpty(execute("SELECT * FROM %s WHERE a = 6")); } @Test @@ -1233,7 +1343,7 @@ public class InsertUpdateIfConditionTest extends CQLTester // rejected: IN doesn't contain null assertRows(execute("DELETE s1 FROM %s WHERE a = 2 IF s2 IN (10,20,30)"), - row(false)); + row(false, null)); assertRows(execute("SELECT * FROM %s WHERE a = 2"), row(2, 2, 2, null, 2)); @@ -1251,7 +1361,7 @@ public class InsertUpdateIfConditionTest extends CQLTester for (String operator : new String[]{ ">", "<", ">=", "<=", "=" }) { assertRows(execute("DELETE s1 FROM %s WHERE a = 5 IF s2 " + operator + " 3"), - row(false)); + row(false, null)); assertRows(execute("SELECT * FROM %s WHERE a = 5"), row(5, 5, 5, null, 5)); } @@ -1262,14 +1372,12 @@ public class InsertUpdateIfConditionTest extends CQLTester { createTable("CREATE TABLE %s (a int, b int, s1 int static, s2 int static, v int, PRIMARY KEY (a, b))"); - // applied: null is indistiguishable from empty value, lwt condition is executed before INSERT assertRows(execute("BEGIN BATCH\n" + "INSERT INTO %1$s (a, b, s1, v) values (2, 2, 2, 2);\n" + "DELETE s1 FROM %1$s WHERE a = 2 IF s2 = null;\n" + "APPLY BATCH"), - row(true)); - assertRows(execute("SELECT * FROM %s WHERE a = 2"), - row(2, 2, null, null, 2)); + row(false)); + assertEmpty(execute("SELECT * FROM %s WHERE a = 2")); // rejected: comparing number with non-existing value always returns false for (String operator: new String[] { ">", "<", ">=", "<=", "="}) @@ -1294,24 +1402,21 @@ public class InsertUpdateIfConditionTest extends CQLTester + "INSERT INTO %1$s (a, b, s1, v) values (4, 4, 4, 4);\n" + "DELETE s1 FROM %1$s WHERE a = 4 IF s2 = null;\n" + "APPLY BATCH"), - row(true)); - assertRows(execute("SELECT * FROM %s WHERE a = 4"), - row(4, 4, null, null, 4)); + row(false)); + assertEmpty(execute("SELECT * FROM %s WHERE a = 4")); assertRows(execute("BEGIN BATCH\n" + "INSERT INTO %1$s (a, b, s1, v) VALUES (5, 5, 5, 5);\n" + "DELETE s1 FROM %1$s WHERE a = 5 IF s1 IN (1,2,null);\n" + "APPLY BATCH"), - row(true)); - assertRows(execute("SELECT * FROM %s WHERE a = 5"), - row(5, 5, null, null, 5)); + row(false)); + assertEmpty(execute("SELECT * FROM %s WHERE a = 5")); assertRows(execute("BEGIN BATCH\n" + "INSERT INTO %1$s (a, b, s1, v) values (7, 7, 7, 7);\n" + "DELETE s1 FROM %1$s WHERE a = 7 IF s2 != 7;\n" + "APPLY BATCH"), - row(true)); - assertRows(execute("SELECT * FROM %s WHERE a = 7"), - row(7, 7, null, null, 7)); + row(false)); + assertEmpty(execute("SELECT * FROM %s WHERE a = 7")); } }
