You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by jb...@apache.org on 2011/06/05 15:41:31 UTC

svn commit: r1132405 - in /cassandra/branches/cassandra-0.8: ./ doc/cql/ src/java/org/apache/cassandra/config/ src/java/org/apache/cassandra/cql/ src/java/org/apache/cassandra/thrift/ test/system/ test/unit/org/apache/cassandra/

Author: jbellis
Date: Sun Jun  5 13:41:30 2011
New Revision: 1132405

URL: http://svn.apache.org/viewvc?rev=1132405&view=rev
Log:
add cql drop index
patch by pyaskevich and jbellis for CASSANDRA-2617

Modified:
    cassandra/branches/cassandra-0.8/CHANGES.txt
    cassandra/branches/cassandra-0.8/doc/cql/CQL.textile
    cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/config/CFMetaData.java
    cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cql/Cql.g
    cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cql/QueryProcessor.java
    cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cql/StatementType.java
    cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/CassandraServer.java
    cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/ThriftValidation.java
    cassandra/branches/cassandra-0.8/test/system/test_cql.py
    cassandra/branches/cassandra-0.8/test/system/test_thrift_server.py
    cassandra/branches/cassandra-0.8/test/unit/org/apache/cassandra/SchemaLoader.java

Modified: cassandra/branches/cassandra-0.8/CHANGES.txt
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/CHANGES.txt?rev=1132405&r1=1132404&r2=1132405&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.8/CHANGES.txt (original)
+++ cassandra/branches/cassandra-0.8/CHANGES.txt Sun Jun  5 13:41:30 2011
@@ -7,6 +7,7 @@
    - counter support (CASSANDRA-2473)
    - improve JDBC spec compliance (CASSANDRA-2720)
    - ALTER TABLE (CASSANDRA-1709)
+   - DROP INDEX (CASSANDRA-2617)
  * add support for comparator parameters and a generic ReverseType
    (CASSANDRA-2355)
  * add CompositeType and DynamicCompositeType (CASSANDRA-2231)

Modified: cassandra/branches/cassandra-0.8/doc/cql/CQL.textile
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/doc/cql/CQL.textile?rev=1132405&r1=1132404&r2=1132405&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.8/doc/cql/CQL.textile (original)
+++ cassandra/branches/cassandra-0.8/doc/cql/CQL.textile Sun Jun  5 13:41:30 2011
@@ -293,6 +293,15 @@ bc. CREATE INDEX [index_name] ON <column
 
 A @CREATE INDEX@ statement is used to create a new, automatic secondary index for the named column.
 
+h2. DROP INDEX
+
+_Synopsis:_
+
+bc. DROP INDEX <INDEX_NAME>
+
+A @DROP INDEX@ statement is used to drop an existing secondary index.
+DROP INDEX <INDEX_NAME> statement will search all ColumnFamilies in the current Keyspace for specified index and delete it if found.
+
 h2. DROP
 
 _Synopsis:_

Modified: cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/config/CFMetaData.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/config/CFMetaData.java?rev=1132405&r1=1132404&r2=1132405&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/config/CFMetaData.java (original)
+++ cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/config/CFMetaData.java Sun Jun  5 13:41:30 2011
@@ -308,6 +308,10 @@ public final class CFMetaData
     /**
      * generate a column family name for an index corresponding to the given column.
      * This is NOT the same as the index's name! This is only used in sstable filenames and is not exposed to users.
+     *
+     * @param info A definition of the column with index
+     *
+     * @return name of the index ColumnFamily
      */
     public String indexColumnFamilyName(ColumnDefinition info)
     {
@@ -373,6 +377,8 @@ public final class CFMetaData
         for (ColumnDef aColumn_metadata : cf.column_metadata)
         {
             ColumnDefinition cd = ColumnDefinition.inflate(aColumn_metadata);
+            if (cd.getIndexName() == null)
+                cd.setIndexName(getDefaultIndexName(comparator, cd.name));
             column_metadata.put(cd.name, cd);
         }
 
@@ -934,6 +940,37 @@ public final class CFMetaData
         return column_metadata.get(name);
     }
 
