[
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