Repository: cassandra Updated Branches: refs/heads/cassandra-2.0 d72777bd5 -> 6574de534
Fix bound building for multi-column IN restrictions Patch by Tyler Hobbs and Sylvain Lebresne as a follow up on CASSANDRA-6875 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/6574de53 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/6574de53 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/6574de53 Branch: refs/heads/cassandra-2.0 Commit: 6574de53429e923121e1ee6df197bfa149208742 Parents: d72777b Author: Tyler Hobbs <[email protected]> Authored: Thu May 29 12:56:12 2014 -0500 Committer: Tyler Hobbs <[email protected]> Committed: Thu May 29 12:56:12 2014 -0500 ---------------------------------------------------------------------- .../cql3/statements/SelectStatement.java | 8 +-- .../cassandra/cql3/MultiColumnRelationTest.java | 64 +++++++++++++++++++- 2 files changed, 66 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/6574de53/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java index 2710f78..7a91517 100644 --- a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java @@ -811,7 +811,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache if (firstRestriction.isSlice()) return buildMultiColumnSliceBound(bound, names, (MultiColumnRestriction.Slice) firstRestriction, isReversed, builder, variables); else if (firstRestriction.isIN()) - return buildMultiColumnInBound(bound, names, (MultiColumnRestriction.IN) firstRestriction, isReversed, builder, variables); + return buildMultiColumnInBound(bound, (MultiColumnRestriction.IN) firstRestriction, isReversed, builder, variables); else return buildMultiColumnEQBound(bound, (MultiColumnRestriction.EQ) firstRestriction, isReversed, builder, variables); } @@ -920,26 +920,24 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache } private List<ByteBuffer> buildMultiColumnInBound(Bound bound, - Collection<CFDefinition.Name> names, MultiColumnRestriction.IN restriction, boolean isReversed, ColumnNameBuilder builder, List<ByteBuffer> variables) throws InvalidRequestException { List<List<ByteBuffer>> splitInValues = restriction.splitValues(variables); + Bound eocBound = isReversed ? Bound.reverse(bound) : bound; // The IN query might not have listed the values in comparator order, so we need to re-sort // the bounds lists to make sure the slices works correctly (also, to avoid duplicates). TreeSet<ByteBuffer> inValues = new TreeSet<>(isReversed ? cfDef.cfm.comparator.reverseComparator : cfDef.cfm.comparator); - Iterator<CFDefinition.Name> iter = names.iterator(); for (List<ByteBuffer> components : splitInValues) { ColumnNameBuilder nameBuilder = builder.copy(); for (ByteBuffer component : components) nameBuilder.add(component); - Bound b = isReversed == isReversedType(iter.next()) ? bound : Bound.reverse(bound); - inValues.add((bound == Bound.END && nameBuilder.remainingCount() > 0) ? nameBuilder.buildAsEndOfRange() : nameBuilder.build()); + inValues.add((eocBound == Bound.END && nameBuilder.remainingCount() > 0) ? nameBuilder.buildAsEndOfRange() : nameBuilder.build()); } return new ArrayList<>(inValues); } http://git-wip-us.apache.org/repos/asf/cassandra/blob/6574de53/test/unit/org/apache/cassandra/cql3/MultiColumnRelationTest.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/cql3/MultiColumnRelationTest.java b/test/unit/org/apache/cassandra/cql3/MultiColumnRelationTest.java index b728cba..121a8d3 100644 --- a/test/unit/org/apache/cassandra/cql3/MultiColumnRelationTest.java +++ b/test/unit/org/apache/cassandra/cql3/MultiColumnRelationTest.java @@ -568,6 +568,68 @@ public class MultiColumnRelationTest checkRow(0, results, 0, 0, 0, 0); checkRow(1, results, 0, 0, 1, 0); checkRow(2, results, 0, 0, 1, 1); + + results = execute("SELECT * FROM %s.multiple_clustering WHERE a=0 AND (b, c) IN ((0, 1)) ORDER BY b DESC, c DESC, d DESC"); + assertEquals(2, results.size()); + checkRow(0, results, 0, 0, 1, 1); + checkRow(1, results, 0, 0, 1, 0); + } + + + @Test + public void testLiteralInReversed() throws Throwable + { + execute("INSERT INTO %s.multiple_clustering_reversed (a, b, c, d) VALUES (0, 1, 0, 0)"); + execute("INSERT INTO %s.multiple_clustering_reversed (a, b, c, d) VALUES (0, 0, 0, 0)"); + execute("INSERT INTO %s.multiple_clustering_reversed (a, b, c, d) VALUES (0, 0, 1, 1)"); + execute("INSERT INTO %s.multiple_clustering_reversed (a, b, c, d) VALUES (0, 0, 1, 0)"); + execute("INSERT INTO %s.multiple_clustering_reversed (a, b, c, d) VALUES (0, -1, 0, 0)"); + + UntypedResultSet results = execute("SELECT * FROM %s.multiple_clustering_reversed WHERE a=0 AND (b, c, d) IN ((0, 1, 0), (0, 1, 1))"); + assertEquals(2, results.size()); + checkRow(0, results, 0, 0, 1, 1); + checkRow(1, results, 0, 0, 1, 0); + + // same query, but reversed order for the IN values + results = execute("SELECT * FROM %s.multiple_clustering_reversed WHERE a=0 AND (b, c, d) IN ((0, 1, 1), (0, 1, 0))"); + assertEquals(2, results.size()); + checkRow(0, results, 0, 0, 1, 1); + checkRow(1, results, 0, 0, 1, 0); + + results = execute("SELECT * FROM %s.multiple_clustering_reversed WHERE a=0 AND (b, c, d) IN ((1, 0, 0), (0, 0, 0), (0, 1, 1), (0, 1, 0), (-1, 0, 0))"); + assertEquals(5, results.size()); + checkRow(0, results, 0, 1, 0, 0); + checkRow(1, results, 0, 0, 0, 0); + checkRow(2, results, 0, 0, 1, 1); + checkRow(3, results, 0, 0, 1, 0); + checkRow(4, results, 0, -1, 0, 0); + + results = execute("SELECT * FROM %s.multiple_clustering_reversed WHERE a=0 AND (b, c, d) IN ((0, 0, 0))"); + assertEquals(1, results.size()); + checkRow(0, results, 0, 0, 0, 0); + + results = execute("SELECT * FROM %s.multiple_clustering_reversed WHERE a=0 AND (b, c, d) IN ((0, 1, 1))"); + assertEquals(1, results.size()); + checkRow(0, results, 0, 0, 1, 1); + + results = execute("SELECT * FROM %s.multiple_clustering_reversed WHERE a=0 AND (b, c, d) IN ((0, 1, 0))"); + assertEquals(1, results.size()); + checkRow(0, results, 0, 0, 1, 0); + + results = execute("SELECT * FROM %s.multiple_clustering_reversed WHERE a=0 and (b, c) IN ((0, 1))"); + assertEquals(2, results.size()); + checkRow(0, results, 0, 0, 1, 1); + checkRow(1, results, 0, 0, 1, 0); + + results = execute("SELECT * FROM %s.multiple_clustering_reversed WHERE a=0 and (b, c) IN ((0, 0))"); + assertEquals(1, results.size()); + checkRow(0, results, 0, 0, 0, 0); + + results = execute("SELECT * FROM %s.multiple_clustering_reversed WHERE a=0 and (b) IN ((0))"); + assertEquals(3, results.size()); + checkRow(0, results, 0, 0, 0, 0); + checkRow(1, results, 0, 0, 1, 1); + checkRow(2, results, 0, 0, 1, 0); } @Test(expected=InvalidRequestException.class) @@ -1109,4 +1171,4 @@ public class MultiColumnRelationTest (long) expected, actual); } } -} \ No newline at end of file +}
