Repository: cassandra Updated Branches: refs/heads/cassandra-2.1 033762099 -> ee55f361b
http://git-wip-us.apache.org/repos/asf/cassandra/blob/ee55f361/src/java/org/apache/cassandra/db/marshal/TypeParser.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/marshal/TypeParser.java b/src/java/org/apache/cassandra/db/marshal/TypeParser.java index 1b83180..cdb5679 100644 --- a/src/java/org/apache/cassandra/db/marshal/TypeParser.java +++ b/src/java/org/apache/cassandra/db/marshal/TypeParser.java @@ -241,7 +241,7 @@ public class TypeParser public Map<ByteBuffer, CollectionType> getCollectionsParameters() throws SyntaxException, ConfigurationException { - Map<ByteBuffer, CollectionType> map = new HashMap<ByteBuffer, CollectionType>(); + Map<ByteBuffer, CollectionType> map = new HashMap<>(); if (isEOS()) return map; @@ -539,25 +539,37 @@ public class TypeParser */ public static String stringifyTypeParameters(List<AbstractType<?>> types) { - StringBuilder sb = new StringBuilder(); - sb.append('(').append(StringUtils.join(types, ",")).append(')'); - return sb.toString(); + return stringifyTypeParameters(types, false); + } + + /** + * Helper function to ease the writing of AbstractType.toString() methods. + */ + public static String stringifyTypeParameters(List<AbstractType<?>> types, boolean ignoreFreezing) + { + StringBuilder sb = new StringBuilder("("); + for (int i = 0; i < types.size(); i++) + { + if (i > 0) + sb.append(","); + sb.append(types.get(i).toString(ignoreFreezing)); + } + return sb.append(')').toString(); } - public static String stringifyCollectionsParameters(Map<ByteBuffer, CollectionType> collections) + public static String stringifyCollectionsParameters(Map<ByteBuffer, ? extends CollectionType> collections) { StringBuilder sb = new StringBuilder(); sb.append('('); boolean first = true; - for (Map.Entry<ByteBuffer, CollectionType> entry : collections.entrySet()) + for (Map.Entry<ByteBuffer, ? extends CollectionType> entry : collections.entrySet()) { if (!first) - { sb.append(','); - } + first = false; sb.append(ByteBufferUtil.bytesToHex(entry.getKey())).append(":"); - entry.getValue().appendToStringBuilder(sb); + sb.append(entry.getValue()); } sb.append(')'); return sb.toString(); @@ -572,7 +584,9 @@ public class TypeParser { sb.append(','); sb.append(ByteBufferUtil.bytesToHex(columnNames.get(i))).append(":"); - sb.append(columnTypes.get(i).toString()); + + // omit FrozenType(...) from fields because it is currently implicit + sb.append(columnTypes.get(i).toString(true)); } sb.append(')'); return sb.toString(); http://git-wip-us.apache.org/repos/asf/cassandra/blob/ee55f361/src/java/org/apache/cassandra/db/marshal/UserType.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/marshal/UserType.java b/src/java/org/apache/cassandra/db/marshal/UserType.java index 44c208f..180d713 100644 --- a/src/java/org/apache/cassandra/db/marshal/UserType.java +++ b/src/java/org/apache/cassandra/db/marshal/UserType.java @@ -61,7 +61,7 @@ public class UserType extends TupleType for (Pair<ByteBuffer, AbstractType> p : params.right) { columnNames.add(p.left); - columnTypes.add(p.right); + columnTypes.add(p.right.freeze()); } return new UserType(keyspace, name, columnNames, columnTypes); } http://git-wip-us.apache.org/repos/asf/cassandra/blob/ee55f361/src/java/org/apache/cassandra/hadoop/pig/CqlStorage.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/hadoop/pig/CqlStorage.java b/src/java/org/apache/cassandra/hadoop/pig/CqlStorage.java index 7a6be71..2ba4dbf 100644 --- a/src/java/org/apache/cassandra/hadoop/pig/CqlStorage.java +++ b/src/java/org/apache/cassandra/hadoop/pig/CqlStorage.java @@ -148,9 +148,9 @@ public class CqlStorage extends AbstractCassandraStorage } AbstractType elementValidator; if (validator instanceof SetType) - elementValidator = ((SetType<?>) validator).elements; + elementValidator = ((SetType<?>) validator).getElementsType(); else if (validator instanceof ListType) - elementValidator = ((ListType<?>) validator).elements; + elementValidator = ((ListType<?>) validator).getElementsType(); else return; @@ -167,8 +167,8 @@ public class CqlStorage extends AbstractCassandraStorage /** set the values of set/list at and after the position of the tuple */ private void setMapTupleValues(Tuple tuple, int position, Object value, AbstractType<?> validator) throws ExecException { - AbstractType<?> keyValidator = ((MapType<?, ?>) validator).keys; - AbstractType<?> valueValidator = ((MapType<?, ?>) validator).values; + AbstractType<?> keyValidator = ((MapType<?, ?>) validator).getKeysType(); + AbstractType<?> valueValidator = ((MapType<?, ?>) validator).getValuesType(); int i = 0; Tuple innerTuple = TupleFactory.getInstance().newTuple(((Map<?,?>) value).size()); http://git-wip-us.apache.org/repos/asf/cassandra/blob/ee55f361/src/java/org/apache/cassandra/serializers/CollectionSerializer.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/serializers/CollectionSerializer.java b/src/java/org/apache/cassandra/serializers/CollectionSerializer.java index 2a5e809..29ae2fd 100644 --- a/src/java/org/apache/cassandra/serializers/CollectionSerializer.java +++ b/src/java/org/apache/cassandra/serializers/CollectionSerializer.java @@ -19,8 +19,10 @@ package org.apache.cassandra.serializers; import java.nio.ByteBuffer; +import java.util.Collection; import java.util.List; +import org.apache.cassandra.transport.Server; import org.apache.cassandra.utils.ByteBufferUtil; public abstract class CollectionSerializer<T> implements TypeSerializer<T> @@ -35,17 +37,17 @@ public abstract class CollectionSerializer<T> implements TypeSerializer<T> { List<ByteBuffer> values = serializeValues(value); // See deserialize() for why using the protocol v3 variant is the right thing to do. - return pack(values, getElementCount(value), 3); + return pack(values, getElementCount(value), Server.VERSION_3); } public T deserialize(ByteBuffer bytes) { // The only cases we serialize/deserialize collections internally (i.e. not for the protocol sake), // is: - // 1) when collections are in UDT values + // 1) when collections are frozen // 2) for internal calls. // In both case, using the protocol 3 version variant is the right thing to do. - return deserializeForNativeProtocol(bytes, 3); + return deserializeForNativeProtocol(bytes, Server.VERSION_3); } public ByteBuffer reserializeToV3(ByteBuffer bytes) @@ -55,11 +57,11 @@ public abstract class CollectionSerializer<T> implements TypeSerializer<T> public void validate(ByteBuffer bytes) throws MarshalException { - // Same thing than above - validateForNativeProtocol(bytes, 3); + // Same thing as above + validateForNativeProtocol(bytes, Server.VERSION_3); } - public static ByteBuffer pack(List<ByteBuffer> buffers, int elements, int version) + public static ByteBuffer pack(Collection<ByteBuffer> buffers, int elements, int version) { int size = 0; for (ByteBuffer bb : buffers) @@ -74,7 +76,7 @@ public abstract class CollectionSerializer<T> implements TypeSerializer<T> protected static void writeCollectionSize(ByteBuffer output, int elements, int version) { - if (version >= 3) + if (version >= Server.VERSION_3) output.putInt(elements); else output.putShort((short)elements); @@ -82,12 +84,12 @@ public abstract class CollectionSerializer<T> implements TypeSerializer<T> public static int readCollectionSize(ByteBuffer input, int version) { - return version >= 3 ? input.getInt() : ByteBufferUtil.readShortLength(input); + return version >= Server.VERSION_3 ? input.getInt() : ByteBufferUtil.readShortLength(input); } protected static int sizeOfCollectionSize(int elements, int version) { - return version >= 3 ? 4 : 2; + return version >= Server.VERSION_3 ? 4 : 2; } protected static void writeValue(ByteBuffer output, ByteBuffer value, int version) @@ -113,7 +115,7 @@ public abstract class CollectionSerializer<T> implements TypeSerializer<T> public static ByteBuffer readValue(ByteBuffer input, int version) { - if (version >= 3) + if (version >= Server.VERSION_3) { int size = input.getInt(); if (size < 0) @@ -129,7 +131,7 @@ public abstract class CollectionSerializer<T> implements TypeSerializer<T> protected static int sizeOfValue(ByteBuffer value, int version) { - if (version >= 3) + if (version >= Server.VERSION_3) { return value == null ? 4 : 4 + value.remaining(); } http://git-wip-us.apache.org/repos/asf/cassandra/blob/ee55f361/src/java/org/apache/cassandra/serializers/ListSerializer.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/serializers/ListSerializer.java b/src/java/org/apache/cassandra/serializers/ListSerializer.java index 7387e1b..aeee2b9 100644 --- a/src/java/org/apache/cassandra/serializers/ListSerializer.java +++ b/src/java/org/apache/cassandra/serializers/ListSerializer.java @@ -18,12 +18,12 @@ package org.apache.cassandra.serializers; +import org.apache.cassandra.transport.Server; + import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; import java.util.*; -import org.apache.cassandra.utils.ByteBufferUtil; - public class ListSerializer<T> extends CollectionSerializer<List<T>> { // interning instances @@ -111,6 +111,34 @@ public class ListSerializer<T> extends CollectionSerializer<List<T>> } } + /** + * Returns the element at the given index in a list. + * @param serializedList a serialized list + * @param index the index to get + * @return the serialized element at the given index, or null if the index exceeds the list size + */ + public ByteBuffer getElement(ByteBuffer serializedList, int index) + { + try + { + ByteBuffer input = serializedList.duplicate(); + int n = readCollectionSize(input, Server.VERSION_3); + if (n <= index) + return null; + + for (int i = 0; i < index; i++) + { + int length = input.getInt(); + input.position(input.position() + length); + } + return readValue(input, Server.VERSION_3); + } + catch (BufferUnderflowException e) + { + throw new MarshalException("Not enough bytes to read a list"); + } + } + public String toString(List<T> value) { StringBuilder sb = new StringBuilder(); @@ -118,13 +146,9 @@ public class ListSerializer<T> extends CollectionSerializer<List<T>> for (T element : value) { if (isFirst) - { isFirst = false; - } else - { sb.append("; "); - } sb.append(elements.toString(element)); } return sb.toString(); http://git-wip-us.apache.org/repos/asf/cassandra/blob/ee55f361/src/java/org/apache/cassandra/serializers/MapSerializer.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/serializers/MapSerializer.java b/src/java/org/apache/cassandra/serializers/MapSerializer.java index dadadd0..bc8e509 100644 --- a/src/java/org/apache/cassandra/serializers/MapSerializer.java +++ b/src/java/org/apache/cassandra/serializers/MapSerializer.java @@ -22,6 +22,8 @@ import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; import java.util.*; +import org.apache.cassandra.db.marshal.AbstractType; +import org.apache.cassandra.transport.Server; import org.apache.cassandra.utils.ByteBufferUtil; import org.apache.cassandra.utils.Pair; @@ -114,6 +116,38 @@ public class MapSerializer<K, V> extends CollectionSerializer<Map<K, V>> } } + /** + * Given a serialized map, gets the value associated with a given key. + * @param serializedMap a serialized map + * @param serializedKey a serialized key + * @param keyType the key type for the map + * @return the value associated with the key if one exists, null otherwise + */ + public ByteBuffer getSerializedValue(ByteBuffer serializedMap, ByteBuffer serializedKey, AbstractType keyType) + { + try + { + ByteBuffer input = serializedMap.duplicate(); + int n = readCollectionSize(input, Server.VERSION_3); + for (int i = 0; i < n; i++) + { + ByteBuffer kbb = readValue(input, Server.VERSION_3); + ByteBuffer vbb = readValue(input, Server.VERSION_3); + int comparison = keyType.compare(kbb, serializedKey); + if (comparison == 0) + return vbb; + else if (comparison > 0) + // since the map is in sorted order, we know we've gone too far and the element doesn't exist + return null; + } + return null; + } + catch (BufferUnderflowException e) + { + throw new MarshalException("Not enough bytes to read a map"); + } + } + public String toString(Map<K, V> value) { StringBuilder sb = new StringBuilder(); @@ -121,13 +155,9 @@ public class MapSerializer<K, V> extends CollectionSerializer<Map<K, V>> for (Map.Entry<K, V> element : value.entrySet()) { if (isFirst) - { isFirst = false; - } else - { sb.append("; "); - } sb.append('('); sb.append(keys.toString(element.getKey())); sb.append(", "); http://git-wip-us.apache.org/repos/asf/cassandra/blob/ee55f361/src/java/org/apache/cassandra/transport/DataType.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/transport/DataType.java b/src/java/org/apache/cassandra/transport/DataType.java index a45d7ce..0ea353a 100644 --- a/src/java/org/apache/cassandra/transport/DataType.java +++ b/src/java/org/apache/cassandra/transport/DataType.java @@ -214,18 +214,18 @@ public enum DataType implements OptionCodec.Codecable<DataType> { if (type instanceof ListType) { - return Pair.<DataType, Object>create(LIST, ((ListType)type).elements); + return Pair.<DataType, Object>create(LIST, ((ListType)type).getElementsType()); } else if (type instanceof MapType) { MapType mt = (MapType)type; - return Pair.<DataType, Object>create(MAP, Arrays.asList(mt.keys, mt.values)); + return Pair.<DataType, Object>create(MAP, Arrays.asList(mt.getKeysType(), mt.getValuesType())); } - else + else if (type instanceof SetType) { - assert type instanceof SetType; - return Pair.<DataType, Object>create(SET, ((SetType)type).elements); + return Pair.<DataType, Object>create(SET, ((SetType)type).getElementsType()); } + throw new AssertionError(); } if (type instanceof UserType && version >= 3) @@ -251,12 +251,12 @@ public enum DataType implements OptionCodec.Codecable<DataType> case CUSTOM: return TypeParser.parse((String)entry.right); case LIST: - return ListType.getInstance((AbstractType)entry.right); + return ListType.getInstance((AbstractType)entry.right, true); case SET: - return SetType.getInstance((AbstractType)entry.right); + return SetType.getInstance((AbstractType)entry.right, true); case MAP: List<AbstractType> l = (List<AbstractType>)entry.right; - return MapType.getInstance(l.get(0), l.get(1)); + return MapType.getInstance(l.get(0), l.get(1), true); case UDT: return (AbstractType)entry.right; case TUPLE: http://git-wip-us.apache.org/repos/asf/cassandra/blob/ee55f361/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 6e4a5a9..aacfb4b 100644 --- a/test/unit/org/apache/cassandra/cql3/CQLTester.java +++ b/test/unit/org/apache/cassandra/cql3/CQLTester.java @@ -37,7 +37,6 @@ import org.slf4j.LoggerFactory; import org.apache.cassandra.SchemaLoader; import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.config.Schema; -import org.apache.cassandra.db.ConsistencyLevel; import org.apache.cassandra.db.Directories; import org.apache.cassandra.db.Keyspace; import org.apache.cassandra.db.marshal.*; @@ -45,7 +44,6 @@ import org.apache.cassandra.exceptions.*; import org.apache.cassandra.io.util.FileUtils; import org.apache.cassandra.serializers.TypeSerializer; import org.apache.cassandra.service.StorageService; -import org.apache.cassandra.utils.ByteBufferUtil; /** * Base class for CQL tests. @@ -96,10 +94,10 @@ public abstract class CQLTester { try { - schemaChange(String.format("DROP TABLE %s.%s", KEYSPACE, tableToDrop)); + schemaChange(String.format("DROP TABLE IF EXISTS %s.%s", KEYSPACE, tableToDrop)); for (String typeName : typesToDrop) - schemaChange(String.format("DROP TYPE %s.%s", KEYSPACE, typeName)); + schemaChange(String.format("DROP TYPE IF EXISTS %s.%s", KEYSPACE, typeName)); // Dropping doesn't delete the sstables. It's not a huge deal but it's cleaner to cleanup after us // Thas said, we shouldn't delete blindly before the SSTableDeletingTask for the table we drop @@ -186,6 +184,21 @@ public abstract class CQLTester schemaChange(fullQuery); } + protected void createTableMayThrow(String query) throws Throwable + { + currentTable = "table_" + seqNumber.getAndIncrement(); + String fullQuery = String.format(query, KEYSPACE + "." + currentTable); + logger.info(fullQuery); + try + { + QueryProcessor.executeOnceInternal(fullQuery); + } + catch (RuntimeException ex) + { + throw ex.getCause(); + } + } + protected void alterTable(String query) { String fullQuery = String.format(query, KEYSPACE + "." + currentTable); @@ -193,6 +206,20 @@ public abstract class CQLTester schemaChange(fullQuery); } + protected void alterTableMayThrow(String query) throws Throwable + { + String fullQuery = String.format(query, KEYSPACE + "." + currentTable); + logger.info(fullQuery); + try + { + QueryProcessor.executeOnceInternal(fullQuery); + } + catch (RuntimeException ex) + { + throw ex.getCause(); + } + } + protected void createIndex(String query) { String fullQuery = String.format(query, KEYSPACE + "." + currentTable); @@ -200,6 +227,20 @@ public abstract class CQLTester schemaChange(fullQuery); } + protected void createIndexMayThrow(String query) throws Throwable + { + String fullQuery = String.format(query, KEYSPACE + "." + currentTable); + logger.info(fullQuery); + try + { + QueryProcessor.executeOnceInternal(fullQuery); + } + catch (RuntimeException ex) + { + throw ex.getCause(); + } + } + private static void schemaChange(String query) { try @@ -262,7 +303,7 @@ public abstract class CQLTester int i = 0; while (iter.hasNext() && i < rows.length) { - Object[] expected = rows[i++]; + Object[] expected = rows[i]; UntypedResultSet.Row actual = iter.next(); Assert.assertEquals(String.format("Invalid number of (expected) values provided for row %d", i), meta.size(), expected.length); @@ -278,6 +319,7 @@ public abstract class CQLTester Assert.fail(String.format("Invalid value for row %d column %d (%s of type %s), expected <%s> but got <%s>", i, j, column.name, column.type.asCQL3Type(), formatValue(expectedByteValue, column.type), formatValue(actualValue, column.type))); } + i++; } if (iter.hasNext()) @@ -311,6 +353,11 @@ public abstract class CQLTester protected void assertInvalid(String query, Object... values) throws Throwable { + assertInvalidMessage(null, query, values); + } + + protected void assertInvalidMessage(String errorMessage, String query, Object... values) throws Throwable + { try { execute(query, values); @@ -321,7 +368,11 @@ public abstract class CQLTester } catch (InvalidRequestException e) { - // This is what we expect + if (errorMessage != null) + { + Assert.assertTrue("Expected error message to contain '" + errorMessage + "', but got '" + e.getMessage() + "'", + e.getMessage().contains(errorMessage)); + } } } @@ -401,7 +452,15 @@ public abstract class CQLTester continue; } - buffers[i] = typeFor(value).decompose(serializeTuples(value)); + try + { + buffers[i] = typeFor(value).decompose(serializeTuples(value)); + } + catch (Exception ex) + { + logger.info("Error serializing query parameter {}:", value, ex); + throw ex; + } } return buffers; } @@ -613,14 +672,14 @@ public abstract class CQLTester { List l = (List)value; AbstractType elt = l.isEmpty() ? BytesType.instance : typeFor(l.get(0)); - return ListType.getInstance(elt); + return ListType.getInstance(elt, true); } if (value instanceof Set) { Set s = (Set)value; AbstractType elt = s.isEmpty() ? BytesType.instance : typeFor(s.iterator().next()); - return SetType.getInstance(elt); + return SetType.getInstance(elt, true); } if (value instanceof Map) @@ -638,7 +697,7 @@ public abstract class CQLTester keys = typeFor(entry.getKey()); values = typeFor(entry.getValue()); } - return MapType.getInstance(keys, values); + return MapType.getInstance(keys, values, true); } throw new IllegalArgumentException("Unsupported value type (value is " + value + ")"); @@ -674,5 +733,10 @@ public abstract class CQLTester sb.append(")"); return sb.toString(); } + + public String toString() + { + return "TupleValue" + toCQLString(); + } } } http://git-wip-us.apache.org/repos/asf/cassandra/blob/ee55f361/test/unit/org/apache/cassandra/cql3/ColumnConditionTest.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/cql3/ColumnConditionTest.java b/test/unit/org/apache/cassandra/cql3/ColumnConditionTest.java index 205babc..3b1a826 100644 --- a/test/unit/org/apache/cassandra/cql3/ColumnConditionTest.java +++ b/test/unit/org/apache/cassandra/cql3/ColumnConditionTest.java @@ -154,9 +154,9 @@ public class ColumnConditionTest { CFMetaData cfm = CFMetaData.compile("create table foo(a int PRIMARY KEY, b int, c list<int>)", "ks"); Map<ByteBuffer, CollectionType> typeMap = new HashMap<>(); - typeMap.put(ByteBufferUtil.bytes("c"), ListType.getInstance(Int32Type.instance)); + typeMap.put(ByteBufferUtil.bytes("c"), ListType.getInstance(Int32Type.instance, true)); CompoundSparseCellNameType.WithCollection nameType = new CompoundSparseCellNameType.WithCollection(Collections.EMPTY_LIST, ColumnToCollectionType.getInstance(typeMap)); - ColumnDefinition definition = new ColumnDefinition(cfm, ByteBufferUtil.bytes("c"), ListType.getInstance(Int32Type.instance), 0, ColumnDefinition.Kind.REGULAR); + ColumnDefinition definition = new ColumnDefinition(cfm, ByteBufferUtil.bytes("c"), ListType.getInstance(Int32Type.instance, true), 0, ColumnDefinition.Kind.REGULAR); List<Cell> cells = new ArrayList<>(columnValues.size()); if (columnValues != null) @@ -169,14 +169,14 @@ public class ColumnConditionTest }; } - return bound.listAppliesTo(ListType.getInstance(Int32Type.instance), cells == null ? null : cells.iterator(), conditionValues, bound.operator); + return bound.listAppliesTo(ListType.getInstance(Int32Type.instance, true), cells == null ? null : cells.iterator(), conditionValues, bound.operator); } @Test // sets use the same check as lists public void testListCollectionBoundAppliesTo() throws InvalidRequestException { - ColumnDefinition definition = new ColumnDefinition("ks", "cf", new ColumnIdentifier("c", true), ListType.getInstance(Int32Type.instance), null, null, null, null, null); + ColumnDefinition definition = new ColumnDefinition("ks", "cf", new ColumnIdentifier("c", true), ListType.getInstance(Int32Type.instance, true), null, null, null, null, null); // EQ ColumnCondition condition = ColumnCondition.condition(definition, null, new Lists.Value(Arrays.asList(ONE)), Operator.EQ); @@ -275,9 +275,9 @@ public class ColumnConditionTest assertTrue(listAppliesTo(bound, list(ByteBufferUtil.EMPTY_BYTE_BUFFER), list(ByteBufferUtil.EMPTY_BYTE_BUFFER))); } - private static Set<ByteBuffer> set(ByteBuffer... values) + private static SortedSet<ByteBuffer> set(ByteBuffer... values) { - Set results = new HashSet<ByteBuffer>(values.length); + SortedSet<ByteBuffer> results = new TreeSet<>(Int32Type.instance); results.addAll(Arrays.asList(values)); return results; } @@ -286,9 +286,9 @@ public class ColumnConditionTest { CFMetaData cfm = CFMetaData.compile("create table foo(a int PRIMARY KEY, b int, c set<int>)", "ks"); Map<ByteBuffer, CollectionType> typeMap = new HashMap<>(); - typeMap.put(ByteBufferUtil.bytes("c"), SetType.getInstance(Int32Type.instance)); + typeMap.put(ByteBufferUtil.bytes("c"), SetType.getInstance(Int32Type.instance, true)); CompoundSparseCellNameType.WithCollection nameType = new CompoundSparseCellNameType.WithCollection(Collections.EMPTY_LIST, ColumnToCollectionType.getInstance(typeMap)); - ColumnDefinition definition = new ColumnDefinition(cfm, ByteBufferUtil.bytes("c"), SetType.getInstance(Int32Type.instance), 0, ColumnDefinition.Kind.REGULAR); + ColumnDefinition definition = new ColumnDefinition(cfm, ByteBufferUtil.bytes("c"), SetType.getInstance(Int32Type.instance, true), 0, ColumnDefinition.Kind.REGULAR); List<Cell> cells = new ArrayList<>(columnValues.size()); if (columnValues != null) @@ -300,13 +300,13 @@ public class ColumnConditionTest }; } - return bound.setAppliesTo(SetType.getInstance(Int32Type.instance), cells == null ? null : cells.iterator(), conditionValues, bound.operator); + return bound.setAppliesTo(SetType.getInstance(Int32Type.instance, true), cells == null ? null : cells.iterator(), conditionValues, bound.operator); } @Test public void testSetCollectionBoundAppliesTo() throws InvalidRequestException { - ColumnDefinition definition = new ColumnDefinition("ks", "cf", new ColumnIdentifier("c", true), SetType.getInstance(Int32Type.instance), null, null, null, null, null); + ColumnDefinition definition = new ColumnDefinition("ks", "cf", new ColumnIdentifier("c", true), SetType.getInstance(Int32Type.instance, true), null, null, null, null, null); // EQ ColumnCondition condition = ColumnCondition.condition(definition, null, new Sets.Value(set(ONE)), Operator.EQ); @@ -419,9 +419,9 @@ public class ColumnConditionTest { CFMetaData cfm = CFMetaData.compile("create table foo(a int PRIMARY KEY, b map<int, int>)", "ks"); Map<ByteBuffer, CollectionType> typeMap = new HashMap<>(); - typeMap.put(ByteBufferUtil.bytes("b"), MapType.getInstance(Int32Type.instance, Int32Type.instance)); + typeMap.put(ByteBufferUtil.bytes("b"), MapType.getInstance(Int32Type.instance, Int32Type.instance, true)); CompoundSparseCellNameType.WithCollection nameType = new CompoundSparseCellNameType.WithCollection(Collections.EMPTY_LIST, ColumnToCollectionType.getInstance(typeMap)); - ColumnDefinition definition = new ColumnDefinition(cfm, ByteBufferUtil.bytes("b"), MapType.getInstance(Int32Type.instance, Int32Type.instance), 0, ColumnDefinition.Kind.REGULAR); + ColumnDefinition definition = new ColumnDefinition(cfm, ByteBufferUtil.bytes("b"), MapType.getInstance(Int32Type.instance, Int32Type.instance, true), 0, ColumnDefinition.Kind.REGULAR); List<Cell> cells = new ArrayList<>(columnValues.size()); if (columnValues != null) @@ -430,13 +430,13 @@ public class ColumnConditionTest cells.add(new BufferCell(nameType.create(Composites.EMPTY, definition, entry.getKey()), entry.getValue())); } - return bound.mapAppliesTo(MapType.getInstance(Int32Type.instance, Int32Type.instance), cells.iterator(), conditionValues, bound.operator); + return bound.mapAppliesTo(MapType.getInstance(Int32Type.instance, Int32Type.instance, true), cells.iterator(), conditionValues, bound.operator); } @Test public void testMapCollectionBoundIsSatisfiedByValue() throws InvalidRequestException { - ColumnDefinition definition = new ColumnDefinition("ks", "cf", new ColumnIdentifier("b", true), MapType.getInstance(Int32Type.instance, Int32Type.instance), null, null, null, null, null); + ColumnDefinition definition = new ColumnDefinition("ks", "cf", new ColumnIdentifier("b", true), MapType.getInstance(Int32Type.instance, Int32Type.instance, true), null, null, null, null, null); Map<ByteBuffer, ByteBuffer> placeholderMap = new TreeMap<>(); placeholderMap.put(ONE, ONE); http://git-wip-us.apache.org/repos/asf/cassandra/blob/ee55f361/test/unit/org/apache/cassandra/cql3/FrozenCollectionsTest.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/cql3/FrozenCollectionsTest.java b/test/unit/org/apache/cassandra/cql3/FrozenCollectionsTest.java new file mode 100644 index 0000000..203adae --- /dev/null +++ b/test/unit/org/apache/cassandra/cql3/FrozenCollectionsTest.java @@ -0,0 +1,791 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.cassandra.cql3; + +import org.apache.cassandra.db.marshal.*; +import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.cassandra.exceptions.InvalidRequestException; +import org.apache.cassandra.exceptions.SyntaxException; +import org.apache.commons.lang3.StringUtils; +import org.junit.Assert; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.assertEquals; + +public class FrozenCollectionsTest extends CQLTester +{ + @Test + public void testPartitionKeyUsage() throws Throwable + { + createTable("CREATE TABLE %s (k frozen<set<int>> PRIMARY KEY, v int)"); + + execute("INSERT INTO %s (k, v) VALUES (?, ?)", set(), 1); + execute("INSERT INTO %s (k, v) VALUES (?, ?)", set(1, 2, 3), 1); + execute("INSERT INTO %s (k, v) VALUES (?, ?)", set(4, 5, 6), 0); + execute("INSERT INTO %s (k, v) VALUES (?, ?)", set(7, 8, 9), 0); + + // overwrite with an update + execute("UPDATE %s SET v=? WHERE k=?", 0, set()); + execute("UPDATE %s SET v=? WHERE k=?", 0, set(1, 2, 3)); + + assertRows(execute("SELECT * FROM %s"), + row(set(), 0), + row(set(1, 2, 3), 0), + row(set(4, 5, 6), 0), + row(set(7, 8, 9), 0) + ); + + assertRows(execute("SELECT k FROM %s"), + row(set()), + row(set(1, 2, 3)), + row(set(4, 5, 6)), + row(set(7, 8, 9)) + ); + + assertRows(execute("SELECT * FROM %s LIMIT 2"), + row(set(), 0), + row(set(1, 2, 3), 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE k=?", set(4, 5, 6)), + row(set(4, 5, 6), 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE k=?", set()), + row(set(), 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE k IN ?", list(set(4, 5, 6), set())), + row(set(4, 5, 6), 0), + row(set(), 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE token(k) >= token(?)", set(4, 5, 6)), + row(set(4, 5, 6), 0), + row(set(7, 8, 9), 0) + ); + + assertInvalid("INSERT INTO %s (k, v) VALUES (null, 0)"); + + execute("DELETE FROM %s WHERE k=?", set()); + execute("DELETE FROM %s WHERE k=?", set(4, 5, 6)); + assertRows(execute("SELECT * FROM %s"), + row(set(1, 2, 3), 0), + row(set(7, 8, 9), 0) + ); + } + + @Test + public void testNestedPartitionKeyUsage() throws Throwable + { + createTable("CREATE TABLE %s (k frozen<map<set<int>, list<int>>> PRIMARY KEY, v int)"); + + execute("INSERT INTO %s (k, v) VALUES (?, ?)", map(), 1); + execute("INSERT INTO %s (k, v) VALUES (?, ?)", map(set(), list(1, 2, 3)), 0); + execute("INSERT INTO %s (k, v) VALUES (?, ?)", map(set(1, 2, 3), list(1, 2, 3)), 1); + execute("INSERT INTO %s (k, v) VALUES (?, ?)", map(set(4, 5, 6), list(1, 2, 3)), 0); + execute("INSERT INTO %s (k, v) VALUES (?, ?)", map(set(7, 8, 9), list(1, 2, 3)), 0); + + // overwrite with an update + execute("UPDATE %s SET v=? WHERE k=?", 0, map()); + execute("UPDATE %s SET v=? WHERE k=?", 0, map(set(1, 2, 3), list(1, 2, 3))); + + assertRows(execute("SELECT * FROM %s"), + row(map(), 0), + row(map(set(), list(1, 2, 3)), 0), + row(map(set(1, 2, 3), list(1, 2, 3)), 0), + row(map(set(4, 5, 6), list(1, 2, 3)), 0), + row(map(set(7, 8, 9), list(1, 2, 3)), 0) + ); + + assertRows(execute("SELECT k FROM %s"), + row(map()), + row(map(set(), list(1, 2, 3))), + row(map(set(1, 2, 3), list(1, 2, 3))), + row(map(set(4, 5, 6), list(1, 2, 3))), + row(map(set(7, 8, 9), list(1, 2, 3))) + ); + + assertRows(execute("SELECT * FROM %s LIMIT 3"), + row(map(), 0), + row(map(set(), list(1, 2, 3)), 0), + row(map(set(1, 2, 3), list(1, 2, 3)), 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE k=?", map(set(4, 5, 6), list(1, 2, 3))), + row(map(set(4, 5, 6), list(1, 2, 3)), 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE k=?", map()), + row(map(), 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE k=?", map(set(), list(1, 2, 3))), + row(map(set(), list(1, 2, 3)), 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE k IN ?", list(map(set(4, 5, 6), list(1, 2, 3)), map(), map(set(), list(1, 2, 3)))), + row(map(set(4, 5, 6), list(1, 2, 3)), 0), + row(map(), 0), + row(map(set(), list(1, 2, 3)), 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE token(k) >= token(?)", map(set(4, 5, 6), list(1, 2, 3))), + row(map(set(4, 5, 6), list(1, 2, 3)), 0), + row(map(set(7, 8, 9), list(1, 2, 3)), 0) + ); + + execute("DELETE FROM %s WHERE k=?", map()); + execute("DELETE FROM %s WHERE k=?", map(set(), list(1, 2, 3))); + execute("DELETE FROM %s WHERE k=?", map(set(4, 5, 6), list(1, 2, 3))); + assertRows(execute("SELECT * FROM %s"), + row(map(set(1, 2, 3), list(1, 2, 3)), 0), + row(map(set(7, 8, 9), list(1, 2, 3)), 0) + ); + + } + + @Test + public void testClusteringKeyUsage() throws Throwable + { + for (String option : Arrays.asList("", " WITH COMPACT STORAGE")) + { + createTable("CREATE TABLE %s (a int, b frozen<set<int>>, c int, PRIMARY KEY (a, b))" + option); + + execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 0, set(), 1); + execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 0, set(1, 2, 3), 1); + execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 0, set(4, 5, 6), 0); + execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 0, set(7, 8, 9), 0); + + // overwrite with an update + execute("UPDATE %s SET c=? WHERE a=? AND b=?", 0, 0, set()); + execute("UPDATE %s SET c=? WHERE a=? AND b=?", 0, 0, set(1, 2, 3)); + + assertRows(execute("SELECT * FROM %s"), + row(0, set(), 0), + row(0, set(1, 2, 3), 0), + row(0, set(4, 5, 6), 0), + row(0, set(7, 8, 9), 0) + ); + + assertRows(execute("SELECT b FROM %s"), + row(set()), + row(set(1, 2, 3)), + row(set(4, 5, 6)), + row(set(7, 8, 9)) + ); + + assertRows(execute("SELECT * FROM %s LIMIT 2"), + row(0, set(), 0), + row(0, set(1, 2, 3), 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a=? AND b=?", 0, set(4, 5, 6)), + row(0, set(4, 5, 6), 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a=? AND b=?", 0, set()), + row(0, set(), 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a=? AND b IN ?", 0, list(set(4, 5, 6), set())), + row(0, set(), 0), + row(0, set(4, 5, 6), 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a=? AND b > ?", 0, set(4, 5, 6)), + row(0, set(7, 8, 9), 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a=? AND b >= ?", 0, set(4, 5, 6)), + row(0, set(4, 5, 6), 0), + row(0, set(7, 8, 9), 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a=? AND b < ?", 0, set(4, 5, 6)), + row(0, set(), 0), + row(0, set(1, 2, 3), 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a=? AND b <= ?", 0, set(4, 5, 6)), + row(0, set(), 0), + row(0, set(1, 2, 3), 0), + row(0, set(4, 5, 6), 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a=? AND b > ? AND b <= ?", 0, set(1, 2, 3), set(4, 5, 6)), + row(0, set(4, 5, 6), 0) + ); + + execute("DELETE FROM %s WHERE a=? AND b=?", 0, set()); + execute("DELETE FROM %s WHERE a=? AND b=?", 0, set(4, 5, 6)); + assertRows(execute("SELECT * FROM %s"), + row(0, set(1, 2, 3), 0), + row(0, set(7, 8, 9), 0) + ); + } + } + + @Test + public void testNestedClusteringKeyUsage() throws Throwable + { + for (String option : Arrays.asList("", " WITH COMPACT STORAGE")) + { + createTable("CREATE TABLE %s (a int, b frozen<map<set<int>, list<int>>>, c frozen<set<int>>, d int, PRIMARY KEY (a, b, c))" + option); + + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, map(), set(), 0); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, map(set(), list(1, 2, 3)), set(), 0); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, map(set(1, 2, 3), list(1, 2, 3)), set(1, 2, 3), 0); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, map(set(4, 5, 6), list(1, 2, 3)), set(1, 2, 3), 0); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, map(set(7, 8, 9), list(1, 2, 3)), set(1, 2, 3), 0); + + assertRows(execute("SELECT * FROM %s"), + row(0, map(), set(), 0), + row(0, map(set(), list(1, 2, 3)), set(), 0), + row(0, map(set(1, 2, 3), list(1, 2, 3)), set(1, 2, 3), 0), + row(0, map(set(4, 5, 6), list(1, 2, 3)), set(1, 2, 3), 0), + row(0, map(set(7, 8, 9), list(1, 2, 3)), set(1, 2, 3), 0) + ); + + assertRows(execute("SELECT b FROM %s"), + row(map()), + row(map(set(), list(1, 2, 3))), + row(map(set(1, 2, 3), list(1, 2, 3))), + row(map(set(4, 5, 6), list(1, 2, 3))), + row(map(set(7, 8, 9), list(1, 2, 3))) + ); + + assertRows(execute("SELECT c FROM %s"), + row(set()), + row(set()), + row(set(1, 2, 3)), + row(set(1, 2, 3)), + row(set(1, 2, 3)) + ); + + assertRows(execute("SELECT * FROM %s LIMIT 3"), + row(0, map(), set(), 0), + row(0, map(set(), list(1, 2, 3)), set(), 0), + row(0, map(set(1, 2, 3), list(1, 2, 3)), set(1, 2, 3), 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a=0 ORDER BY b DESC LIMIT 4"), + row(0, map(set(7, 8, 9), list(1, 2, 3)), set(1, 2, 3), 0), + row(0, map(set(4, 5, 6), list(1, 2, 3)), set(1, 2, 3), 0), + row(0, map(set(1, 2, 3), list(1, 2, 3)), set(1, 2, 3), 0), + row(0, map(set(), list(1, 2, 3)), set(), 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a=? AND b=?", 0, map()), + row(0, map(), set(), 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a=? AND b=?", 0, map(set(), list(1, 2, 3))), + row(0, map(set(), list(1, 2, 3)), set(), 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a=? AND b=?", 0, map(set(1, 2, 3), list(1, 2, 3))), + row(0, map(set(1, 2, 3), list(1, 2, 3)), set(1, 2, 3), 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a=? AND b=? AND c=?", 0, map(set(), list(1, 2, 3)), set()), + row(0, map(set(), list(1, 2, 3)), set(), 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a=? AND (b, c) IN ?", 0, list(tuple(map(set(4, 5, 6), list(1, 2, 3)), set(1, 2, 3)), + tuple(map(), set()))), + row(0, map(), set(), 0), + row(0, map(set(4, 5, 6), list(1, 2, 3)), set(1, 2, 3), 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a=? AND b > ?", 0, map(set(4, 5, 6), list(1, 2, 3))), + row(0, map(set(7, 8, 9), list(1, 2, 3)), set(1, 2, 3), 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a=? AND b >= ?", 0, map(set(4, 5, 6), list(1, 2, 3))), + row(0, map(set(4, 5, 6), list(1, 2, 3)), set(1, 2, 3), 0), + row(0, map(set(7, 8, 9), list(1, 2, 3)), set(1, 2, 3), 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a=? AND b < ?", 0, map(set(4, 5, 6), list(1, 2, 3))), + row(0, map(), set(), 0), + row(0, map(set(), list(1, 2, 3)), set(), 0), + row(0, map(set(1, 2, 3), list(1, 2, 3)), set(1, 2, 3), 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a=? AND b <= ?", 0, map(set(4, 5, 6), list(1, 2, 3))), + row(0, map(), set(), 0), + row(0, map(set(), list(1, 2, 3)), set(), 0), + row(0, map(set(1, 2, 3), list(1, 2, 3)), set(1, 2, 3), 0), + row(0, map(set(4, 5, 6), list(1, 2, 3)), set(1, 2, 3), 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a=? AND b > ? AND b <= ?", 0, map(set(1, 2, 3), list(1, 2, 3)), map(set(4, 5, 6), list(1, 2, 3))), + row(0, map(set(4, 5, 6), list(1, 2, 3)), set(1, 2, 3), 0) + ); + + execute("DELETE FROM %s WHERE a=? AND b=? AND c=?", 0, map(), set()); + assertEmpty(execute("SELECT * FROM %s WHERE a=? AND b=? AND c=?", 0, map(), set())); + + execute("DELETE FROM %s WHERE a=? AND b=? AND c=?", 0, map(set(), list(1, 2, 3)), set()); + assertEmpty(execute("SELECT * FROM %s WHERE a=? AND b=? AND c=?", 0, map(set(), list(1, 2, 3)), set())); + + execute("DELETE FROM %s WHERE a=? AND b=? AND c=?", 0, map(set(4, 5, 6), list(1, 2, 3)), set(1, 2, 3)); + assertEmpty(execute("SELECT * FROM %s WHERE a=? AND b=? AND c=?", 0, map(set(4, 5, 6), list(1, 2, 3)), set(1, 2, 3))); + + assertRows(execute("SELECT * FROM %s"), + row(0, map(set(1, 2, 3), list(1, 2, 3)), set(1, 2, 3), 0), + row(0, map(set(7, 8, 9), list(1, 2, 3)), set(1, 2, 3), 0) + ); + } + } + + @Test + public void testNormalColumnUsage() throws Throwable + { + for (String option : Arrays.asList("", " WITH COMPACT STORAGE")) + { + createTable("CREATE TABLE %s (a int PRIMARY KEY, b frozen<map<set<int>, list<int>>>, c frozen<set<int>>)" + option); + + execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 0, map(), set()); + execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 1, map(set(), list(99999, 999999, 99999)), set()); + execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 2, map(set(1, 2, 3), list(1, 2, 3)), set(1, 2, 3)); + execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 3, map(set(4, 5, 6), list(1, 2, 3)), set(1, 2, 3)); + execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 4, map(set(7, 8, 9), list(1, 2, 3)), set(1, 2, 3)); + + // overwrite with update + execute ("UPDATE %s SET b=? WHERE a=?", map(set(), list(1, 2, 3)), 1); + + assertRows(execute("SELECT * FROM %s"), + row(0, map(), set()), + row(1, map(set(), list(1, 2, 3)), set()), + row(2, map(set(1, 2, 3), list(1, 2, 3)), set(1, 2, 3)), + row(3, map(set(4, 5, 6), list(1, 2, 3)), set(1, 2, 3)), + row(4, map(set(7, 8, 9), list(1, 2, 3)), set(1, 2, 3)) + ); + + assertRows(execute("SELECT b FROM %s"), + row(map()), + row(map(set(), list(1, 2, 3))), + row(map(set(1, 2, 3), list(1, 2, 3))), + row(map(set(4, 5, 6), list(1, 2, 3))), + row(map(set(7, 8, 9), list(1, 2, 3))) + ); + + assertRows(execute("SELECT c FROM %s"), + row(set()), + row(set()), + row(set(1, 2, 3)), + row(set(1, 2, 3)), + row(set(1, 2, 3)) + ); + + assertRows(execute("SELECT * FROM %s WHERE a=?", 3), + row(3, map(set(4, 5, 6), list(1, 2, 3)), set(1, 2, 3)) + ); + + execute("UPDATE %s SET b=? WHERE a=?", null, 1); + assertRows(execute("SELECT * FROM %s WHERE a=?", 1), + row(1, null, set()) + ); + + execute("UPDATE %s SET b=? WHERE a=?", map(), 1); + assertRows(execute("SELECT * FROM %s WHERE a=?", 1), + row(1, map(), set()) + ); + + execute("UPDATE %s SET c=? WHERE a=?", null, 2); + assertRows(execute("SELECT * FROM %s WHERE a=?", 2), + row(2, map(set(1, 2, 3), list(1, 2, 3)), null) + ); + + execute("UPDATE %s SET c=? WHERE a=?", set(), 2); + assertRows(execute("SELECT * FROM %s WHERE a=?", 2), + row(2, map(set(1, 2, 3), list(1, 2, 3)), set()) + ); + + execute("DELETE b FROM %s WHERE a=?", 3); + assertRows(execute("SELECT * FROM %s WHERE a=?", 3), + row(3, null, set(1, 2, 3)) + ); + + execute("DELETE c FROM %s WHERE a=?", 4); + assertRows(execute("SELECT * FROM %s WHERE a=?", 4), + row(4, map(set(7, 8, 9), list(1, 2, 3)), null) + ); + } + } + + @Test + public void testStaticColumnUsage() throws Throwable + { + createTable("CREATE TABLE %s (a int, b int, c frozen<map<set<int>, list<int>>> static, d int, PRIMARY KEY (a, b))"); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, map(), 0); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, map(), 0); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 1, 0, map(set(), list(1, 2, 3)), 0); + execute("INSERT INTO %s (a, b, d) VALUES (?, ?, ?)", 1, 1, 0); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 2, 0, map(set(1, 2, 3), list(1, 2, 3)), 0); + + assertRows(execute("SELECT * FROM %s"), + row(0, 0, map(), 0), + row(0, 1, map(), 0), + row(1, 0, map(set(), list(1, 2, 3)), 0), + row(1, 1, map(set(), list(1, 2, 3)), 0), + row(2, 0, map(set(1, 2, 3), list(1, 2, 3)), 0) + ); + + assertRows(execute("SELECT * FROM %s WHERE a=? AND b=?", 0, 1), + row(0, 1, map(), 0) + ); + + execute("DELETE c FROM %s WHERE a=?", 0); + assertRows(execute("SELECT * FROM %s"), + row(0, 0, null, 0), + row(0, 1, null, 0), + row(1, 0, map(set(), list(1, 2, 3)), 0), + row(1, 1, map(set(), list(1, 2, 3)), 0), + row(2, 0, map(set(1, 2, 3), list(1, 2, 3)), 0) + ); + + execute("DELETE FROM %s WHERE a=?", 0); + assertRows(execute("SELECT * FROM %s"), + row(1, 0, map(set(), list(1, 2, 3)), 0), + row(1, 1, map(set(), list(1, 2, 3)), 0), + row(2, 0, map(set(1, 2, 3), list(1, 2, 3)), 0) + ); + + execute("UPDATE %s SET c=? WHERE a=?", map(set(1, 2, 3), list(1, 2, 3)), 1); + assertRows(execute("SELECT * FROM %s"), + row(1, 0, map(set(1, 2, 3), list(1, 2, 3)), 0), + row(1, 1, map(set(1, 2, 3), list(1, 2, 3)), 0), + row(2, 0, map(set(1, 2, 3), list(1, 2, 3)), 0) + ); + } + + private void assertInvalidCreateWithMessage(String createTableStatement, String errorMessage) throws Throwable + { + try + { + createTableMayThrow(createTableStatement); + Assert.fail("Expected CREATE TABLE statement to error: " + createTableStatement); + } + catch (InvalidRequestException | ConfigurationException | SyntaxException ex) + { + Assert.assertTrue("Expected error message to contain '" + errorMessage + "', but got '" + ex.getMessage() + "'", + ex.getMessage().contains(errorMessage)); + } + } + + private void assertInvalidAlterWithMessage(String createTableStatement, String errorMessage) throws Throwable + { + try + { + alterTableMayThrow(createTableStatement); + Assert.fail("Expected CREATE TABLE statement to error: " + createTableStatement); + } + catch (InvalidRequestException | ConfigurationException ex) + { + Assert.assertTrue("Expected error message to contain '" + errorMessage + "', but got '" + ex.getMessage() + "'", + ex.getMessage().contains(errorMessage)); + } + } + + @Test + public void testInvalidOperations() throws Throwable + { + // lists + createTable("CREATE TABLE %s (k int PRIMARY KEY, l frozen<list<int>>)"); + assertInvalid("UPDATE %s SET l[?]=? WHERE k=?", 0, 0, 0); + assertInvalid("UPDATE %s SET l = ? + l WHERE k=?", list(0), 0); + assertInvalid("UPDATE %s SET l = l + ? WHERE k=?", list(4), 0); + assertInvalid("UPDATE %s SET l = l - ? WHERE k=?", list(3), 0); + assertInvalid("DELETE l[?] FROM %s WHERE k=?", 0, 0); + + // sets + createTable("CREATE TABLE %s (k int PRIMARY KEY, s frozen<set<int>>)"); + assertInvalid("UPDATE %s SET s = s + ? WHERE k=?", set(0), 0); + assertInvalid("UPDATE %s SET s = s - ? WHERE k=?", set(3), 0); + + // maps + createTable("CREATE TABLE %s (k int PRIMARY KEY, m frozen<map<int, int>>)"); + assertInvalid("UPDATE %s SET m[?]=? WHERE k=?", 0, 0, 0); + assertInvalid("UPDATE %s SET m = m + ? WHERE k=?", map(4, 4), 0); + assertInvalid("DELETE m[?] FROM %s WHERE k=?", 0, 0); + + assertInvalidCreateWithMessage("CREATE TABLE %s (k int PRIMARY KEY, t set<set<int>>)", + "Non-frozen collections are not allowed inside collections"); + + assertInvalidCreateWithMessage("CREATE TABLE %s (k int PRIMARY KEY, t frozen<set<counter>>)", + "Counters are not allowed inside collections"); + + assertInvalidCreateWithMessage("CREATE TABLE %s (k int PRIMARY KEY, t frozen<text>)", + "frozen<> is only allowed on collections, tuples, and user-defined types"); + } + + @Test + public void testAltering() throws Throwable + { + createTable("CREATE TABLE %s (a int, b frozen<list<int>>, c frozen<list<int>>, PRIMARY KEY (a, b))"); + + alterTable("ALTER TABLE %s ALTER c TYPE frozen<list<blob>>"); + + assertInvalidAlterWithMessage("ALTER TABLE %s ALTER b TYPE frozen<list<blob>>", + "types are not order-compatible"); + + assertInvalidAlterWithMessage("ALTER TABLE %s ALTER b TYPE list<int>", + "types are not order-compatible"); + + assertInvalidAlterWithMessage("ALTER TABLE %s ALTER c TYPE list<blob>", + "types are incompatible"); + + alterTable("ALTER TABLE %s DROP c"); + alterTable("ALTER TABLE %s ADD c frozen<set<int>>"); + assertInvalidAlterWithMessage("ALTER TABLE %s ALTER c TYPE frozen<set<blob>>", + "types are incompatible"); + + alterTable("ALTER TABLE %s DROP c"); + alterTable("ALTER TABLE %s ADD c frozen<map<int, int>>"); + assertInvalidAlterWithMessage("ALTER TABLE %s ALTER c TYPE frozen<map<blob, int>>", + "types are incompatible"); + alterTable("ALTER TABLE %s ALTER c TYPE frozen<map<int, blob>>"); + } + + private void assertInvalidIndexCreationWithMessage(String statement, String errorMessage) throws Throwable + { + try + { + createIndexMayThrow(statement); + Assert.fail("Expected index creation to fail: " + statement); + } + catch (InvalidRequestException ex) + { + Assert.assertTrue("Expected error message to contain '" + errorMessage + "', but got '" + ex.getMessage() + "'", + ex.getMessage().contains(errorMessage)); + } + } + + @Test + public void testSecondaryIndex() throws Throwable + { + createTable("CREATE TABLE %s (a frozen<map<int, text>> PRIMARY KEY, b frozen<map<int, text>>)"); + + // for now, we don't support indexing values or keys of collections in the primary key + assertInvalidIndexCreationWithMessage("CREATE INDEX ON %s (full(a))", "Cannot create secondary index on partition key column"); + assertInvalidIndexCreationWithMessage("CREATE INDEX ON %s (keys(a))", "Cannot create index on keys of frozen<map> column"); + assertInvalidIndexCreationWithMessage("CREATE INDEX ON %s (keys(b))", "Cannot create index on keys of frozen<map> column"); + + createTable("CREATE TABLE %s (a int, b frozen<list<int>>, c frozen<set<int>>, d frozen<map<int, text>>, PRIMARY KEY (a, b))"); + + createIndex("CREATE INDEX ON %s (full(b))"); + createIndex("CREATE INDEX ON %s (full(c))"); + createIndex("CREATE INDEX ON %s (full(d))"); + + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, list(1, 2, 3), set(1, 2, 3), map(1, "a")); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, list(4, 5, 6), set(1, 2, 3), map(1, "a")); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 1, list(1, 2, 3), set(4, 5, 6), map(2, "b")); + execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 1, list(4, 5, 6), set(4, 5, 6), map(2, "b")); + + // CONTAINS KEY doesn't work on non-maps + assertInvalidMessage("Cannot use CONTAINS KEY on non-map column", + "SELECT * FROM %s WHERE b CONTAINS KEY ?", 1); + + assertInvalidMessage("Cannot use CONTAINS KEY on non-map column", + "SELECT * FROM %s WHERE b CONTAINS KEY ? ALLOW FILTERING", 1); + + assertInvalidMessage("Cannot use CONTAINS KEY on non-map column", + "SELECT * FROM %s WHERE c CONTAINS KEY ?", 1); + + // normal indexes on frozen collections don't support CONTAINS or CONTAINS KEY + assertInvalidMessage("No secondary indexes on the restricted columns support the provided operator", + "SELECT * FROM %s WHERE b CONTAINS ?", 1); + + assertInvalidMessage("No secondary indexes on the restricted columns support the provided operator", + "SELECT * FROM %s WHERE b CONTAINS ? ALLOW FILTERING", 1); + + assertInvalidMessage("No secondary indexes on the restricted columns support the provided operator", + "SELECT * FROM %s WHERE d CONTAINS KEY ?", 1); + + assertInvalidMessage("No secondary indexes on the restricted columns support the provided operator", + "SELECT * FROM %s WHERE d CONTAINS KEY ? ALLOW FILTERING", 1); + + assertInvalidMessage("No secondary indexes on the restricted columns support the provided operator", + "SELECT * FROM %s WHERE b CONTAINS ? AND d CONTAINS KEY ? ALLOW FILTERING", 1, 1); + + // index lookup on b + assertRows(execute("SELECT * FROM %s WHERE b=?", list(1, 2, 3)), + row(0, list(1, 2, 3), set(1, 2, 3), map(1, "a")), + row(1, list(1, 2, 3), set(4, 5, 6), map(2, "b")) + ); + + assertEmpty(execute("SELECT * FROM %s WHERE b=?", list(-1))); + + assertInvalidMessage("ALLOW FILTERING", "SELECT * FROM %s WHERE b=? AND c=?", list(1, 2, 3), set(4, 5, 6)); + assertRows(execute("SELECT * FROM %s WHERE b=? AND c=? ALLOW FILTERING", list(1, 2, 3), set(4, 5, 6)), + row(1, list(1, 2, 3), set(4, 5, 6), map(2, "b")) + ); + + assertInvalidMessage("ALLOW FILTERING", "SELECT * FROM %s WHERE b=? AND c CONTAINS ?", list(1, 2, 3), 5); + assertRows(execute("SELECT * FROM %s WHERE b=? AND c CONTAINS ? ALLOW FILTERING", list(1, 2, 3), 5), + row(1, list(1, 2, 3), set(4, 5, 6), map(2, "b")) + ); + + assertInvalidMessage("ALLOW FILTERING", "SELECT * FROM %s WHERE b=? AND d=?", list(1, 2, 3), map(1, "a")); + assertRows(execute("SELECT * FROM %s WHERE b=? AND d=? ALLOW FILTERING", list(1, 2, 3), map(1, "a")), + row(0, list(1, 2, 3), set(1, 2, 3), map(1, "a")) + ); + + assertInvalidMessage("ALLOW FILTERING", "SELECT * FROM %s WHERE b=? AND d CONTAINS ?", list(1, 2, 3), "a"); + assertRows(execute("SELECT * FROM %s WHERE b=? AND d CONTAINS ? ALLOW FILTERING", list(1, 2, 3), "a"), + row(0, list(1, 2, 3), set(1, 2, 3), map(1, "a")) + ); + + assertInvalidMessage("ALLOW FILTERING", "SELECT * FROM %s WHERE b=? AND d CONTAINS KEY ?", list(1, 2, 3), 1); + assertRows(execute("SELECT * FROM %s WHERE b=? AND d CONTAINS KEY ? ALLOW FILTERING", list(1, 2, 3), 1), + row(0, list(1, 2, 3), set(1, 2, 3), map(1, "a")) + ); + + // index lookup on c + assertRows(execute("SELECT * FROM %s WHERE c=?", set(1, 2, 3)), + row(0, list(1, 2, 3), set(1, 2, 3), map(1, "a")), + row(0, list(4, 5, 6), set(1, 2, 3), map(1, "a")) + ); + + // ordering of c should not matter + assertRows(execute("SELECT * FROM %s WHERE c=?", set(2, 1, 3)), + row(0, list(1, 2, 3), set(1, 2, 3), map(1, "a")), + row(0, list(4, 5, 6), set(1, 2, 3), map(1, "a")) + ); + + assertEmpty(execute("SELECT * FROM %s WHERE c=?", set(-1))); + + assertInvalidMessage("ALLOW FILTERING", "SELECT * FROM %s WHERE c=? AND b=?", set(1, 2, 3), list(1, 2, 3)); + assertRows(execute("SELECT * FROM %s WHERE c=? AND b=? ALLOW FILTERING", set(1, 2, 3), list(1, 2, 3)), + row(0, list(1, 2, 3), set(1, 2, 3), map(1, "a")) + ); + + assertInvalidMessage("ALLOW FILTERING", "SELECT * FROM %s WHERE c=? AND b CONTAINS ?", set(1, 2, 3), 1); + assertRows(execute("SELECT * FROM %s WHERE c=? AND b CONTAINS ? ALLOW FILTERING", set(1, 2, 3), 1), + row(0, list(1, 2, 3), set(1, 2, 3), map(1, "a")) + ); + + assertInvalidMessage("ALLOW FILTERING", "SELECT * FROM %s WHERE c=? AND d = ?", set(1, 2, 3), map(1, "a")); + assertRows(execute("SELECT * FROM %s WHERE c=? AND d = ? ALLOW FILTERING", set(1, 2, 3), map(1, "a")), + row(0, list(1, 2, 3), set(1, 2, 3), map(1, "a")), + row(0, list(4, 5, 6), set(1, 2, 3), map(1, "a")) + ); + + assertInvalidMessage("ALLOW FILTERING", "SELECT * FROM %s WHERE c=? AND d CONTAINS ?", set(1, 2, 3), "a"); + assertRows(execute("SELECT * FROM %s WHERE c=? AND d CONTAINS ? ALLOW FILTERING", set(1, 2, 3), "a"), + row(0, list(1, 2, 3), set(1, 2, 3), map(1, "a")), + row(0, list(4, 5, 6), set(1, 2, 3), map(1, "a")) + ); + + assertInvalidMessage("ALLOW FILTERING", "SELECT * FROM %s WHERE c=? AND d CONTAINS KEY ?", set(1, 2, 3), 1); + assertRows(execute("SELECT * FROM %s WHERE c=? AND d CONTAINS KEY ? ALLOW FILTERING", set(1, 2, 3), 1), + row(0, list(1, 2, 3), set(1, 2, 3), map(1, "a")), + row(0, list(4, 5, 6), set(1, 2, 3), map(1, "a")) + ); + + // index lookup on d + assertRows(execute("SELECT * FROM %s WHERE d=?", map(1, "a")), + row(0, list(1, 2, 3), set(1, 2, 3), map(1, "a")), + row(0, list(4, 5, 6), set(1, 2, 3), map(1, "a")) + ); + + assertRows(execute("SELECT * FROM %s WHERE d=?", map(2, "b")), + row(1, list(1, 2, 3), set(4, 5, 6), map(2, "b")), + row(1, list(4, 5, 6), set(4, 5, 6), map(2, "b")) + ); + + assertEmpty(execute("SELECT * FROM %s WHERE d=?", map(3, "c"))); + + assertInvalidMessage("ALLOW FILTERING", "SELECT * FROM %s WHERE d=? AND c=?", map(1, "a"), set(1, 2, 3)); + assertRows(execute("SELECT * FROM %s WHERE d=? AND b=? ALLOW FILTERING", map(1, "a"), list(1, 2, 3)), + row(0, list(1, 2, 3), set(1, 2, 3), map(1, "a")) + ); + + assertInvalidMessage("ALLOW FILTERING", "SELECT * FROM %s WHERE d=? AND b CONTAINS ?", map(1, "a"), 3); + assertRows(execute("SELECT * FROM %s WHERE d=? AND b CONTAINS ? ALLOW FILTERING", map(1, "a"), 3), + row(0, list(1, 2, 3), set(1, 2, 3), map(1, "a")) + ); + + assertInvalidMessage("ALLOW FILTERING", "SELECT * FROM %s WHERE d=? AND b=? AND c=?", map(1, "a"), list(1, 2, 3), set(1, 2, 3)); + assertRows(execute("SELECT * FROM %s WHERE d=? AND b=? AND c=? ALLOW FILTERING", map(1, "a"), list(1, 2, 3), set(1, 2, 3)), + row(0, list(1, 2, 3), set(1, 2, 3), map(1, "a")) + ); + + assertRows(execute("SELECT * FROM %s WHERE d=? AND b CONTAINS ? AND c CONTAINS ? ALLOW FILTERING", map(1, "a"), 2, 2), + row(0, list(1, 2, 3), set(1, 2, 3), map(1, "a")) + ); + + execute("DELETE d FROM %s WHERE a=? AND b=?", 0, list(1, 2, 3)); + assertRows(execute("SELECT * FROM %s WHERE d=?", map(1, "a")), + row(0, list(4, 5, 6), set(1, 2, 3), map(1, "a")) + ); + } + + @Test + public void testUserDefinedTypes() throws Throwable + { + String myType = createType("CREATE TYPE %s (a set<int>, b tuple<list<int>>)"); + createTable("CREATE TABLE %s (k int PRIMARY KEY, v frozen<" + myType + ">)"); + execute("INSERT INTO %s (k, v) VALUES (?, {a: ?, b: ?})", 0, set(1, 2, 3), tuple(list(1, 2, 3))); + assertRows(execute("SELECT v.a, v.b FROM %s WHERE k=?", 0), + row(set(1, 2, 3), tuple(list(1, 2, 3))) + ); + } + + private static String clean(String classname) + { + return StringUtils.remove(classname, "org.apache.cassandra.db.marshal."); + } + + @Test + public void testToString() + { + // set<frozen<list<int>>> + SetType t = SetType.getInstance(ListType.getInstance(Int32Type.instance, false), true); + assertEquals("SetType(FrozenType(ListType(Int32Type)))", clean(t.toString())); + assertEquals("SetType(ListType(Int32Type))", clean(t.toString(true))); + + // frozen<set<list<int>>> + t = SetType.getInstance(ListType.getInstance(Int32Type.instance, false), false); + assertEquals("FrozenType(SetType(ListType(Int32Type)))", clean(t.toString())); + assertEquals("SetType(ListType(Int32Type))", clean(t.toString(true))); + + // map<frozen<list<int>>, int> + MapType m = MapType.getInstance(ListType.getInstance(Int32Type.instance, false), Int32Type.instance, true); + assertEquals("MapType(FrozenType(ListType(Int32Type)),Int32Type)", clean(m.toString())); + assertEquals("MapType(ListType(Int32Type),Int32Type)", clean(m.toString(true))); + + // frozen<map<list<int>, int>> + m = MapType.getInstance(ListType.getInstance(Int32Type.instance, false), Int32Type.instance, false); + assertEquals("FrozenType(MapType(ListType(Int32Type),Int32Type))", clean(m.toString())); + assertEquals("MapType(ListType(Int32Type),Int32Type)", clean(m.toString(true))); + + // tuple<set<int>> + List<AbstractType<?>> types = new ArrayList<>(); + types.add(SetType.getInstance(Int32Type.instance, true)); + TupleType tuple = new TupleType(types); + assertEquals("TupleType(SetType(Int32Type))", clean(tuple.toString())); + } +} http://git-wip-us.apache.org/repos/asf/cassandra/blob/ee55f361/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 53e7e71..ce935e3 100644 --- a/test/unit/org/apache/cassandra/cql3/TupleTypeTest.java +++ b/test/unit/org/apache/cassandra/cql3/TupleTypeTest.java @@ -24,26 +24,30 @@ public class TupleTypeTest extends CQLTester @Test public void testTuplePutAndGet() throws Throwable { - createTable("CREATE TABLE %s (k int PRIMARY KEY, t frozen<tuple<int, text, double>>)"); + String[] valueTypes = {"frozen<tuple<int, text, double>>", "tuple<int, text, double>"}; + for (String valueType : valueTypes) + { + createTable("CREATE TABLE %s (k int PRIMARY KEY, t " + valueType + ")"); - 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)); - assertAllRows( - row(0, tuple(3, "foo", 3.4)), - row(1, tuple(8, "bar", 0.2)) - ); + 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)); + assertAllRows( + row(0, tuple(3, "foo", 3.4)), + row(1, tuple(8, "bar", 0.2)) + ); - // nulls - execute("INSERT INTO %s (k, t) VALUES (?, ?)", 2, tuple(5, null, 3.4)); - assertRows(execute("SELECT * FROM %s WHERE k=?", 2), - row(2, tuple(5, null, 3.4)) - ); + // nulls + execute("INSERT INTO %s (k, t) VALUES (?, ?)", 2, tuple(5, null, 3.4)); + assertRows(execute("SELECT * FROM %s WHERE k=?", 2), + row(2, tuple(5, null, 3.4)) + ); - // incomplete tuple - execute("INSERT INTO %s (k, t) VALUES (?, ?)", 3, tuple(5, "bar")); - assertRows(execute("SELECT * FROM %s WHERE k=?", 3), - row(3, tuple(5, "bar")) - ); + // incomplete tuple + execute("INSERT INTO %s (k, t) VALUES (?, ?)", 3, tuple(5, "bar")); + assertRows(execute("SELECT * FROM %s WHERE k=?", 3), + row(3, tuple(5, "bar")) + ); + } } @Test @@ -94,10 +98,4 @@ public class TupleTypeTest extends CQLTester assertInvalidSyntax("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/ee55f361/test/unit/org/apache/cassandra/db/marshal/CollectionTypeTest.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/db/marshal/CollectionTypeTest.java b/test/unit/org/apache/cassandra/db/marshal/CollectionTypeTest.java index 18156c3..92990e9 100644 --- a/test/unit/org/apache/cassandra/db/marshal/CollectionTypeTest.java +++ b/test/unit/org/apache/cassandra/db/marshal/CollectionTypeTest.java @@ -36,7 +36,7 @@ public class CollectionTypeTest @Test public void testListComparison() { - ListType<String> lt = ListType.getInstance(UTF8Type.instance); + ListType<String> lt = ListType.getInstance(UTF8Type.instance, true); ByteBuffer[] lists = new ByteBuffer[] { ByteBufferUtil.EMPTY_BYTE_BUFFER, @@ -63,7 +63,7 @@ public class CollectionTypeTest @Test public void testSetComparison() { - SetType<String> st = SetType.getInstance(UTF8Type.instance); + SetType<String> st = SetType.getInstance(UTF8Type.instance, true); ByteBuffer[] sets = new ByteBuffer[] { ByteBufferUtil.EMPTY_BYTE_BUFFER, @@ -90,7 +90,7 @@ public class CollectionTypeTest @Test public void testMapComparison() { - MapType<String, String> mt = MapType.getInstance(UTF8Type.instance, UTF8Type.instance); + MapType<String, String> mt = MapType.getInstance(UTF8Type.instance, UTF8Type.instance, true); ByteBuffer[] maps = new ByteBuffer[] { ByteBufferUtil.EMPTY_BYTE_BUFFER, @@ -119,8 +119,8 @@ public class CollectionTypeTest @Test public void listSerDerTest() { - ListSerializer<String> sls = ListType.getInstance(UTF8Type.instance).getSerializer(); - ListSerializer<Integer> ils = ListType.getInstance(Int32Type.instance).getSerializer(); + ListSerializer<String> sls = ListType.getInstance(UTF8Type.instance, true).getSerializer(); + ListSerializer<Integer> ils = ListType.getInstance(Int32Type.instance, true).getSerializer(); List<String> sl = Arrays.asList("Foo", "Bar"); List<Integer> il = Arrays.asList(3, 1, 5); @@ -143,8 +143,8 @@ public class CollectionTypeTest @Test public void setSerDerTest() { - SetSerializer<String> sss = SetType.getInstance(UTF8Type.instance).getSerializer(); - SetSerializer<Integer> iss = SetType.getInstance(Int32Type.instance).getSerializer(); + SetSerializer<String> sss = SetType.getInstance(UTF8Type.instance, true).getSerializer(); + SetSerializer<Integer> iss = SetType.getInstance(Int32Type.instance, true).getSerializer(); Set<String> ss = new HashSet(){{ add("Foo"); add("Bar"); }}; Set<Integer> is = new HashSet(){{ add(3); add(1); add(5); }}; @@ -167,8 +167,8 @@ public class CollectionTypeTest @Test public void setMapDerTest() { - MapSerializer<String, String> sms = MapType.getInstance(UTF8Type.instance, UTF8Type.instance).getSerializer(); - MapSerializer<Integer, Integer> ims = MapType.getInstance(Int32Type.instance, Int32Type.instance).getSerializer(); + MapSerializer<String, String> sms = MapType.getInstance(UTF8Type.instance, UTF8Type.instance, true).getSerializer(); + MapSerializer<Integer, Integer> ims = MapType.getInstance(Int32Type.instance, Int32Type.instance, true).getSerializer(); Map<String, String> sm = new HashMap(){{ put("Foo", "xxx"); put("Bar", "yyy"); }}; Map<Integer, Integer> im = new HashMap(){{ put(3, 0); put(1, 8); put(5, 2); }}; @@ -187,8 +187,8 @@ public class CollectionTypeTest // non map value assertInvalid(sms, UTF8Type.instance.getSerializer().serialize("foo")); - MapSerializer<Integer, String> sims = MapType.getInstance(Int32Type.instance, UTF8Type.instance).getSerializer(); - MapSerializer<String, Integer> isms = MapType.getInstance(UTF8Type.instance, Int32Type.instance).getSerializer(); + MapSerializer<Integer, String> sims = MapType.getInstance(Int32Type.instance, UTF8Type.instance, true).getSerializer(); + MapSerializer<String, Integer> isms = MapType.getInstance(UTF8Type.instance, Int32Type.instance, true).getSerializer(); // only key are invalid assertInvalid(isms, sb); http://git-wip-us.apache.org/repos/asf/cassandra/blob/ee55f361/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 9b66efb..649f7a2 100644 --- a/test/unit/org/apache/cassandra/transport/SerDeserTest.java +++ b/test/unit/org/apache/cassandra/transport/SerDeserTest.java @@ -31,7 +31,6 @@ import org.apache.cassandra.serializers.CollectionSerializer; import org.apache.cassandra.transport.Event.TopologyChange; import org.apache.cassandra.transport.Event.SchemaChange; import org.apache.cassandra.transport.Event.StatusChange; -import org.apache.cassandra.utils.ByteBufferUtil; import org.apache.cassandra.utils.FBUtilities; import org.apache.cassandra.utils.Pair; @@ -53,7 +52,7 @@ public class SerDeserTest public void collectionSerDeserTest(int version) throws Exception { // Lists - ListType<?> lt = ListType.getInstance(Int32Type.instance); + ListType<?> lt = ListType.getInstance(Int32Type.instance, true); List<Integer> l = Arrays.asList(2, 6, 1, 9); List<ByteBuffer> lb = new ArrayList<>(l.size()); @@ -63,7 +62,7 @@ public class SerDeserTest assertEquals(l, lt.getSerializer().deserializeForNativeProtocol(CollectionSerializer.pack(lb, lb.size(), version), version)); // Sets - SetType<?> st = SetType.getInstance(UTF8Type.instance); + SetType<?> st = SetType.getInstance(UTF8Type.instance, true); Set<String> s = new LinkedHashSet<>(); s.addAll(Arrays.asList("bar", "foo", "zee")); @@ -74,7 +73,7 @@ public class SerDeserTest assertEquals(s, st.getSerializer().deserializeForNativeProtocol(CollectionSerializer.pack(sb, sb.size(), version), version)); // Maps - MapType<?, ?> mt = MapType.getInstance(UTF8Type.instance, LongType.instance); + MapType<?, ?> mt = MapType.getInstance(UTF8Type.instance, LongType.instance, true); Map<String, Long> m = new LinkedHashMap<>(); m.put("bar", 12L); m.put("foo", 42L); @@ -165,9 +164,9 @@ public class SerDeserTest public void udtSerDeserTest(int version) throws Exception { - ListType<?> lt = ListType.getInstance(Int32Type.instance); - SetType<?> st = SetType.getInstance(UTF8Type.instance); - MapType<?, ?> mt = MapType.getInstance(UTF8Type.instance, LongType.instance); + ListType<?> lt = ListType.getInstance(Int32Type.instance, true); + SetType<?> st = SetType.getInstance(UTF8Type.instance, true); + MapType<?, ?> mt = MapType.getInstance(UTF8Type.instance, LongType.instance, true); UserType udt = new UserType("ks", bb("myType"), http://git-wip-us.apache.org/repos/asf/cassandra/blob/ee55f361/tools/stress/src/org/apache/cassandra/stress/generate/values/Lists.java ---------------------------------------------------------------------- diff --git a/tools/stress/src/org/apache/cassandra/stress/generate/values/Lists.java b/tools/stress/src/org/apache/cassandra/stress/generate/values/Lists.java index 6480d7a..bfa58ea 100644 --- a/tools/stress/src/org/apache/cassandra/stress/generate/values/Lists.java +++ b/tools/stress/src/org/apache/cassandra/stress/generate/values/Lists.java @@ -33,7 +33,7 @@ public class Lists extends Generator<List> public Lists(String name, Generator valueType, GeneratorConfig config) { - super(ListType.getInstance(valueType.type), config, name, List.class); + super(ListType.getInstance(valueType.type, true), config, name, List.class); this.valueType = valueType; buffer = new Object[(int) sizeDistribution.maxValue()]; } http://git-wip-us.apache.org/repos/asf/cassandra/blob/ee55f361/tools/stress/src/org/apache/cassandra/stress/generate/values/Sets.java ---------------------------------------------------------------------- diff --git a/tools/stress/src/org/apache/cassandra/stress/generate/values/Sets.java b/tools/stress/src/org/apache/cassandra/stress/generate/values/Sets.java index 8246286..5c17b4e 100644 --- a/tools/stress/src/org/apache/cassandra/stress/generate/values/Sets.java +++ b/tools/stress/src/org/apache/cassandra/stress/generate/values/Sets.java @@ -32,7 +32,7 @@ public class Sets extends Generator<Set> public Sets(String name, Generator valueType, GeneratorConfig config) { - super(SetType.getInstance(valueType.type), config, name, Set.class); + super(SetType.getInstance(valueType.type, true), config, name, Set.class); this.valueType = valueType; }