This is an automated email from the ASF dual-hosted git repository. snazy pushed a commit to branch cassandra-3.11 in repository https://gitbox.apache.org/repos/asf/cassandra.git
The following commit(s) were added to refs/heads/cassandra-3.11 by this push: new d51c18f Frozen RawTuple is not annotated with frozen in the toString method d51c18f is described below commit d51c18f807c5c88ef44114341592214747487645 Author: Yifan Cai <yc25c...@gmail.com> AuthorDate: Wed Jul 22 11:08:28 2020 +0200 Frozen RawTuple is not annotated with frozen in the toString method Patch by Yifan Cai; reviewed by Robert Stupp for CASSANDRA-15857 --- CHANGES.txt | 4 + src/java/org/apache/cassandra/cql3/CQL3Type.java | 20 +- .../cql3/statements/CreateAggregateStatement.java | 2 +- .../cql3/statements/CreateFunctionStatement.java | 2 +- .../cql3/statements/DropAggregateStatement.java | 2 +- .../cql3/statements/DropFunctionStatement.java | 2 +- .../cassandra/cql3/validation/entities/UFTest.java | 13 ++ .../cql3/validation/entities/UFTypesTest.java | 34 ++-- .../validation/operations/AggregationTest.java | 46 ++++- .../cassandra/io/sstable/CQLSSTableWriterTest.java | 209 +++++++++++---------- 10 files changed, 197 insertions(+), 137 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index b5b406b..22e7d1a 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,7 @@ +3.11.8 + * Frozen RawTuple is not annotated with frozen in the toString method (CASSANDRA-15857) + + 3.11.7 * Fix cqlsh output when fetching all rows in batch mode (CASSANDRA-15905) * Upgrade Jackson to 2.9.10 (CASSANDRA-15867) diff --git a/src/java/org/apache/cassandra/cql3/CQL3Type.java b/src/java/org/apache/cassandra/cql3/CQL3Type.java index 095d536..d1e6809 100644 --- a/src/java/org/apache/cassandra/cql3/CQL3Type.java +++ b/src/java/org/apache/cassandra/cql3/CQL3Type.java @@ -511,6 +511,11 @@ public interface CQL3Type return false; } + public boolean isTuple() + { + return false; + } + public String keyspace() { return null; @@ -660,7 +665,8 @@ public interface CQL3Type { assert values != null : "Got null values type for a collection"; - if (!frozen && values.supportsFreezing() && !values.frozen) + // skip if innerType is tuple, since tuple is implicitly forzen + if (!frozen && values.supportsFreezing() && !values.frozen && !values.isTuple()) throwNestedNonFrozenError(values); // we represent Thrift supercolumns as maps, internally, and we do allow counters in supercolumns. Thus, @@ -701,8 +707,6 @@ public interface CQL3Type throw new InvalidRequestException("Non-frozen collections are not allowed inside collections: " + this); else if (innerType.isUDT()) throw new InvalidRequestException("Non-frozen UDTs are not allowed inside collections: " + this); - else - throw new InvalidRequestException("Non-frozen tuples are not allowed inside collections: " + this); } public boolean referencesUserType(String name) @@ -805,7 +809,9 @@ public interface CQL3Type private RawTuple(List<CQL3Type.Raw> types) { + frozen = true; this.types = types; + freeze(); } public boolean supportsFreezing() @@ -824,9 +830,6 @@ public interface CQL3Type public CQL3Type prepare(String keyspace, Types udts) throws InvalidRequestException { - if (!frozen) - freeze(); - List<AbstractType<?>> ts = new ArrayList<>(types.size()); for (CQL3Type.Raw t : types) { @@ -838,6 +841,11 @@ public interface CQL3Type return new Tuple(new TupleType(ts)); } + public boolean isTuple() + { + return true; + } + public boolean referencesUserType(String name) { return types.stream().anyMatch(t -> t.referencesUserType(name)); diff --git a/src/java/org/apache/cassandra/cql3/statements/CreateAggregateStatement.java b/src/java/org/apache/cassandra/cql3/statements/CreateAggregateStatement.java index e8a5e06..d0e7ebb 100644 --- a/src/java/org/apache/cassandra/cql3/statements/CreateAggregateStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/CreateAggregateStatement.java @@ -141,7 +141,7 @@ public final class CreateAggregateStatement extends SchemaAlteringStatement private AbstractType<?> prepareType(String typeName, CQL3Type.Raw rawType) { - if (rawType.isFrozen()) + if (!rawType.isTuple() && rawType.isFrozen()) throw new InvalidRequestException(String.format("The function %s should not be frozen; remove the frozen<> modifier", typeName)); // UDT are not supported non frozen but we do not allow the frozen keyword for argument. So for the moment we diff --git a/src/java/org/apache/cassandra/cql3/statements/CreateFunctionStatement.java b/src/java/org/apache/cassandra/cql3/statements/CreateFunctionStatement.java index dfe522b..1e1c2ed 100644 --- a/src/java/org/apache/cassandra/cql3/statements/CreateFunctionStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/CreateFunctionStatement.java @@ -170,7 +170,7 @@ public final class CreateFunctionStatement extends SchemaAlteringStatement private AbstractType<?> prepareType(String typeName, CQL3Type.Raw rawType) { - if (rawType.isFrozen()) + if (!rawType.isTuple() && rawType.isFrozen()) throw new InvalidRequestException(String.format("The function %s should not be frozen; remove the frozen<> modifier", typeName)); // UDT are not supported non frozen but we do not allow the frozen keyword for argument. So for the moment we diff --git a/src/java/org/apache/cassandra/cql3/statements/DropAggregateStatement.java b/src/java/org/apache/cassandra/cql3/statements/DropAggregateStatement.java index ae8ad8c..218a8ee 100644 --- a/src/java/org/apache/cassandra/cql3/statements/DropAggregateStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/DropAggregateStatement.java @@ -139,7 +139,7 @@ public final class DropAggregateStatement extends SchemaAlteringStatement private AbstractType<?> prepareType(String typeName, CQL3Type.Raw rawType) { - if (rawType.isFrozen()) + if (!rawType.isTuple() && rawType.isFrozen()) throw new InvalidRequestException(String.format("The function %s should not be frozen; remove the frozen<> modifier", typeName)); // UDT are not supported non frozen but we do not allow the frozen keyword for argument. So for the moment we diff --git a/src/java/org/apache/cassandra/cql3/statements/DropFunctionStatement.java b/src/java/org/apache/cassandra/cql3/statements/DropFunctionStatement.java index 8845a82..fd86e00 100644 --- a/src/java/org/apache/cassandra/cql3/statements/DropFunctionStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/DropFunctionStatement.java @@ -70,7 +70,7 @@ public final class DropFunctionStatement extends SchemaAlteringStatement argTypes = new ArrayList<>(argRawTypes.size()); for (CQL3Type.Raw rawType : argRawTypes) { - if (rawType.isFrozen()) + if (!rawType.isTuple() && rawType.isFrozen()) throw new InvalidRequestException("The function arguments should not be frozen; remove the frozen<> modifier"); // UDT are not supported non frozen but we do not allow the frozen keyword for argument. So for the moment we diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/UFTest.java b/test/unit/org/apache/cassandra/cql3/validation/entities/UFTest.java index 6f3616c..e28af27 100644 --- a/test/unit/org/apache/cassandra/cql3/validation/entities/UFTest.java +++ b/test/unit/org/apache/cassandra/cql3/validation/entities/UFTest.java @@ -110,6 +110,19 @@ public class UFTest extends CQLTester assertLastSchemaChange(Event.SchemaChange.Change.DROPPED, Event.SchemaChange.Target.FUNCTION, KEYSPACE, parseFunctionName(f).name, "double", "double"); + + // The function with nested tuple should be created without throwing InvalidRequestException. See CASSANDRA-15857 + String f1 = createFunction(KEYSPACE, + "list<tuple<int, int>>, double", + "CREATE OR REPLACE FUNCTION %s(state list<tuple<int, int>>, val double) " + + "RETURNS NULL ON NULL INPUT " + + "RETURNS double " + + "LANGUAGE javascript " + + "AS '\"string\";';"); + + assertLastSchemaChange(Event.SchemaChange.Change.CREATED, Event.SchemaChange.Target.FUNCTION, + KEYSPACE, parseFunctionName(f1).name, + "list<frozen<tuple<int, int>>>", "double"); // CASSANDRA-14825: remove frozen from param } @Test diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/UFTypesTest.java b/test/unit/org/apache/cassandra/cql3/validation/entities/UFTypesTest.java index 3f1bcb1..63f65ec 100644 --- a/test/unit/org/apache/cassandra/cql3/validation/entities/UFTypesTest.java +++ b/test/unit/org/apache/cassandra/cql3/validation/entities/UFTypesTest.java @@ -34,6 +34,7 @@ import org.junit.Test; import com.datastax.driver.core.Row; import org.apache.cassandra.cql3.CQLTester; import org.apache.cassandra.cql3.UntypedResultSet; +import org.apache.cassandra.transport.Event; import org.apache.cassandra.transport.ProtocolVersion; import org.apache.cassandra.utils.UUIDGen; @@ -452,19 +453,20 @@ public class UFTypesTest extends CQLTester execute("INSERT INTO %s (a, b) VALUES (?, ?)", 2, tuple(4, 5)); execute("INSERT INTO %s (a, b) VALUES (?, ?)", 3, tuple(7, 8)); - assertInvalidMessage("The function arguments should not be frozen", - "CREATE OR REPLACE FUNCTION " + KEYSPACE + ".withFrozenArg(values frozen<tuple<int, int>>) " + - "CALLED ON NULL INPUT " + - "RETURNS text " + - "LANGUAGE java\n" + - "AS 'return values.toString();';"); - - assertInvalidMessage("The function return type should not be frozen", - "CREATE OR REPLACE FUNCTION " + KEYSPACE + ".frozenReturnType(values tuple<int, int>) " + - "CALLED ON NULL INPUT " + - "RETURNS frozen<tuple<int, int>> " + - "LANGUAGE java\n" + - "AS 'return values;';"); + // Tuples are always frozen. Both 'tuple' and 'frozen tuple' have the same effect. + // So allows to create function with explicit frozen tuples as argument and return types. + String toDrop = createFunction(KEYSPACE, + "frozen<tuple<int, int>>", + "CREATE FUNCTION %s (values frozen<tuple<int, int>>) " + + "CALLED ON NULL INPUT " + + "RETURNS frozen<tuple<int, int>> " + + "LANGUAGE java\n" + + "AS 'return values;';"); + // Same as above, dropping a function with explicity frozen tuple should be allowed. + schemaChange("DROP FUNCTION " + toDrop + "(frozen<tuple<int, int>>);"); + assertLastSchemaChange(Event.SchemaChange.Change.DROPPED, Event.SchemaChange.Target.FUNCTION, + KEYSPACE, shortFunctionName(toDrop), + "frozen<tuple<int, int>>"); String functionName = createFunction(KEYSPACE, "tuple<int, int>", @@ -490,8 +492,10 @@ public class UFTypesTest extends CQLTester assertRows(execute("SELECT a FROM %s WHERE b = " + functionName + "(?)", tuple(1, 2)), row(1)); - assertInvalidMessage("The function arguments should not be frozen", - "DROP FUNCTION " + functionName + "(frozen<tuple<int, int>>);"); + schemaChange("DROP FUNCTION " + functionName + "(frozen<tuple<int, int>>);"); + assertLastSchemaChange(Event.SchemaChange.Change.DROPPED, Event.SchemaChange.Target.FUNCTION, + KEYSPACE, shortFunctionName(functionName), + "frozen<tuple<int, int>>"); } @Test diff --git a/test/unit/org/apache/cassandra/cql3/validation/operations/AggregationTest.java b/test/unit/org/apache/cassandra/cql3/validation/operations/AggregationTest.java index 9841482..b2cf5dd 100644 --- a/test/unit/org/apache/cassandra/cql3/validation/operations/AggregationTest.java +++ b/test/unit/org/apache/cassandra/cql3/validation/operations/AggregationTest.java @@ -459,6 +459,26 @@ public class AggregationTest extends CQLTester assertLastSchemaChange(Event.SchemaChange.Change.DROPPED, Event.SchemaChange.Target.AGGREGATE, KEYSPACE, parseFunctionName(a).name, "double"); + + // The aggregate with nested tuple should be created without throwing InvalidRequestException. See CASSANDRA-15857 + String f1 = createFunction(KEYSPACE, + "double, double", + "CREATE OR REPLACE FUNCTION %s(state double, val list<tuple<int, int>>) " + + "RETURNS NULL ON NULL INPUT " + + "RETURNS double " + + "LANGUAGE javascript " + + "AS '\"string\";';"); + + String a1 = createAggregate(KEYSPACE, + "list<tuple<int, int>>", + "CREATE OR REPLACE AGGREGATE %s(list<tuple<int, int>>) " + + "SFUNC " + shortFunctionName(f1) + " " + + "STYPE double " + + "INITCOND 0"); + + assertLastSchemaChange(Event.SchemaChange.Change.CREATED, Event.SchemaChange.Target.AGGREGATE, + KEYSPACE, parseFunctionName(a1).name, + "list<frozen<tuple<int, int>>>"); // CASSANDRA-14825: remove frozen from param } @Test @@ -1618,12 +1638,20 @@ public class AggregationTest extends CQLTester "LANGUAGE java " + "AS 'return state;'"); - assertInvalidMessage("The function state type should not be frozen", - "CREATE AGGREGATE %s(tuple<int, int>) " + - "SFUNC " + parseFunctionName(fState).name + ' ' + - "STYPE frozen<tuple<int, int>> " + - "FINALFUNC " + parseFunctionName(fFinal).name + ' ' + - "INITCOND null"); + // Tuples are always frozen. Both 'tuple' and 'frozen tuple' have the same effect. + // So allows to create aggregate with explicit frozen tuples as argument and state types. + String toDrop = createAggregate(KEYSPACE, + "frozen<tuple<int, int>>", + "CREATE AGGREGATE %s(frozen<tuple<int, int>>) " + + "SFUNC " + parseFunctionName(fState).name + ' ' + + "STYPE frozen<tuple<int, int>> " + + "FINALFUNC " + parseFunctionName(fFinal).name + ' ' + + "INITCOND null"); + // Same as above, dropping a function with explicity frozen tuple should be allowed. + schemaChange("DROP AGGREGATE " + toDrop + "(frozen<tuple<int, int>>);"); + assertLastSchemaChange(Event.SchemaChange.Change.DROPPED, Event.SchemaChange.Target.AGGREGATE, + KEYSPACE, shortFunctionName(toDrop), + "frozen<tuple<int, int>>"); String aggregation = createAggregate(KEYSPACE, "tuple<int, int>", @@ -1636,8 +1664,10 @@ public class AggregationTest extends CQLTester assertRows(execute("SELECT " + aggregation + "(b) FROM %s"), row(tuple(7, 8))); - assertInvalidMessage("The function arguments should not be frozen", - "DROP AGGREGATE %s (frozen<tuple<int, int>>);"); + schemaChange("DROP AGGREGATE " + aggregation + "(frozen<tuple<int, int>>);"); + assertLastSchemaChange(Event.SchemaChange.Change.DROPPED, Event.SchemaChange.Target.AGGREGATE, + KEYSPACE, shortFunctionName(aggregation), + "frozen<tuple<int, int>>"); } @Test diff --git a/test/unit/org/apache/cassandra/io/sstable/CQLSSTableWriterTest.java b/test/unit/org/apache/cassandra/io/sstable/CQLSSTableWriterTest.java index a400612..dbeefbb 100644 --- a/test/unit/org/apache/cassandra/io/sstable/CQLSSTableWriterTest.java +++ b/test/unit/org/apache/cassandra/io/sstable/CQLSSTableWriterTest.java @@ -19,14 +19,19 @@ package org.apache.cassandra.io.sstable; import java.io.File; import java.io.FilenameFilter; +import java.io.IOException; import java.nio.ByteBuffer; import java.util.*; import java.util.concurrent.ExecutionException; +import java.util.concurrent.atomic.AtomicInteger; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.io.Files; +import org.apache.commons.io.FileUtils; +import org.junit.After; +import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -52,6 +57,13 @@ import static org.junit.Assert.fail; public class CQLSSTableWriterTest { + private static final AtomicInteger idGen = new AtomicInteger(0); + private String keyspace; + private String table; + private String qualifiedTable; + private File dataDir; + private File tempDir; + static { DatabaseDescriptor.daemonInitialization(); @@ -65,24 +77,35 @@ public class CQLSSTableWriterTest StorageService.instance.initServer(); } + @Before + public void perTestSetup() + { + tempDir = Files.createTempDir(); + keyspace = "cql_keyspace" + idGen.incrementAndGet(); + table = "table" + idGen.incrementAndGet(); + qualifiedTable = keyspace + '.' + table; + dataDir = new File(tempDir.getAbsolutePath() + File.separator + keyspace + File.separator + table); + assert dataDir.mkdirs(); + } + + @After + public void cleanup() throws IOException + { + FileUtils.deleteDirectory(tempDir); + } + + @Test public void testUnsortedWriter() throws Exception { try (AutoCloseable switcher = Util.switchPartitioner(ByteOrderedPartitioner.instance)) { - String KS = "cql_keyspace"; - String TABLE = "table1"; - - File tempdir = Files.createTempDir(); - File dataDir = new File(tempdir.getAbsolutePath() + File.separator + KS + File.separator + TABLE); - assert dataDir.mkdirs(); - - String schema = "CREATE TABLE cql_keyspace.table1 (" + String schema = "CREATE TABLE " + qualifiedTable + " (" + " k int PRIMARY KEY," + " v1 text," + " v2 int" + ")"; - String insert = "INSERT INTO cql_keyspace.table1 (k, v1, v2) VALUES (?, ?, ?)"; + String insert = "INSERT INTO " + qualifiedTable + " (k, v1, v2) VALUES (?, ?, ?)"; CQLSSTableWriter writer = CQLSSTableWriter.builder() .inDirectory(dataDir) .forTable(schema) @@ -95,9 +118,9 @@ public class CQLSSTableWriterTest writer.close(); - loadSSTables(dataDir, KS); + loadSSTables(dataDir, keyspace); - UntypedResultSet rs = QueryProcessor.executeInternal("SELECT * FROM cql_keyspace.table1;"); + UntypedResultSet rs = QueryProcessor.executeInternal("SELECT * FROM " + qualifiedTable + ";"); assertEquals(4, rs.size()); Iterator<UntypedResultSet.Row> iter = rs.iterator(); @@ -129,19 +152,12 @@ public class CQLSSTableWriterTest @Test public void testForbidCounterUpdates() throws Exception { - String KS = "cql_keyspace"; - String TABLE = "counter1"; - - File tempdir = Files.createTempDir(); - File dataDir = new File(tempdir.getAbsolutePath() + File.separator + KS + File.separator + TABLE); - assert dataDir.mkdirs(); - - String schema = "CREATE TABLE cql_keyspace.counter1 (" + + String schema = "CREATE TABLE " + qualifiedTable + " (" + " my_id int, " + " my_counter counter, " + " PRIMARY KEY (my_id)" + ")"; - String insert = String.format("UPDATE cql_keyspace.counter1 SET my_counter = my_counter - ? WHERE my_id = ?"); + String insert = String.format("UPDATE " + qualifiedTable + " SET my_counter = my_counter - ? WHERE my_id = ?"); try { CQLSSTableWriter.builder().inDirectory(dataDir) @@ -162,17 +178,11 @@ public class CQLSSTableWriterTest // Check that the write respect the buffer size even if we only insert rows withing the same partition (#7360) // To do that simply, we use a writer with a buffer of 1MB, and write 2 rows in the same partition with a value // > 1MB and validate that this created more than 1 sstable. - String KS = "ks"; - String TABLE = "test"; - - File tempdir = Files.createTempDir(); - File dataDir = new File(tempdir.getAbsolutePath() + File.separator + KS + File.separator + TABLE); - assert dataDir.mkdirs(); - String schema = "CREATE TABLE ks.test (" + String schema = "CREATE TABLE " + qualifiedTable + " (" + " k int PRIMARY KEY," + " v blob" + ")"; - String insert = "INSERT INTO ks.test (k, v) VALUES (?, ?)"; + String insert = "INSERT INTO " + qualifiedTable + " (k, v) VALUES (?, ?)"; CQLSSTableWriter writer = CQLSSTableWriter.builder() .inDirectory(dataDir) .using(insert) @@ -201,15 +211,14 @@ public class CQLSSTableWriterTest public void testSyncNoEmptyRows() throws Exception { // Check that the write does not throw an empty partition error (#9071) - File tempdir = Files.createTempDir(); - String schema = "CREATE TABLE ks.test2 (" + String schema = "CREATE TABLE " + qualifiedTable + " (" + " k UUID," + " c int," + " PRIMARY KEY (k)" + ")"; - String insert = "INSERT INTO ks.test2 (k, c) VALUES (?, ?)"; + String insert = "INSERT INTO " + qualifiedTable + " (k, c) VALUES (?, ?)"; CQLSSTableWriter writer = CQLSSTableWriter.builder() - .inDirectory(tempdir) + .inDirectory(dataDir) .forTable(schema) .using(insert) .withBufferSizeInMB(1) @@ -229,23 +238,25 @@ public class CQLSSTableWriterTest { private final File dataDir; private final int id; + private final String qualifiedTable; public volatile Exception exception; - public WriterThread(File dataDir, int id) + public WriterThread(File dataDir, int id, String qualifiedTable) { this.dataDir = dataDir; this.id = id; + this.qualifiedTable = qualifiedTable; } @Override public void run() { - String schema = "CREATE TABLE cql_keyspace2.table2 (" + String schema = "CREATE TABLE " + qualifiedTable + " (" + " k int," + " v int," + " PRIMARY KEY (k, v)" + ")"; - String insert = "INSERT INTO cql_keyspace2.table2 (k, v) VALUES (?, ?)"; + String insert = "INSERT INTO " + qualifiedTable + " (k, v) VALUES (?, ?)"; CQLSSTableWriter writer = CQLSSTableWriter.builder() .inDirectory(dataDir) .forTable(schema) @@ -269,17 +280,10 @@ public class CQLSSTableWriterTest @Test public void testConcurrentWriters() throws Exception { - final String KS = "cql_keyspace2"; - final String TABLE = "table2"; - - File tempdir = Files.createTempDir(); - File dataDir = new File(tempdir.getAbsolutePath() + File.separator + KS + File.separator + TABLE); - assert dataDir.mkdirs(); - WriterThread[] threads = new WriterThread[5]; for (int i = 0; i < threads.length; i++) { - WriterThread thread = new WriterThread(dataDir, i); + WriterThread thread = new WriterThread(dataDir, i, qualifiedTable); threads[i] = thread; thread.start(); } @@ -294,9 +298,9 @@ public class CQLSSTableWriterTest } } - loadSSTables(dataDir, KS); + loadSSTables(dataDir, keyspace); - UntypedResultSet rs = QueryProcessor.executeInternal("SELECT * FROM cql_keyspace2.table2;"); + UntypedResultSet rs = QueryProcessor.executeInternal("SELECT * FROM " + qualifiedTable + ";"); assertEquals(threads.length * NUMBER_WRITES_IN_RUNNABLE, rs.size()); } @@ -304,26 +308,19 @@ public class CQLSSTableWriterTest @SuppressWarnings("unchecked") public void testWritesWithUdts() throws Exception { - final String KS = "cql_keyspace3"; - final String TABLE = "table3"; - - final String schema = "CREATE TABLE " + KS + "." + TABLE + " (" + final String schema = "CREATE TABLE " + qualifiedTable + " (" + " k int," + " v1 list<frozen<tuple2>>," + " v2 frozen<tuple3>," + " PRIMARY KEY (k)" + ")"; - File tempdir = Files.createTempDir(); - File dataDir = new File(tempdir.getAbsolutePath() + File.separator + KS + File.separator + TABLE); - assert dataDir.mkdirs(); - CQLSSTableWriter writer = CQLSSTableWriter.builder() .inDirectory(dataDir) - .withType("CREATE TYPE " + KS + ".tuple2 (a int, b int)") - .withType("CREATE TYPE " + KS + ".tuple3 (a int, b int, c int)") + .withType("CREATE TYPE " + keyspace + ".tuple2 (a int, b int)") + .withType("CREATE TYPE " + keyspace + ".tuple3 (a int, b int, c int)") .forTable(schema) - .using("INSERT INTO " + KS + "." + TABLE + " (k, v1, v2) " + + .using("INSERT INTO " + keyspace + "." + table + " (k, v1, v2) " + "VALUES (?, ?, ?)").build(); UserType tuple2Type = writer.getUDType("tuple2"); @@ -346,9 +343,9 @@ public class CQLSSTableWriterTest } writer.close(); - loadSSTables(dataDir, KS); + loadSSTables(dataDir, keyspace); - UntypedResultSet resultSet = QueryProcessor.executeInternal("SELECT * FROM " + KS + "." + TABLE); + UntypedResultSet resultSet = QueryProcessor.executeInternal("SELECT * FROM " + keyspace + "." + table); TypeCodec collectionCodec = UDHelper.codecFor(DataType.CollectionType.frozenList(tuple2Type)); TypeCodec tuple3Codec = UDHelper.codecFor(tuple3Type); @@ -377,25 +374,18 @@ public class CQLSSTableWriterTest @SuppressWarnings("unchecked") public void testWritesWithDependentUdts() throws Exception { - final String KS = "cql_keyspace4"; - final String TABLE = "table4"; - - final String schema = "CREATE TABLE " + KS + "." + TABLE + " (" + final String schema = "CREATE TABLE " + qualifiedTable + " (" + " k int," + " v1 frozen<nested_tuple>," + " PRIMARY KEY (k)" + ")"; - File tempdir = Files.createTempDir(); - File dataDir = new File(tempdir.getAbsolutePath() + File.separator + KS + File.separator + TABLE); - assert dataDir.mkdirs(); - CQLSSTableWriter writer = CQLSSTableWriter.builder() .inDirectory(dataDir) - .withType("CREATE TYPE " + KS + ".nested_tuple (c int, tpl frozen<tuple2>)") - .withType("CREATE TYPE " + KS + ".tuple2 (a int, b int)") + .withType("CREATE TYPE " + keyspace + ".nested_tuple (c int, tpl frozen<tuple2>)") + .withType("CREATE TYPE " + keyspace + ".tuple2 (a int, b int)") .forTable(schema) - .using("INSERT INTO " + KS + "." + TABLE + " (k, v1) " + + .using("INSERT INTO " + keyspace + "." + table + " (k, v1) " + "VALUES (?, ?)") .build(); @@ -417,9 +407,9 @@ public class CQLSSTableWriterTest } writer.close(); - loadSSTables(dataDir, KS); + loadSSTables(dataDir, keyspace); - UntypedResultSet resultSet = QueryProcessor.executeInternal("SELECT * FROM " + KS + "." + TABLE); + UntypedResultSet resultSet = QueryProcessor.executeInternal("SELECT * FROM " + keyspace + "." + table); assertEquals(resultSet.size(), 100); int cnt = 0; @@ -440,10 +430,7 @@ public class CQLSSTableWriterTest @Test public void testUnsetValues() throws Exception { - final String KS = "cql_keyspace5"; - final String TABLE = "table5"; - - final String schema = "CREATE TABLE " + KS + "." + TABLE + " (" + final String schema = "CREATE TABLE " + qualifiedTable + " (" + " k int," + " c1 int," + " c2 int," @@ -451,14 +438,10 @@ public class CQLSSTableWriterTest + " PRIMARY KEY (k, c1, c2)" + ")"; - File tempdir = Files.createTempDir(); - File dataDir = new File(tempdir.getAbsolutePath() + File.separator + KS + File.separator + TABLE); - assert dataDir.mkdirs(); - CQLSSTableWriter writer = CQLSSTableWriter.builder() .inDirectory(dataDir) .forTable(schema) - .using("INSERT INTO " + KS + "." + TABLE + " (k, c1, c2, v) " + + .using("INSERT INTO " + qualifiedTable + " (k, c1, c2, v) " + "VALUES (?, ?, ?, ?)") .build(); @@ -508,9 +491,9 @@ public class CQLSSTableWriterTest writer.addRow(5, 5, 5, "5"); writer.close(); - loadSSTables(dataDir, KS); + loadSSTables(dataDir, keyspace); - UntypedResultSet resultSet = QueryProcessor.executeInternal("SELECT * FROM " + KS + "." + TABLE); + UntypedResultSet resultSet = QueryProcessor.executeInternal("SELECT * FROM " + qualifiedTable); Iterator<UntypedResultSet.Row> iter = resultSet.iterator(); UntypedResultSet.Row r1 = iter.next(); assertEquals(1, r1.getInt("k")); @@ -543,10 +526,7 @@ public class CQLSSTableWriterTest @Test public void testUpdateStatement() throws Exception { - final String KS = "cql_keyspace6"; - final String TABLE = "table6"; - - final String schema = "CREATE TABLE " + KS + "." + TABLE + " (" + final String schema = "CREATE TABLE " + qualifiedTable + " (" + " k int," + " c1 int," + " c2 int," @@ -554,14 +534,10 @@ public class CQLSSTableWriterTest + " PRIMARY KEY (k, c1, c2)" + ")"; - File tempdir = Files.createTempDir(); - File dataDir = new File(tempdir.getAbsolutePath() + File.separator + KS + File.separator + TABLE); - assert dataDir.mkdirs(); - CQLSSTableWriter writer = CQLSSTableWriter.builder() .inDirectory(dataDir) .forTable(schema) - .using("UPDATE " + KS + "." + TABLE + " SET v = ? " + + .using("UPDATE " + qualifiedTable + " SET v = ? " + "WHERE k = ? AND c1 = ? AND c2 = ?") .build(); @@ -570,9 +546,9 @@ public class CQLSSTableWriterTest writer.addRow(null, 7, 8, 9); writer.addRow(CQLSSTableWriter.UNSET_VALUE, 10, 11, 12); writer.close(); - loadSSTables(dataDir, KS); + loadSSTables(dataDir, keyspace); - UntypedResultSet resultSet = QueryProcessor.executeInternal("SELECT * FROM " + KS + "." + TABLE); + UntypedResultSet resultSet = QueryProcessor.executeInternal("SELECT * FROM " + qualifiedTable); assertEquals(2, resultSet.size()); Iterator<UntypedResultSet.Row> iter = resultSet.iterator(); @@ -592,10 +568,7 @@ public class CQLSSTableWriterTest @Test public void testNativeFunctions() throws Exception { - final String KS = "cql_keyspace7"; - final String TABLE = "table7"; - - final String schema = "CREATE TABLE " + KS + "." + TABLE + " (" + final String schema = "CREATE TABLE " + qualifiedTable + " (" + " k int," + " c1 int," + " c2 int," @@ -603,23 +576,19 @@ public class CQLSSTableWriterTest + " PRIMARY KEY (k, c1, c2)" + ")"; - File tempdir = Files.createTempDir(); - File dataDir = new File(tempdir.getAbsolutePath() + File.separator + KS + File.separator + TABLE); - assert dataDir.mkdirs(); - CQLSSTableWriter writer = CQLSSTableWriter.builder() .inDirectory(dataDir) .forTable(schema) - .using("INSERT INTO " + KS + "." + TABLE + " (k, c1, c2, v) VALUES (?, ?, ?, textAsBlob(?))") + .using("INSERT INTO " + qualifiedTable + " (k, c1, c2, v) VALUES (?, ?, ?, textAsBlob(?))") .build(); writer.addRow(1, 2, 3, "abc"); writer.addRow(4, 5, 6, "efg"); writer.close(); - loadSSTables(dataDir, KS); + loadSSTables(dataDir, keyspace); - UntypedResultSet resultSet = QueryProcessor.executeInternal("SELECT * FROM " + KS + "." + TABLE); + UntypedResultSet resultSet = QueryProcessor.executeInternal("SELECT * FROM " + qualifiedTable); assertEquals(2, resultSet.size()); Iterator<UntypedResultSet.Row> iter = resultSet.iterator(); @@ -638,6 +607,38 @@ public class CQLSSTableWriterTest assertFalse(iter.hasNext()); } + @Test + public void testWriteWithNestedTupleUdt() throws Exception + { + // Check the writer does not throw "InvalidRequestException: Non-frozen tuples are not allowed inside collections: list<tuple<int, int>>" + // See CASSANDRA-15857 + final String schema = "CREATE TABLE " + qualifiedTable + " (" + + " k int," + + " v1 frozen<nested_type>," + + " PRIMARY KEY (k)" + + ")"; + + CQLSSTableWriter writer = CQLSSTableWriter.builder() + .inDirectory(dataDir) + .withType("CREATE TYPE " + keyspace + ".nested_type (a list<tuple<int, int>>)") + .forTable(schema) + .using("INSERT INTO " + qualifiedTable + " (k, v1) " + + "VALUES (?, ?)").build(); + + UserType nestedType = writer.getUDType("nested_type"); + for (int i = 0; i < 100; i++) + { + writer.addRow(i, nestedType.newValue() + .setList("a", Collections.emptyList())); + } + + writer.close(); + loadSSTables(dataDir, keyspace); + + UntypedResultSet resultSet = QueryProcessor.executeInternal("SELECT * FROM " + qualifiedTable); + assertEquals(100, resultSet.size()); + } + private static void loadSSTables(File dataDir, String ks) throws ExecutionException, InterruptedException { SSTableLoader loader = new SSTableLoader(dataDir, new SSTableLoader.Client() --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org For additional commands, e-mail: commits-h...@cassandra.apache.org