Repository: cassandra
Updated Branches:
  refs/heads/trunk 6f2b855c6 -> 737a3385c


Fix sorting for queries with an IN condition on partition key columns

patch by Benjamin Lerer; reviewed by Sam Tunnicliffe for CASSANDRA-10363


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/f587397c
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/f587397c
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/f587397c

Branch: refs/heads/trunk
Commit: f587397c9c41c1a68b4e46fc16bad8d48c975e4d
Parents: 806378c
Author: blerer <benjamin.le...@datastax.com>
Authored: Fri Oct 16 14:41:54 2015 +0200
Committer: blerer <benjamin.le...@datastax.com>
Committed: Fri Oct 16 14:41:54 2015 +0200

----------------------------------------------------------------------
 .../cassandra/cql3/ColumnSpecification.java     | 10 ++++
 .../org/apache/cassandra/cql3/ResultSet.java    |  5 ++
 .../apache/cassandra/cql3/UntypedResultSet.java |  6 +--
 .../cql3/statements/SelectStatement.java        | 18 +------
 .../cassandra/cql3/statements/Selection.java    | 45 +++++++++++++++-
 .../org/apache/cassandra/cql3/CQLTester.java    |  3 +-
 .../operations/SelectOrderByTest.java           | 54 +++++++++++++++++++-
 7 files changed, 116 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/f587397c/src/java/org/apache/cassandra/cql3/ColumnSpecification.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/ColumnSpecification.java 
b/src/java/org/apache/cassandra/cql3/ColumnSpecification.java
index f5f921d..836c6b9 100644
--- a/src/java/org/apache/cassandra/cql3/ColumnSpecification.java
+++ b/src/java/org/apache/cassandra/cql3/ColumnSpecification.java
@@ -55,4 +55,14 @@ public class ColumnSpecification
     {
         return Objects.hashCode(ksName, cfName, name, type);
     }
+
+    @Override
+    public String toString()
+    {
+        return Objects.toStringHelper(this)
+                      .add("name", name)
+                      .add("type", type)
+                      .toString();
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/f587397c/src/java/org/apache/cassandra/cql3/ResultSet.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/ResultSet.java 
b/src/java/org/apache/cassandra/cql3/ResultSet.java
index 813fd48..85cba57 100644
--- a/src/java/org/apache/cassandra/cql3/ResultSet.java
+++ b/src/java/org/apache/cassandra/cql3/ResultSet.java
@@ -284,6 +284,11 @@ public class ResultSet
             return names == null ? columnCount : names.size();
         }
 
+        /**
+         * Adds the specified column which will not be serialized.
+         *
+         * @param name the column
+         */
         public void addNonSerializedColumn(ColumnSpecification name)
         {
             // See comment above. Because columnCount doesn't account the 
newly added name, it

http://git-wip-us.apache.org/repos/asf/cassandra/blob/f587397c/src/java/org/apache/cassandra/cql3/UntypedResultSet.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/UntypedResultSet.java 
b/src/java/org/apache/cassandra/cql3/UntypedResultSet.java
index 81482ef..a0b6ae7 100644
--- a/src/java/org/apache/cassandra/cql3/UntypedResultSet.java
+++ b/src/java/org/apache/cassandra/cql3/UntypedResultSet.java
@@ -76,7 +76,7 @@ public abstract class UntypedResultSet implements 
Iterable<UntypedResultSet.Row>
         {
             if (cqlRows.rows.size() != 1)
                 throw new IllegalStateException("One row required, " + 
cqlRows.rows.size() + " found");
-            return new Row(cqlRows.metadata.names, cqlRows.rows.get(0));
+            return new Row(cqlRows.metadata.requestNames(), 
cqlRows.rows.get(0));
         }
 
         public Iterator<Row> iterator()
@@ -89,7 +89,7 @@ public abstract class UntypedResultSet implements 
Iterable<UntypedResultSet.Row>
                 {
                     if (!iter.hasNext())
                         return endOfData();
-                    return new Row(cqlRows.metadata.names, iter.next());
+                    return new Row(cqlRows.metadata.requestNames(), 
iter.next());
                 }
             };
         }
@@ -154,7 +154,7 @@ public abstract class UntypedResultSet implements 
Iterable<UntypedResultSet.Row>
             this.select = select;
             this.pager = pager;
             this.pageSize = pageSize;
-            this.metadata = select.getResultMetadata().names;
+            this.metadata = select.getResultMetadata().requestNames();
         }
 
         public int size()

http://git-wip-us.apache.org/repos/asf/cassandra/blob/f587397c/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 44b780e..8a6d704 100644
--- a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
@@ -2207,7 +2207,7 @@ public class SelectStatement implements CQLStatement
                     if (def == null)
                         handleUnrecognizedOrderingColumn(column);
 
