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"


Reply via email to