+    /**
+     * Convert a null index_name to appropriate default name according to column status
+     * @param cf_def Thrift ColumnFamily Definition
+     */
+    public static void addDefaultIndexNames(org.apache.cassandra.thrift.CfDef cf_def) throws InvalidRequestException
+    {
+        if (cf_def.column_metadata == null)
+            return;
+
+        AbstractType comparator;
+        try
+        {
+            comparator = TypeParser.parse(cf_def.comparator_type);
+        }
+        catch (ConfigurationException e)
+        {
+            throw new InvalidRequestException(e.getMessage());
+        }
+
+        for (org.apache.cassandra.thrift.ColumnDef column : cf_def.column_metadata)
+        {
+            if (column.index_type != null && column.index_name == null)
+                column.index_name = getDefaultIndexName(comparator, column.name);
+        }
+    }
+
+    public static String getDefaultIndexName(AbstractType comparator, ByteBuffer columnName)
+    {
+        return comparator.getString(columnName).replaceAll("\\W", "") + "_idx";
+    }
+
     @Override
     public String toString()
     {

Modified: cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cql/Cql.g
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cql/Cql.g?rev=1132405&r1=1132404&r2=1132405&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cql/Cql.g (original)
+++ cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cql/Cql.g Sun Jun  5 13:41:30 2011
@@ -113,6 +113,7 @@ query returns [CQLStatement stmnt]
     | 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); }
+    | dropIndexStatement   { $stmnt = new CQLStatement(StatementType.DROP_INDEX, $dropIndexStatement.expr); }
     | dropKeyspaceStatement { $stmnt = new CQLStatement(StatementType.DROP_KEYSPACE, $dropKeyspaceStatement.ksp); }
     | dropColumnFamilyStatement { $stmnt = new CQLStatement(StatementType.DROP_COLUMNFAMILY, $dropColumnFamilyStatement.cfam); }
     | alterTableStatement { $stmnt = new CQLStatement(StatementType.ALTER_TABLE, $alterTableStatement.expr); }
@@ -383,6 +384,15 @@ createIndexStatement returns [CreateInde
     : K_CREATE K_INDEX (idxName=IDENT)? K_ON cf=( IDENT | STRING_LITERAL | INTEGER ) '(' columnName=term ')' endStmnt
       { $expr = new CreateIndexStatement($idxName.text, $cf.text, columnName); }
     ;
+/**
+ * DROP INDEX ON <CF>.<COLUMN_OR_INDEX_NAME>
+ * DROP INDEX <INDEX_NAME>
+ */
+dropIndexStatement returns [DropIndexStatement expr]
+    :
+      K_DROP K_INDEX index=( IDENT | STRING_LITERAL | INTEGER ) endStmnt
+      { $expr = new DropIndexStatement($index.text); }
+    ;
 
 /** DROP KEYSPACE <KSP>; */
 dropKeyspaceStatement returns [String ksp]

Modified: cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cql/QueryProcessor.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cql/QueryProcessor.java?rev=1132405&r1=1132404&r2=1132405&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cql/QueryProcessor.java (original)
+++ cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cql/QueryProcessor.java Sun Jun  5 13:41:30 2011
@@ -47,7 +47,6 @@ import org.apache.cassandra.db.filter.Qu
 import org.apache.cassandra.db.marshal.AbstractType;
 import org.apache.cassandra.db.marshal.MarshalException;
 import org.apache.cassandra.db.migration.*;
-import org.apache.cassandra.db.migration.avro.CfDef;
 import org.apache.cassandra.dht.*;
 import org.apache.cassandra.dht.Token;
 import org.apache.cassandra.service.ClientState;
@@ -641,7 +640,7 @@ public class QueryProcessor
                 {
                     KsDef ksd = new KsDef(create.getName(),
                                           create.getStrategyClass(),
-                                          Collections.<org.apache.cassandra.thrift.CfDef>emptyList())
+                                          Collections.<CfDef>emptyList())
                                 .setStrategy_options(create.getStrategyOptions());
                     ThriftValidation.validateKsDef(ksd);
                     applyMigrationOnStage(new AddKeyspace(KSMetaData.fromThrift(ksd)));
@@ -695,37 +694,58 @@ public class QueryProcessor
                                                                                       createIdx.getColumnFamily()));
                 if (oldCfm == null)
                     throw new InvalidRequestException("No such column family: " + createIdx.getColumnFamily());
