[ 
https://issues.apache.org/jira/browse/CASSANDRA-4327?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13292655#comment-13292655
 ] 

Stephen Powis edited comment on CASSANDRA-4327 at 6/11/12 1:55 PM:
-------------------------------------------------------------------

-- edit -- 
whoops
                
      was (Author: stephen.powis):
    diff --git 
a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java 
b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
index 9fb9bd7..7d13412 100644
--- a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
@@ -802,6 +802,9 @@ public class SelectStatement implements CQLStatement
                 cqlRows.add(new CqlRow(row.key.key, thriftColumns));
             }
         }
+        
+        // Order results
+        orderResults(cqlRows, parameters);
 
         // Internal calls always return columns in the comparator order, even 
when reverse was set
         if (isReversed)
@@ -812,6 +815,54 @@ public class SelectStatement implements CQLStatement
 
         return cqlRows;
     }
+    
+    /**
+     * Orders results when multiple keys are selected (using IN)
+     * Not a complete implementation
+     */
+    private void orderResults (List<CqlRow> cqlRows, Parameters parameters)
+    {
+       // If no rows, or we are not doing an IN query
+       if (cqlRows.size() == 0 || keyRestriction == null || 
keyRestriction.eqValues.size() < 2) 
+               return; 
+               
+               // Figure out what we are ordering by
+       String orderName = null;
+       int sortOrderColumnIndex = -1;
+       CFDefinition.Name name;
+       AbstractType<?> colType = null;
+               for (Map.Entry<ColumnIdentifier, Boolean> entry : 
parameters.orderings.entrySet()) {
+                   ColumnIdentifier column = entry.getKey();
+                   name = cfDef.get(column);
+                   orderName = name.toString();
+                   colType = name.type;
+               }
+               
+               // If no order, just return
+               if (orderName == null)
+                       return;
+               
+               // Grab first cqlRow
+               CqlRow cqlRow = cqlRows.get(0);
+               
+               // Loop over columns to find index
+               List<Column> columns = cqlRow.getColumns();
+               for (int x=0; x<columns.size(); x++) 
+               {
+                       // Grab column
+                       Column column = columns.get(x);
+                       
+                       // Grab name
+                       String colName = new String(column.getName());
+                       String colValue = new String(column.getValue());
+                       if (colName.equals(orderName)) 
+                       {
+                               sortOrderColumnIndex = x;
+                               x = columns.size();
+                       }
+               }
+               Collections.sort(cqlRows, new 
CqlRowComparator(sortOrderColumnIndex, colType));
+    }
 
     /**
      * For sparse composite, returns wheter two columns belong to the same
@@ -1068,8 +1119,8 @@ public class SelectStatement implements CQLStatement
                 // since otherwise the order will be primarily on the row key.
                 // TODO: we could allow ordering for IN queries, as we can do 
the
                 // sorting post-query easily, but we will have to add it
-                if (stmt.keyRestriction == null || 
!stmt.keyRestriction.isEquality() || stmt.keyRestriction.eqValues.size() != 1)
-                    throw new InvalidRequestException("Ordering is only 
supported if the first part of the PRIMARY KEY is restricted by an Equal");
+                //if (stmt.keyRestriction == null || 
!stmt.keyRestriction.isEquality() || stmt.keyRestriction.eqValues.size() != 1)
+                //    throw new InvalidRequestException("Ordering is only 
supported if the first part of the PRIMARY KEY is restricted by an Equal");
             }
 
             // If this is a query on tokens, it's necessary a range query 
(there can be more than one key per token), so reject IN queries (as we don't 
know how to do them)
@@ -1273,4 +1324,29 @@ public class SelectStatement implements CQLStatement
             this.isCount = isCount;
         }
     }
+    
+    /**
+     * quick and dirty CqlRowcomparator
+     * I'm guessing something like this may already exist elsewhere in the code
+     * that should be used instead?
+     */
+    private static class CqlRowComparator implements Comparator<CqlRow> 
+    {
+        private int sortIndex;
+        private AbstractType<?> colType;
+
+        private CqlRowComparator(int sortIndex, AbstractType<?> colType) 
+        {
+            this.sortIndex = sortIndex;
+            this.colType = colType;
+        }
+
+        public int compare(CqlRow o1, CqlRow o2) 
+        {
+             // Grab values we need to compare
+            Column col1 = o1.getColumns().get(sortIndex);
+            Column col2 = o2.getColumns().get(sortIndex);
+            return colType.compare(col1.bufferForValue(), 
col2.bufferForValue());
+        }
+    }
 }

                  
> Sorting results when using IN() 
> --------------------------------
>
>                 Key: CASSANDRA-4327
>                 URL: https://issues.apache.org/jira/browse/CASSANDRA-4327
>             Project: Cassandra
>          Issue Type: Improvement
>    Affects Versions: 1.1.1
>            Reporter: Stephen Powis
>            Priority: Minor
>              Labels: cql3, patch, sort
>             Fix For: 1.1.2
>
>         Attachments: trunk-4327.txt
>
>
> Using the following test schema:
> CREATE TABLE test (
>   my_id varchar, 
>   time_id uuid,
>   value int,
>   PRIMARY KEY (my_id, time_id)
> );
> When you issue a CQL3 query like: 
> select * from test where my_id in('key1', 'key2') order by time_id; 
> You receive the error:
> "Ordering is only supported if the first part of the PRIMARY KEY is 
> restricted by an Equal"
> I'm including a patch I put together after spending an hour or two poking 
> thru the code base that sorts the results for these types of queries.  I'm 
> hoping someone with a deeper understanding of Cassandra's code base can take 
> a look at it, clean it up or use it as a starting place, and include it in an 
> upcoming release.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: 
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Reply via email to