Author: eevans
Date: Thu Mar 17 19:40:56 2011
New Revision: 1082662
URL: http://svn.apache.org/viewvc?rev=1082662&view=rev
Log:
working slice-all queries (SELECT *)
Patch by eevans
Modified:
cassandra/trunk/src/java/org/apache/cassandra/cql/Cql.g
cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java
cassandra/trunk/test/system/test_cql.py
Modified: cassandra/trunk/src/java/org/apache/cassandra/cql/Cql.g
URL:
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/Cql.g?rev=1082662&r1=1082661&r2=1082662&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/Cql.g (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/Cql.g Thu Mar 17 19:40:56
2011
@@ -143,6 +143,7 @@ selectExpression returns [SelectExpressi
( first=term { $expr = new SelectExpression(first, count, reversed); }
(',' next=term { $expr.and(next); })*
| start=term RANGEOP finish=term { $expr = new SelectExpression(start,
finish, count, reversed); }
+ | '\*' { $expr = new SelectExpression(new Term(), new Term(), count,
reversed); }
)
;
Modified: cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java
URL:
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java?rev=1082662&r1=1082661&r2=1082662&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java
(original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java Thu
Mar 17 19:40:56 2011
@@ -100,15 +100,15 @@ public class QueryProcessor
// ...a range (slice) of column names
else
{
- validateColumnNames(keyspace,
- select.getColumnFamily(),
-
select.getColumnStart().getByteBuffer(comparator),
-
select.getColumnFinish().getByteBuffer(comparator));
+ ByteBuffer start =
select.getColumnStart().getByteBuffer(comparator);
+ ByteBuffer finish =
select.getColumnFinish().getByteBuffer(comparator);
+
+ validateSliceRange(keyspace, select.getColumnFamily(), start,
finish, select.isColumnsReversed());
commands.add(new SliceFromReadCommand(keyspace,
key,
queryPath,
-
select.getColumnStart().getByteBuffer(comparator),
-
select.getColumnFinish().getByteBuffer(comparator),
+ start,
+ finish,
select.isColumnsReversed(),
select.getColumnsLimit()));
}
@@ -370,9 +370,11 @@ public class QueryProcessor
for (ByteBuffer name : columns)
{
if (name.remaining() > IColumn.MAX_NAME_LENGTH)
- throw new InvalidRequestException();
+ throw new InvalidRequestException(String.format("column name
is too long (%s > %s)",
+
name.remaining(),
+
IColumn.MAX_NAME_LENGTH));
if (name.remaining() == 0)
- throw new InvalidRequestException();
+ throw new InvalidRequestException("zero-length column name");
try
{
comparator.validate(name);
@@ -419,11 +421,36 @@ public class QueryProcessor
throws InvalidRequestException
{
if (predicate.slice_range != null)
- validateColumnNames(keyspace, columnFamily,
predicate.slice_range.start, predicate.slice_range.finish);
+ validateSliceRange(keyspace, columnFamily, predicate.slice_range);
else
validateColumnNames(keyspace, columnFamily,
predicate.column_names);
}
+ private static void validateSliceRange(String keyspace, String
columnFamily, SliceRange range)
+ throws InvalidRequestException
+ {
+ validateSliceRange(keyspace, columnFamily, range.start, range.finish,
range.reversed);
+ }
+
+ private static void validateSliceRange(String keyspace, String
columnFamily, ByteBuffer start, ByteBuffer finish, boolean reversed)
+ throws InvalidRequestException
+ {
+ AbstractType<?> comparator = ColumnFamily.getComparatorFor(keyspace,
columnFamily, null);
+ try
+ {
+ comparator.validate(start);
+ comparator.validate(finish);
+ }
+ catch (MarshalException e)
+ {
+ throw new InvalidRequestException(e.getMessage());
+ }
+
+ Comparator<ByteBuffer> orderedComparator = reversed ?
comparator.reverseComparator: comparator;
+ if (start.remaining() > 0 && finish.remaining() > 0 &&
orderedComparator.compare(start, finish) > 0)
+ throw new InvalidRequestException("range finish must come after
start in traversal order");
+ }
+
// Copypasta from CassandraServer (where it is private).
private static void validateSchemaAgreement() throws
SchemaDisagreementException
{
Modified: cassandra/trunk/test/system/test_cql.py
URL:
http://svn.apache.org/viewvc/cassandra/trunk/test/system/test_cql.py?rev=1082662&r1=1082661&r2=1082662&view=diff
==============================================================================
--- cassandra/trunk/test/system/test_cql.py (original)
+++ cassandra/trunk/test/system/test_cql.py Thu Mar 17 19:40:56 2011
@@ -187,6 +187,14 @@ class TestCql(ThriftTester):
assert r[0].columns[0].value == "a"
assert r[0].columns[1].value == "b"
assert r[0].columns[2].value == "c"
+
+ def test_select_columns_slice_all(self):
+ "slice all columns in a row"
+ conn = init()
+ r = conn.execute("SELECT * FROM StandardString1 WHERE KEY = 'ka';")
+ assert len(r[0].columns) == 2
+ r = conn.execute("SELECT ''..'' FROM StandardString1 WHERE KEY =
'ka';")
+ assert len(r[0].columns) == 2
def test_select_columns_slice_with_limit(self):
"range of columns (slice) by row with limit"