Repository: cassandra Updated Branches: refs/heads/trunk 66fb8f51e -> 677230df6
http://git-wip-us.apache.org/repos/asf/cassandra/blob/677230df/test/unit/org/apache/cassandra/cql3/validation/entities/UserTypesTest.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/UserTypesTest.java b/test/unit/org/apache/cassandra/cql3/validation/entities/UserTypesTest.java index d9df206..5501561 100644 --- a/test/unit/org/apache/cassandra/cql3/validation/entities/UserTypesTest.java +++ b/test/unit/org/apache/cassandra/cql3/validation/entities/UserTypesTest.java @@ -73,32 +73,86 @@ public class UserTypesTest extends CQLTester execute("INSERT INTO %s(k, v) VALUES (?, {x:?})", 1, -104.99251); execute("UPDATE %s SET b = ? WHERE k = ?", true, 1); - assertRows(execute("SELECT v.x FROM %s WHERE k = ? AND v = {x:?}", 1, -104.99251), - row(-104.99251) - ); - - flush(); - - assertRows(execute("SELECT v.x FROM %s WHERE k = ? AND v = {x:?}", 1, -104.99251), - row(-104.99251) + beforeAndAfterFlush(() -> + assertRows(execute("SELECT v.x FROM %s WHERE k = ? AND v = {x:?}", 1, -104.99251), + row(-104.99251) + ) ); } @Test - public void testCreateInvalidTablesWithUDT() throws Throwable + public void testInvalidUDTStatements() throws Throwable { - String myType = createType("CREATE TYPE %s (f int)"); - - // Using a UDT without frozen shouldn't work - assertInvalidMessage("Non-frozen User-Defined types are not supported, please use frozen<>", - "CREATE TABLE " + KEYSPACE + ".wrong (k int PRIMARY KEY, v " + KEYSPACE + '.' + myType + ")"); - + String typename = createType("CREATE TYPE %s (a int)"); + String myType = KEYSPACE + '.' + typename; + + // non-frozen UDTs in a table PK + assertInvalidMessage("Invalid non-frozen user-defined type for PRIMARY KEY component k", + "CREATE TABLE " + KEYSPACE + ".wrong (k " + myType + " PRIMARY KEY , v int)"); + assertInvalidMessage("Invalid non-frozen user-defined type for PRIMARY KEY component k2", + "CREATE TABLE " + KEYSPACE + ".wrong (k1 int, k2 " + myType + ", v int, PRIMARY KEY (k1, k2))"); + + // non-frozen UDTs in a collection + assertInvalidMessage("Non-frozen UDTs are not allowed inside collections: list<" + myType + ">", + "CREATE TABLE " + KEYSPACE + ".wrong (k int PRIMARY KEY, v list<" + myType + ">)"); + assertInvalidMessage("Non-frozen UDTs are not allowed inside collections: set<" + myType + ">", + "CREATE TABLE " + KEYSPACE + ".wrong (k int PRIMARY KEY, v set<" + myType + ">)"); + assertInvalidMessage("Non-frozen UDTs are not allowed inside collections: map<" + myType + ", int>", + "CREATE TABLE " + KEYSPACE + ".wrong (k int PRIMARY KEY, v map<" + myType + ", int>)"); + assertInvalidMessage("Non-frozen UDTs are not allowed inside collections: map<int, " + myType + ">", + "CREATE TABLE " + KEYSPACE + ".wrong (k int PRIMARY KEY, v map<int, " + myType + ">)"); + + // non-frozen UDT in a collection (as part of a UDT definition) + assertInvalidMessage("Non-frozen UDTs are not allowed inside collections: list<" + myType + ">", + "CREATE TYPE " + KEYSPACE + ".wrong (a int, b list<" + myType + ">)"); + + // non-frozen UDT in a UDT + assertInvalidMessage("A user type cannot contain non-frozen UDTs", + "CREATE TYPE " + KEYSPACE + ".wrong (a int, b " + myType + ")"); + + // referencing a UDT in another keyspace assertInvalidMessage("Statement on keyspace " + KEYSPACE + " cannot refer to a user type in keyspace otherkeyspace;" + " user types can only be used in the keyspace they are defined in", "CREATE TABLE " + KEYSPACE + ".wrong (k int PRIMARY KEY, v frozen<otherKeyspace.myType>)"); + // referencing an unknown UDT assertInvalidMessage("Unknown type " + KEYSPACE + ".unknowntype", "CREATE TABLE " + KEYSPACE + ".wrong (k int PRIMARY KEY, v frozen<" + KEYSPACE + '.' + "unknownType>)"); + + // bad deletions on frozen UDTs + createTable("CREATE TABLE %s (a int PRIMARY KEY, b frozen<" + myType + ">, c int)"); + assertInvalidMessage("Frozen UDT column b does not support field deletion", "DELETE b.a FROM %s WHERE a = 0"); + assertInvalidMessage("Invalid field deletion operation for non-UDT column c", "DELETE c.a FROM %s WHERE a = 0"); + + // bad updates on frozen UDTs + assertInvalidMessage("Invalid operation (b.a = 0) for frozen UDT column b", "UPDATE %s SET b.a = 0 WHERE a = 0"); + assertInvalidMessage("Invalid operation (c.a = 0) for non-UDT column c", "UPDATE %s SET c.a = 0 WHERE a = 0"); + + // bad deletions on non-frozen UDTs + createTable("CREATE TABLE %s (a int PRIMARY KEY, b " + myType + ", c int)"); + assertInvalidMessage("UDT column b does not have a field named foo", "DELETE b.foo FROM %s WHERE a = 0"); + + // bad updates on non-frozen UDTs + assertInvalidMessage("UDT column b does not have a field named foo", "UPDATE %s SET b.foo = 0 WHERE a = 0"); + + // bad insert on non-frozen UDTs + assertInvalidMessage("Unknown field 'foo' in value of user defined type", "INSERT INTO %s (a, b, c) VALUES (0, {a: 0, foo: 0}, 0)"); + if (usePrepared()) + { + assertInvalidMessage("Expected 1 value for " + typename + " column, but got more", + "INSERT INTO %s (a, b, c) VALUES (0, ?, 0)", userType("a", 0, "foo", 0)); + } + else + { + assertInvalidMessage("Unknown field 'foo' in value of user defined type " + typename, + "INSERT INTO %s (a, b, c) VALUES (0, ?, 0)", userType("a", 0, "foo", 0)); + } + + // non-frozen UDT with non-frozen nested collection + String typename2 = createType("CREATE TYPE %s (bar int, foo list<int>)"); + String myType2 = KEYSPACE + '.' + typename2; + assertInvalidMessage("Non-frozen UDTs with nested non-frozen collections are not supported", + "CREATE TABLE " + KEYSPACE + ".wrong (k int PRIMARY KEY, v " + myType2 + ")"); } @Test @@ -106,24 +160,61 @@ public class UserTypesTest extends CQLTester { String myType = KEYSPACE + '.' + createType("CREATE TYPE %s (a int)"); createTable("CREATE TABLE %s (a int PRIMARY KEY, b frozen<" + myType + ">)"); - execute("INSERT INTO %s (a, b) VALUES (1, {a: 1})"); + execute("INSERT INTO %s (a, b) VALUES (1, ?)", userType("a", 1)); assertRows(execute("SELECT b.a FROM %s"), row(1)); flush(); - execute("ALTER TYPE " + myType + " ADD b int"); - execute("INSERT INTO %s (a, b) VALUES (2, {a: 2, b :2})"); + schemaChange("ALTER TYPE " + myType + " ADD b int"); + execute("INSERT INTO %s (a, b) VALUES (2, ?)", userType("a", 2, "b", 2)); - assertRows(execute("SELECT b.a, b.b FROM %s"), - row(1, null), - row(2, 2)); - - flush(); + beforeAndAfterFlush(() -> + assertRows(execute("SELECT b.a, b.b FROM %s"), + row(1, null), + row(2, 2)) + ); + } - assertRows(execute("SELECT b.a, b.b FROM %s"), - row(1, null), - row(2, 2)); + @Test + public void testAlterNonFrozenUDT() throws Throwable + { + String myType = KEYSPACE + '.' + createType("CREATE TYPE %s (a int, b text)"); + createTable("CREATE TABLE %s (k int PRIMARY KEY, v " + myType + ")"); + execute("INSERT INTO %s (k, v) VALUES (0, ?)", userType("a", 1, "b", "abc")); + + beforeAndAfterFlush(() -> { + assertRows(execute("SELECT v FROM %s"), row(userType("a", 1, "b", "abc"))); + assertRows(execute("SELECT v.a FROM %s"), row(1)); + assertRows(execute("SELECT v.b FROM %s"), row("abc")); + }); + + schemaChange("ALTER TYPE " + myType + " RENAME b TO foo"); + assertRows(execute("SELECT v FROM %s"), row(userType("a", 1, "b", "abc"))); + assertRows(execute("SELECT v.a FROM %s"), row(1)); + assertRows(execute("SELECT v.foo FROM %s"), row("abc")); + + execute("UPDATE %s SET v.foo = 'def' WHERE k = 0"); + assertRows(execute("SELECT v FROM %s"), row(userType("a", 1, "foo", "def"))); + assertRows(execute("SELECT v.a FROM %s"), row(1)); + assertRows(execute("SELECT v.foo FROM %s"), row("def")); + + execute("INSERT INTO %s (k, v) VALUES (0, ?)", userType("a", 2, "foo", "def")); + assertRows(execute("SELECT v FROM %s"), row(userType("a", 2, "foo", "def"))); + assertRows(execute("SELECT v.a FROM %s"), row(2)); + assertRows(execute("SELECT v.foo FROM %s"), row("def")); + + schemaChange("ALTER TYPE " + myType + " ADD c int"); + assertRows(execute("SELECT v FROM %s"), row(userType("a", 2, "foo", "def", "c", null))); + assertRows(execute("SELECT v.a FROM %s"), row(2)); + assertRows(execute("SELECT v.foo FROM %s"), row("def")); + assertRows(execute("SELECT v.c FROM %s"), row(new Object[] {null})); + + execute("INSERT INTO %s (k, v) VALUES (0, ?)", userType("a", 3, "foo", "abc", "c", 0)); + beforeAndAfterFlush(() -> { + assertRows(execute("SELECT v FROM %s"), row(userType("a", 3, "foo", "abc", "c", 0))); + assertRows(execute("SELECT v.c FROM %s"), row(0)); + }); } @Test @@ -134,11 +225,14 @@ public class UserTypesTest extends CQLTester String myOtherType = createType("CREATE TYPE %s (a frozen<" + myType + ">)"); createTable("CREATE TABLE %s (k int PRIMARY KEY, v frozen<" + myType + ">, z frozen<" + myOtherType + ">)"); - assertInvalidMessage("Invalid unset value for field 'y' of user defined type " + myType, - "INSERT INTO %s (k, v) VALUES (10, {x:?, y:?})", 1, unset()); + if (usePrepared()) + { + assertInvalidMessage("Invalid unset value for field 'y' of user defined type " + myType, + "INSERT INTO %s (k, v) VALUES (10, {x:?, y:?})", 1, unset()); - assertInvalidMessage("Invalid unset value for field 'y' of user defined type " + myType, - "INSERT INTO %s (k, v, z) VALUES (10, {x:?, y:?}, {a:{x: ?, y: ?}})", 1, 1, 1, unset()); + assertInvalidMessage("Invalid unset value for field 'y' of user defined type " + myType, + "INSERT INTO %s (k, v, z) VALUES (10, {x:?, y:?}, {a:{x: ?, y: ?}})", 1, 1, 1, unset()); + } } @Test @@ -153,28 +247,22 @@ public class UserTypesTest extends CQLTester createTable("CREATE TABLE %s (x int PRIMARY KEY, y " + columnType + ")"); - execute("INSERT INTO %s (x, y) VALUES(1, {'firstValue':{a:1}})"); - assertRows(execute("SELECT * FROM %s"), row(1, map("firstValue", userType(1)))); + execute("INSERT INTO %s (x, y) VALUES(1, ?)", map("firstValue", userType("a", 1))); + assertRows(execute("SELECT * FROM %s"), row(1, map("firstValue", userType("a", 1)))); flush(); execute("ALTER TYPE " + KEYSPACE + "." + ut1 + " ADD b int"); - execute("INSERT INTO %s (x, y) VALUES(2, {'secondValue':{a:2, b:2}})"); - execute("INSERT INTO %s (x, y) VALUES(3, {'thirdValue':{a:3}})"); - execute("INSERT INTO %s (x, y) VALUES(4, {'fourthValue':{b:4}})"); - - assertRows(execute("SELECT * FROM %s"), - row(1, map("firstValue", userType(1))), - row(2, map("secondValue", userType(2, 2))), - row(3, map("thirdValue", userType(3, null))), - row(4, map("fourthValue", userType(null, 4)))); - - flush(); - - assertRows(execute("SELECT * FROM %s"), - row(1, map("firstValue", userType(1))), - row(2, map("secondValue", userType(2, 2))), - row(3, map("thirdValue", userType(3, null))), - row(4, map("fourthValue", userType(null, 4)))); + execute("INSERT INTO %s (x, y) VALUES(2, ?)", map("secondValue", userType("a", 2, "b", 2))); + execute("INSERT INTO %s (x, y) VALUES(3, ?)", map("thirdValue", userType("a", 3, "b", null))); + execute("INSERT INTO %s (x, y) VALUES(4, ?)", map("fourthValue", userType("a", null, "b", 4))); + + beforeAndAfterFlush(() -> + assertRows(execute("SELECT * FROM %s"), + row(1, map("firstValue", userType("a", 1))), + row(2, map("secondValue", userType("a", 2, "b", 2))), + row(3, map("thirdValue", userType("a", 3, "b", null))), + row(4, map("fourthValue", userType("a", null, "b", 4)))) + ); } } @@ -190,28 +278,22 @@ public class UserTypesTest extends CQLTester createTable("CREATE TABLE %s (x int PRIMARY KEY, y " + columnType + ")"); - execute("INSERT INTO %s (x, y) VALUES(1, {1} )"); - assertRows(execute("SELECT * FROM %s"), row(1, set(userType(1)))); + execute("INSERT INTO %s (x, y) VALUES(1, ?)", set(userType("a", 1))); + assertRows(execute("SELECT * FROM %s"), row(1, set(userType("a", 1)))); flush(); execute("ALTER TYPE " + KEYSPACE + "." + ut1 + " ADD b int"); - execute("INSERT INTO %s (x, y) VALUES(2, {{a:2, b:2}})"); - execute("INSERT INTO %s (x, y) VALUES(3, {{a:3}})"); - execute("INSERT INTO %s (x, y) VALUES(4, {{b:4}})"); - - assertRows(execute("SELECT * FROM %s"), - row(1, set(userType(1))), - row(2, set(userType(2, 2))), - row(3, set(userType(3, null))), - row(4, set(userType(null, 4)))); - - flush(); - - assertRows(execute("SELECT * FROM %s"), - row(1, set(userType(1))), - row(2, set(userType(2, 2))), - row(3, set(userType(3, null))), - row(4, set(userType(null, 4)))); + execute("INSERT INTO %s (x, y) VALUES(2, ?)", set(userType("a", 2, "b", 2))); + execute("INSERT INTO %s (x, y) VALUES(3, ?)", set(userType("a", 3, "b", null))); + execute("INSERT INTO %s (x, y) VALUES(4, ?)", set(userType("a", null, "b", 4))); + + beforeAndAfterFlush(() -> + assertRows(execute("SELECT * FROM %s"), + row(1, set(userType("a", 1))), + row(2, set(userType("a", 2, "b", 2))), + row(3, set(userType("a", 3, "b", null))), + row(4, set(userType("a", null, "b", 4)))) + ); } } @@ -227,28 +309,22 @@ public class UserTypesTest extends CQLTester createTable("CREATE TABLE %s (x int PRIMARY KEY, y " + columnType + ")"); - execute("INSERT INTO %s (x, y) VALUES(1, [1] )"); - assertRows(execute("SELECT * FROM %s"), row(1, list(userType(1)))); + execute("INSERT INTO %s (x, y) VALUES(1, ?)", list(userType("a", 1))); + assertRows(execute("SELECT * FROM %s"), row(1, list(userType("a", 1)))); flush(); execute("ALTER TYPE " + KEYSPACE + "." + ut1 + " ADD b int"); - execute("INSERT INTO %s (x, y) VALUES(2, [{a:2, b:2}])"); - execute("INSERT INTO %s (x, y) VALUES(3, [{a:3}])"); - execute("INSERT INTO %s (x, y) VALUES(4, [{b:4}])"); - - assertRows(execute("SELECT * FROM %s"), - row(1, list(userType(1))), - row(2, list(userType(2, 2))), - row(3, list(userType(3, null))), - row(4, list(userType(null, 4)))); - - flush(); - - assertRows(execute("SELECT * FROM %s"), - row(1, list(userType(1))), - row(2, list(userType(2, 2))), - row(3, list(userType(3, null))), - row(4, list(userType(null, 4)))); + execute("INSERT INTO %s (x, y) VALUES (2, ?)", list(userType("a", 2, "b", 2))); + execute("INSERT INTO %s (x, y) VALUES (3, ?)", list(userType("a", 3, "b", null))); + execute("INSERT INTO %s (x, y) VALUES (4, ?)", list(userType("a", null, "b", 4))); + + beforeAndAfterFlush(() -> + assertRows(execute("SELECT * FROM %s"), + row(1, list(userType("a", 1))), + row(2, list(userType("a", 2, "b", 2))), + row(3, list(userType("a", 3, "b", null))), + row(4, list(userType("a", null, "b", 4)))) + ); } } @@ -259,28 +335,22 @@ public class UserTypesTest extends CQLTester createTable("CREATE TABLE %s (a int PRIMARY KEY, b frozen<tuple<int, " + KEYSPACE + "." + type + ">>)"); - execute("INSERT INTO %s (a, b) VALUES(1, (1, {a:1, b:1}))"); - assertRows(execute("SELECT * FROM %s"), row(1, tuple(1, userType(1, 1)))); + execute("INSERT INTO %s (a, b) VALUES(1, (1, ?))", userType("a", 1, "b", 1)); + assertRows(execute("SELECT * FROM %s"), row(1, tuple(1, userType("a", 1, "b", 1)))); flush(); execute("ALTER TYPE " + KEYSPACE + "." + type + " ADD c int"); - execute("INSERT INTO %s (a, b) VALUES(2, (2, {a: 2, b: 2, c: 2}))"); - execute("INSERT INTO %s (a, b) VALUES(3, (3, {a: 3, b: 3}))"); - execute("INSERT INTO %s (a, b) VALUES(4, (4, {b:4}))"); - - assertRows(execute("SELECT * FROM %s"), - row(1, tuple(1, userType(1, 1))), - row(2, tuple(2, userType(2, 2, 2))), - row(3, tuple(3, userType(3, 3, null))), - row(4, tuple(4, userType(null, 4, null)))); + execute("INSERT INTO %s (a, b) VALUES (2, (2, ?))", userType("a", 2, "b", 2, "c", 2)); + execute("INSERT INTO %s (a, b) VALUES (3, (3, ?))", userType("a", 3, "b", 3, "c", null)); + execute("INSERT INTO %s (a, b) VALUES (4, (4, ?))", userType("a", null, "b", 4, "c", null)); - flush(); - - assertRows(execute("SELECT * FROM %s"), - row(1, tuple(1, userType(1, 1))), - row(2, tuple(2, userType(2, 2, 2))), - row(3, tuple(3, userType(3, 3, null))), - row(4, tuple(4, userType(null, 4, null)))); + beforeAndAfterFlush(() -> + assertRows(execute("SELECT * FROM %s"), + row(1, tuple(1, userType("a", 1, "b", 1))), + row(2, tuple(2, userType("a", 2, "b", 2, "c", 2))), + row(3, tuple(3, userType("a", 3, "b", 3, "c", null))), + row(4, tuple(4, userType("a", null, "b", 4, "c", null)))) + ); } @Test @@ -290,28 +360,22 @@ public class UserTypesTest extends CQLTester createTable("CREATE TABLE %s (a int PRIMARY KEY, b frozen<tuple<int, tuple<int, " + KEYSPACE + "." + type + ">>>)"); - execute("INSERT INTO %s (a, b) VALUES(1, (1, (1, {a:1, b:1})))"); - assertRows(execute("SELECT * FROM %s"), row(1, tuple(1, tuple(1, userType(1, 1))))); + execute("INSERT INTO %s (a, b) VALUES(1, (1, (1, ?)))", userType("a", 1, "b", 1)); + assertRows(execute("SELECT * FROM %s"), row(1, tuple(1, tuple(1, userType("a", 1, "b", 1))))); flush(); execute("ALTER TYPE " + KEYSPACE + "." + type + " ADD c int"); - execute("INSERT INTO %s (a, b) VALUES(2, (2, (1, {a: 2, b: 2, c: 2})))"); - execute("INSERT INTO %s (a, b) VALUES(3, (3, (1, {a: 3, b: 3})))"); - execute("INSERT INTO %s (a, b) VALUES(4, (4, (1, {b:4})))"); + execute("INSERT INTO %s (a, b) VALUES(2, (2, (1, ?)))", userType("a", 2, "b", 2, "c", 2)); + execute("INSERT INTO %s (a, b) VALUES(3, (3, ?))", tuple(1, userType("a", 3, "b", 3, "c", null))); + execute("INSERT INTO %s (a, b) VALUES(4, ?)", tuple(4, tuple(1, userType("a", null, "b", 4, "c", null)))); - assertRows(execute("SELECT * FROM %s"), - row(1, tuple(1, tuple(1, userType(1, 1)))), - row(2, tuple(2, tuple(1, userType(2, 2, 2)))), - row(3, tuple(3, tuple(1, userType(3, 3, null)))), - row(4, tuple(4, tuple(1, userType(null, 4, null))))); - - flush(); - - assertRows(execute("SELECT * FROM %s"), - row(1, tuple(1, tuple(1, userType(1, 1)))), - row(2, tuple(2, tuple(1, userType(2, 2, 2)))), - row(3, tuple(3, tuple(1, userType(3, 3, null)))), - row(4, tuple(4, tuple(1, userType(null, 4, null))))); + beforeAndAfterFlush(() -> + assertRows(execute("SELECT * FROM %s"), + row(1, tuple(1, tuple(1, userType("a", 1, "b", 1)))), + row(2, tuple(2, tuple(1, userType("a", 2, "b", 2, "c", 2)))), + row(3, tuple(3, tuple(1, userType("a", 3, "b", 3, "c", null)))), + row(4, tuple(4, tuple(1, userType("a", null, "b", 4, "c", null))))) + ); } @Test @@ -322,28 +386,24 @@ public class UserTypesTest extends CQLTester createTable("CREATE TABLE %s (a int PRIMARY KEY, b frozen<" + KEYSPACE + "." + otherType + ">)"); - execute("INSERT INTO %s (a, b) VALUES(1, {x: {a:1, b:1}})"); + execute("INSERT INTO %s (a, b) VALUES(1, {x: ?})", userType("a", 1, "b", 1)); + assertRows(execute("SELECT b.x.a, b.x.b FROM %s"), row(1, 1)); + execute("INSERT INTO %s (a, b) VALUES(1, ?)", userType("x", userType("a", 1, "b", 1))); assertRows(execute("SELECT b.x.a, b.x.b FROM %s"), row(1, 1)); flush(); execute("ALTER TYPE " + KEYSPACE + "." + type + " ADD c int"); - execute("INSERT INTO %s (a, b) VALUES(2, {x: {a: 2, b: 2, c: 2}})"); - execute("INSERT INTO %s (a, b) VALUES(3, {x: {a: 3, b: 3}})"); - execute("INSERT INTO %s (a, b) VALUES(4, {x: {b:4}})"); - - assertRows(execute("SELECT b.x.a, b.x.b, b.x.c FROM %s"), - row(1, 1, null), - row(2, 2, 2), - row(3, 3, null), - row(null, 4, null)); - - flush(); - - assertRows(execute("SELECT b.x.a, b.x.b, b.x.c FROM %s"), - row(1, 1, null), - row(2, 2, 2), - row(3, 3, null), - row(null, 4, null)); + execute("INSERT INTO %s (a, b) VALUES(2, {x: ?})", userType("a", 2, "b", 2, "c", 2)); + execute("INSERT INTO %s (a, b) VALUES(3, {x: ?})", userType("a", 3, "b", 3)); + execute("INSERT INTO %s (a, b) VALUES(4, {x: ?})", userType("a", null, "b", 4)); + + beforeAndAfterFlush(() -> + assertRows(execute("SELECT b.x.a, b.x.b, b.x.c FROM %s"), + row(1, 1, null), + row(2, 2, 2), + row(3, 3, null), + row(null, 4, null)) + ); } /** @@ -383,10 +443,11 @@ public class UserTypesTest extends CQLTester createTable("CREATE TABLE %s (id int PRIMARY KEY, val frozen<" + type2 + ">)"); - execute("INSERT INTO %s (id, val) VALUES (0, { s : {{ s : {'foo', 'bar'}, m : { 'foo' : 'bar' }, l : ['foo', 'bar']} }})"); + execute("INSERT INTO %s (id, val) VALUES (0, ?)", + userType("s", set(userType("s", set("foo", "bar"), "m", map("foo", "bar"), "l", list("foo", "bar"))))); - // TODO: check result once we have an easy way to do it. For now we just check it doesn't crash - execute("SELECT * FROM %s"); + assertRows(execute("SELECT * FROM %s"), + row(0, userType("s", set(userType("s", set("foo", "bar"), "m", map("foo", "bar"), "l", list("foo", "bar")))))); } /** @@ -398,9 +459,11 @@ public class UserTypesTest extends CQLTester String typeName = createType("CREATE TYPE %s (fooint int, fooset set <text>)"); createTable("CREATE TABLE %s (key int PRIMARY KEY, data frozen <" + typeName + ">)"); - execute("INSERT INTO %s (key, data) VALUES (1, {fooint: 1, fooset: {'2'}})"); + execute("INSERT INTO %s (key, data) VALUES (1, ?)", userType("fooint", 1, "fooset", set("2"))); execute("ALTER TYPE " + keyspace() + "." + typeName + " ADD foomap map <int,text>"); - execute("INSERT INTO %s (key, data) VALUES (1, {fooint: 1, fooset: {'2'}, foomap: {3 : 'bar'}})"); + execute("INSERT INTO %s (key, data) VALUES (1, ?)", userType("fooint", 1, "fooset", set("2"), "foomap", map(3, "bar"))); + assertRows(execute("SELECT * FROM %s"), + row(1, userType("fooint", 1, "fooset", set("2"), "foomap", map(3, "bar")))); } @Test @@ -464,13 +527,13 @@ public class UserTypesTest extends CQLTester type1 = createType("CREATE TYPE %s (foo ascii)"); String type2 = createType("CREATE TYPE %s (foo frozen<" + type1 + ">)"); - assertComplexInvalidAlterDropStatements(type1, type2, "{foo: 'abc'}"); + assertComplexInvalidAlterDropStatements(type1, type2, "{foo: {foo: 'abc'}}"); type1 = createType("CREATE TYPE %s (foo ascii)"); type2 = createType("CREATE TYPE %s (foo frozen<" + type1 + ">)"); assertComplexInvalidAlterDropStatements(type1, "list<frozen<" + type2 + ">>", - "[{foo: 'abc'}]"); + "[{foo: {foo: 'abc'}}]"); type1 = createType("CREATE TYPE %s (foo ascii)"); type2 = createType("CREATE TYPE %s (foo frozen<set<" + type1 + ">>)"); @@ -515,6 +578,110 @@ public class UserTypesTest extends CQLTester assertInvalidMessage("Cannot drop user type " + typeWithKs(t), "DROP TYPE " + typeWithKs(t) + ';'); } + @Test + public void testInsertNonFrozenUDT() throws Throwable + { + String typeName = createType("CREATE TYPE %s (a int, b text)"); + createTable("CREATE TABLE %s (k int PRIMARY KEY, v " + typeName + ")"); + + execute("INSERT INTO %s (k, v) VALUES (?, {a: ?, b: ?})", 0, 0, "abc"); + assertRows(execute("SELECT * FROM %s WHERE k = ?", 0), row(0, userType("a", 0, "b", "abc"))); + + execute("INSERT INTO %s (k, v) VALUES (?, ?)", 0, userType("a", 0, "b", "abc")); + assertRows(execute("SELECT * FROM %s WHERE k = ?", 0), row(0, userType("a", 0, "b", "abc"))); + + execute("INSERT INTO %s (k, v) VALUES (?, {a: ?, b: ?})", 0, 0, null); + assertRows(execute("SELECT * FROM %s WHERE k = ?", 0), row(0, userType("a", 0, "b", null))); + + execute("INSERT INTO %s (k, v) VALUES (?, ?)", 0, userType("a", null, "b", "abc")); + assertRows(execute("SELECT * FROM %s WHERE k = ?", 0), row(0, userType("a", null, "b", "abc"))); + } + + @Test + public void testUpdateNonFrozenUDT() throws Throwable + { + String typeName = createType("CREATE TYPE %s (a int, b text)"); + createTable("CREATE TABLE %s (k int PRIMARY KEY, v " + typeName + ")"); + + execute("INSERT INTO %s (k, v) VALUES (?, ?)", 0, userType("a", 0, "b", "abc")); + assertRows(execute("SELECT * FROM %s WHERE k = ?", 0), row(0, userType("a", 0, "b", "abc"))); + + // overwrite the whole UDT + execute("UPDATE %s SET v = ? WHERE k = ?", userType("a", 1, "b", "def"), 0); + assertRows(execute("SELECT * FROM %s WHERE k = ?", 0), row(0, userType("a", 1, "b", "def"))); + + execute("UPDATE %s SET v = ? WHERE k = ?", userType("a", 0, "b", null), 0); + assertRows(execute("SELECT * FROM %s WHERE k = ?", 0), row(0, userType("a", 0, "b", null))); + + execute("UPDATE %s SET v = ? WHERE k = ?", userType("a", null, "b", "abc"), 0); + assertRows(execute("SELECT * FROM %s WHERE k = ?", 0), row(0, userType("a", null, "b", "abc"))); + + // individually set fields to non-null values + execute("UPDATE %s SET v.a = ? WHERE k = ?", 1, 0); + assertRows(execute("SELECT * FROM %s WHERE k = ?", 0), row(0, userType("a", 1, "b", "abc"))); + + execute("UPDATE %s SET v.b = ? WHERE k = ?", "def", 0); + assertRows(execute("SELECT * FROM %s WHERE k = ?", 0), row(0, userType("a", 1, "b", "def"))); + + execute("UPDATE %s SET v.a = ?, v.b = ? WHERE k = ?", 0, "abc", 0); + assertRows(execute("SELECT * FROM %s WHERE k = ?", 0), row(0, userType("a", 0, "b", "abc"))); + + execute("UPDATE %s SET v.b = ?, v.a = ? WHERE k = ?", "abc", 0, 0); + assertRows(execute("SELECT * FROM %s WHERE k = ?", 0), row(0, userType("a", 0, "b", "abc"))); + + // individually set fields to null values + execute("UPDATE %s SET v.a = ? WHERE k = ?", null, 0); + assertRows(execute("SELECT * FROM %s WHERE k = ?", 0), row(0, userType("a", null, "b", "abc"))); + + execute("UPDATE %s SET v.a = ? WHERE k = ?", 0, 0); + execute("UPDATE %s SET v.b = ? WHERE k = ?", null, 0); + assertRows(execute("SELECT * FROM %s WHERE k = ?", 0), row(0, userType("a", 0, "b", null))); + + execute("UPDATE %s SET v.a = ? WHERE k = ?", null, 0); + assertRows(execute("SELECT * FROM %s WHERE k = ?", 0), row(0, null)); + + assertInvalid("UPDATE %s SET v.bad = ? FROM %s WHERE k = ?", 0, 0); + assertInvalid("UPDATE %s SET v = ? FROM %s WHERE k = ?", 0, 0); + assertInvalid("UPDATE %s SET v = ? FROM %s WHERE k = ?", userType("a", 1, "b", "abc", "bad", 123), 0); + } + + @Test + public void testDeleteNonFrozenUDT() throws Throwable + { + String typeName = createType("CREATE TYPE %s (a int, b text)"); + createTable("CREATE TABLE %s (k int PRIMARY KEY, v " + typeName + ")"); + + execute("INSERT INTO %s (k, v) VALUES (?, ?)", 0, userType("a", 0, "b", "abc")); + assertRows(execute("SELECT * FROM %s WHERE k = ?", 0), row(0, userType("a", 0, "b", "abc"))); + + execute("DELETE v.b FROM %s WHERE k = ?", 0); + assertRows(execute("SELECT * FROM %s WHERE k = ?", 0), row(0, userType("a", 0, "b", null))); + + execute("INSERT INTO %s (k, v) VALUES (?, ?)", 0, userType("a", 0, "b", "abc")); + execute("DELETE v.a FROM %s WHERE k = ?", 0); + assertRows(execute("SELECT * FROM %s WHERE k = ?", 0), row(0, userType("a", null, "b", "abc"))); + + execute("DELETE v.b FROM %s WHERE k = ?", 0); + assertRows(execute("SELECT * FROM %s WHERE k = ?", 0), row(0, null)); + + // delete both fields at once + execute("INSERT INTO %s (k, v) VALUES (?, ?)", 0, userType("a", 0, "b", "abc")); + execute("DELETE v.a, v.b FROM %s WHERE k = ?", 0); + assertRows(execute("SELECT * FROM %s WHERE k = ?", 0), row(0, null)); + + // same, but reverse field order + execute("INSERT INTO %s (k, v) VALUES (?, ?)", 0, userType("a", 0, "b", "abc")); + execute("DELETE v.b, v.a FROM %s WHERE k = ?", 0); + assertRows(execute("SELECT * FROM %s WHERE k = ?", 0), row(0, null)); + + // delete the whole thing at once + execute("INSERT INTO %s (k, v) VALUES (?, ?)", 0, userType("a", 0, "b", "abc")); + execute("DELETE v FROM %s WHERE k = ?", 0); + assertRows(execute("SELECT * FROM %s WHERE k = ?", 0), row(0, null)); + + assertInvalid("DELETE v.bad FROM %s WHERE k = ?", 0); + } + private String typeWithKs(String type1) { return keyspace() + '.' + type1; http://git-wip-us.apache.org/repos/asf/cassandra/blob/677230df/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 ade80bb..9094d4f 100644 --- a/test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionTest.java +++ b/test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionTest.java @@ -384,6 +384,377 @@ public class InsertUpdateIfConditionTest extends CQLTester assertRows(execute("INSERT INTO %s (partition, key, owner) VALUES ('a', 'c', 'x') IF NOT EXISTS"), row(true)); } + @Test + public void testWholeUDT() throws Throwable + { + String typename = createType("CREATE TYPE %s (a int, b text)"); + String myType = KEYSPACE + '.' + typename; + + for (boolean frozen : new boolean[] {false, true}) + { + createTable(String.format("CREATE TABLE %%s (k int PRIMARY KEY, v %s)", + frozen + ? "frozen<" + myType + ">" + : myType)); + + Object v = userType("a", 0, "b", "abc"); + execute("INSERT INTO %s (k, v) VALUES (0, ?)", v); + + checkAppliesUDT("v = {a: 0, b: 'abc'}", v); + checkAppliesUDT("v != null", v); + checkAppliesUDT("v != {a: 1, b: 'abc'}", v); + checkAppliesUDT("v != {a: 0, b: 'def'}", v); + checkAppliesUDT("v > {a: -1, b: 'abc'}", v); + checkAppliesUDT("v > {a: 0, b: 'aaa'}", v); + checkAppliesUDT("v > {a: 0}", v); + checkAppliesUDT("v >= {a: 0, b: 'aaa'}", v); + checkAppliesUDT("v >= {a: 0, b: 'abc'}", v); + checkAppliesUDT("v < {a: 0, b: 'zzz'}", v); + checkAppliesUDT("v < {a: 1, b: 'abc'}", v); + checkAppliesUDT("v < {a: 1}", v); + checkAppliesUDT("v <= {a: 0, b: 'zzz'}", v); + checkAppliesUDT("v <= {a: 0, b: 'abc'}", v); + checkAppliesUDT("v IN (null, {a: 0, b: 'abc'}, {a: 1})", v); + + // multiple conditions + checkAppliesUDT("v > {a: -1, b: 'abc'} AND v > {a: 0}", v); + checkAppliesUDT("v != null AND v IN ({a: 0, b: 'abc'})", v); + + // should not apply + checkDoesNotApplyUDT("v = {a: 0, b: 'def'}", v); + checkDoesNotApplyUDT("v = {a: 1, b: 'abc'}", v); + checkDoesNotApplyUDT("v = null", v); + checkDoesNotApplyUDT("v != {a: 0, b: 'abc'}", v); + checkDoesNotApplyUDT("v > {a: 1, b: 'abc'}", v); + checkDoesNotApplyUDT("v > {a: 0, b: 'zzz'}", v); + checkDoesNotApplyUDT("v >= {a: 1, b: 'abc'}", v); + checkDoesNotApplyUDT("v >= {a: 0, b: 'zzz'}", v); + checkDoesNotApplyUDT("v < {a: -1, b: 'abc'}", v); + checkDoesNotApplyUDT("v < {a: 0, b: 'aaa'}", v); + checkDoesNotApplyUDT("v <= {a: -1, b: 'abc'}", v); + checkDoesNotApplyUDT("v <= {a: 0, b: 'aaa'}", v); + checkDoesNotApplyUDT("v IN ({a: 0}, {b: 'abc'}, {a: 0, b: 'def'}, null)", v); + checkDoesNotApplyUDT("v IN ()", v); + + // multiple conditions + checkDoesNotApplyUDT("v IN () AND v IN ({a: 0, b: 'abc'})", v); + checkDoesNotApplyUDT("v > {a: 0, b: 'aaa'} AND v < {a: 0, b: 'aaa'}", v); + + // invalid conditions + checkInvalidUDT("v = {a: 1, b: 'abc', c: 'foo'}", v, InvalidRequestException.class); + checkInvalidUDT("v = {foo: 'foo'}", v, InvalidRequestException.class); + checkInvalidUDT("v < {a: 1, b: 'abc', c: 'foo'}", v, InvalidRequestException.class); + checkInvalidUDT("v < null", v, InvalidRequestException.class); + checkInvalidUDT("v <= {a: 1, b: 'abc', c: 'foo'}", v, InvalidRequestException.class); + checkInvalidUDT("v <= null", v, InvalidRequestException.class); + checkInvalidUDT("v > {a: 1, b: 'abc', c: 'foo'}", v, InvalidRequestException.class); + checkInvalidUDT("v > null", v, InvalidRequestException.class); + checkInvalidUDT("v >= {a: 1, b: 'abc', c: 'foo'}", v, InvalidRequestException.class); + checkInvalidUDT("v >= null", v, InvalidRequestException.class); + checkInvalidUDT("v IN null", v, SyntaxException.class); + checkInvalidUDT("v IN 367", v, SyntaxException.class); + checkInvalidUDT("v CONTAINS KEY 123", v, SyntaxException.class); + checkInvalidUDT("v CONTAINS 'bar'", v, SyntaxException.class); + + + /////////////////// null suffix on stored udt //////////////////// + v = userType("a", 0, "b", null); + execute("INSERT INTO %s (k, v) VALUES (0, ?)", v); + + checkAppliesUDT("v = {a: 0}", v); + checkAppliesUDT("v = {a: 0, b: null}", v); + checkAppliesUDT("v != null", v); + checkAppliesUDT("v != {a: 1, b: null}", v); + checkAppliesUDT("v != {a: 1}", v); + checkAppliesUDT("v != {a: 0, b: 'def'}", v); + checkAppliesUDT("v > {a: -1, b: 'abc'}", v); + checkAppliesUDT("v > {a: -1}", v); + checkAppliesUDT("v >= {a: 0}", v); + checkAppliesUDT("v >= {a: -1, b: 'abc'}", v); + checkAppliesUDT("v < {a: 0, b: 'zzz'}", v); + checkAppliesUDT("v < {a: 1, b: 'abc'}", v); + checkAppliesUDT("v < {a: 1}", v); + checkAppliesUDT("v <= {a: 0, b: 'zzz'}", v); + checkAppliesUDT("v <= {a: 0}", v); + checkAppliesUDT("v IN (null, {a: 0, b: 'abc'}, {a: 0})", v); + + // multiple conditions + checkAppliesUDT("v > {a: -1, b: 'abc'} AND v >= {a: 0}", v); + checkAppliesUDT("v != null AND v IN ({a: 0}, {a: 0, b: null})", v); + + // should not apply + checkDoesNotApplyUDT("v = {a: 0, b: 'def'}", v); + checkDoesNotApplyUDT("v = {a: 1}", v); + checkDoesNotApplyUDT("v = {b: 'abc'}", v); + checkDoesNotApplyUDT("v = null", v); + checkDoesNotApplyUDT("v != {a: 0}", v); + checkDoesNotApplyUDT("v != {a: 0, b: null}", v); + checkDoesNotApplyUDT("v > {a: 1, b: 'abc'}", v); + checkDoesNotApplyUDT("v > {a: 0}", v); + checkDoesNotApplyUDT("v >= {a: 1, b: 'abc'}", v); + checkDoesNotApplyUDT("v >= {a: 1}", v); + checkDoesNotApplyUDT("v < {a: -1, b: 'abc'}", v); + checkDoesNotApplyUDT("v < {a: -1}", v); + checkDoesNotApplyUDT("v < {a: 0}", v); + checkDoesNotApplyUDT("v <= {a: -1, b: 'abc'}", v); + checkDoesNotApplyUDT("v <= {a: -1}", v); + checkDoesNotApplyUDT("v IN ({a: 1}, {b: 'abc'}, {a: 0, b: 'def'}, null)", v); + checkDoesNotApplyUDT("v IN ()", v); + + // multiple conditions + checkDoesNotApplyUDT("v IN () AND v IN ({a: 0})", v); + checkDoesNotApplyUDT("v > {a: -1} AND v < {a: 0}", v); + + + /////////////////// null prefix on stored udt //////////////////// + v = userType("a", null, "b", "abc"); + execute("INSERT INTO %s (k, v) VALUES (0, ?)", v); + + checkAppliesUDT("v = {a: null, b: 'abc'}", v); + checkAppliesUDT("v = {b: 'abc'}", v); + checkAppliesUDT("v != null", v); + checkAppliesUDT("v != {a: 0, b: 'abc'}", v); + checkAppliesUDT("v != {a: 0}", v); + checkAppliesUDT("v != {b: 'def'}", v); + checkAppliesUDT("v > {a: null, b: 'aaa'}", v); + checkAppliesUDT("v > {b: 'aaa'}", v); + checkAppliesUDT("v >= {a: null, b: 'aaa'}", v); + checkAppliesUDT("v >= {b: 'abc'}", v); + checkAppliesUDT("v < {a: null, b: 'zzz'}", v); + checkAppliesUDT("v < {a: 0, b: 'abc'}", v); + checkAppliesUDT("v < {a: 0}", v); + checkAppliesUDT("v < {b: 'zzz'}", v); + checkAppliesUDT("v <= {a: null, b: 'zzz'}", v); + checkAppliesUDT("v <= {a: 0}", v); + checkAppliesUDT("v <= {b: 'abc'}", v); + checkAppliesUDT("v IN (null, {a: null, b: 'abc'}, {a: 0})", v); + checkAppliesUDT("v IN (null, {a: 0, b: 'abc'}, {b: 'abc'})", v); + + // multiple conditions + checkAppliesUDT("v > {b: 'aaa'} AND v >= {b: 'abc'}", v); + checkAppliesUDT("v != null AND v IN ({a: 0}, {a: null, b: 'abc'})", v); + + // should not apply + checkDoesNotApplyUDT("v = {a: 0, b: 'def'}", v); + checkDoesNotApplyUDT("v = {a: 1}", v); + checkDoesNotApplyUDT("v = {b: 'def'}", v); + checkDoesNotApplyUDT("v = null", v); + checkDoesNotApplyUDT("v != {b: 'abc'}", v); + checkDoesNotApplyUDT("v != {a: null, b: 'abc'}", v); + checkDoesNotApplyUDT("v > {a: 1, b: 'abc'}", v); + checkDoesNotApplyUDT("v > {a: null, b: 'zzz'}", v); + checkDoesNotApplyUDT("v > {b: 'zzz'}", v); + checkDoesNotApplyUDT("v >= {a: null, b: 'zzz'}", v); + checkDoesNotApplyUDT("v >= {a: 1}", v); + checkDoesNotApplyUDT("v >= {b: 'zzz'}", v); + checkDoesNotApplyUDT("v < {a: null, b: 'aaa'}", v); + checkDoesNotApplyUDT("v < {b: 'aaa'}", v); + checkDoesNotApplyUDT("v <= {a: null, b: 'aaa'}", v); + checkDoesNotApplyUDT("v <= {b: 'aaa'}", v); + checkDoesNotApplyUDT("v IN ({a: 1}, {a: 1, b: 'abc'}, {a: null, b: 'def'}, null)", v); + checkDoesNotApplyUDT("v IN ()", v); + + // multiple conditions + checkDoesNotApplyUDT("v IN () AND v IN ({b: 'abc'})", v); + checkDoesNotApplyUDT("v IN () AND v IN ({a: null, b: 'abc'})", v); + checkDoesNotApplyUDT("v > {a: -1} AND v < {a: 0}", v); + + + /////////////////// null udt //////////////////// + v = null; + execute("INSERT INTO %s (k, v) VALUES (0, ?)", v); + + checkAppliesUDT("v = null", v); + checkAppliesUDT("v IN (null, {a: null, b: 'abc'}, {a: 0})", v); + checkAppliesUDT("v IN (null, {a: 0, b: 'abc'}, {b: 'abc'})", v); + + // multiple conditions + checkAppliesUDT("v = null AND v IN (null, {a: 0}, {a: null, b: 'abc'})", v); + + // should not apply + checkDoesNotApplyUDT("v = {a: 0, b: 'def'}", v); + checkDoesNotApplyUDT("v = {a: 1}", v); + checkDoesNotApplyUDT("v = {b: 'def'}", v); + checkDoesNotApplyUDT("v != null", v); + checkDoesNotApplyUDT("v > {a: 1, b: 'abc'}", v); + checkDoesNotApplyUDT("v > {a: null, b: 'zzz'}", v); + checkDoesNotApplyUDT("v > {b: 'zzz'}", v); + checkDoesNotApplyUDT("v >= {a: null, b: 'zzz'}", v); + checkDoesNotApplyUDT("v >= {a: 1}", v); + checkDoesNotApplyUDT("v >= {b: 'zzz'}", v); + checkDoesNotApplyUDT("v < {a: null, b: 'aaa'}", v); + checkDoesNotApplyUDT("v < {b: 'aaa'}", v); + checkDoesNotApplyUDT("v <= {a: null, b: 'aaa'}", v); + checkDoesNotApplyUDT("v <= {b: 'aaa'}", v); + checkDoesNotApplyUDT("v IN ({a: 1}, {a: 1, b: 'abc'}, {a: null, b: 'def'})", v); + checkDoesNotApplyUDT("v IN ()", v); + + // multiple conditions + checkDoesNotApplyUDT("v IN () AND v IN ({b: 'abc'})", v); + checkDoesNotApplyUDT("v > {a: -1} AND v < {a: 0}", v); + + } + } + + @Test + public void testUDTField() throws Throwable + { + String typename = createType("CREATE TYPE %s (a int, b text)"); + String myType = KEYSPACE + '.' + typename; + + for (boolean frozen : new boolean[] {false, true}) + { + createTable(String.format("CREATE TABLE %%s (k int PRIMARY KEY, v %s)", + frozen + ? "frozen<" + myType + ">" + : myType)); + + Object v = userType("a", 0, "b", "abc"); + execute("INSERT INTO %s (k, v) VALUES (0, ?)", v); + + checkAppliesUDT("v.a = 0", v); + checkAppliesUDT("v.b = 'abc'", v); + checkAppliesUDT("v.a < 1", v); + checkAppliesUDT("v.b < 'zzz'", v); + checkAppliesUDT("v.b <= 'bar'", v); + checkAppliesUDT("v.b > 'aaa'", v); + checkAppliesUDT("v.b >= 'abc'", v); + checkAppliesUDT("v.a != -1", v); + checkAppliesUDT("v.b != 'xxx'", v); + checkAppliesUDT("v.a != null", v); + checkAppliesUDT("v.b != null", v); + checkAppliesUDT("v.a IN (null, 0, 1)", v); + checkAppliesUDT("v.b IN (null, 'xxx', 'abc')", v); + checkAppliesUDT("v.b > 'aaa' AND v.b < 'zzz'", v); + checkAppliesUDT("v.a = 0 AND v.b > 'aaa'", v); + + // do not apply + checkDoesNotApplyUDT("v.a = -1", v); + checkDoesNotApplyUDT("v.b = 'xxx'", v); + checkDoesNotApplyUDT("v.a < -1", v); + checkDoesNotApplyUDT("v.b < 'aaa'", v); + checkDoesNotApplyUDT("v.b <= 'aaa'", v); + checkDoesNotApplyUDT("v.b > 'zzz'", v); + checkDoesNotApplyUDT("v.b >= 'zzz'", v); + checkDoesNotApplyUDT("v.a != 0", v); + checkDoesNotApplyUDT("v.b != 'abc'", v); + checkDoesNotApplyUDT("v.a IN (null, -1)", v); + checkDoesNotApplyUDT("v.b IN (null, 'xxx')", v); + checkDoesNotApplyUDT("v.a IN ()", v); + checkDoesNotApplyUDT("v.b IN ()", v); + checkDoesNotApplyUDT("v.b != null AND v.b IN ()", v); + + // invalid + checkInvalidUDT("v.c = null", v, InvalidRequestException.class); + checkInvalidUDT("v.a < null", v, InvalidRequestException.class); + checkInvalidUDT("v.a <= null", v, InvalidRequestException.class); + checkInvalidUDT("v.a > null", v, InvalidRequestException.class); + checkInvalidUDT("v.a >= null", v, InvalidRequestException.class); + checkInvalidUDT("v.a IN null", v, SyntaxException.class); + checkInvalidUDT("v.a IN 367", v, SyntaxException.class); + checkInvalidUDT("v.b IN (1, 2, 3)", v, InvalidRequestException.class); + checkInvalidUDT("v.a CONTAINS 367", v, SyntaxException.class); + checkInvalidUDT("v.a CONTAINS KEY 367", v, SyntaxException.class); + + + /////////////// null suffix on udt //////////////// + v = userType("a", 0, "b", null); + execute("INSERT INTO %s (k, v) VALUES (0, ?)", v); + + checkAppliesUDT("v.a = 0", v); + checkAppliesUDT("v.b = null", v); + checkAppliesUDT("v.b != 'xxx'", v); + checkAppliesUDT("v.a != null", v); + checkAppliesUDT("v.a IN (null, 0, 1)", v); + checkAppliesUDT("v.b IN (null, 'xxx', 'abc')", v); + checkAppliesUDT("v.a = 0 AND v.b = null", v); + + // do not apply + checkDoesNotApplyUDT("v.b = 'abc'", v); + checkDoesNotApplyUDT("v.a < -1", v); + checkDoesNotApplyUDT("v.b < 'aaa'", v); + checkDoesNotApplyUDT("v.b <= 'aaa'", v); + checkDoesNotApplyUDT("v.b > 'zzz'", v); + checkDoesNotApplyUDT("v.b >= 'zzz'", v); + checkDoesNotApplyUDT("v.a != 0", v); + checkDoesNotApplyUDT("v.b != null", v); + checkDoesNotApplyUDT("v.a IN (null, -1)", v); + checkDoesNotApplyUDT("v.b IN ('xxx', 'abc')", v); + checkDoesNotApplyUDT("v.a IN ()", v); + checkDoesNotApplyUDT("v.b IN ()", v); + checkDoesNotApplyUDT("v.b != null AND v.b IN ()", v); + + + /////////////// null prefix on udt //////////////// + v = userType("a", null, "b", "abc"); + execute("INSERT INTO %s (k, v) VALUES (0, ?)", v); + + checkAppliesUDT("v.a = null", v); + checkAppliesUDT("v.b = 'abc'", v); + checkAppliesUDT("v.a != 0", v); + checkAppliesUDT("v.b != null", v); + checkAppliesUDT("v.a IN (null, 0, 1)", v); + checkAppliesUDT("v.b IN (null, 'xxx', 'abc')", v); + checkAppliesUDT("v.a = null AND v.b = 'abc'", v); + + // do not apply + checkDoesNotApplyUDT("v.a = 0", v); + checkDoesNotApplyUDT("v.a < -1", v); + checkDoesNotApplyUDT("v.b >= 'zzz'", v); + checkDoesNotApplyUDT("v.a != null", v); + checkDoesNotApplyUDT("v.b != 'abc'", v); + checkDoesNotApplyUDT("v.a IN (-1, 0)", v); + checkDoesNotApplyUDT("v.b IN (null, 'xxx')", v); + checkDoesNotApplyUDT("v.a IN ()", v); + checkDoesNotApplyUDT("v.b IN ()", v); + checkDoesNotApplyUDT("v.b != null AND v.b IN ()", v); + + + /////////////// null udt //////////////// + v = null; + execute("INSERT INTO %s (k, v) VALUES (0, ?)", v); + + checkAppliesUDT("v.a = null", v); + checkAppliesUDT("v.b = null", v); + checkAppliesUDT("v.a != 0", v); + checkAppliesUDT("v.b != 'abc'", v); + checkAppliesUDT("v.a IN (null, 0, 1)", v); + checkAppliesUDT("v.b IN (null, 'xxx', 'abc')", v); + checkAppliesUDT("v.a = null AND v.b = null", v); + + // do not apply + checkDoesNotApplyUDT("v.a = 0", v); + checkDoesNotApplyUDT("v.a < -1", v); + checkDoesNotApplyUDT("v.b >= 'zzz'", v); + checkDoesNotApplyUDT("v.a != null", v); + checkDoesNotApplyUDT("v.b != null", v); + checkDoesNotApplyUDT("v.a IN (-1, 0)", v); + checkDoesNotApplyUDT("v.b IN ('xxx', 'abc')", v); + checkDoesNotApplyUDT("v.a IN ()", v); + checkDoesNotApplyUDT("v.b IN ()", v); + checkDoesNotApplyUDT("v.b != null AND v.b IN ()", v); + } + } + + void checkAppliesUDT(String condition, Object value) throws Throwable + { + assertRows(execute("UPDATE %s SET v = ? WHERE k = 0 IF " + condition, value), row(true)); + assertRows(execute("SELECT * FROM %s"), row(0, value)); + } + + void checkDoesNotApplyUDT(String condition, Object value) throws Throwable + { + assertRows(execute("UPDATE %s SET v = ? WHERE k = 0 IF " + condition, value), + row(false, value)); + assertRows(execute("SELECT * FROM %s"), row(0, value)); + } + + void checkInvalidUDT(String condition, Object value, Class<? extends Throwable> expected) throws Throwable + { + assertInvalidThrow(expected, "UPDATE %s SET v = ? WHERE k = 0 IF " + condition, value); + assertRows(execute("SELECT * FROM %s"), row(0, value)); + } + /** * Migrated from cql_tests.py:TestCQL.whole_list_conditional_test() */ http://git-wip-us.apache.org/repos/asf/cassandra/blob/677230df/test/unit/org/apache/cassandra/schema/LegacySchemaMigratorTest.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/schema/LegacySchemaMigratorTest.java b/test/unit/org/apache/cassandra/schema/LegacySchemaMigratorTest.java index 0340fd3..9432c90 100644 --- a/test/unit/org/apache/cassandra/schema/LegacySchemaMigratorTest.java +++ b/test/unit/org/apache/cassandra/schema/LegacySchemaMigratorTest.java @@ -87,7 +87,7 @@ public class LegacySchemaMigratorTest } // make sure that we've read *exactly* the same set of keyspaces/tables/types/functions - assertEquals(expected, actual); + assertEquals(expected.diff(actual).toString(), expected, actual); // check that the build status of all indexes has been updated to use the new // format of index name: the index_name column of system.IndexInfo used to @@ -311,17 +311,20 @@ public class LegacySchemaMigratorTest UserType udt1 = new UserType(keyspace, bytes("udt1"), new ArrayList<ByteBuffer>() {{ add(bytes("col1")); add(bytes("col2")); }}, - new ArrayList<AbstractType<?>>() {{ add(UTF8Type.instance); add(Int32Type.instance); }}); + new ArrayList<AbstractType<?>>() {{ add(UTF8Type.instance); add(Int32Type.instance); }}, + true); UserType udt2 = new UserType(keyspace, bytes("udt2"), new ArrayList<ByteBuffer>() {{ add(bytes("col3")); add(bytes("col4")); }}, - new ArrayList<AbstractType<?>>() {{ add(BytesType.instance); add(BooleanType.instance); }}); + new ArrayList<AbstractType<?>>() {{ add(BytesType.instance); add(BooleanType.instance); }}, + true); UserType udt3 = new UserType(keyspace, bytes("udt3"), new ArrayList<ByteBuffer>() {{ add(bytes("col5")); }}, - new ArrayList<AbstractType<?>>() {{ add(AsciiType.instance); }}); + new ArrayList<AbstractType<?>>() {{ add(AsciiType.instance); }}, + true); return KeyspaceMetadata.create(keyspace, KeyspaceParams.simple(1), @@ -431,12 +434,14 @@ public class LegacySchemaMigratorTest UserType udt1 = new UserType(keyspace, bytes("udt1"), new ArrayList<ByteBuffer>() {{ add(bytes("col1")); add(bytes("col2")); }}, - new ArrayList<AbstractType<?>>() {{ add(UTF8Type.instance); add(Int32Type.instance); }}); + new ArrayList<AbstractType<?>>() {{ add(UTF8Type.instance); add(Int32Type.instance); }}, + true); UserType udt2 = new UserType(keyspace, bytes("udt2"), new ArrayList<ByteBuffer>() {{ add(bytes("col1")); add(bytes("col2")); }}, - new ArrayList<AbstractType<?>>() {{ add(ListType.getInstance(udt1, false)); add(Int32Type.instance); }}); + new ArrayList<AbstractType<?>>() {{ add(ListType.getInstance(udt1, false)); add(Int32Type.instance); }}, + true); UDFunction udf1 = UDFunction.create(new FunctionName(keyspace, "udf"), ImmutableList.of(new ColumnIdentifier("col1", false), new ColumnIdentifier("col2", false)), @@ -478,12 +483,14 @@ public class LegacySchemaMigratorTest UserType udt1 = new UserType(keyspace, bytes("udt1"), new ArrayList<ByteBuffer>() {{ add(bytes("col1")); add(bytes("col2")); }}, - new ArrayList<AbstractType<?>>() {{ add(UTF8Type.instance); add(Int32Type.instance); }}); + new ArrayList<AbstractType<?>>() {{ add(UTF8Type.instance); add(Int32Type.instance); }}, + true); UserType udt2 = new UserType(keyspace, bytes("udt2"), new ArrayList<ByteBuffer>() {{ add(bytes("col1")); add(bytes("col2")); }}, - new ArrayList<AbstractType<?>>() {{ add(ListType.getInstance(udt1, false)); add(Int32Type.instance); }}); + new ArrayList<AbstractType<?>>() {{ add(ListType.getInstance(udt1, false)); add(Int32Type.instance); }}, + true); UDFunction udf1 = UDFunction.create(new FunctionName(keyspace, "udf1"), ImmutableList.of(new ColumnIdentifier("col1", false), new ColumnIdentifier("col2", false)), http://git-wip-us.apache.org/repos/asf/cassandra/blob/677230df/test/unit/org/apache/cassandra/transport/SerDeserTest.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/transport/SerDeserTest.java b/test/unit/org/apache/cassandra/transport/SerDeserTest.java index fdb346e..0b19151 100644 --- a/test/unit/org/apache/cassandra/transport/SerDeserTest.java +++ b/test/unit/org/apache/cassandra/transport/SerDeserTest.java @@ -184,7 +184,8 @@ public class SerDeserTest UserType udt = new UserType("ks", bb("myType"), Arrays.asList(bb("f1"), bb("f2"), bb("f3"), bb("f4")), - Arrays.asList(LongType.instance, lt, st, mt)); + Arrays.asList(LongType.instance, lt, st, mt), + true); Map<ColumnIdentifier, Term.Raw> value = new HashMap<>(); value.put(ci("f1"), lit(42));