-                
+
+                boolean columnExists = false;
                 ByteBuffer columnName = createIdx.getColumnName().getByteBuffer();
-                ColumnDefinition columnDef = oldCfm.getColumn_metadata().get(columnName);
-                
-                // Meta-data for this column already exists
-                if (columnDef != null)
+                // mutating oldCfm directly would be bad, but mutating a Thrift copy is fine.  This also
+                // sets us up to use validateCfDef to check for index name collisions.
+                CfDef cf_def = CFMetaData.convertToThrift(oldCfm);
+                for (ColumnDef cd : cf_def.column_metadata)
                 {
-                    // 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);
+                    if (cd.name.equals(columnName))
+                    {
+                        if (cd.index_type != null)
+                            throw new InvalidRequestException("Index already exists");
+                        logger.debug("Updating column {} definition for index {}", oldCfm.comparator.getString(columnName), createIdx.getIndexName());
+                        cd.setIndex_type(IndexType.KEYS);
+                        cd.setIndex_name(createIdx.getIndexName());
+                        columnExists = true;
+                        break;
+                    }
                 }
-                // No meta-data, create a new column definition from scratch.
-                else
+                if (!columnExists)
+                    throw new InvalidRequestException("No column definition found for column " + oldCfm.comparator.getString(columnName));
+
+                CFMetaData.addDefaultIndexNames(cf_def);
+                ThriftValidation.validateCfDef(cf_def, oldCfm);
+                try
                 {
-                    columnDef = new ColumnDefinition(columnName,
-                                                     DatabaseDescriptor.getValueValidator(keyspace,
-                                                                                          createIdx.getColumnFamily(),
-                                                                                          columnName),
-                                                     org.apache.cassandra.thrift.IndexType.KEYS,
-                                                     createIdx.getIndexName());
+                    applyMigrationOnStage(new UpdateColumnFamily(CFMetaData.convertToAvro(cf_def)));
+                }
+                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;
                 }
                 
-                CfDef cfamilyDef = CFMetaData.convertToAvro(oldCfm);
-                cfamilyDef.column_metadata.add(columnDef.deflate());
-                
+                result.type = CqlResultType.VOID;
+                return result;
+
+            case DROP_INDEX:
+                DropIndexStatement dropIdx = (DropIndexStatement)statement.statement;
+                clientState.hasColumnFamilyListAccess(Permission.WRITE);
+                validateSchemaAgreement();
+
                 try
                 {
-                    applyMigrationOnStage(new UpdateColumnFamily(cfamilyDef));
+                    applyMigrationOnStage(dropIdx.generateMutation(clientState.getKeyspace()));
                 }
                 catch (ConfigurationException e)
                 {
@@ -739,10 +759,10 @@ public class QueryProcessor
                     ex.initCause(e);
                     throw ex;
                 }
-                
+
                 result.type = CqlResultType.VOID;
                 return result;
-                
+
             case DROP_KEYSPACE:
                 String deleteKeyspace = (String)statement.statement;
                 clientState.hasKeyspaceListAccess(Permission.WRITE);

