cassandra-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Stephen Powis (JIRA)" <j...@apache.org>
Subject [jira] [Comment Edited] (CASSANDRA-4327) Sorting results when using IN()
Date Mon, 11 Jun 2012 13:56:43 GMT

    [ 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

        

Mime
View raw message