Ensure Relation#toRestriction() handles ReversedType properly
patch by Caleb Rackliffe; reviewed by David Capwell for CASSANDRA-19950
diff --git a/CHANGES.txt b/CHANGES.txt
index 1797b9f..ffd8e96 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
5.1
+ * Ensure Relation#toRestriction() handles ReversedType properly (CASSANDRA-19950)
* Add JSON and YAML output option to nodetool gcstats (CASSANDRA-19771)
* Introduce metadata serialization version V4 (CASSANDRA-19970)
* Allow CMS reconfiguration to work around DOWN nodes (CASSANDRA-19943)
diff --git a/src/java/org/apache/cassandra/cql3/ColumnsExpression.java b/src/java/org/apache/cassandra/cql3/ColumnsExpression.java
index 8e52623..78b0b8e 100644
--- a/src/java/org/apache/cassandra/cql3/ColumnsExpression.java
+++ b/src/java/org/apache/cassandra/cql3/ColumnsExpression.java
@@ -368,7 +368,7 @@
*/
public boolean isMapElementExpression()
{
- return kind == Kind.ELEMENT && element != null && element.kind() == ElementExpression.Kind.COLLECTION_ELEMENT && firstColumn().type instanceof MapType;
+ return kind == Kind.ELEMENT && element != null && element.kind() == ElementExpression.Kind.COLLECTION_ELEMENT && firstColumn().type.unwrap() instanceof MapType;
}
/**
diff --git a/src/java/org/apache/cassandra/cql3/ElementExpression.java b/src/java/org/apache/cassandra/cql3/ElementExpression.java
index 6a218fe..3665f71 100644
--- a/src/java/org/apache/cassandra/cql3/ElementExpression.java
+++ b/src/java/org/apache/cassandra/cql3/ElementExpression.java
@@ -214,11 +214,13 @@
{
if (kind == Kind.COLLECTION_ELEMENT)
{
- if (!(column.type.isCollection()))
+ AbstractType<?> baseType = column.type.unwrap();
+
+ if (!(baseType.isCollection()))
throw invalidRequest("Invalid element access syntax for non-collection column %s", column.name);
Term term = prepareCollectionElement(column);
- CollectionType<?> collectionType = (CollectionType<?>) column.type;
+ CollectionType<?> collectionType = (CollectionType<?>) baseType;
AbstractType<?> elementType = collectionType.valueComparator();
AbstractType<?> keyOrIndexType = collectionType.isMap() ? ((MapType<?, ?>) collectionType).getKeysType() : Int32Type.instance;
return new ElementExpression(kind, elementType, keyOrIndexType, term);
@@ -238,7 +240,7 @@
private Term prepareCollectionElement(ColumnMetadata receiver)
{
ColumnSpecification elementSpec;
- switch ((((CollectionType<?>) receiver.type).kind))
+ switch ((((CollectionType<?>) receiver.type.unwrap()).kind))
{
case LIST:
elementSpec = Lists.indexSpecOf(receiver);
diff --git a/src/java/org/apache/cassandra/cql3/Relation.java b/src/java/org/apache/cassandra/cql3/Relation.java
index 86d8db1..9fbd3ad 100644
--- a/src/java/org/apache/cassandra/cql3/Relation.java
+++ b/src/java/org/apache/cassandra/cql3/Relation.java
@@ -24,7 +24,9 @@
import org.apache.cassandra.cql3.restrictions.SimpleRestriction;
import org.apache.cassandra.cql3.restrictions.SingleRestriction;
-import org.apache.cassandra.cql3.terms.*;
+import org.apache.cassandra.cql3.terms.Term;
+import org.apache.cassandra.cql3.terms.Terms;
+import org.apache.cassandra.db.marshal.AbstractType;
import org.apache.cassandra.db.marshal.CollectionType;
import org.apache.cassandra.db.marshal.ListType;
import org.apache.cassandra.db.marshal.MapType;
@@ -198,9 +200,10 @@
if (columnsExpression.isMapElementExpression())
{
ColumnMetadata column = columnsExpression.firstColumn();
- checkFalse(column.type instanceof ListType, "Indexes on list entries (%s[index] = value) are not supported.", column.name);
- checkTrue(column.type instanceof MapType, "Column %s cannot be used as a map", column.name);
- checkTrue(column.type.isMultiCell(), "Map-entry predicates on frozen map column %s are not supported", column.name);
+ AbstractType<?> baseType = column.type.unwrap();
+ checkFalse(baseType instanceof ListType, "Indexes on list entries (%s[index] = value) are not supported.", column.name);
+ checkTrue(baseType instanceof MapType, "Column %s cannot be used as a map", column.name);
+ checkTrue(baseType.isMultiCell(), "Map-entry predicates on frozen map column %s are not supported", column.name);
columnsExpression.collectMarkerSpecification(boundNames);
}
diff --git a/test/unit/org/apache/cassandra/cql3/validation/operations/SelectSingleColumnRelationTest.java b/test/unit/org/apache/cassandra/cql3/validation/operations/SelectSingleColumnRelationTest.java
index 2cfd05c..5024eea 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/operations/SelectSingleColumnRelationTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/operations/SelectSingleColumnRelationTest.java
@@ -30,6 +30,14 @@
public class SelectSingleColumnRelationTest extends CQLTester
{
@Test
+ public void textInvalidMapEntryPredicate() throws Throwable
+ {
+ createTable("CREATE TABLE %s (pk int, ck frozen<map<int, int>>, v int, PRIMARY KEY(pk, ck)) WITH CLUSTERING ORDER BY (ck DESC)");
+ assertInvalidMessage("Map-entry predicates on frozen map column ck are not supported",
+ "SELECT * FROM %s WHERE pk=? AND ck[0] = ?", 0, 0);
+ }
+
+ @Test
public void testInvalidCollectionEqualityRelation() throws Throwable
{
createTable("CREATE TABLE %s (a int PRIMARY KEY, b set<int>, c list<int>, d map<int, int>)");