Modified: cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cql/StatementType.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cql/StatementType.java?rev=1132405&r1=1132404&r2=1132405&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cql/StatementType.java (original)
+++ cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cql/StatementType.java Sun Jun  5 13:41:30 2011
@@ -24,7 +24,7 @@ import java.util.EnumSet;
 
 public enum StatementType
 {
-    SELECT, INSERT, UPDATE, BATCH, USE, TRUNCATE, DELETE, CREATE_KEYSPACE, CREATE_COLUMNFAMILY, CREATE_INDEX,
+    SELECT, INSERT, UPDATE, BATCH, USE, TRUNCATE, DELETE, CREATE_KEYSPACE, CREATE_COLUMNFAMILY, CREATE_INDEX, DROP_INDEX,
         DROP_KEYSPACE, DROP_COLUMNFAMILY, ALTER_TABLE;
     
     // Statement types that don't require a keyspace to be set.

Modified: cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/CassandraServer.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/CassandraServer.java?rev=1132405&r1=1132404&r2=1132405&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/CassandraServer.java (original)
+++ cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/CassandraServer.java Sun Jun  5 13:41:30 2011
@@ -799,7 +799,8 @@ public class CassandraServer implements 
     {
         logger.debug("add_column_family");
         state().hasColumnFamilyListAccess(Permission.WRITE);
-        ThriftValidation.validateCfDef(cf_def);
+        CFMetaData.addDefaultIndexNames(cf_def);
+        ThriftValidation.validateCfDef(cf_def, null);
         validateSchemaAgreement();
 
         try
@@ -866,10 +867,11 @@ public class CassandraServer implements 
         try
         {
             Collection<CFMetaData> cfDefs = new ArrayList<CFMetaData>(ks_def.cf_defs.size());
-            for (CfDef cfDef : ks_def.cf_defs)
+            for (CfDef cf_def : ks_def.cf_defs)
             {
-                ThriftValidation.validateCfDef(cfDef);
-                cfDefs.add(CFMetaData.fromThrift(cfDef));
+                CFMetaData.addDefaultIndexNames(cf_def);
+                ThriftValidation.validateCfDef(cf_def, null);
+                cfDefs.add(CFMetaData.fromThrift(cf_def));
             }
 
             ThriftValidation.validateKsDef(ks_def);
@@ -953,11 +955,10 @@ public class CassandraServer implements 
     {
         logger.debug("update_column_family");
         state().hasColumnFamilyListAccess(Permission.WRITE);
-        ThriftValidation.validateCfDef(cf_def);
         if (cf_def.keyspace == null || cf_def.name == null)
             throw new InvalidRequestException("Keyspace and CF name must be set.");
         CFMetaData oldCfm = DatabaseDescriptor.getCFMetaData(CFMetaData.getId(cf_def.keyspace, cf_def.name));
-        if (oldCfm == null) 
+        if (oldCfm == null)
             throw new InvalidRequestException("Could not find column family definition to modify.");
         validateSchemaAgreement();
 

Modified: cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/ThriftValidation.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/ThriftValidation.java?rev=1132405&r1=1132404&r2=1132405&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/ThriftValidation.java (original)
+++ cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/ThriftValidation.java Sun Jun  5 13:41:30 2011
@@ -29,6 +29,7 @@ import org.apache.cassandra.db.marshal.A
 import org.apache.cassandra.db.marshal.AsciiType;
 import org.apache.cassandra.db.marshal.MarshalException;
 import org.apache.cassandra.db.marshal.TypeParser;
+import org.apache.cassandra.db.migration.Migration;
 import org.apache.cassandra.dht.IPartitioner;
 import org.apache.cassandra.dht.RandomPartitioner;
 import org.apache.cassandra.dht.Token;
@@ -513,7 +514,7 @@ public class ThriftValidation
             throw new InvalidRequestException("No indexed columns present in index clause with operator EQ");
     }
 
-    public static void validateCfDef(CfDef cf_def) throws InvalidRequestException
+    public static void validateCfDef(CfDef cf_def, CFMetaData old) throws InvalidRequestException
     {
         try
         {
@@ -533,6 +534,22 @@ public class ThriftValidation
                 }
             }
 
+            if (cf_def.key_alias != null)
+            {
+                if (!cf_def.key_alias.hasRemaining())
+                    throw new InvalidRequestException("key_alias may not be empty");
+                try
+                {
+                    // it's hard to use a key in a select statement if we can't type it.
+                    // for now let's keep it simple and require ascii.
+                    AsciiType.instance.validate(cf_def.key_alias);
+                }
+                catch (MarshalException e)
+                {
+                    throw new InvalidRequestException("Key aliases must be ascii");
+                }
+            }
+
             ColumnFamilyType cfType = ColumnFamilyType.create(cf_def.column_type);
             if (cfType == null)
                 throw new InvalidRequestException("invalid column type " + cf_def.column_type);
@@ -550,16 +567,17 @@ public class ThriftValidation
                                     ? TypeParser.parse(cf_def.comparator_type)
                                     : TypeParser.parse(cf_def.subcomparator_type);
 
+            // initialize a set of names NOT in the CF under consideration
             Set<String> indexNames = new HashSet<String>();
-            for (ColumnDef c : cf_def.column_metadata)
+            for (ColumnFamilyStore cfs : ColumnFamilyStore.all())
             {
-                // Ensure that given idx_names and auto_generated idx_names cannot collide
-                CFMetaData cfm = CFMetaData.fromThrift(cf_def);
-                String idxName = cfm.indexColumnFamilyName(ColumnDefinition.fromColumnDef(c));
-                if (indexNames.contains(idxName))
-                    throw new InvalidRequestException("Duplicate index names " + idxName);
-                indexNames.add(idxName);
+                if (!cfs.getColumnFamilyName().equals(cf_def.name))
+                    for (ColumnDefinition cd : cfs.metadata.getColumn_metadata().values())
+                        indexNames.add(cd.getIndexName());
+            }
 
+            for (ColumnDef c : cf_def.column_metadata)
+            {
                 TypeParser.parse(c.validation_class);
 
                 try
@@ -572,11 +590,31 @@ public class ThriftValidation
                                                                     ByteBufferUtil.bytesToHex(c.name), cf_def.comparator_type));
                 }
 
-                if ((c.index_name != null) && (c.index_type == null))
-                    throw new ConfigurationException("index_name cannot be set without index_type");
-
-                if (cfType == ColumnFamilyType.Super && c.index_type != null)
-                    throw new InvalidRequestException("Secondary indexes are not supported on supercolumns");
+                if (c.index_type == null)
+                {
+                    if (c.index_name != null)
+                        throw new ConfigurationException("index_name cannot be set without index_type");
+                }
+                else
+                {
+                    if (cfType == ColumnFamilyType.Super)
+                        throw new InvalidRequestException("Secondary indexes are not supported on supercolumns");
+                    assert c.index_name != null; // should have a default set by now if none was provided
+                    if (!Migration.isLegalName(c.index_name))
+                        throw new InvalidRequestException("Illegal index name " + c.index_name);
+                    // check index names against this CF _and_ globally
+                    if (indexNames.contains(c.index_name))
+                        throw new InvalidRequestException("Duplicate index name " + c.index_name);
+                    indexNames.add(c.index_name);
+
+                    ColumnDefinition oldCd = old == null ? null : old.getColumnDefinition(c.name);
+                    if (oldCd != null && oldCd.getIndexType() != null)
+                    {
+                        assert oldCd.getIndexName() != null;
+                        if (!oldCd.getIndexName().equals(c.index_name))
+                            throw new InvalidRequestException("Cannot modify index name");
+                    }
+                }
             }
             validateMinMaxCompactionThresholds(cf_def);
             validateMemtableSettings(cf_def);

