Author: eevans Date: Thu Feb 17 01:23:28 2011 New Revision: 1071468 URL: http://svn.apache.org/viewvc?rev=1071468&view=rev Log: CREATE INDEX implementation
Patch by eevans for CASSANDRA-1709 Added: cassandra/trunk/src/java/org/apache/cassandra/cql/CreateIndexStatement.java Modified: 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/StatementType.java 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=1071468&r1=1071467&r2=1071468&view=diff ============================================================================== --- cassandra/trunk/src/java/org/apache/cassandra/cql/Cql.g (original) +++ cassandra/trunk/src/java/org/apache/cassandra/cql/Cql.g Thu Feb 17 01:23:28 2011 @@ -64,6 +64,7 @@ query returns [CQLStatement stmnt] | deleteStatement { $stmnt = new CQLStatement(StatementType.DELETE, $deleteStatement.expr); } | createKeyspaceStatement { $stmnt = new CQLStatement(StatementType.CREATE_KEYSPACE, $createKeyspaceStatement.expr); } | createColumnFamilyStatement { $stmnt = new CQLStatement(StatementType.CREATE_COLUMNFAMILY, $createColumnFamilyStatement.expr); } + | createIndexStatement { $stmnt = new CQLStatement(StatementType.CREATE_INDEX, $createIndexStatement.expr); } ; // USE <KEYSPACE>; @@ -242,6 +243,12 @@ createCfamKeywordArgument returns [Strin | value=( STRING_LITERAL | INTEGER | FLOAT ) { $arg = $value.text; } ; +/** CREATE INDEX [indexName] ON columnFamily (columnName); */ +createIndexStatement returns [CreateIndexStatement expr] + : K_CREATE K_INDEX (idxName=IDENT)? K_ON cf=IDENT '(' columnName=term ')' endStmnt + { $expr = new CreateIndexStatement($idxName.text, $cf.text, columnName); } + ; + comparatorType : 'bytes' | 'ascii' | 'utf8' | 'int' | 'long' | 'uuid' | 'timeuuid' ; @@ -323,6 +330,8 @@ K_IN: I N; K_CREATE: C R E A T E; K_KEYSPACE: K E Y S P A C E; K_COLUMNFAMILY: C O L U M N F A M I L Y; +K_INDEX: I N D E X; +K_ON: O N; // Case-insensitive alpha characters fragment A: ('a'|'A'); Added: cassandra/trunk/src/java/org/apache/cassandra/cql/CreateIndexStatement.java URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/CreateIndexStatement.java?rev=1071468&view=auto ============================================================================== --- cassandra/trunk/src/java/org/apache/cassandra/cql/CreateIndexStatement.java (added) +++ cassandra/trunk/src/java/org/apache/cassandra/cql/CreateIndexStatement.java Thu Feb 17 01:23:28 2011 @@ -0,0 +1,54 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.cassandra.cql; + +/** A <code>CREATE INDEX</code> statement parsed from a CQL query. */ +public class CreateIndexStatement +{ + private final String columnFamily; + private final String indexName; + private final Term columnName; + + public CreateIndexStatement(String indexName, String columnFamily, Term columnName) + { + this.indexName = indexName; + this.columnFamily = columnFamily; + this.columnName = columnName; + } + + /** Column family namespace. */ + public String getColumnFamily() + { + return columnFamily; + } + + /** Column name to index. */ + public Term getColumnName() + { + return columnName; + } + + /** Index name (or null). */ + public String getIndexName() + { + return indexName; + } +} 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=1071468&r1=1071467&r2=1071468&view=diff ============================================================================== --- cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java (original) +++ cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java Thu Feb 17 01:23:28 2011 @@ -35,13 +35,18 @@ import org.slf4j.LoggerFactory; import org.antlr.runtime.*; import org.apache.cassandra.concurrent.Stage; import org.apache.cassandra.concurrent.StageManager; +import org.apache.cassandra.config.CFMetaData; +import org.apache.cassandra.config.ColumnDefinition; import org.apache.cassandra.config.ConfigurationException; +import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.config.KSMetaData; import org.apache.cassandra.db.*; import org.apache.cassandra.db.filter.QueryPath; import org.apache.cassandra.db.migration.AddColumnFamily; import org.apache.cassandra.db.migration.AddKeyspace; import org.apache.cassandra.db.migration.Migration; +import org.apache.cassandra.db.migration.UpdateColumnFamily; +import org.apache.cassandra.db.migration.avro.CfDef; import org.apache.cassandra.db.marshal.AbstractType; import org.apache.cassandra.db.marshal.MarshalException; import org.apache.cassandra.dht.AbstractBounds; @@ -584,6 +589,65 @@ public class QueryProcessor avroResult.type = CqlResultType.VOID; return avroResult; + case CREATE_INDEX: + CreateIndexStatement createIdx = (CreateIndexStatement)statement.statement; + CFMetaData oldCfm = DatabaseDescriptor.getCFMetaData(CFMetaData.getId(keyspace, + createIdx.getColumnFamily())); + if (oldCfm == null) + throw new InvalidRequestException("No such column family: " + createIdx.getColumnFamily()); + + ByteBuffer columnName = createIdx.getColumnName().getByteBuffer(); + ColumnDefinition columnDef = oldCfm.getColumn_metadata().get(columnName); + + // Meta-data for this column already exists + if (columnDef != null) + { + // This column is already indexed, stop, drop, and roll. + if (columnDef.getIndexType() != null) + throw new InvalidRequestException("Index exists"); + // Add index attrs to the existing definition + columnDef.setIndexName(createIdx.getIndexName()); + columnDef.setIndexType(org.apache.cassandra.thrift.IndexType.KEYS); + } + // No meta-data, create a new column definition from scratch. + else + { + try + { + columnDef = new ColumnDefinition(columnName, + null, + org.apache.cassandra.thrift.IndexType.KEYS, + createIdx.getIndexName()); + } + catch (ConfigurationException e) + { + // This should never happen + throw new RuntimeException("Unexpected error creating ColumnDefinition", e); + } + } + + CfDef cfamilyDef = CFMetaData.convertToAvro(oldCfm); + cfamilyDef.column_metadata.add(columnDef.deflate()); + + try + { + applyMigrationOnStage(new UpdateColumnFamily(cfamilyDef)); + } + catch (ConfigurationException e) + { + InvalidRequestException ex = new InvalidRequestException(e.toString()); + ex.initCause(e); + throw ex; + } + catch (IOException e) + { + InvalidRequestException ex = new InvalidRequestException(e.toString()); + ex.initCause(e); + throw ex; + } + + avroResult.type = CqlResultType.VOID; + return avroResult; } return null; // We should never get here. 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=1071468&r1=1071467&r2=1071468&view=diff ============================================================================== --- cassandra/trunk/src/java/org/apache/cassandra/cql/StatementType.java (original) +++ cassandra/trunk/src/java/org/apache/cassandra/cql/StatementType.java Thu Feb 17 01:23:28 2011 @@ -22,5 +22,5 @@ package org.apache.cassandra.cql; public enum StatementType { - SELECT, UPDATE, BATCH_UPDATE, USE, TRUNCATE, DELETE, CREATE_KEYSPACE, CREATE_COLUMNFAMILY; + SELECT, UPDATE, BATCH_UPDATE, USE, TRUNCATE, DELETE, CREATE_KEYSPACE, CREATE_COLUMNFAMILY, CREATE_INDEX; }