mirror of https://github.com/apache/cassandra
Fix prepared marker for collections inside UDT
patch by slebresne; reviewed by thobbs for CASSANDRA-7472
This commit is contained in:
parent
92cb551ae3
commit
9b539f966f
|
|
@ -1,4 +1,5 @@
|
|||
2.1.0
|
||||
* Fix prepared marker for collections inside UDT (CASSANDRA-7472)
|
||||
* Remove left-over populate_io_cache_on_flush and replicate_on_write
|
||||
uses (CASSANDRA-7493)
|
||||
* (Windows) handle spaces in path names (CASSANDRA-7451)
|
||||
|
|
|
|||
|
|
@ -110,8 +110,6 @@ public abstract class QueryOptions
|
|||
*/
|
||||
public abstract int getProtocolVersion();
|
||||
|
||||
public abstract QueryOptions withProtocolVersion(int version);
|
||||
|
||||
// Mainly for the sake of BatchQueryOptions
|
||||
abstract SpecificOptions getSpecificOptions();
|
||||
|
||||
|
|
@ -139,11 +137,6 @@ public abstract class QueryOptions
|
|||
this.protocolVersion = protocolVersion;
|
||||
}
|
||||
|
||||
public QueryOptions withProtocolVersion(int version)
|
||||
{
|
||||
return new DefaultQueryOptions(consistency, values, skipMetadata, options, version);
|
||||
}
|
||||
|
||||
public ConsistencyLevel getConsistency()
|
||||
{
|
||||
return consistency;
|
||||
|
|
@ -205,11 +198,6 @@ public abstract class QueryOptions
|
|||
wrapped.prepare(specs);
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryOptions withProtocolVersion(int version)
|
||||
{
|
||||
return new DefaultQueryOptions(getConsistency(), getValues(), skipMetadata(), getSpecificOptions(), version);
|
||||
}
|
||||
}
|
||||
|
||||
static class OptionsWithNames extends QueryOptionsWrapper
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ public class Tuples
|
|||
|
||||
values.add(value);
|
||||
}
|
||||
DelayedValue value = new DelayedValue(values);
|
||||
DelayedValue value = new DelayedValue((TupleType)receiver.type, values);
|
||||
return allTerminal ? value.bind(QueryOptions.DEFAULT) : value;
|
||||
}
|
||||
|
||||
|
|
@ -81,6 +81,7 @@ public class Tuples
|
|||
throw new InvalidRequestException(String.format("Expected %d elements in value tuple, but got %d: %s", receivers.size(), elements.size(), this));
|
||||
|
||||
List<Term> values = new ArrayList<>(elements.size());
|
||||
List<AbstractType<?>> types = new ArrayList<>(elements.size());
|
||||
boolean allTerminal = true;
|
||||
for (int i = 0; i < elements.size(); i++)
|
||||
{
|
||||
|
|
@ -89,8 +90,9 @@ public class Tuples
|
|||
allTerminal = false;
|
||||
|
||||
values.add(t);
|
||||
types.add(receivers.get(i).type);
|
||||
}
|
||||
DelayedValue value = new DelayedValue(values);
|
||||
DelayedValue value = new DelayedValue(new TupleType(types), values);
|
||||
return allTerminal ? value.bind(QueryOptions.DEFAULT) : value;
|
||||
}
|
||||
|
||||
|
|
@ -166,10 +168,12 @@ public class Tuples
|
|||
*/
|
||||
public static class DelayedValue extends Term.NonTerminal
|
||||
{
|
||||
public final TupleType type;
|
||||
public final List<Term> elements;
|
||||
|
||||
public DelayedValue(List<Term> elements)
|
||||
public DelayedValue(TupleType type, List<Term> elements)
|
||||
{
|
||||
this.type = type;
|
||||
this.elements = elements;
|
||||
}
|
||||
|
||||
|
|
@ -190,13 +194,17 @@ public class Tuples
|
|||
|
||||
private ByteBuffer[] bindInternal(QueryOptions options) throws InvalidRequestException
|
||||
{
|
||||
// Inside tuples, we must force the serialization of collections whatever the protocol version is in
|
||||
// use since we're going to store directly that serialized value.
|
||||
options = options.withProtocolVersion(3);
|
||||
int version = options.getProtocolVersion();
|
||||
|
||||
ByteBuffer[] buffers = new ByteBuffer[elements.size()];
|
||||
for (int i = 0; i < elements.size(); i++)
|
||||
{
|
||||
buffers[i] = elements.get(i).bindAndGet(options);
|
||||
// Inside tuples, we must force the serialization of collections to v3 whatever protocol
|
||||
// version is in use since we're going to store directly that serialized value.
|
||||
if (version < 3 && type.type(i).isCollection())
|
||||
buffers[i] = ((CollectionType)type.type(i)).getSerializer().reserializeToV3(buffers[i]);
|
||||
}
|
||||
return buffers;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ package org.apache.cassandra.cql3;
|
|||
import java.nio.ByteBuffer;
|
||||
import java.util.*;
|
||||
|
||||
import org.apache.cassandra.db.marshal.CollectionType;
|
||||
import org.apache.cassandra.db.marshal.UserType;
|
||||
import org.apache.cassandra.db.marshal.UTF8Type;
|
||||
import org.apache.cassandra.exceptions.InvalidRequestException;
|
||||
|
|
@ -33,10 +34,11 @@ public abstract class UserTypes
|
|||
|
||||
public static ColumnSpecification fieldSpecOf(ColumnSpecification column, int field)
|
||||
{
|
||||
UserType ut = (UserType)column.type;
|
||||
return new ColumnSpecification(column.ksName,
|
||||
column.cfName,
|
||||
new ColumnIdentifier(column.name + "." + field, true),
|
||||
((UserType)column.type).fieldType(field));
|
||||
new ColumnIdentifier(column.name + "." + UTF8Type.instance.compose(ut.fieldName(field)), true),
|
||||
ut.fieldType(field));
|
||||
}
|
||||
|
||||
public static class Literal implements Term.Raw
|
||||
|
|
@ -150,13 +152,17 @@ public abstract class UserTypes
|
|||
|
||||
private ByteBuffer[] bindInternal(QueryOptions options) throws InvalidRequestException
|
||||
{
|
||||
// Inside UDT values, we must force the serialization of collections whatever the protocol version is in
|
||||
// use since we're going to store directly that serialized value.
|
||||
options = options.withProtocolVersion(3);
|
||||
int version = options.getProtocolVersion();
|
||||
|
||||
ByteBuffer[] buffers = new ByteBuffer[values.size()];
|
||||
for (int i = 0; i < type.size(); i++)
|
||||
{
|
||||
buffers[i] = values.get(i).bindAndGet(options);
|
||||
// Inside UDT values, we must force the serialization of collections to v3 whatever protocol
|
||||
// version is in use since we're going to store directly that serialized value.
|
||||
if (version < 3 && type.fieldType(i).isCollection())
|
||||
buffers[i] = ((CollectionType)type.fieldType(i)).getSerializer().reserializeToV3(buffers[i]);
|
||||
}
|
||||
return buffers;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,9 @@ public abstract class CollectionType<T> extends AbstractType<T>
|
|||
|
||||
public abstract List<ByteBuffer> serializedValues(List<Cell> cells);
|
||||
|
||||
@Override
|
||||
public abstract CollectionSerializer<T> getSerializer();
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -48,6 +48,11 @@ public abstract class CollectionSerializer<T> implements TypeSerializer<T>
|
|||
return deserializeForNativeProtocol(bytes, 3);
|
||||
}
|
||||
|
||||
public ByteBuffer reserializeToV3(ByteBuffer bytes)
|
||||
{
|
||||
return serialize(deserializeForNativeProtocol(bytes, 2));
|
||||
}
|
||||
|
||||
public void validate(ByteBuffer bytes) throws MarshalException
|
||||
{
|
||||
// Same thing than above
|
||||
|
|
|
|||
Loading…
Reference in New Issue