-                    int index = indexOf(def, stmt.selection);
+                    int index = stmt.selection.getResultSetIndex(def);
                     if (index < 0)
                         index = stmt.selection.addColumnForOrdering(def);
                     stmt.orderingIndexes.put(def.name, index);
@@ -2326,22 +2326,6 @@ public class SelectStatement implements CQLStatement
             return needFiltering;
         }
 
-        private int indexOf(ColumnDefinition def, Selection selection)
-        {
-            return indexOf(def, selection.getColumns().iterator());
-        }
-
-        private int indexOf(final ColumnDefinition def, 
Iterator<ColumnDefinition> defs)
-        {
-            return Iterators.indexOf(defs, new Predicate<ColumnDefinition>()
-                                           {
-                                               public boolean 
apply(ColumnDefinition n)
-                                               {
-                                                   return 
def.name.equals(n.name);
-                                               }
-                                           });
-        }
-
         private SingleColumnRelation 
findInclusiveClusteringRelationForCompact(CFMetaData cfm)
         {
             for (Relation r : whereClause)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/f587397c/src/java/org/apache/cassandra/cql3/statements/Selection.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/Selection.java 
b/src/java/org/apache/cassandra/cql3/statements/Selection.java
index d29b917..f50ec1b 100644
--- a/src/java/org/apache/cassandra/cql3/statements/Selection.java
+++ b/src/java/org/apache/cassandra/cql3/statements/Selection.java
@@ -20,7 +20,6 @@ package org.apache.cassandra.cql3.statements;
 import java.nio.ByteBuffer;
 import java.util.*;
 
-import com.google.common.collect.Iterators;
 import com.google.common.collect.Lists;
 
 import org.apache.cassandra.cql3.ColumnSpecification;
@@ -105,6 +104,29 @@ public abstract class Selection
         return columns.size() - 1;
     }
 
+    /**
+     * Returns the index of the specified column within the resultset
+     * @param c the column
+     * @return the index of the specified column within the resultset or -1
+     */
+    public int getResultSetIndex(ColumnDefinition c)
+    {
+        return getColumnIndex(c);
+    }
+
+    /**
+     * Returns the index of the specified column
+     * @param c the column
+     * @return the index of the specified column or -1
+     */
+    protected final int getColumnIndex(ColumnDefinition c)
+    {
+        for (int i = 0, m = columns.size(); i < m; i++)
+            if (columns.get(i).name.equals(c.name))
+                return i;
+        return -1;
+    }
+
     private static boolean requiresProcessing(List<RawSelector> rawSelectors)
     {
         for (RawSelector rawSelector : rawSelectors)
@@ -507,11 +529,30 @@ public abstract class Selection
         }
 
         @Override
+        public int getResultSetIndex(ColumnDefinition c)
+        {
+            int index = getColumnIndex(c);
+
+            if (index < 0)
+                return -1;
+
+            for (int i = 0, m = selectors.size(); i < m; i++)
+            {
+                Selector selector = selectors.get(i);
+                if (selector instanceof SimpleSelector && ((SimpleSelector) 
selector).idx == index)
+                {
+                    return i;
+                }
+            }
+            return -1;
+        }
+
+        @Override
         public int addColumnForOrdering(ColumnDefinition c)
         {
             int index = super.addColumnForOrdering(c);
             selectors.add(new SimpleSelector(c.name.toString(), index, 
c.type));
-            return index;
+            return selectors.size() - 1;
         }
     }
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/f587397c/test/unit/org/apache/cassandra/cql3/CQLTester.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/CQLTester.java 
b/test/unit/org/apache/cassandra/cql3/CQLTester.java
index 8e620af..5288c2f 100644
--- a/test/unit/org/apache/cassandra/cql3/CQLTester.java
+++ b/test/unit/org/apache/cassandra/cql3/CQLTester.java
@@ -416,8 +416,7 @@ public abstract class CQLTester
             for (int j = 0; j < meta.size(); j++)
             {
                 ColumnSpecification column = meta.get(j);
-                Object expectedValue = expected[j];
-                ByteBuffer expectedByteValue = makeByteBuffer(expected[j], 
(AbstractType)column.type);
+                ByteBuffer expectedByteValue = makeByteBuffer(expected[j], 
column.type);
                 ByteBuffer actualValue = 
actual.getBytes(column.name.toString());
 
                 if (!Objects.equal(expectedByteValue, actualValue))

http://git-wip-us.apache.org/repos/asf/cassandra/blob/f587397c/test/unit/org/apache/cassandra/cql3/validation/operations/SelectOrderByTest.java
----------------------------------------------------------------------
diff --git 
a/test/unit/org/apache/cassandra/cql3/validation/operations/SelectOrderByTest.java
 
b/test/unit/org/apache/cassandra/cql3/validation/operations/SelectOrderByTest.java
index 9d2e594..cf923bc 100644
--- 
a/test/unit/org/apache/cassandra/cql3/validation/operations/SelectOrderByTest.java
+++ 
b/test/unit/org/apache/cassandra/cql3/validation/operations/SelectOrderByTest.java
@@ -316,7 +316,7 @@ public class SelectOrderByTest extends CQLTester
     }
 
     /**
-     * Check that order-by works with IN (#4327)
+     * Check that order-by works with IN (#4327, #10363)
      * migrated from cql_tests.py:TestCQL.order_by_with_in_test()
      */
     @Test
