You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by ee...@apache.org on 2010/10/31 15:37:57 UTC

svn commit: r1029368 - in /cassandra/trunk: doc/cql/ drivers/py/cql/ lib/ src/java/org/apache/cassandra/avro/ src/java/org/apache/cassandra/cql/ test/system/

Author: eevans
Date: Sun Oct 31 14:37:56 2010
New Revision: 1029368

URL: http://svn.apache.org/viewvc?rev=1029368&view=rev
Log:
misc (de)bug rollup

* propagate parse exceptions as avro InvalidRequestExceptions
* use more reasonable defaults for col and row limits (else OOM)
* working range query system test
* actually set column timestamp in return results
* validate keys in UPDATE
* process row mutations exactly once
* javadoc cleanup / updates
* explicitly disabled nagle in python driver
* query logging is brutal, move to trace
* upgrade jetty to 6.1.24

Patch by eevans

Added:
    cassandra/trunk/lib/jetty-6.1.24.jar
    cassandra/trunk/lib/jetty-util-6.1.24.jar
Removed:
    cassandra/trunk/lib/jetty-6.1.21.jar
    cassandra/trunk/lib/jetty-util-6.1.21.jar
Modified:
    cassandra/trunk/doc/cql/CQL.textile
    cassandra/trunk/drivers/py/cql/__init__.py
    cassandra/trunk/src/java/org/apache/cassandra/avro/AvroValidation.java
    cassandra/trunk/src/java/org/apache/cassandra/cql/CQLStatement.java
    cassandra/trunk/src/java/org/apache/cassandra/cql/Column.java
    cassandra/trunk/src/java/org/apache/cassandra/cql/Cql.g
    cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java
    cassandra/trunk/src/java/org/apache/cassandra/cql/Relation.java
    cassandra/trunk/src/java/org/apache/cassandra/cql/Row.java
    cassandra/trunk/src/java/org/apache/cassandra/cql/SelectStatement.java
    cassandra/trunk/src/java/org/apache/cassandra/cql/StatementType.java
    cassandra/trunk/src/java/org/apache/cassandra/cql/Term.java
    cassandra/trunk/src/java/org/apache/cassandra/cql/UpdateStatement.java
    cassandra/trunk/test/system/__init__.py
    cassandra/trunk/test/system/test_cql.py

Modified: cassandra/trunk/doc/cql/CQL.textile
URL: http://svn.apache.org/viewvc/cassandra/trunk/doc/cql/CQL.textile?rev=1029368&r1=1029367&r2=1029368&view=diff
==============================================================================
--- cassandra/trunk/doc/cql/CQL.textile (original)
+++ cassandra/trunk/doc/cql/CQL.textile Sun Oct 31 14:37:56 2010
@@ -54,7 +54,7 @@ h3. Limits
 bc. 
 SELECT ... <EXPRESSION> [ROWLIMIT N | COLLIMIT N] ...
 
-Limiting the number of row and/or column results can be achieved by including one or both of the optional @ROWLIMIT@ and @COLLIMIT@ clauses after a @SELECT@ expression.
+Limiting the number of row and/or column results can be achieved by including one or both of the optional @ROWLIMIT@ and @COLLIMIT@ clauses after a @SELECT@ expression. Both @ROWLIMIT@ and @COLLIMIT@ default to 10,000 when left unset.
 
 h3. Ordering
 

Modified: cassandra/trunk/drivers/py/cql/__init__.py
URL: http://svn.apache.org/viewvc/cassandra/trunk/drivers/py/cql/__init__.py?rev=1029368&r1=1029367&r2=1029368&view=diff
==============================================================================
--- cassandra/trunk/drivers/py/cql/__init__.py (original)
+++ cassandra/trunk/drivers/py/cql/__init__.py Sun Oct 31 14:37:56 2010
@@ -1,6 +1,6 @@
 
 from avro.ipc  import HTTPTransceiver, Requestor
-import avro.protocol, zlib
+import avro.protocol, zlib, socket
 from os.path   import exists, abspath, dirname, join
 
 def _load_protocol():
@@ -29,6 +29,8 @@ DEFAULT_COMPRESSION = 'GZIP'
 class Connection(object):
     def __init__(self, keyspace, host, port=9160):
         client = HTTPTransceiver(host, port)
+        # disabled nagle
+        client.conn.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
         self.requestor = Requestor(_load_protocol(), client)
         if keyspace:
             self.execute('USE %s' % keyspace)