Modified: cassandra/branches/cassandra-0.8/test/system/test_cql.py
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/test/system/test_cql.py?rev=1132405&r1=1132404&r2=1132405&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.8/test/system/test_cql.py (original)
+++ cassandra/branches/cassandra-0.8/test/system/test_cql.py Sun Jun  5 13:41:30 2011
@@ -530,7 +530,7 @@ class TestCql(ThriftTester):
         "creating column indexes"
         cursor = init()
         cursor.execute("USE Keyspace1")
-        cursor.execute("CREATE COLUMNFAMILY CreateIndex1 (KEY text PRIMARY KEY)")
+        cursor.execute("CREATE COLUMNFAMILY CreateIndex1 (KEY text PRIMARY KEY, items text, stuff int)")
         cursor.execute("CREATE INDEX namedIndex ON CreateIndex1 (items)")
         cursor.execute("CREATE INDEX ON CreateIndex1 (stuff)")
 
@@ -539,10 +539,9 @@ class TestCql(ThriftTester):
         cfam = [i for i in ksdef.cf_defs if i.name == "CreateIndex1"][0]
         items = [i for i in cfam.column_metadata if i.name == "items"][0]
         stuff = [i for i in cfam.column_metadata if i.name == "stuff"][0]
-        assert items.index_name == "namedIndex", "missing index (or name)"
+        assert items.index_name == "namedIndex", items.index_name
         assert items.index_type == 0, "missing index"
