diff --git a/CHANGES.txt b/CHANGES.txt index e93b16c817..5404f83a98 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -26,6 +26,8 @@ * Configurable client timeout for cqlsh (CASSANDRA-7516) * Include snippet of CQL query near syntax error in messages (CASSANDRA-7111) Merged from 2.0: + * Explicitly disallow mixing multi-column and single-column + relations on clustering columns (CASSANDRA-7711) * Better error message when condition is set on PK column (CASSANDRA-7804) * Don't send schema change responses and events for no-op DDL statements (CASSANDRA-7600) @@ -69,7 +71,6 @@ Merged from 2.0: 2.0.10 ->>>>>>> cassandra-2.0 * Don't send schema change responses and events for no-op DDL statements (CASSANDRA-7600) * (Hadoop) fix cluster initialisation for a split fetching (CASSANDRA-7774) diff --git a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java index a2e6624e38..586eb853f0 100644 --- a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java @@ -1386,6 +1386,8 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache */ boolean hasQueriableIndex = false; boolean hasQueriableClusteringColumnIndex = false; + boolean hasSingleColumnRelations = false; + boolean hasMultiColumnRelations = false; for (Relation relation : whereClause) { if (relation.isMultiColumn()) @@ -1399,6 +1401,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache hasQueriableIndex |= queriable[0]; hasQueriableClusteringColumnIndex |= queriable[1]; names.add(def); + hasMultiColumnRelations |= ColumnDefinition.Kind.CLUSTERING_COLUMN.equals(def.kind); } updateRestrictionsForRelation(stmt, names, rel, boundNames); } @@ -1410,9 +1413,12 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache boolean[] queriable = processRelationEntity(stmt, relation, entity, def); hasQueriableIndex |= queriable[0]; hasQueriableClusteringColumnIndex |= queriable[1]; + hasSingleColumnRelations |= ColumnDefinition.Kind.CLUSTERING_COLUMN.equals(def.kind); updateRestrictionsForRelation(stmt, def, rel, boundNames); } } + if (hasSingleColumnRelations && hasMultiColumnRelations) + throw new InvalidRequestException("Mixing single column relations and multi column relations on clustering columns is not allowed"); // At this point, the select statement if fully constructed, but we still have a few things to validate processPartitionKeyRestrictions(stmt, hasQueriableIndex, cfm); diff --git a/test/unit/org/apache/cassandra/cql3/MultiColumnRelationTest.java b/test/unit/org/apache/cassandra/cql3/MultiColumnRelationTest.java index bfc6d2d189..bcf4f27328 100644 --- a/test/unit/org/apache/cassandra/cql3/MultiColumnRelationTest.java +++ b/test/unit/org/apache/cassandra/cql3/MultiColumnRelationTest.java @@ -69,6 +69,9 @@ public class MultiColumnRelationTest extends CQLTester assertInvalid("SELECT * FROM %s WHERE (a, b, c, d) IN ((?, ?, ?, ?))", 0, 1, 2, 3); assertInvalid("SELECT * FROM %s WHERE (c, d) IN ((?, ?))", 0, 1); + + assertInvalid("SELECT * FROM %s WHERE a = ? AND (b, c) in ((?, ?), (?, ?)) AND d > ?", 0, 0, 0, 0, 0, 0); + } @Test