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 2011/02/17 02:23:28 UTC

svn commit: r1071468 - in /cassandra/trunk/src/java/org/apache/cassandra/cql: Cql.g CreateIndexStatement.java QueryProcessor.java StatementType.java

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;
 }