mirror of https://github.com/apache/cassandra
Merge branch 'cassandra-4.0' into cassandra-4.1
This commit is contained in:
commit
7f4e9bb67b
|
|
@ -6,6 +6,7 @@
|
|||
* Fix COPY ... TO STDOUT behavior in cqlsh (CASSANDRA-18353)
|
||||
* Remove six and Py2SaferScanner merge cruft (CASSANDRA-18354)
|
||||
Merged from 4.0:
|
||||
* NPE when deserializing malformed collections from client (CASSANDRA-18505)
|
||||
* Improve 'Not enough space for compaction' logging messages (CASSANDRA-18260)
|
||||
* Incremental repairs fail on mixed IPv4/v6 addresses serializing SyncRequest (CASSANDRA-18474)
|
||||
* Deadlock updating sstable metadata if disk boundaries need reloading (CASSANDRA-18443)
|
||||
|
|
|
|||
|
|
@ -127,6 +127,14 @@ public abstract class CollectionSerializer<T> extends TypeSerializer<T>
|
|||
return accessor.slice(input, offset + TypeSizes.INT_SIZE, size);
|
||||
}
|
||||
|
||||
public static <V> V readNonNullValue(V input, ValueAccessor<V> accessor, int offset, ProtocolVersion version)
|
||||
{
|
||||
V value = readValue(input, accessor, offset, version);
|
||||
if (value == null)
|
||||
throw new MarshalException("Null value read when not allowed");
|
||||
return value;
|
||||
}
|
||||
|
||||
protected static void skipValue(ByteBuffer input, ProtocolVersion version)
|
||||
{
|
||||
int size = input.getInt();
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ public class ListSerializer<T> extends CollectionSerializer<List<T>>
|
|||
int offset = sizeOfCollectionSize(n, version);
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
V value = readValue(input, accessor, offset, version);
|
||||
V value = readNonNullValue(input, accessor, offset, version);
|
||||
offset += sizeOfValue(value, accessor, version);
|
||||
elements.validate(value, accessor);
|
||||
}
|
||||
|
|
@ -103,7 +103,12 @@ public class ListSerializer<T> extends CollectionSerializer<List<T>>
|
|||
List<T> l = new ArrayList<T>(Math.min(n, 256));
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
// We can have nulls in lists that are used for IN values
|
||||
// CASSANDRA-6839: "We can have nulls in lists that are used for IN values"
|
||||
// CASSANDRA-8613 checks IN clauses and throws an exception if null is in the list.
|
||||
// Leaving for this as-is for now in case there is some unknown use
|
||||
// for it, but should likely be changed to readNonNull. Validate has been
|
||||
// changed to throw on null elements as otherwise it would NPE, and it's unclear
|
||||
// if callers could handle null elements.
|
||||
V databb = readValue(input, accessor, offset, version);
|
||||
offset += sizeOfValue(databb, accessor, version);
|
||||
if (databb != null)
|
||||
|
|
|
|||
|
|
@ -88,11 +88,11 @@ public class MapSerializer<K, V> extends CollectionSerializer<Map<K, V>>
|
|||
int offset = sizeOfCollectionSize(n, version);
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
T key = readValue(input, accessor, offset, version);
|
||||
T key = readNonNullValue(input, accessor, offset, version);
|
||||
offset += sizeOfValue(key, accessor, version);
|
||||
keys.validate(key, accessor);
|
||||
|
||||
T value = readValue(input, accessor, offset, version);
|
||||
T value = readNonNullValue(input, accessor, offset, version);
|
||||
offset += sizeOfValue(value, accessor, version);
|
||||
values.validate(value, accessor);
|
||||
}
|
||||
|
|
@ -122,11 +122,11 @@ public class MapSerializer<K, V> extends CollectionSerializer<Map<K, V>>
|
|||
Map<K, V> m = new LinkedHashMap<K, V>(Math.min(n, 256));
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
I key = readValue(input, accessor, offset, version);
|
||||
I key = readNonNullValue(input, accessor, offset, version);
|
||||
offset += sizeOfValue(key, accessor, version);
|
||||
keys.validate(key, accessor);
|
||||
|
||||
I value = readValue(input, accessor, offset, version);
|
||||
I value = readNonNullValue(input, accessor, offset, version);
|
||||
offset += sizeOfValue(value, accessor, version);
|
||||
values.validate(value, accessor);
|
||||
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ public class SetSerializer<T> extends CollectionSerializer<Set<T>>
|
|||
int offset = sizeOfCollectionSize(n, version);
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
V value = readValue(input, accessor, offset, version);
|
||||
V value = readNonNullValue(input, accessor, offset, version);
|
||||
offset += sizeOfValue(value, accessor, version);
|
||||
elements.validate(value, accessor);
|
||||
}
|
||||
|
|
@ -110,7 +110,7 @@ public class SetSerializer<T> extends CollectionSerializer<Set<T>>
|
|||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
V value = readValue(input, accessor, offset, version);
|
||||
V value = readNonNullValue(input, accessor, offset, version);
|
||||
offset += sizeOfValue(value, accessor, version);
|
||||
elements.validate(value, accessor);
|
||||
l.add(elements.deserialize(value, accessor));
|
||||
|
|
|
|||
|
|
@ -976,7 +976,7 @@ public class CollectionsTest extends CQLTester
|
|||
createTable("CREATE TABLE %s(pk int PRIMARY KEY, s set<text>)");
|
||||
assertInvalidMessage("Not enough bytes to read a set",
|
||||
"INSERT INTO %s (pk, s) VALUES (?, ?)", 1, "test");
|
||||
assertInvalidMessage("String didn't validate.",
|
||||
assertInvalidMessage("Null value read when not allowed",
|
||||
"INSERT INTO %s (pk, s) VALUES (?, ?)", 1, Long.MAX_VALUE);
|
||||
assertInvalidMessage("Not enough bytes to read a set",
|
||||
"INSERT INTO %s (pk, s) VALUES (?, ?)", 1, "");
|
||||
|
|
@ -990,7 +990,7 @@ public class CollectionsTest extends CQLTester
|
|||
createTable("CREATE TABLE %s(pk int PRIMARY KEY, m map<text, text>)");
|
||||
assertInvalidMessage("Not enough bytes to read a map",
|
||||
"INSERT INTO %s (pk, m) VALUES (?, ?)", 1, "test");
|
||||
assertInvalidMessage("String didn't validate.",
|
||||
assertInvalidMessage("Null value read when not allowed",
|
||||
"INSERT INTO %s (pk, m) VALUES (?, ?)", 1, Long.MAX_VALUE);
|
||||
assertInvalidMessage("Not enough bytes to read a map",
|
||||
"INSERT INTO %s (pk, m) VALUES (?, ?)", 1, "");
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import org.apache.cassandra.cql3.*;
|
|||
import org.apache.cassandra.db.ConsistencyLevel;
|
||||
import org.apache.cassandra.db.marshal.*;
|
||||
import org.apache.cassandra.serializers.CollectionSerializer;
|
||||
import org.apache.cassandra.serializers.MarshalException;
|
||||
import org.apache.cassandra.service.ClientState;
|
||||
import org.apache.cassandra.service.QueryState;
|
||||
import org.apache.cassandra.transport.Event.TopologyChange;
|
||||
|
|
@ -107,6 +108,41 @@ public class SerDeserTest
|
|||
assertEquals(m, mt.getSerializer().deserializeForNativeProtocol(CollectionSerializer.pack(mb, m.size(), version), version));
|
||||
}
|
||||
|
||||
@Test(expected = MarshalException.class)
|
||||
public void setsMayNotContainNullsTest()
|
||||
{
|
||||
ProtocolVersion version = ProtocolVersion.MIN_SUPPORTED_VERSION;
|
||||
SetType<?> st = SetType.getInstance(UTF8Type.instance, true);
|
||||
List<ByteBuffer> sb = new ArrayList<>(1);
|
||||
sb.add(null);
|
||||
|
||||
st.getSerializer().deserializeForNativeProtocol(CollectionSerializer.pack(sb, sb.size(), version), version);
|
||||
}
|
||||
|
||||
@Test(expected = MarshalException.class)
|
||||
public void mapKeysMayNotContainNullsTest()
|
||||
{
|
||||
ProtocolVersion version = ProtocolVersion.MIN_SUPPORTED_VERSION;
|
||||
MapType<?, ?> mt = MapType.getInstance(UTF8Type.instance, LongType.instance, true);
|
||||
List<ByteBuffer> mb = new ArrayList<>(2);
|
||||
mb.add(null);
|
||||
mb.add(LongType.instance.decompose(999L));
|
||||
|
||||
mt.getSerializer().deserializeForNativeProtocol(CollectionSerializer.pack(mb, mb.size(), version), version);
|
||||
}
|
||||
|
||||
@Test(expected = MarshalException.class)
|
||||
public void mapValueMayNotContainNullsTest()
|
||||
{
|
||||
ProtocolVersion version = ProtocolVersion.MIN_SUPPORTED_VERSION;
|
||||
MapType<?, ?> mt = MapType.getInstance(UTF8Type.instance, LongType.instance, true);
|
||||
List<ByteBuffer> mb = new ArrayList<>(2);
|
||||
mb.add(UTF8Type.instance.decompose("danger"));
|
||||
mb.add(null);
|
||||
|
||||
mt.getSerializer().deserializeForNativeProtocol(CollectionSerializer.pack(mb, mb.size(), version), version);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void eventSerDeserTest() throws Exception
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue