Minor fixes for CQL3 patch by slebresne; reviewed by jbellis for CASSANDRA-4185
- Fix float parsing - Refuse more invalidate create statements - Fix count in select - Disallow counters in primary keys Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/5f1c5ad3 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/5f1c5ad3 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/5f1c5ad3 Branch: refs/heads/cassandra-1.1 Commit: 5f1c5ad393a0ce5e455f865a7883303ca5e51690 Parents: e53d980 Author: Sylvain Lebresne <sylv...@datastax.com> Authored: Thu May 3 09:18:59 2012 +0200 Committer: Sylvain Lebresne <sylv...@datastax.com> Committed: Thu May 3 09:23:00 2012 +0200 ---------------------------------------------------------------------- CHANGES.txt | 1 + src/java/org/apache/cassandra/cql3/Cql.g | 14 ++++++++++++-- .../cql3/statements/AlterTableStatement.java | 7 ++++++- .../statements/CreateColumnFamilyStatement.java | 14 +++++++++++++- .../cassandra/cql3/statements/SelectStatement.java | 15 ++++++++------- 5 files changed, 40 insertions(+), 11 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/5f1c5ad3/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index 2bbe377..9a0569f 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -26,6 +26,7 @@ * (cql3) Fix order by for reversed queries (CASSANDRA-4160) * (cql3) Add ReversedType support (CASSANDRA-4004) * (cql3) Add timeuuid type (CASSANDRA-4194) + * (cql3) Minor fixes (CASSANDRA-4185) Merged from 1.0: * Fix super columns bug where cache is not updated (CASSANDRA-4190) * fix maxTimestamp to include row tombstones (CASSANDRA-4116) http://git-wip-us.apache.org/repos/asf/cassandra/blob/5f1c5ad3/src/java/org/apache/cassandra/cql3/Cql.g ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/Cql.g b/src/java/org/apache/cassandra/cql3/Cql.g index f72aeda..3220c1a 100644 --- a/src/java/org/apache/cassandra/cql3/Cql.g +++ b/src/java/org/apache/cassandra/cql3/Cql.g @@ -50,6 +50,11 @@ options { recognitionErrors.add(hdr + " " + msg); } + public void addRecognitionError(String msg) + { + recognitionErrors.add(msg); + } + public List<String> getRecognitionErrors() { return recognitionErrors; @@ -159,7 +164,7 @@ selectStatement returns [SelectStatement.RawStatement expr] int limit = 10000; Map<ColumnIdentifier, Boolean> orderings = new LinkedHashMap<ColumnIdentifier, Boolean>(); } - : K_SELECT ( sclause=selectClause | (K_COUNT '(' sclause=selectClause ')' { isCount = true; }) ) + : K_SELECT ( sclause=selectClause | (K_COUNT '(' sclause=selectCountClause ')' { isCount = true; }) ) K_FROM cf=columnFamilyName ( K_USING K_CONSISTENCY K_LEVEL { cLevel = ConsistencyLevel.valueOf($K_LEVEL.text.toUpperCase()); } )? ( K_WHERE wclause=whereClause )? @@ -179,6 +184,11 @@ selectClause returns [List<ColumnIdentifier> expr] | '\*' { $expr = Collections.<ColumnIdentifier>emptyList();} ; +selectCountClause returns [List<ColumnIdentifier> expr] + : c=selectClause { $expr = c; } + | i=INTEGER { if (!i.getText().equals("1")) addRecognitionError("Only COUNT(1) is supported, got COUNT(" + i.getText() + ")"); $expr = Collections.<ColumnIdentifier>emptyList();} + ; + whereClause returns [List<Relation> clause] @init{ $clause = new ArrayList<Relation>(); } : first=relation { $clause.add(first); } (K_AND next=relation { $clause.add(next); })* @@ -618,7 +628,7 @@ QMARK * to support multiple (see @lexer::members near the top of the grammar). */ FLOAT - : INTEGER '.' INTEGER + : INTEGER '.' DIGIT* ; IDENT http://git-wip-us.apache.org/repos/asf/cassandra/blob/5f1c5ad3/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java b/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java index bb2c7e8..b1291fe 100644 --- a/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java @@ -24,7 +24,9 @@ import java.util.*; import org.apache.cassandra.cql3.*; import org.apache.cassandra.config.*; import org.apache.cassandra.io.compress.CompressionParameters; +import org.apache.cassandra.db.marshal.AbstractType; import org.apache.cassandra.db.marshal.CompositeType; +import org.apache.cassandra.db.marshal.CounterColumnType; import org.apache.cassandra.service.MigrationManager; import org.apache.cassandra.thrift.CfDef; import org.apache.cassandra.thrift.ColumnDef; @@ -90,7 +92,10 @@ public class AlterTableStatement extends SchemaAlteringStatement switch (name.kind) { case KEY_ALIAS: - cfm.keyValidator(CFPropDefs.parseType(validator)); + AbstractType<?> newType = CFPropDefs.parseType(validator); + if (newType instanceof CounterColumnType) + throw new InvalidRequestException(String.format("counter type is not supported for PRIMARY KEY part %s", columnName)); + cfm.keyValidator(newType); break; case COLUMN_ALIAS: throw new InvalidRequestException(String.format("Cannot alter PRIMARY KEY part %s", columnName)); http://git-wip-us.apache.org/repos/asf/cassandra/blob/5f1c5ad3/src/java/org/apache/cassandra/cql3/statements/CreateColumnFamilyStatement.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/statements/CreateColumnFamilyStatement.java b/src/java/org/apache/cassandra/cql3/statements/CreateColumnFamilyStatement.java index eb0aeb4..9ee0f94 100644 --- a/src/java/org/apache/cassandra/cql3/statements/CreateColumnFamilyStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/CreateColumnFamilyStatement.java @@ -36,6 +36,7 @@ import org.apache.cassandra.db.ColumnFamilyType; import org.apache.cassandra.db.marshal.AbstractType; import org.apache.cassandra.db.marshal.CompositeType; import org.apache.cassandra.db.marshal.ReversedType; +import org.apache.cassandra.db.marshal.CounterColumnType; import org.apache.cassandra.service.ClientState; import org.apache.cassandra.service.MigrationManager; import org.apache.cassandra.thrift.CqlResult; @@ -175,6 +176,8 @@ public class CreateColumnFamilyStatement extends SchemaAlteringStatement stmt.keyAlias = keyAliases.get(0).key; stmt.keyValidator = getTypeAndRemove(stmt.columns, keyAliases.get(0)); + if (stmt.keyValidator instanceof CounterColumnType) + throw new InvalidRequestException(String.format("counter type is not supported for PRIMARY KEY part %s", stmt.keyAlias)); // Handle column aliases if (columnAliases != null && !columnAliases.isEmpty()) @@ -185,6 +188,8 @@ public class CreateColumnFamilyStatement extends SchemaAlteringStatement { stmt.columnAliases.add(columnAliases.get(0).key); stmt.comparator = getTypeAndRemove(stmt.columns, columnAliases.get(0)); + if (stmt.comparator instanceof CounterColumnType) + throw new InvalidRequestException(String.format("counter type is not supported for PRIMARY KEY part %s", stmt.columnAliases.get(0))); } else { @@ -192,7 +197,11 @@ public class CreateColumnFamilyStatement extends SchemaAlteringStatement for (ColumnIdentifier t : columnAliases) { stmt.columnAliases.add(t.key); - types.add(getTypeAndRemove(stmt.columns, t)); + + AbstractType<?> type = getTypeAndRemove(stmt.columns, t); + if (type instanceof CounterColumnType) + throw new InvalidRequestException(String.format("counter type is not supported for PRIMARY KEY part %s", t.key)); + types.add(type); } // For sparse, we must add the last UTF8 component if (!useCompactStorage) @@ -210,6 +219,9 @@ public class CreateColumnFamilyStatement extends SchemaAlteringStatement if (useCompactStorage) { + // There should at least have been one column alias + if (stmt.columnAliases.isEmpty()) + throw new InvalidRequestException("COMPACT STORAGE requires at least one column part of the clustering key, none found"); // There should be only one column definition remaining, which gives us the default validator. if (stmt.columns.isEmpty()) throw new InvalidRequestException("COMPACT STORAGE requires one definition not part of the PRIMARY KEY, none found"); http://git-wip-us.apache.org/repos/asf/cassandra/blob/5f1c5ad3/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java index 00c3b24..561db9a 100644 --- a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java @@ -145,6 +145,10 @@ public class SelectStatement implements CQLStatement CqlResult result = new CqlResult(); result.type = CqlResultType.ROWS; + // Even for count, we need to process the result as it'll group some column together in sparse column families + CqlMetadata schema = createSchema(); + List<CqlRow> cqlRows = process(rows, schema, variables); + // count resultset is a single column named "count" if (parameters.isCount) { @@ -152,15 +156,15 @@ public class SelectStatement implements CQLStatement Collections.<ByteBuffer, String>emptyMap(), "AsciiType", "LongType"); - List<Column> columns = Collections.singletonList(new Column(countColumn).setValue(ByteBufferUtil.bytes((long) rows.size()))); + List<Column> columns = Collections.singletonList(new Column(countColumn).setValue(ByteBufferUtil.bytes((long) cqlRows.size()))); result.rows = Collections.singletonList(new CqlRow(countColumn, columns)); return result; } else { // otherwise create resultset from query results - result.schema = createSchema(); - result.rows = process(rows, result.schema, variables); + result.schema = schema; + result.rows = cqlRows; return result; } } @@ -822,10 +826,7 @@ public class SelectStatement implements CQLStatement // Select clause if (parameters.isCount) { - if (selectClause.size() != 1) - throw new InvalidRequestException("Only COUNT(*) and COUNT(1) operations are currently supported."); - String columnName = selectClause.get(0).toString(); - if (!columnName.equals("*") && !columnName.equals("1")) + if (!selectClause.isEmpty()) throw new InvalidRequestException("Only COUNT(*) and COUNT(1) operations are currently supported."); } else