-        assert not stuff.index_name, \
-            "index_name should be unset, not %s" % stuff.index_name
+        assert stuff.index_name != None, "index_name should be set"
         assert stuff.index_type == 0, "missing index"
 
         # already indexed
@@ -550,6 +549,34 @@ class TestCql(ThriftTester):
                       cursor.execute,
                       "CREATE INDEX ON CreateIndex1 (stuff)")
 
+    def test_drop_indexes(self):
+        "droping indexes on columns"
+        cursor = init()
+        cursor.execute("""CREATE KEYSPACE DropIndexTests WITH strategy_options:replication_factor = '1'
+                                                            AND strategy_class = 'SimpleStrategy';""")
+        cursor.execute("USE DropIndexTests")
+        cursor.execute("CREATE COLUMNFAMILY IndexedCF (KEY text PRIMARY KEY, n text)")
+        cursor.execute("CREATE INDEX namedIndex ON IndexedCF (n)")
+
+        ksdef = thrift_client.describe_keyspace("DropIndexTests")
+        columns = ksdef.cf_defs[0].column_metadata
+
+        assert columns[0].index_name == "namedIndex"
+        assert columns[0].index_type == 0
+
+        # testing "DROP INDEX <INDEX_NAME>"
+        cursor.execute("DROP INDEX namedIndex")
+
+        ksdef = thrift_client.describe_keyspace("DropIndexTests")
+        columns = ksdef.cf_defs[0].column_metadata
+
+        assert columns[0].index_type == None
+        assert columns[0].index_name == None
+
+        assert_raises(cql.ProgrammingError,
+                      cursor.execute,
+                      "DROP INDEX undefIndex")
+
     def test_time_uuid(self):
         "store and retrieve time-based (type 1) uuids"
         cursor = init()

Modified: cassandra/branches/cassandra-0.8/test/system/test_thrift_server.py
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/test/system/test_thrift_server.py?rev=1132405&r1=1132404&r2=1132405&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.8/test/system/test_thrift_server.py (original)
+++ cassandra/branches/cassandra-0.8/test/system/test_thrift_server.py Sun Jun  5 13:41:30 2011
@@ -1421,7 +1421,7 @@ class TestMutations(ThriftTester):
         client.system_update_column_family(modified_cf)
 
         # Add a second indexed CF ...
-        birthdate_coldef = ColumnDef('birthdate', 'BytesType', IndexType.KEYS, 'birthdate_index')
+        birthdate_coldef = ColumnDef('birthdate', 'BytesType', IndexType.KEYS, 'birthdate2_index')
         age_coldef = ColumnDef('age', 'BytesType', IndexType.KEYS, 'age_index')
         cfdef = CfDef('Keyspace1', 'BlankCF2', column_metadata=[birthdate_coldef, age_coldef])
         client.system_add_column_family(cfdef)

Modified: cassandra/branches/cassandra-0.8/test/unit/org/apache/cassandra/SchemaLoader.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/test/unit/org/apache/cassandra/SchemaLoader.java?rev=1132405&r1=1132404&r2=1132405&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.8/test/unit/org/apache/cassandra/SchemaLoader.java (original)
+++ cassandra/branches/cassandra-0.8/test/unit/org/apache/cassandra/SchemaLoader.java Sun Jun  5 13:41:30 2011
@@ -21,6 +21,7 @@ package org.apache.cassandra;
 import java.nio.ByteBuffer;
 import java.util.*;
 
+import org.apache.cassandra.utils.ByteBufferUtil;
 import org.apache.commons.lang.NotImplementedException;
 
 import com.google.common.base.Charsets;
@@ -249,7 +250,7 @@ public class SchemaLoader
                     {{
                         ByteBuffer cName = ByteBuffer.wrap("birthdate".getBytes(Charsets.UTF_8));
                         IndexType keys = withIdxType ? IndexType.KEYS : null;
-                        put(cName, new ColumnDefinition(cName, LongType.instance, keys, null));
+                        put(cName, new ColumnDefinition(cName, LongType.instance, keys, ByteBufferUtil.bytesToHex(cName)));
                     }});
     }
     private static CFMetaData jdbcCFMD(String ksName, String cfName, AbstractType comp)