INSERT statement fails when Tuple type is used as clustering column with default DESC order
patch by Stavros Kontopoulos, reviewed by jasobrown for CASSANDRA-13717 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/a08a816a Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/a08a816a Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/a08a816a Branch: refs/heads/trunk Commit: a08a816a6a3497046ba75a38d76d5095347dfe95 Parents: a586f6c Author: Stavros Kontopoulos <stavros.kontopou...@lightbend.com> Authored: Thu Aug 10 04:23:26 2017 +0300 Committer: Jason Brown <jasedbr...@gmail.com> Committed: Tue Sep 12 14:10:34 2017 -0700 ---------------------------------------------------------------------- CHANGES.txt | 1 + src/java/org/apache/cassandra/cql3/Tuples.java | 24 +++++++++++++++----- .../cql3/validation/entities/TupleTypeTest.java | 14 ++++++++++++ 3 files changed, 33 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/a08a816a/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index 6053117..3d3903e 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 3.0.15 + * INSERT statement fails when Tuple type is used as clustering column with default DESC order (CASSANDRA-13717) * Fix pending view mutations handling and cleanup batchlog when there are local and remote paired mutations (CASSANDRA-13069) * Improve config validation and documentation on overflow and NPE (CASSANDRA-13622) * Range deletes in a CAS batch are ignored (CASSANDRA-13655) http://git-wip-us.apache.org/repos/asf/cassandra/blob/a08a816a/src/java/org/apache/cassandra/cql3/Tuples.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/Tuples.java b/src/java/org/apache/cassandra/cql3/Tuples.java index ee08efe..c7564d3 100644 --- a/src/java/org/apache/cassandra/cql3/Tuples.java +++ b/src/java/org/apache/cassandra/cql3/Tuples.java @@ -47,7 +47,7 @@ public class Tuples return new ColumnSpecification(column.ksName, column.cfName, new ColumnIdentifier(String.format("%s[%d]", column.name, component), true), - ((TupleType)column.type).type(component)); + (getTupleType(column.type)).type(component)); } /** @@ -77,7 +77,7 @@ public class Tuples values.add(value); } - DelayedValue value = new DelayedValue((TupleType)receiver.type, values); + DelayedValue value = new DelayedValue(getTupleType(receiver.type), values); return allTerminal ? value.bind(QueryOptions.DEFAULT) : value; } @@ -104,10 +104,10 @@ public class Tuples private void validateAssignableTo(String keyspace, ColumnSpecification receiver) throws InvalidRequestException { - if (!(receiver.type instanceof TupleType)) + if (!checkIfTupleType(receiver.type)) throw new InvalidRequestException(String.format("Invalid tuple type literal for %s of type %s", receiver.name, receiver.type.asCQL3Type())); - TupleType tt = (TupleType)receiver.type; + TupleType tt = getTupleType(receiver.type); for (int i = 0; i < elements.size(); i++) { if (i >= tt.size()) @@ -256,7 +256,7 @@ public class Tuples List<?> l = type.getSerializer().deserializeForNativeProtocol(value, options.getProtocolVersion()); assert type.getElementsType() instanceof TupleType; - TupleType tupleType = (TupleType) type.getElementsType(); + TupleType tupleType = Tuples.getTupleType(type.getElementsType()); // type.split(bytes) List<List<ByteBuffer>> elements = new ArrayList<>(l.size()); @@ -375,7 +375,7 @@ public class Tuples ByteBuffer value = options.getValues().get(bindIndex); if (value == ByteBufferUtil.UNSET_BYTE_BUFFER) throw new InvalidRequestException(String.format("Invalid unset value for tuple %s", receiver.name)); - return value == null ? null : Value.fromSerialized(value, (TupleType)receiver.type); + return value == null ? null : Value.fromSerialized(value, getTupleType(receiver.type)); } } @@ -412,4 +412,16 @@ public class Tuples sb.append(')'); return sb.toString(); } + + public static boolean checkIfTupleType(AbstractType<?> tuple) + { + return (tuple instanceof TupleType) || + (tuple instanceof ReversedType && ((ReversedType) tuple).baseType instanceof TupleType); + + } + + public static TupleType getTupleType(AbstractType<?> tuple) + { + return (tuple instanceof ReversedType ? ((TupleType) ((ReversedType) tuple).baseType) : (TupleType)tuple); + } } http://git-wip-us.apache.org/repos/asf/cassandra/blob/a08a816a/test/unit/org/apache/cassandra/cql3/validation/entities/TupleTypeTest.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/TupleTypeTest.java b/test/unit/org/apache/cassandra/cql3/validation/entities/TupleTypeTest.java index cbe4a15..bace751 100644 --- a/test/unit/org/apache/cassandra/cql3/validation/entities/TupleTypeTest.java +++ b/test/unit/org/apache/cassandra/cql3/validation/entities/TupleTypeTest.java @@ -17,6 +17,10 @@ */ package org.apache.cassandra.cql3.validation.entities; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Locale; + import org.junit.Test; import org.apache.cassandra.cql3.CQLTester; @@ -211,4 +215,14 @@ public class TupleTypeTest extends CQLTester assertInvalidMessage("Not enough bytes to read 0th component", "INSERT INTO %s (pk, t) VALUES (?, ?)", 1, Long.MAX_VALUE); } + + @Test + public void testReversedTypeTuple() throws Throwable + { + // CASSANDRA-13717 + createTable("CREATE TABLE %s (id int, tdemo frozen<tuple<timestamp, varchar>>, primary key (id, tdemo)) with clustering order by (tdemo desc)"); + execute("INSERT INTO %s (id, tdemo) VALUES (1, ('2017-02-03 03:05+0000','Europe'))"); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mmX", Locale.ENGLISH); + assertRows(execute("SELECT tdemo FROM %s"), row(tuple( df.parse("2017-02-03 03:05+0000"), "Europe"))); + } } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org For additional commands, e-mail: commits-h...@cassandra.apache.org