@@ -337,6 +337,58 @@ public class SelectOrderByTest extends CQLTester
 
         assertRows(execute("SELECT my_id, col1 FROM %s WHERE my_id in('key1', 
'key2', 'key3') ORDER BY col1"),
                    row("key1", 1), row("key3", 2), row("key2", 3));
+
+        createTable("CREATE TABLE %s (pk1 int, pk2 int, c int, v text, PRIMARY 
KEY ((pk1, pk2), c) )");
+        execute("INSERT INTO %s (pk1, pk2, c, v) VALUES (?, ?, ?, ?)", 1, 1, 
2, "A");
+        execute("INSERT INTO %s (pk1, pk2, c, v) VALUES (?, ?, ?, ?)", 1, 2, 
1, "B");
+        execute("INSERT INTO %s (pk1, pk2, c, v) VALUES (?, ?, ?, ?)", 1, 3, 
3, "C");
+        execute("INSERT INTO %s (pk1, pk2, c, v) VALUES (?, ?, ?, ?)", 1, 1, 
4, "D");
+
+        assertRows(execute("SELECT v, ttl(v), c FROM %s where pk1 = ? AND pk2 
IN (?, ?) ORDER BY c; ", 1, 1, 2),
+                   row("B", null, 1),
+                   row("A", null, 2),
+                   row("D", null, 4));
+
+        assertRows(execute("SELECT v, ttl(v), c as name_1 FROM %s where pk1 = 
? AND pk2 IN (?, ?) ORDER BY c; ", 1, 1, 2),
+                   row("B", null, 1),
+                   row("A", null, 2),
+                   row("D", null, 4));
+
+        assertRows(execute("SELECT v FROM %s where pk1 = ? AND pk2 IN (?, ?) 
ORDER BY c; ", 1, 1, 2),
+                   row("B"),
+                   row("A"),
+                   row("D"));
+
+        assertRows(execute("SELECT v as c FROM %s where pk1 = ? AND pk2 IN (?, 
?) ORDER BY c; ", 1, 1, 2),
+                   row("B"),
+                   row("A"),
+                   row("D"));
+
+        createTable("CREATE TABLE %s (pk1 int, pk2 int, c1 int, c2 int, v 
text, PRIMARY KEY ((pk1, pk2), c1, c2) )");
+        execute("INSERT INTO %s (pk1, pk2, c1, c2, v) VALUES (?, ?, ?, ?, ?)", 
1, 1, 4, 4, "A");
+        execute("INSERT INTO %s (pk1, pk2, c1, c2, v) VALUES (?, ?, ?, ?, ?)", 
1, 2, 1, 2, "B");
+        execute("INSERT INTO %s (pk1, pk2, c1, c2, v) VALUES (?, ?, ?, ?, ?)", 
1, 3, 3, 3, "C");
+        execute("INSERT INTO %s (pk1, pk2, c1, c2, v) VALUES (?, ?, ?, ?, ?)", 
1, 1, 4, 1, "D");
+
+        assertRows(execute("SELECT v, ttl(v), c1, c2 FROM %s where pk1 = ? AND 
pk2 IN (?, ?) ORDER BY c1, c2; ", 1, 1, 2),
+                   row("B", null, 1, 2),
+                   row("D", null, 4, 1),
+                   row("A", null, 4, 4));
+
+        assertRows(execute("SELECT v, ttl(v), c1 as name_1, c2 as name_2 FROM 
%s where pk1 = ? AND pk2 IN (?, ?) ORDER BY c1, c2; ", 1, 1, 2),
+                   row("B", null, 1, 2),
+                   row("D", null, 4, 1),
+                   row("A", null, 4, 4));
+
+        assertRows(execute("SELECT v FROM %s where pk1 = ? AND pk2 IN (?, ?) 
ORDER BY c1, c2; ", 1, 1, 2),
+                   row("B"),
+                   row("D"),
+                   row("A"));
+
+        assertRows(execute("SELECT v as c2 FROM %s where pk1 = ? AND pk2 IN 
(?, ?) ORDER BY c1, c2; ", 1, 1, 2),
+                   row("B"),
+                   row("D"),
+                   row("A"));
     }
 
     /**

Reply via email to