Added: cassandra/trunk/lib/jetty-6.1.24.jar
URL: http://svn.apache.org/viewvc/cassandra/trunk/lib/jetty-6.1.24.jar?rev=1029368&view=auto
==============================================================================
Files cassandra/trunk/lib/jetty-6.1.24.jar (added) and cassandra/trunk/lib/jetty-6.1.24.jar Sun Oct 31 14:37:56 2010 differ

Added: cassandra/trunk/lib/jetty-util-6.1.24.jar
URL: http://svn.apache.org/viewvc/cassandra/trunk/lib/jetty-util-6.1.24.jar?rev=1029368&view=auto
==============================================================================
Files cassandra/trunk/lib/jetty-util-6.1.24.jar (added) and cassandra/trunk/lib/jetty-util-6.1.24.jar Sun Oct 31 14:37:56 2010 differ

Modified: cassandra/trunk/src/java/org/apache/cassandra/avro/AvroValidation.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/avro/AvroValidation.java?rev=1029368&r1=1029367&r2=1029368&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/avro/AvroValidation.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/avro/AvroValidation.java Sun Oct 31 14:37:56 2010
@@ -68,7 +68,7 @@ public class AvroValidation
     }
     
     // FIXME: could use method in ThriftValidation
-    static ColumnFamilyType validateColumnFamily(String keyspace, String columnFamily) throws InvalidRequestException
+    public static ColumnFamilyType validateColumnFamily(String keyspace, String columnFamily) throws InvalidRequestException
     {
         if (columnFamily.isEmpty())
             throw newInvalidRequestException("non-empty columnfamily is required");

Modified: cassandra/trunk/src/java/org/apache/cassandra/cql/CQLStatement.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/CQLStatement.java?rev=1029368&r1=1029367&r2=1029368&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/CQLStatement.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/CQLStatement.java Sun Oct 31 14:37:56 2010
@@ -1,4 +1,3 @@
-package org.apache.cassandra.cql;
 /*
  * 
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -19,7 +18,7 @@ package org.apache.cassandra.cql;
  * under the License.
  * 
  */
-
+package org.apache.cassandra.cql;
 
 public class CQLStatement
 {

Modified: cassandra/trunk/src/java/org/apache/cassandra/cql/Column.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/Column.java?rev=1029368&r1=1029367&r2=1029368&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/Column.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/Column.java Sun Oct 31 14:37:56 2010
@@ -1,4 +1,3 @@
-package org.apache.cassandra.cql;
 /*
  * 
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -19,8 +18,12 @@ package org.apache.cassandra.cql;
  * under the License.
  * 
  */
+package org.apache.cassandra.cql;
 
-
+/**
+ * Represents a column definition parsed from CQL query statement.
+ *
+ */
 public class Column
 {
     private final Term name;

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=1029368&r1=1029367&r2=1029368&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/Cql.g (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/Cql.g Sun Oct 31 14:37:56 2010
@@ -6,7 +6,35 @@ options {
 
 @header {
     package org.apache.cassandra.cql;
+    import java.util.ArrayList;
     import org.apache.cassandra.thrift.ConsistencyLevel;
+    import org.apache.cassandra.avro.InvalidRequestException;
+}
+
+@members {
+    private List<String> recognitionErrors = new ArrayList<String>();
+    
+    public void displayRecognitionError(String[] tokenNames, RecognitionException e)
+    {
+        String hdr = getErrorHeader(e);
+        String msg = getErrorMessage(e, tokenNames);
+        recognitionErrors.add(hdr + " " + msg);
+    }
+    
+    public List<String> getRecognitionErrors()
+    {
+        return recognitionErrors;
+    }
+    
+    public void throwLastRecognitionError() throws InvalidRequestException
+    {
+        if (recognitionErrors.size() > 0)
+        {
+            InvalidRequestException invalidExcep = new InvalidRequestException();
+            invalidExcep.why = recognitionErrors.get((recognitionErrors.size()-1));
+            throw invalidExcep;
+        }
+    }
 }
 
 @lexer::header {
@@ -36,8 +64,8 @@ useStatement returns [String keyspace]
  */
 selectStatement returns [SelectStatement expr]
     : { 
-          int numRecords = Integer.MAX_VALUE;
-          int numColumns = Integer.MAX_VALUE;
+          int numRecords = 10000;
+          int numColumns = 10000;
           boolean reversed = false;
           ConsistencyLevel cLevel = ConsistencyLevel.ONE;
       }

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=1029368&r1=1029367&r2=1029368&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java Sun Oct 31 14:37:56 2010
@@ -59,6 +59,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import static org.apache.cassandra.avro.AvroValidation.validateKey;
+import static org.apache.cassandra.avro.AvroValidation.validateColumnFamily;
 
 public class QueryProcessor
 {
@@ -185,10 +186,11 @@ public class QueryProcessor
     public static CqlResult process(String queryString, ClientState clientState)
     throws RecognitionException, UnavailableException, InvalidRequestException, TimedOutException
     {
-        logger.debug("CQL QUERY: {}", queryString);
+        logger.trace("CQL QUERY: {}", queryString);
         
         CqlParser parser = getParser(queryString);
         CQLStatement statement = parser.query();
+        parser.throwLastRecognitionError();
         String keyspace = clientState.getKeyspace();
         
         CqlResult avroResult = new CqlResult();
@@ -221,6 +223,7 @@ public class QueryProcessor
                         Column avroColumn = new Column();
                         avroColumn.name = column.name();
                         avroColumn.value = column.value();
+                        avroColumn.timestamp = column.timestamp();
                         avroColumns.add(avroColumn);
                     }
                     
@@ -236,12 +239,15 @@ public class QueryProcessor
                 
             case UPDATE:
                 UpdateStatement update = (UpdateStatement)statement.statement;
+                validateColumnFamily(keyspace, update.getColumnFamily());
+                
                 avroResult.type = CqlResultType.VOID;
                 
                 List<RowMutation> rowMutations = new ArrayList<RowMutation>();
                 
                 for (Row row : update.getRows())
                 {
+                    validateKey(row.getKey().getByteBuffer());
                     RowMutation rm = new RowMutation(keyspace, row.getKey().getByteBuffer());
                     
                     for (org.apache.cassandra.cql.Column col : row.getColumns())
@@ -249,8 +255,9 @@ public class QueryProcessor
                         rm.add(new QueryPath(update.getColumnFamily(), null, col.getName().getByteBuffer()),
                                col.getValue().getByteBuffer(),
                                System.currentTimeMillis());
-                        rowMutations.add(rm);
                     }
+                    
+                    rowMutations.add(rm);
                 }
                 
                 try

Modified: cassandra/trunk/src/java/org/apache/cassandra/cql/Relation.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/Relation.java?rev=1029368&r1=1029367&r2=1029368&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/Relation.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/Relation.java Sun Oct 31 14:37:56 2010
@@ -1,4 +1,3 @@
-package org.apache.cassandra.cql;
 /*
  * 
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -19,13 +18,11 @@ package org.apache.cassandra.cql;
  * under the License.
  * 
  */
-
+package org.apache.cassandra.cql;
 
 /**
- * Relations encapsulate the relationship between an entity and a value. For
- * example, KEY > 'start' or COLUMN = 'somecolumn'.
- * 
- * @author eevans
+ * Relations encapsulate the relationship between an entity of some kind, and
+ * a value (term). For example, KEY > 'start' or COLUMN = 1000L.
  *
  */
 public class Relation
@@ -37,9 +34,9 @@ public class Relation
     /**
      * Creates a new relation.
      * 
-     * @param entity the kind of relation this is; what the value is compared to.
-     * @param type the type of relation; how how this entity relates to the value.
-     * @param value the value being compared to the entity.
+     * @param entity the kind of relation this is; what the term is being compared to.
+     * @param type the type that describes how this entity relates to the value.
+     * @param value the value being compared.
      */
     public Relation(String entity, String type, Term value)
     {

Modified: cassandra/trunk/src/java/org/apache/cassandra/cql/Row.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/Row.java?rev=1029368&r1=1029367&r2=1029368&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/Row.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/Row.java Sun Oct 31 14:37:56 2010
@@ -1,4 +1,3 @@
-package org.apache.cassandra.cql;
 /*
  * 
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -19,11 +18,15 @@ package org.apache.cassandra.cql;
  * under the License.
  * 
  */
-
+package org.apache.cassandra.cql;
 
 import java.util.ArrayList;
 import java.util.List;
 
+/**
+ * Represents a row parsed from a CQL statement.
+ *
+ */
 public class Row
 {
     private final Term key;
@@ -35,6 +38,11 @@ public class Row
         columns.add(firstColumn);
     }
     
+    /**
+     * Add a new column definition to this row.
+     * 
+     * @param col the CQL column to add.
+     */
     public void and(Column col)
     {
         columns.add(col);

Modified: cassandra/trunk/src/java/org/apache/cassandra/cql/SelectStatement.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/SelectStatement.java?rev=1029368&r1=1029367&r2=1029368&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/SelectStatement.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/SelectStatement.java Sun Oct 31 14:37:56 2010
@@ -1,4 +1,3 @@
-package org.apache.cassandra.cql;
 /*
  * 
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -19,15 +18,13 @@ package org.apache.cassandra.cql;
  * under the License.
  * 
  */
-
+package org.apache.cassandra.cql;
 
 import org.apache.cassandra.thrift.ConsistencyLevel;
 
 /**
  * Encapsulates a completely parsed SELECT query, including the target
  * column family, expression, result count, and ordering clause.
- * 
- * @author eevans
  *
  */
 public class SelectStatement

Modified: cassandra/trunk/src/java/org/apache/cassandra/cql/StatementType.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/StatementType.java?rev=1029368&r1=1029367&r2=1029368&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/StatementType.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/StatementType.java Sun Oct 31 14:37:56 2010
@@ -1,4 +1,3 @@
-package org.apache.cassandra.cql;
 /*
  * 
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -19,7 +18,7 @@ package org.apache.cassandra.cql;
  * under the License.
  * 
  */
-
+package org.apache.cassandra.cql;
 
 public enum StatementType
 {

Modified: cassandra/trunk/src/java/org/apache/cassandra/cql/Term.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/Term.java?rev=1029368&r1=1029367&r2=1029368&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/Term.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/Term.java Sun Oct 31 14:37:56 2010
@@ -1,4 +1,3 @@
-package org.apache.cassandra.cql;
 /*
  * 
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -19,17 +18,13 @@ package org.apache.cassandra.cql;
  * under the License.
  * 
  */
-
+package org.apache.cassandra.cql;
 
 import java.nio.ByteBuffer;
-
 import org.apache.cassandra.utils.FBUtilities;
 
 /**
- * Represents a term processed from a CQL query statement.  Terms are things
- * like strings, numbers, UUIDs, etc.
- * 
- * @author eevans
+ * A term parsed from a CQL statement.
  *
  */
 public class Term
@@ -57,9 +52,9 @@ public class Term
     }
 
     /**
-     * Get the text that was parsed to create this term.
+     * Returns the text parsed to create this term.
      * 
-     * @return the string term as parsed from a CQL statement.
+     * @return the string term acquired from a CQL statement.
      */
     public String getText()
     {
@@ -67,9 +62,9 @@ public class Term
     }
     
     /**
-     * Get the typed value, serialized to a ByteBuffer.
+     * Returns the typed value, serialized to a ByteBuffer.
      * 
-     * @return
+     * @return a ByteBuffer of the value.
      */
     public ByteBuffer getByteBuffer()
     {
@@ -86,7 +81,7 @@ public class Term
     }
 
     /**
-     * Get the term's type.
+     * Obtain the term's type.
      * 
      * @return the type
      */

Modified: cassandra/trunk/src/java/org/apache/cassandra/cql/UpdateStatement.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/UpdateStatement.java?rev=1029368&r1=1029367&r2=1029368&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/UpdateStatement.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/UpdateStatement.java Sun Oct 31 14:37:56 2010
@@ -1,4 +1,3 @@
-package org.apache.cassandra.cql;
 /*
  * 
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -19,19 +18,30 @@ package org.apache.cassandra.cql;
  * under the License.
  * 
  */
-
+package org.apache.cassandra.cql;
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.apache.cassandra.thrift.ConsistencyLevel;
 
+/**
+ * An <code>UPDATE</code> statement parsed from a CQL query statement.
+ *
+ */
 public class UpdateStatement
 {
     private String columnFamily;
     private List<Row> rows = new ArrayList<Row>();
     private ConsistencyLevel cLevel;
     
+    /**
+     * Creates a new UpdateStatement from a column family name, a row definition,
+     * and a consistency level.
+     * 
+     * @param columnFamily column family name
+     * @param first a row definition instance
+     * @param cLevel the thrift consistency level
+     */
     public UpdateStatement(String columnFamily, Row first, ConsistencyLevel cLevel)
     {
         this.columnFamily = columnFamily;
@@ -39,6 +49,11 @@ public class UpdateStatement
         and(first);
     }
     
+    /**
+     * Adds a new row definition to this <code>UPDATE</code>.
+     * 
+     * @param row the row definition to add.
+     */
     public void and(Row row)
     {
         rows.add(row);
@@ -58,4 +73,10 @@ public class UpdateStatement
     {
         return columnFamily;
     }
+    
+    public String toString()
+    {
+        return "UpdateStatement(columnFamily=" + columnFamily + ", " +
+            "row=" + rows + ", " + "consistency=" + cLevel + ")";
+    }
 }

Modified: cassandra/trunk/test/system/__init__.py
URL: http://svn.apache.org/viewvc/cassandra/trunk/test/system/__init__.py?rev=1029368&r1=1029367&r2=1029368&view=diff
==============================================================================
--- cassandra/trunk/test/system/__init__.py (original)
+++ cassandra/trunk/test/system/__init__.py Sun Oct 31 14:37:56 2010
@@ -207,6 +207,12 @@ class AvroTester(BaseTester):
 
         keyspace1['cf_defs'].append({
             'keyspace': 'Keyspace1',
+            'name': 'StandardLong1',
+            'comparator_type': 'LongType',
+        })
+
+        keyspace1['cf_defs'].append({
+            'keyspace': 'Keyspace1',
             'name': 'Super1',
             'column_type': 'Super',
             'comparator_type': 'BytesType',

Modified: cassandra/trunk/test/system/test_cql.py
URL: http://svn.apache.org/viewvc/cassandra/trunk/test/system/test_cql.py?rev=1029368&r1=1029367&r2=1029368&view=diff
==============================================================================
--- cassandra/trunk/test/system/test_cql.py (original)
+++ cassandra/trunk/test/system/test_cql.py Sun Oct 31 14:37:56 2010
@@ -17,18 +17,18 @@ def load_sample(dbconn):
             ROW("kc", COL("cc1", "vc1"), COL("col", "val")) AND
             ROW("kd", COL("cd1", "vd1"), COL("col", "val"));
     """)
-    #dbconn.execute("""
-    #  UPDATE
-    #      StandardLong1
-    #  WITH
-    #    ROW("aa", COL(1L, "1"), COL(2L, "2"), COL(3L, "3"), COL(4L, "4")) AND
-    #    ROW("ab", COL(5L, "5"), COL(6L, "6"), COL(7L, "8"), COL(9L, "9")) AND
-    #    ROW("ac", COL(9L, "9"), COL(8L, "8"), COL(7L, "7"), COL(6L, "6")) AND
-    #    ROW("ad", COL(5L, "5"), COL(4L, "4"), COL(3L, "3"), COL(2L, "2")) AND
-    #    ROW("ae", COL(1L, "1"), COL(2L, "2"), COL(3L, "3"), COL(4L, "4")) AND
-    #    ROW("af", COL(1L, "1"), COL(2L, "2"), COL(3L, "3"), COL(4L, "4")) AND
-    #    ROW("ag", COL(5L, "5"), COL(6L, "6"), COL(7L, "8"), COL(9L, "9")));
-    #""")
+    dbconn.execute("""
+      UPDATE
+          StandardLong1
+      WITH
+        ROW("aa", COL(1L, "1"), COL(2L, "2"), COL(3L, "3"), COL(4L, "4")) AND
+        ROW("ab", COL(5L, "5"), COL(6L, "6"), COL(7L, "8"), COL(9L, "9")) AND
+        ROW("ac", COL(9L, "9"), COL(8L, "8"), COL(7L, "7"), COL(6L, "6")) AND
+        ROW("ad", COL(5L, "5"), COL(4L, "4"), COL(3L, "3"), COL(2L, "2")) AND
+        ROW("ae", COL(1L, "1"), COL(2L, "2"), COL(3L, "3"), COL(4L, "4")) AND
+        ROW("af", COL(1L, "1"), COL(2L, "2"), COL(3L, "3"), COL(4L, "4")) AND
+        ROW("ag", COL(5L, "5"), COL(6L, "6"), COL(7L, "8"), COL(9L, "9"));
+    """)
 
 def init(keyspace="Keyspace1"):
     dbconn = Connection(keyspace, 'localhost', 9170)
@@ -81,9 +81,9 @@ class TestCql(AvroTester):
             assert result['key'] in ("ka", "kd", "kb")
             assert len(result['columns']) == 2
 
-    #def test_select_row_range(self):
-    #    "retrieve a range of rows with columns"
-    #    conn = init()
-    #    r = conn.execute("""
-    #        SELECT FROM Standard1Long WHERE KEY > "ad" AND KEY < "ag";
-    #    """)
+    def test_select_row_range(self):
+        "retrieve a range of rows with columns"
+        conn = init()
+        r = conn.execute("""
+            SELECT FROM StandardLong1 WHERE KEY > "ad" AND KEY < "ag";
+        """)