Repository: cassandra Updated Branches: refs/heads/cassandra-2.1 e0d7c77f3 -> e75fe5c4f refs/heads/cassandra-2.1.0 02be0dedd -> 82136e3b7 refs/heads/trunk 873d06490 -> ed0532c64
Ability to freeze UDT patch by slebresne; reviewed by iamaleksey for CASSANDRA-7857 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/02be0ded Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/02be0ded Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/02be0ded Branch: refs/heads/cassandra-2.1 Commit: 02be0dedd9773f1f2f7ce19dfeca82eed5456ca1 Parents: 92a254a Author: Sylvain Lebresne <sylv...@datastax.com> Authored: Tue Sep 2 10:41:48 2014 +0200 Committer: Sylvain Lebresne <sylv...@datastax.com> Committed: Tue Sep 2 10:41:48 2014 +0200 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../org/apache/cassandra/cql3/CQL3Type.java | 44 ++++++++++++++++++++ src/java/org/apache/cassandra/cql3/Cql.g | 9 ++++ .../org/apache/cassandra/cql3/CQLTester.java | 5 +-- .../apache/cassandra/cql3/TupleTypeTest.java | 16 ++++--- .../apache/cassandra/cql3/UserTypesTest.java | 15 ++++--- 6 files changed, 76 insertions(+), 14 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/02be0ded/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index 477a332..b33bec4 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 2.1.0-rc7 + * Add frozen keyword and require UDT to be frozen (CASSANDRA-7857) * Track added sstable size correctly (CASSANDRA-7239) * (cqlsh) Fix case insensitivity (CASSANDRA-7834) * Fix failure to stream ranges when moving (CASSANDRA-7836) http://git-wip-us.apache.org/repos/asf/cassandra/blob/02be0ded/src/java/org/apache/cassandra/cql3/CQL3Type.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/CQL3Type.java b/src/java/org/apache/cassandra/cql3/CQL3Type.java index a26a903..1589d6a 100644 --- a/src/java/org/apache/cassandra/cql3/CQL3Type.java +++ b/src/java/org/apache/cassandra/cql3/CQL3Type.java @@ -284,6 +284,8 @@ public interface CQL3Type // actual type used, so Raw is a "not yet prepared" CQL3Type. public abstract class Raw { + protected boolean frozen; + public boolean isCollection() { return false; @@ -294,6 +296,12 @@ public interface CQL3Type return false; } + public Raw freeze() + { + frozen = true; + return this; + } + public abstract CQL3Type prepare(String keyspace) throws InvalidRequestException; public static Raw from(CQL3Type type) @@ -345,6 +353,16 @@ public interface CQL3Type return new RawTuple(ts); } + public static Raw frozen(CQL3Type.Raw t) throws InvalidRequestException + { + if (t instanceof RawUT) + return ((RawUT)t).freeze(); + if (t instanceof RawTuple) + return ((RawTuple)t).freeze(); + + throw new InvalidRequestException("frozen<> is only currently only allowed on User-Defined and tuple types"); + } + private static class RawType extends Raw { private CQL3Type type; @@ -384,6 +402,13 @@ public interface CQL3Type this.values = values; } + public Raw freeze() + { + keys.freeze(); + values.freeze(); + return super.freeze(); + } + public boolean isCollection() { return true; @@ -445,9 +470,17 @@ public interface CQL3Type if (type == null) throw new InvalidRequestException("Unknown type " + name); + if (!frozen) + throw new InvalidRequestException("Non-frozen User-Defined types are not supported, please use frozen<>"); + return new UserDefined(name.toString(), type); } + public boolean isUDT() + { + return true; + } + @Override public String toString() { @@ -464,6 +497,13 @@ public interface CQL3Type this.types = types; } + public Raw freeze() + { + for (CQL3Type.Raw t : types) + t.freeze(); + return super.freeze(); + } + public boolean isCollection() { return false; @@ -474,6 +514,10 @@ public interface CQL3Type List<AbstractType<?>> ts = new ArrayList<>(types.size()); for (CQL3Type.Raw t : types) ts.add(t.prepare(keyspace).getType()); + + if (!frozen) + throw new InvalidRequestException("Non-frozen tuples are not supported, please use frozen<>"); + return new Tuple(new TupleType(ts)); } http://git-wip-us.apache.org/repos/asf/cassandra/blob/02be0ded/src/java/org/apache/cassandra/cql3/Cql.g ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/Cql.g b/src/java/org/apache/cassandra/cql3/Cql.g index 1ff6ab2..6247a03 100644 --- a/src/java/org/apache/cassandra/cql3/Cql.g +++ b/src/java/org/apache/cassandra/cql3/Cql.g @@ -1071,6 +1071,14 @@ comparatorType returns [CQL3Type.Raw t] | c=collection_type { $t = c; } | tt=tuple_type { $t = tt; } | id=userTypeName { $t = CQL3Type.Raw.userType(id); } + | K_FROZEN '<' f=comparatorType '>' + { + try { + $t = CQL3Type.Raw.frozen(f); + } catch (InvalidRequestException e) { + addRecognitionError(e.getMessage()); + } + } | s=STRING_LITERAL { try { @@ -1277,6 +1285,7 @@ K_TUPLE: T U P L E; K_TRIGGER: T R I G G E R; K_STATIC: S T A T I C; +K_FROZEN: F R O Z E N; // Case-insensitive alpha characters fragment A: ('a'|'A'); http://git-wip-us.apache.org/repos/asf/cassandra/blob/02be0ded/test/unit/org/apache/cassandra/cql3/CQLTester.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/cql3/CQLTester.java b/test/unit/org/apache/cassandra/cql3/CQLTester.java index c412fe3..d56b5df 100644 --- a/test/unit/org/apache/cassandra/cql3/CQLTester.java +++ b/test/unit/org/apache/cassandra/cql3/CQLTester.java @@ -204,12 +204,9 @@ public abstract class CQLTester protected UntypedResultSet execute(String query, Object... values) throws Throwable { - if (currentTable == null) - throw new RuntimeException("You must create a table first with createTable"); - try { - query = String.format(query, KEYSPACE + "." + currentTable); + query = currentTable == null ? query : String.format(query, KEYSPACE + "." + currentTable); UntypedResultSet rs; if (USE_PREPARED_VALUES) http://git-wip-us.apache.org/repos/asf/cassandra/blob/02be0ded/test/unit/org/apache/cassandra/cql3/TupleTypeTest.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/cql3/TupleTypeTest.java b/test/unit/org/apache/cassandra/cql3/TupleTypeTest.java index 84512a5..4ce24f8 100644 --- a/test/unit/org/apache/cassandra/cql3/TupleTypeTest.java +++ b/test/unit/org/apache/cassandra/cql3/TupleTypeTest.java @@ -24,7 +24,7 @@ public class TupleTypeTest extends CQLTester @Test public void testTuplePutAndGet() throws Throwable { - createTable("CREATE TABLE %s (k int PRIMARY KEY, t tuple<int, text, double>)"); + createTable("CREATE TABLE %s (k int PRIMARY KEY, t frozen<tuple<int, text, double>>)"); execute("INSERT INTO %s (k, t) VALUES (?, ?)", 0, tuple(3, "foo", 3.4)); execute("INSERT INTO %s (k, t) VALUES (?, ?)", 1, tuple(8, "bar", 0.2)); @@ -49,7 +49,7 @@ public class TupleTypeTest extends CQLTester @Test public void testNestedTuple() throws Throwable { - createTable("CREATE TABLE %s (k int PRIMARY KEY, t tuple<int, tuple<text, double>>)"); + createTable("CREATE TABLE %s (k int PRIMARY KEY, t frozen<tuple<int, tuple<text, double>>>)"); execute("INSERT INTO %s (k, t) VALUES (?, ?)", 0, tuple(3, tuple("foo", 3.4))); execute("INSERT INTO %s (k, t) VALUES (?, ?)", 1, tuple(8, tuple("bar", 0.2))); @@ -62,7 +62,7 @@ public class TupleTypeTest extends CQLTester @Test public void testTupleInPartitionKey() throws Throwable { - createTable("CREATE TABLE %s (t tuple<int, text> PRIMARY KEY)"); + createTable("CREATE TABLE %s (t frozen<tuple<int, text>> PRIMARY KEY)"); execute("INSERT INTO %s (t) VALUES (?)", tuple(3, "foo")); assertAllRows(row(tuple(3, "foo"))); @@ -71,7 +71,7 @@ public class TupleTypeTest extends CQLTester @Test public void testTupleInClusteringKey() throws Throwable { - createTable("CREATE TABLE %s (k int, t tuple<int, text>, PRIMARY KEY (k, t))"); + createTable("CREATE TABLE %s (k int, t frozen<tuple<int, text>>, PRIMARY KEY (k, t))"); execute("INSERT INTO %s (k, t) VALUES (?, ?)", 0, tuple(5, "bar")); execute("INSERT INTO %s (k, t) VALUES (?, ?)", 0, tuple(3, "foo")); @@ -89,9 +89,15 @@ public class TupleTypeTest extends CQLTester @Test public void testInvalidQueries() throws Throwable { - createTable("CREATE TABLE %s (k int PRIMARY KEY, t tuple<int, text, double>)"); + createTable("CREATE TABLE %s (k int PRIMARY KEY, t frozen<tuple<int, text, double>>)"); assertInvalid("INSERT INTO %s (k, t) VALUES (0, ())"); assertInvalid("INSERT INTO %s (k, t) VALUES (0, (2, 'foo', 3.1, 'bar'))"); } + + @Test + public void testNonFrozenTuple() throws Throwable + { + assertInvalid("CREATE TABLE wrong (k int PRIMARY KEY, v tuple<int, text>)"); + } } http://git-wip-us.apache.org/repos/asf/cassandra/blob/02be0ded/test/unit/org/apache/cassandra/cql3/UserTypesTest.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/cql3/UserTypesTest.java b/test/unit/org/apache/cassandra/cql3/UserTypesTest.java index c7f1851..ca84102 100644 --- a/test/unit/org/apache/cassandra/cql3/UserTypesTest.java +++ b/test/unit/org/apache/cassandra/cql3/UserTypesTest.java @@ -25,32 +25,37 @@ public class UserTypesTest extends CQLTester public void testInvalidField() throws Throwable { String myType = createType("CREATE TYPE %s (f int)"); - createTable("CREATE TABLE %s (k int PRIMARY KEY, v " + myType + ")"); + createTable("CREATE TABLE %s (k int PRIMARY KEY, v frozen<" + myType + ">)"); // 's' is not a field of myType assertInvalid("INSERT INTO %s (k, v) VALUES (?, {s : ?})", 0, 1); } - @Test public void testFor7684() throws Throwable { String myType = createType("CREATE TYPE %s (x double)"); - createTable("CREATE TABLE %s (k int, v " + myType + ", b boolean static, PRIMARY KEY (k, v))"); + createTable("CREATE TABLE %s (k int, v frozen<" + myType + ">, b boolean static, PRIMARY KEY (k, v))"); execute("INSERT INTO %s(k, v) VALUES (?, {x:?})", 1, -104.99251); execute("UPDATE %s SET b = ? WHERE k = ?", true, 1); - System.out.println("-- First query"); assertRows(execute("SELECT v.x FROM %s WHERE k = ? AND v = {x:?}", 1, -104.99251), row(-104.99251) ); flush(); - System.out.println("-- 2nd query"); assertRows(execute("SELECT v.x FROM %s WHERE k = ? AND v = {x:?}", 1, -104.99251), row(-104.99251) ); } + + @Test + public void testNonFrozenUDT() throws Throwable + { + // Using a UDT without frozen shouldn't work + String myType = createType("CREATE TYPE %s (f int)"); + assertInvalid("CREATE TABLE wrong (k int PRIMARY KEY, v " + myType + ")"); + } }