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/11/12 20:33:07 UTC
svn commit: r1034538 - in /cassandra/trunk: drivers/py/cql/ interface/
src/java/org/apache/cassandra/cql/ test/system/
Author: eevans
Date: Fri Nov 12 19:33:06 2010
New Revision: 1034538
URL: http://svn.apache.org/viewvc?rev=1034538&view=rev
Log:
SELECT COUNT(...) FROM support
Patch by eevans
Modified:
cassandra/trunk/drivers/py/cql/__init__.py
cassandra/trunk/interface/cassandra.genavro
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/SelectStatement.java
cassandra/trunk/test/system/test_cql.py
Modified: cassandra/trunk/drivers/py/cql/__init__.py
URL: http://svn.apache.org/viewvc/cassandra/trunk/drivers/py/cql/__init__.py?rev=1034538&r1=1034537&r2=1034538&view=diff
==============================================================================
--- cassandra/trunk/drivers/py/cql/__init__.py (original)
+++ cassandra/trunk/drivers/py/cql/__init__.py Fri Nov 12 19:33:06 2010
@@ -51,6 +51,9 @@ class Connection(object):
if response['type'] == 'ROWS':
return response['rows']
+ if response['type'] == 'INT':
+ return response['num']
+
return None
@classmethod
Modified: cassandra/trunk/interface/cassandra.genavro
URL: http://svn.apache.org/viewvc/cassandra/trunk/interface/cassandra.genavro?rev=1034538&r1=1034537&r2=1034538&view=diff
==============================================================================
--- cassandra/trunk/interface/cassandra.genavro (original)
+++ cassandra/trunk/interface/cassandra.genavro Fri Nov 12 19:33:06 2010
@@ -381,7 +381,7 @@ protocol Cassandra {
}
enum CqlResultType {
- ROWS, VOID
+ ROWS, VOID, INT
}
record CqlRow {
@@ -392,6 +392,7 @@ protocol Cassandra {
record CqlResult {
CqlResultType type;
union { array<CqlRow>, null } rows;
+ union { int, null } num;
}
/**
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=1034538&r1=1034537&r2=1034538&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/Cql.g (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/Cql.g Fri Nov 12 19:33:06 2010
@@ -65,15 +65,22 @@ useStatement returns [String keyspace]
selectStatement returns [SelectStatement expr]
: {
int numRecords = 10000;
+ SelectExpression expression = null;
+ boolean isCountOp = false;
ConsistencyLevel cLevel = ConsistencyLevel.ONE;
}
- K_SELECT selectExpression K_FROM columnFamily=IDENT
+ K_SELECT
+ ( s1=selectExpression { expression = s1; }
+ | K_COUNT '(' s2=selectExpression ')' { expression = s2; isCountOp = true; }
+ )
+ K_FROM columnFamily=IDENT
( K_USING K_CONSISTENCY '.' K_LEVEL { cLevel = ConsistencyLevel.valueOf($K_LEVEL.text); } )?
( K_WHERE whereClause )?
( K_LIMIT rows=INTEGER { numRecords = Integer.parseInt($rows.text); } )?
endStmnt
{
- return new SelectStatement($selectExpression.expr,
+ return new SelectStatement(expression,
+ isCountOp,
$columnFamily.text,
cLevel,
$whereClause.clause,
@@ -169,6 +176,7 @@ K_LEVEL: ( O N E
K_USE: U S E;
K_FIRST: F I R S T;
K_REVERSED: R E V E R S E D;
+K_COUNT: C O U N T;
// Case-insensitive alpha characters
fragment A: ('a'|'A');
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=1034538&r1=1034537&r2=1034538&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java Fri Nov 12 19:33:06 2010
@@ -235,6 +235,9 @@ public class QueryProcessor
/* Test for SELECT-specific taboos */
private static void validateSelect(String keyspace, SelectStatement select) throws InvalidRequestException
{
+ if (select.isCountOperation() && (select.isKeyRange() || select.getKeys().size() < 1))
+ throw newInvalidRequestException("Counts can only be performed for a single record (Hint: KEY=term)");
+
// Finish key w/o start key (KEY < foo)
if (!select.isKeyRange() && (select.getKeyFinish() != null))
throw newInvalidRequestException("Key range clauses must include a start key (i.e. KEY > term)");
@@ -282,14 +285,23 @@ public class QueryProcessor
validateColumnFamily(keyspace, select.getColumnFamily());
validateSelect(keyspace, select);
- List<CqlRow> avroRows = new ArrayList<CqlRow>();
- avroResult.type = CqlResultType.ROWS;
List<org.apache.cassandra.db.Row> rows = null;
// By-key
if (!select.isKeyRange() && (select.getKeys().size() > 0))
{
rows = getSlice(keyspace, select);
+
+ // Only return the column count, (of the at-most 1 row).
+ if (select.isCountOperation())
+ {
+ avroResult.type = CqlResultType.INT;
+ if (rows.size() > 0)
+ avroResult.num = rows.get(0).cf != null ? rows.get(0).cf.getSortedColumns().size() : 0;
+ else
+ avroResult.num = 0;
+ return avroResult;
+ }
}
else
{
@@ -305,6 +317,9 @@ public class QueryProcessor
}
}
+ List<CqlRow> avroRows = new ArrayList<CqlRow>();
+ avroResult.type = CqlResultType.ROWS;
+
// Create the result set
for (org.apache.cassandra.db.Row row : rows)
{
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=1034538&r1=1034537&r2=1034538&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/SelectStatement.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/SelectStatement.java Fri Nov 12 19:33:06 2010
@@ -32,15 +32,17 @@ import org.apache.cassandra.thrift.Consi
public class SelectStatement
{
private final SelectExpression expression;
+ private final boolean isCountOper;
private final String columnFamily;
private final ConsistencyLevel cLevel;
private final WhereClause clause;
private final int numRecords;
- public SelectStatement(SelectExpression expression, String columnFamily, ConsistencyLevel cLevel,
- WhereClause clause, int numRecords)
+ public SelectStatement(SelectExpression expression, boolean isCountOper, String columnFamily,
+ ConsistencyLevel cLevel, WhereClause clause, int numRecords)
{
this.expression = expression;
+ this.isCountOper = isCountOper;
this.columnFamily = columnFamily;
this.cLevel = cLevel;
this.clause = (clause != null) ? clause : new WhereClause();
@@ -116,4 +118,9 @@ public class SelectStatement
{
return expression.getColumnsLimit();
}
+
+ public boolean isCountOperation()
+ {
+ return isCountOper;
+ }
}
Modified: cassandra/trunk/test/system/test_cql.py
URL: http://svn.apache.org/viewvc/cassandra/trunk/test/system/test_cql.py?rev=1034538&r1=1034537&r2=1034538&view=diff
==============================================================================
--- cassandra/trunk/test/system/test_cql.py (original)
+++ cassandra/trunk/test/system/test_cql.py Fri Nov 12 19:33:06 2010
@@ -151,3 +151,9 @@ class TestCql(AvroTester):
assert r[1]['key'] == "kb"
assert r[2]['key'] == "kc"
+ def test_column_count(self):
+ "getting a result count instead of results"
+ conn = init()
+ r = conn.execute('SELECT COUNT(1L..4L) FROM StandardLong1 WHERE KEY = "aa";')
+ assert r == 4
+