Updated Branches:
  refs/heads/trunk 273924847 -> a950b9257

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a950b925/src/java/org/apache/cassandra/db/index/composites/CompositesSearcher.java
----------------------------------------------------------------------
diff --git 
a/src/java/org/apache/cassandra/db/index/composites/CompositesSearcher.java 
b/src/java/org/apache/cassandra/db/index/composites/CompositesSearcher.java
index 09747c0..0d8cdb9 100644
--- a/src/java/org/apache/cassandra/db/index/composites/CompositesSearcher.java
+++ b/src/java/org/apache/cassandra/db/index/composites/CompositesSearcher.java
@@ -21,6 +21,7 @@ import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.*;
 
+import org.apache.cassandra.cql3.ColumnNameBuilder;
 import org.apache.cassandra.db.*;
 import org.apache.cassandra.db.filter.*;
 import org.apache.cassandra.db.index.AbstractSimplePerColumnSecondaryIndex;
@@ -41,40 +42,9 @@ public class CompositesSearcher extends 
SecondaryIndexSearcher
 {
     private static final Logger logger = 
LoggerFactory.getLogger(CompositesSearcher.class);
 
-    private final int prefixSize;
-
-    public CompositesSearcher(SecondaryIndexManager indexManager, 
Set<ByteBuffer> columns, int prefixSize)
+    public CompositesSearcher(SecondaryIndexManager indexManager, 
Set<ByteBuffer> columns)
     {
         super(indexManager, columns);
-        this.prefixSize = prefixSize;
-    }
-
-    private IndexExpression highestSelectivityPredicate(List<IndexExpression> 
clause)
-    {
-        IndexExpression best = null;
-        int bestMeanCount = Integer.MAX_VALUE;
-        for (IndexExpression expression : clause)
-        {
-            //skip columns belonging to a different index type
-            if(!columns.contains(expression.column_name))
-                continue;
-
-            SecondaryIndex index = 
indexManager.getIndexForColumn(expression.column_name);
-            if (index == null || (expression.op != IndexOperator.EQ))
-                continue;
-            int columns = index.getIndexCfs().getMeanColumns();
-            if (columns < bestMeanCount)
-            {
-                best = expression;
-                bestMeanCount = columns;
-            }
-        }
-        return best;
-    }
-
-    public boolean isIndexing(List<IndexExpression> clause)
-    {
-        return highestSelectivityPredicate(clause) != null;
     }
 
     @Override
@@ -85,13 +55,31 @@ public class CompositesSearcher extends 
SecondaryIndexSearcher
         return baseCfs.filter(getIndexedIterator(range, filter), filter);
     }
 
+    private ByteBuffer makePrefix(CompositesIndex index, ByteBuffer key, 
ExtendedFilter filter, boolean isStart)
+    {
+        if (key.remaining() == 0)
+            return ByteBufferUtil.EMPTY_BYTE_BUFFER;
+
+        ColumnNameBuilder builder;
+        if (filter.originalFilter() instanceof SliceQueryFilter)
+        {
+            SliceQueryFilter originalFilter = 
(SliceQueryFilter)filter.originalFilter();
+            builder = index.makeIndexColumnNameBuilder(key, isStart ? 
originalFilter.start() : originalFilter.finish());
+        }
+        else
+        {
+            builder = index.getIndexComparator().builder().add(key);
+        }
+        return isStart ? builder.build() : builder.buildAsEndOfRange();
+    }
+
     public ColumnFamilyStore.AbstractScanIterator getIndexedIterator(final 
AbstractBounds<RowPosition> range, final ExtendedFilter filter)
     {
         // Start with the most-restrictive indexed clause, then apply 
remaining clauses
         // to each row matching that clause.
         // TODO: allow merge join instead of just one index + loop
         final IndexExpression primary = 
highestSelectivityPredicate(filter.getClause());
-        final SecondaryIndex index = 
indexManager.getIndexForColumn(primary.column_name);
+        final CompositesIndex index = 
(CompositesIndex)indexManager.getIndexForColumn(primary.column_name);
         assert index != null;
         final DecoratedKey indexKey = index.getIndexKeyFor(primary.value);
 
@@ -101,7 +89,7 @@ public class CompositesSearcher extends 
SecondaryIndexSearcher
 
         /*
          * XXX: If the range requested is a token range, we'll have to start 
at the beginning (and stop at the end) of
-         * the indexed row unfortunately (which will be inefficient), because 
we have not way to intuit the small
+         * the indexed row unfortunately (which will be inefficient), because 
we have not way to intuit the smallest
          * possible key having a given token. A fix would be to actually store 
the token along the key in the
          * indexed row.
          */
@@ -112,50 +100,8 @@ public class CompositesSearcher extends 
SecondaryIndexSearcher
         final CompositeType indexComparator = 
(CompositeType)index.getIndexCfs().getComparator();
 
         CompositeType.Builder builder = null;
-        if (startKey.remaining() > 0)
-        {
-            builder = indexComparator.builder().add(startKey);
-            // For names filter, we have no choice but to query from the 
beginning of the key. This can be highly inefficient however.
-            if (filter.originalFilter() instanceof SliceQueryFilter)
-            {
-                ByteBuffer[] components = 
baseComparator.split(((SliceQueryFilter)filter.originalFilter()).start());
-                for (int i = 0; i < Math.min(prefixSize, components.length); 
++i)
-                    builder.add(components[i]);
-            }
-        }
-        final ByteBuffer startPrefix = startKey.remaining() == 0 ? 
ByteBufferUtil.EMPTY_BYTE_BUFFER : builder.build();
-
-        if (endKey.remaining() > 0)
-        {
-            builder = indexComparator.builder().add(endKey);
-            // For names filter, we have no choice but to query until the end 
of the key. This can be highly inefficient however.
-            if (filter.originalFilter() instanceof SliceQueryFilter)
-            {
-                ByteBuffer[] components = 
baseComparator.split(((SliceQueryFilter)filter.originalFilter()).finish());
-                for (int i = 0; i < Math.min(prefixSize, components.length); 
++i)
-                    builder.add(components[i]);
-            }
-        }
-        final ByteBuffer endPrefix = endKey.remaining() == 0 ? 
ByteBufferUtil.EMPTY_BYTE_BUFFER : builder.buildAsEndOfRange();
-
-        // We will need to filter clustering keys based on the user filter. If
-        // it is a names filter, we are really interested on the clustering
-        // part, not the actual column name (NOTE: this is a hack that assumes 
CQL3).
-        final SliceQueryFilter originalFilter;
-        if (filter.originalFilter() instanceof SliceQueryFilter)
-        {
-            originalFilter = (SliceQueryFilter)filter.originalFilter();
-        }
-        else
-        {
-            ByteBuffer first = 
((NamesQueryFilter)filter.originalFilter()).columns.iterator().next();
-            ByteBuffer[] components = baseComparator.split(first);
-            builder = baseComparator.builder();
-            // All all except the last component, since it's the column name
-            for (int i = 0; i < components.length - 1; i++)
-                builder.add(components[i]);
-            originalFilter = new SliceQueryFilter(builder.copy().build(), 
builder.copy().buildAsEndOfRange(), false, Integer.MAX_VALUE);
-        }
+        final ByteBuffer startPrefix = makePrefix(index, startKey, filter, 
true);
+        final ByteBuffer endPrefix = makePrefix(index, endKey, filter, false);
 
         return new ColumnFamilyStore.AbstractScanIterator()
         {
@@ -223,7 +169,7 @@ public class CompositesSearcher extends 
SecondaryIndexSearcher
                                                                              
false,
                                                                              
rowsPerQuery);
                         ColumnFamily indexRow = 
index.getIndexCfs().getColumnFamily(indexFilter);
-                        if (indexRow == null)
+                        if (indexRow == null || indexRow.isEmpty())
                             return makeReturn(currentKey, data);
 
                         Collection<Column> sortedColumns = 
indexRow.getSortedColumns();
@@ -238,12 +184,6 @@ public class CompositesSearcher extends 
SecondaryIndexSearcher
                             indexColumns.poll();
                             logger.trace("Skipping {}", 
indexComparator.getString(firstColumn.name()));
                         }
-                        else if (range instanceof Range && 
!indexColumns.isEmpty() && firstColumn.name().equals(startPrefix))
-                        {
-                            // skip key excluded by range
-                            indexColumns.poll();
-                            logger.trace("Skipping first key as range excludes 
it");
-                        }
                     }
 
                     while (!indexColumns.isEmpty() && columnsCount <= limit)
@@ -256,8 +196,8 @@ public class CompositesSearcher extends 
SecondaryIndexSearcher
                             continue;
                         }
 
-                        ByteBuffer[] components = 
indexComparator.split(lastSeenPrefix);
-                        DecoratedKey dk = 
baseCfs.partitioner.decorateKey(components[0]);
+                        CompositesIndex.IndexedEntry entry = 
index.decodeEntry(indexKey, column);
+                        DecoratedKey dk = 
baseCfs.partitioner.decorateKey(entry.indexedKey);
 
                         // Are we done for this row?
                         if (currentKey == null)
@@ -277,52 +217,52 @@ public class CompositesSearcher extends 
SecondaryIndexSearcher
                                 return makeReturn(previousKey, data);
                         }
 
-                        if (!range.right.isMinimum(baseCfs.partitioner) && 
range.right.compareTo(dk) < 0)
-                        {
-                            logger.trace("Reached end of assigned scan range");
-                            return endOfData();
-                        }
                         if (!range.contains(dk))
                         {
-                            logger.debug("Skipping entry {} outside of 
assigned scan range", dk.token);
-                            continue;
+                            // Either we're not yet in the range cause the 
range is start excluding, or we're
+                            // past it.
+                            if (!range.right.isMinimum(baseCfs.partitioner) && 
range.right.compareTo(dk) < 0)
+                            {
+                                logger.trace("Reached end of assigned scan 
range");
+                                return endOfData();
+                            }
+                            else
+                            {
+                                logger.debug("Skipping entry {} before 
assigned scan range", dk.token);
+                                continue;
+                            }
                         }
 
-                        logger.trace("Adding index hit to current row for {}", 
indexComparator.getString(lastSeenPrefix));
-                        // For sparse composites, we're good querying the 
whole logical row
-                        // Obviously if this index is used for other usage, 
that might be inefficient
-                        CompositeType.Builder builder = 
baseComparator.builder();
-                        for (int i = 0; i < prefixSize; i++)
-                            builder.add(components[i + 1]);
-
-                        // Does this "row" match the user original filter
-                        ByteBuffer start = builder.copy().build();
-                        if (!originalFilter.includes(baseComparator, start))
+                        // Check if this entry cannot be a hit due to the 
original column filter
+                        ByteBuffer start = entry.indexedEntryStart();
+                        if 
(!filter.originalFilter().maySelectPrefix(baseComparator, start))
                             continue;
 
-                        SliceQueryFilter dataFilter = new 
SliceQueryFilter(start, builder.copy().buildAsEndOfRange(), false, 
Integer.MAX_VALUE, prefixSize);
+                        logger.trace("Adding index hit to current row for {}", 
indexComparator.getString(column.name()));
+
+                        // We always query the whole CQL3 row. In the case 
where the original filter was a name filter this might be
+                        // slightly wasteful, but this probably doesn't matter 
in practice and it simplify things.
+                        SliceQueryFilter dataFilter = new 
SliceQueryFilter(start,
+                                                                           
entry.indexedEntryEnd(),
+                                                                           
false,
+                                                                           
Integer.MAX_VALUE,
+                                                                           
baseCfs.metadata.clusteringKeyColumns().size());
                         ColumnFamily newData = baseCfs.getColumnFamily(new 
QueryFilter(dk, baseCfs.name, dataFilter));
-                        if (newData != null)
+                        if (index.isStale(entry, newData))
                         {
-                            ByteBuffer baseColumnName = 
builder.copy().add(primary.column_name).build();
-                            ByteBuffer indexedValue = indexKey.key;
+                            index.delete(entry);
+                            continue;
+                        }
 
-                            if (isIndexValueStale(newData, baseColumnName, 
indexedValue))
-                            {
-                                // delete the index entry w/ its own timestamp
-                                Column dummyColumn = new 
Column(baseColumnName, indexedValue, column.timestamp());
-                                ((PerColumnSecondaryIndex) 
index).delete(dk.key, dummyColumn);
-                                continue;
-                            }
+                        assert newData != null : "An entry with not data 
should have been considered stale";
 
-                            if (!filter.isSatisfiedBy(newData, builder))
-                                continue;
+                        if (!filter.isSatisfiedBy(dk.key, newData, 
entry.indexedEntryNameBuilder))
+                            continue;
 
-                            if (data == null)
-                                data = 
TreeMapBackedSortedColumns.factory.create(baseCfs.metadata);
-                            data.resolve(newData);
-                            columnsCount += dataFilter.lastCounted();
-                        }
+                        if (data == null)
+                            data = 
TreeMapBackedSortedColumns.factory.create(baseCfs.metadata);
+                        data.resolve(newData);
+                        columnsCount += dataFilter.lastCounted();
                     }
                  }
              }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a950b925/src/java/org/apache/cassandra/db/index/keys/KeysIndex.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/index/keys/KeysIndex.java 
b/src/java/org/apache/cassandra/db/index/keys/KeysIndex.java
index 8d065ab..190afc1 100644
--- a/src/java/org/apache/cassandra/db/index/keys/KeysIndex.java
+++ b/src/java/org/apache/cassandra/db/index/keys/KeysIndex.java
@@ -21,6 +21,7 @@ import java.nio.ByteBuffer;
 import java.util.Set;
 
 import org.apache.cassandra.config.ColumnDefinition;
+import org.apache.cassandra.db.ColumnFamily;
 import org.apache.cassandra.db.Column;
 import org.apache.cassandra.db.index.AbstractSimplePerColumnSecondaryIndex;
 import org.apache.cassandra.db.index.SecondaryIndexSearcher;
@@ -33,9 +34,9 @@ import org.apache.cassandra.exceptions.ConfigurationException;
  */
 public class KeysIndex extends AbstractSimplePerColumnSecondaryIndex
 {
-    public void init(ColumnDefinition columnDef)
+    protected ByteBuffer getIndexedValue(ByteBuffer rowKey, Column column)
     {
-        // Nothing specific
+        return column.value();
     }
 
     protected ByteBuffer makeIndexColumnName(ByteBuffer rowKey, Column column)
@@ -48,6 +49,16 @@ public class KeysIndex extends 
AbstractSimplePerColumnSecondaryIndex
         return new KeysSearcher(baseCfs.indexManager, columns);
     }
 
+    public boolean isIndexEntryStale(ByteBuffer indexedValue, ColumnFamily 
data)
+    {
+        Column liveColumn = data.getColumn(columnDef.name);
+        if (liveColumn == null || liveColumn.isMarkedForDelete())
+            return true;
+
+        ByteBuffer liveValue = liveColumn.value();
+        return columnDef.getValidator().compare(indexedValue, liveValue) != 0;
+    }
+
     public void validateOptions() throws ConfigurationException
     {
         // no options used

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a950b925/src/java/org/apache/cassandra/db/index/keys/KeysSearcher.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/index/keys/KeysSearcher.java 
b/src/java/org/apache/cassandra/db/index/keys/KeysSearcher.java
index d5ea553..9f5c594 100644
--- a/src/java/org/apache/cassandra/db/index/keys/KeysSearcher.java
+++ b/src/java/org/apache/cassandra/db/index/keys/KeysSearcher.java
@@ -46,34 +46,6 @@ public class KeysSearcher extends SecondaryIndexSearcher
         super(indexManager, columns);
     }
 
-    private IndexExpression highestSelectivityPredicate(List<IndexExpression> 
clause)
-    {
-        IndexExpression best = null;
-        int bestMeanCount = Integer.MAX_VALUE;
-        for (IndexExpression expression : clause)
-        {
-            //skip columns belonging to a different index type
-            if(!columns.contains(expression.column_name))
-                continue;
-
-            SecondaryIndex index = 
indexManager.getIndexForColumn(expression.column_name);
-            if (index == null || (expression.op != IndexOperator.EQ))
-                continue;
-            int columns = index.getIndexCfs().getMeanColumns();
-            if (columns < bestMeanCount)
-            {
-                best = expression;
-                bestMeanCount = columns;
-            }
-        }
-        return best;
-    }
-
-    public boolean isIndexing(List<IndexExpression> clause)
-    {
-        return highestSelectivityPredicate(clause) != null;
-    }
-
     @Override
     public List<Row> search(List<IndexExpression> clause, 
AbstractBounds<RowPosition> range, int maxResults, IDiskAtomFilter dataFilter, 
boolean countCQL3Rows)
     {
@@ -201,8 +173,8 @@ public class KeysSearcher extends SecondaryIndexSearcher
                             if (cf != null)
                                 data.addAll(cf, HeapAllocator.instance);
                         }
-                        
-                        if (isIndexValueStale(data, primary.column_name, 
indexKey.key))
+
+                        if (((KeysIndex)index).isIndexEntryStale(indexKey.key, 
data))
                         {
                             // delete the index entry w/ its own timestamp
                             Column dummyColumn = new 
Column(primary.column_name, indexKey.key, column.timestamp());

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a950b925/src/java/org/apache/cassandra/db/marshal/AbstractType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/AbstractType.java 
b/src/java/org/apache/cassandra/db/marshal/AbstractType.java
index e261e9d..6804034 100644
--- a/src/java/org/apache/cassandra/db/marshal/AbstractType.java
+++ b/src/java/org/apache/cassandra/db/marshal/AbstractType.java
@@ -19,7 +19,9 @@ package org.apache.cassandra.db.marshal;
 
 import java.nio.ByteBuffer;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Comparator;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
@@ -246,6 +248,24 @@ public abstract class AbstractType<T> implements 
Comparator<ByteBuffer>
     }
 
     /**
+     * The number of subcomponents this type has.
+     * This is always 1, i.e. the type has only itself as "subcomponents", 
except for CompositeType.
+     */
+    public int componentsCount()
+    {
+        return 1;
+    }
+
+    /**
+     * Return a list of the "subcomponents" this type has.
+     * This always return a singleton list with the type itself except for 
CompositeType.
+     */
+    public List<AbstractType<?>> getComponents()
+    {
+        return Collections.<AbstractType<?>>singletonList(this);
+    }
+
+    /**
      * This must be overriden by subclasses if necessary so that for any
      * AbstractType, this == TypeParser.parse(toString()).
      *

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a950b925/src/java/org/apache/cassandra/db/marshal/CompositeType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/CompositeType.java 
b/src/java/org/apache/cassandra/db/marshal/CompositeType.java
index c33903e..0db6368 100644
--- a/src/java/org/apache/cassandra/db/marshal/CompositeType.java
+++ b/src/java/org/apache/cassandra/db/marshal/CompositeType.java
@@ -149,6 +149,18 @@ public class CompositeType extends AbstractCompositeType
     }
 
     @Override
+    public int componentsCount()
+    {
+        return types.size();
+    }
+
+    @Override
+    public List<AbstractType<?>> getComponents()
+    {
+        return types;
+    }
+
+    @Override
     public boolean isCompatibleWith(AbstractType<?> previous)
     {
         if (this == previous)
@@ -305,6 +317,11 @@ public class CompositeType extends AbstractCompositeType
             return composite.types.size() - components.size();
         }
 
+        public ByteBuffer get(int i)
+        {
+            return components.get(i);
+        }
+
         public ByteBuffer build()
         {
             DataOutputBuffer out = new DataOutputBuffer(serializedSize);
@@ -337,5 +354,13 @@ public class CompositeType extends AbstractCompositeType
         {
             return new Builder(this);
         }
+
+        public ByteBuffer getComponent(int i)
+        {
+            if (i >= components.size())
+                throw new IllegalArgumentException();
+
+            return components.get(i);
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a950b925/src/java/org/apache/cassandra/service/MigrationManager.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/MigrationManager.java 
b/src/java/org/apache/cassandra/service/MigrationManager.java
index 3d742a8..b9fcddb 100644
--- a/src/java/org/apache/cassandra/service/MigrationManager.java
+++ b/src/java/org/apache/cassandra/service/MigrationManager.java
@@ -241,7 +241,7 @@ public class MigrationManager implements 
IEndpointStateChangeSubscriber
         announce(oldKsm.toSchemaUpdate(ksm, FBUtilities.timestampMicros()));
     }
 
-    public static void announceColumnFamilyUpdate(CFMetaData cfm) throws 
ConfigurationException
+    public static void announceColumnFamilyUpdate(CFMetaData cfm, boolean 
fromThrift) throws ConfigurationException
     {
         cfm.validate();
 
@@ -252,7 +252,7 @@ public class MigrationManager implements 
IEndpointStateChangeSubscriber
         oldCfm.validateCompatility(cfm);
 
         logger.info(String.format("Update ColumnFamily '%s/%s' From %s To %s", 
cfm.ksName, cfm.cfName, oldCfm, cfm));
-        announce(oldCfm.toSchemaUpdate(cfm, FBUtilities.timestampMicros()));
+        announce(oldCfm.toSchemaUpdate(cfm, FBUtilities.timestampMicros(), 
fromThrift));
     }
 
     public static void announceKeyspaceDrop(String ksName) throws 
ConfigurationException

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a950b925/src/java/org/apache/cassandra/thrift/CassandraServer.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/thrift/CassandraServer.java 
b/src/java/org/apache/cassandra/thrift/CassandraServer.java
index 3722670..b9d3901 100644
--- a/src/java/org/apache/cassandra/thrift/CassandraServer.java
+++ b/src/java/org/apache/cassandra/thrift/CassandraServer.java
@@ -1536,7 +1536,7 @@ public class CassandraServer implements Cassandra.Iface
             CFMetaData cfm = CFMetaData.fromThrift(cf_def);
             CFMetaData.validateCompactionOptions(cfm.compactionStrategyClass, 
cfm.compactionStrategyOptions);
             cfm.addDefaultIndexNames();
-            MigrationManager.announceColumnFamilyUpdate(cfm);
+            MigrationManager.announceColumnFamilyUpdate(cfm, true);
             return Schema.instance.getVersion().toString();
         }
         catch (RequestValidationException e)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a950b925/src/java/org/apache/cassandra/utils/ByteBufferUtil.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/ByteBufferUtil.java 
b/src/java/org/apache/cassandra/utils/ByteBufferUtil.java
index 0b27d03..1ff2fc9 100644
--- a/src/java/org/apache/cassandra/utils/ByteBufferUtil.java
+++ b/src/java/org/apache/cassandra/utils/ByteBufferUtil.java
@@ -534,4 +534,14 @@ public class ByteBufferUtil
     {
         return ByteBuffer.wrap(UUIDGen.decompose(uuid));
     }
+
+    // Returns whether {@code prefix} is a prefix of {@code value}.
+    public static boolean isPrefix(ByteBuffer prefix, ByteBuffer value)
+    {
+        if (prefix.remaining() > value.remaining())
+            return false;
+
+        int diff = value.remaining() - prefix.remaining();
+        return prefix.equals(value.duplicate().limit(value.remaining() - 
diff));
+    }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a950b925/test/unit/org/apache/cassandra/SchemaLoader.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/SchemaLoader.java 
b/test/unit/org/apache/cassandra/SchemaLoader.java
index b7abacb..e3ef01a 100644
--- a/test/unit/org/apache/cassandra/SchemaLoader.java
+++ b/test/unit/org/apache/cassandra/SchemaLoader.java
@@ -133,21 +133,9 @@ public class SchemaLoader
 
         // these column definitions will will be applied to the jdbc utf and 
integer column familes respectively.
         Map<ByteBuffer, ColumnDefinition> integerColumn = new 
HashMap<ByteBuffer, ColumnDefinition>();
-        integerColumn.put(IntegerType.instance.fromString("42"), new 
ColumnDefinition(
-            IntegerType.instance.fromString("42"),
-            UTF8Type.instance,
-            null,
-            null,
-            null,
-            null));
+        integerColumn.put(IntegerType.instance.fromString("42"), 
ColumnDefinition.regularDef(IntegerType.instance.fromString("42"), 
UTF8Type.instance, null));
         Map<ByteBuffer, ColumnDefinition> utf8Column = new HashMap<ByteBuffer, 
ColumnDefinition>();
-        utf8Column.put(UTF8Type.instance.fromString("fortytwo"), new 
ColumnDefinition(
-            UTF8Type.instance.fromString("fortytwo"),
-            IntegerType.instance,
-            null,
-            null,
-            null,
-            null));
+        utf8Column.put(UTF8Type.instance.fromString("fortytwo"), 
ColumnDefinition.regularDef(UTF8Type.instance.fromString("fortytwo"), 
IntegerType.instance, null));
 
         // Make it easy to test compaction
         Map<String, String> compactionOptions = new HashMap<String, String>();
@@ -338,12 +326,11 @@ 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, withIdxType ? ByteBufferUtil.bytesToHex(cName) : 
null, null));
+                        put(cName, ColumnDefinition.regularDef(cName, 
LongType.instance, null).setIndex(withIdxType ? 
ByteBufferUtil.bytesToHex(cName) : null, keys, null));
                     }});
     }
     private static CFMetaData compositeIndexCFMD(String ksName, String cfName, 
final Boolean withIdxType, boolean withOldCfIds) throws ConfigurationException
     {
-        final Map<String, String> idxOpts = 
Collections.singletonMap(CompositesIndex.PREFIX_SIZE_OPTION, "1");
         final CompositeType composite = 
CompositeType.getInstance(Arrays.asList(new 
AbstractType<?>[]{UTF8Type.instance, UTF8Type.instance})); 
         return new CFMetaData(ksName,
                 cfName,
@@ -354,7 +341,8 @@ public class SchemaLoader
                 {{
                    ByteBuffer cName = 
ByteBuffer.wrap("col1".getBytes(Charsets.UTF_8));
                    IndexType idxType = withIdxType ? IndexType.COMPOSITES : 
null;
-                   put(cName, new ColumnDefinition(cName, UTF8Type.instance, 
idxType, idxOpts, withIdxType ? "col1_idx" : null, 1));
+                   put(cName, ColumnDefinition.regularDef(cName, 
UTF8Type.instance, 1)
+                                              .setIndex(withIdxType ? 
"col1_idx" : null, idxType, Collections.<String, String>emptyMap()));
                 }});
     }
     

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a950b925/test/unit/org/apache/cassandra/cli/CliTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cli/CliTest.java 
b/test/unit/org/apache/cassandra/cli/CliTest.java
index 0a3497b..886eb71 100644
--- a/test/unit/org/apache/cassandra/cli/CliTest.java
+++ b/test/unit/org/apache/cassandra/cli/CliTest.java
@@ -50,7 +50,6 @@ public class CliTest extends SchemaLoader
         "create column family 123 with comparator=UTF8Type and 
column_metadata=[{ column_name:world, validation_class:IntegerType, 
index_type:0, index_name:IdxName }, " +
                                                                                
"{ column_name:world2, validation_class:LongType, index_type:KEYS, 
index_name:LongIdxName}, " +
                                                                                
"{ column_name:617070, validation_class:UTF8Type, index_type:KEYS }, " +
-                                                                               
"{ column_name:28292, validation_class:UTF8Type, index_type:CUSTOM, 
index_options:{class_name:'org.apache.cassandra.db.index.keys.KeysIndex', 
foo:bar}}," +
                                                                                
"{ column_name:'-617071', validation_class:UTF8Type, index_type:KEYS }," +
                                                                                
"{ column_name:time_spent_uuid, validation_class:TimeUUIDType}] and 
default_validation_class=UTF8Type;",
         "assume 123 keys as utf8;",

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a950b925/test/unit/org/apache/cassandra/config/CFMetaDataTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/config/CFMetaDataTest.java 
b/test/unit/org/apache/cassandra/config/CFMetaDataTest.java
index 8ca83ce..d6670ed 100644
--- a/test/unit/org/apache/cassandra/config/CFMetaDataTest.java
+++ b/test/unit/org/apache/cassandra/config/CFMetaDataTest.java
@@ -129,12 +129,11 @@ public class CFMetaDataTest extends SchemaLoader
         // are only used by CQL (so far) so we don't expose them through thrift
         // There is a CFM with componentIndex defined in Keyspace2 which is 
used by 
         // ColumnFamilyStoreTest to verify index repair (CASSANDRA-2897)
-        for (Map.Entry<ByteBuffer, ColumnDefinition> cMeta: 
cfm.column_metadata.entrySet())
+        for (ColumnDefinition def: cfm.allColumns())
         {
-            // Non-null componentIndex are only used by CQL (so far) so we 
don't expose
-            // them through thrift
-            if (cMeta.getValue().componentIndex != null)
-                cfm.column_metadata.remove(cMeta.getKey());
+            // Remove what we know is not thrift compatible
+            if (!def.isThriftCompatible())
+                cfm.removeColumnDefinition(def);
         }
 
         // Test thrift conversion

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a950b925/test/unit/org/apache/cassandra/config/ColumnDefinitionTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/config/ColumnDefinitionTest.java 
b/test/unit/org/apache/cassandra/config/ColumnDefinitionTest.java
index 1e2ef9c..fa7343c 100644
--- a/test/unit/org/apache/cassandra/config/ColumnDefinitionTest.java
+++ b/test/unit/org/apache/cassandra/config/ColumnDefinitionTest.java
@@ -33,19 +33,10 @@ public class ColumnDefinitionTest
     @Test
     public void testSerializeDeserialize() throws Exception
     {
-        ColumnDefinition cd0 = new 
ColumnDefinition(ByteBufferUtil.bytes("TestColumnDefinitionName0"),
-                                                    BytesType.instance,
-                                                    IndexType.KEYS,
-                                                    null,
-                                                    "random index name 0",
-                                                    null);
+        ColumnDefinition cd0 = 
ColumnDefinition.regularDef(ByteBufferUtil.bytes("TestColumnDefinitionName0"), 
BytesType.instance, null)
+                                               .setIndex("random index name 
0", IndexType.KEYS, null);
 
-        ColumnDefinition cd1 = new 
ColumnDefinition(ByteBufferUtil.bytes("TestColumnDefinition1"),
-                                                    LongType.instance,
-                                                    null,
-                                                    null,
-                                                    null,
-                                                    null);
+        ColumnDefinition cd1 = 
ColumnDefinition.regularDef(ByteBufferUtil.bytes("TestColumnDefinition1"), 
LongType.instance, null);
 
         testSerializeDeserialize(cd0);
         testSerializeDeserialize(cd1);

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a950b925/test/unit/org/apache/cassandra/config/DefsTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/config/DefsTest.java 
b/test/unit/org/apache/cassandra/config/DefsTest.java
index 76cab94..66d5f81 100644
--- a/test/unit/org/apache/cassandra/config/DefsTest.java
+++ b/test/unit/org/apache/cassandra/config/DefsTest.java
@@ -63,7 +63,7 @@ public class DefsTest extends SchemaLoader
         for (int i = 0; i < 5; i++)
         {
             ByteBuffer name = ByteBuffer.wrap(new byte[] { (byte)i });
-            indexes.put(name, new ColumnDefinition(name, BytesType.instance, 
IndexType.KEYS, null, Integer.toString(i), null));
+            indexes.put(name, ColumnDefinition.regularDef(name, 
BytesType.instance, null).setIndex(Integer.toString(i), IndexType.KEYS, null));
         }
         CFMetaData cfm = new CFMetaData("Keyspace1",
                                         "TestApplyCFM_CF",
@@ -80,34 +80,26 @@ public class DefsTest extends SchemaLoader
            .columnMetadata(indexes);
 
         // we'll be adding this one later. make sure it's not already there.
-        assert cfm.getColumn_metadata().get(ByteBuffer.wrap(new byte[] { 5 })) 
== null;
+        assert cfm.getColumnDefinition(ByteBuffer.wrap(new byte[] { 5 })) == 
null;
 
         CFMetaData cfNew = cfm.clone();
 
         // add one.
-        ColumnDefinition addIndexDef = new 
ColumnDefinition(ByteBuffer.wrap(new byte[] { 5 }),
-                                                            BytesType.instance,
-                                                            IndexType.KEYS,
-                                                            null,
-                                                            "5",
-                                                            null);
+        ColumnDefinition addIndexDef = 
ColumnDefinition.regularDef(ByteBuffer.wrap(new byte[] { 5 }), 
BytesType.instance, null)
+                                                       .setIndex("5", 
IndexType.KEYS, null);
         cfNew.addColumnDefinition(addIndexDef);
 
         // remove one.
-        ColumnDefinition removeIndexDef = new 
ColumnDefinition(ByteBuffer.wrap(new byte[] { 0 }),
-                                                               
BytesType.instance,
-                                                               IndexType.KEYS,
-                                                               null,
-                                                               "0",
-                                                               null);
+        ColumnDefinition removeIndexDef = 
ColumnDefinition.regularDef(ByteBuffer.wrap(new byte[] { 0 }), 
BytesType.instance, null)
+                                                          .setIndex("0", 
IndexType.KEYS, null);
         assert cfNew.removeColumnDefinition(removeIndexDef);
 
         cfm.apply(cfNew);
 
         for (int i = 1; i < indexes.size(); i++)
-            assert cfm.getColumn_metadata().get(ByteBuffer.wrap(new byte[] { 1 
})) != null;
-        assert cfm.getColumn_metadata().get(ByteBuffer.wrap(new byte[] { 0 })) 
== null;
-        assert cfm.getColumn_metadata().get(ByteBuffer.wrap(new byte[] { 5 })) 
!= null;
+            assert cfm.getColumnDefinition(ByteBuffer.wrap(new byte[] { 1 })) 
!= null;
+        assert cfm.getColumnDefinition(ByteBuffer.wrap(new byte[] { 0 })) == 
null;
+        assert cfm.getColumnDefinition(ByteBuffer.wrap(new byte[] { 5 })) != 
null;
     }
 
     @Test
@@ -435,22 +427,22 @@ public class DefsTest extends SchemaLoader
 
         // test valid operations.
         newCfm.comment("Modified comment");
-        MigrationManager.announceColumnFamilyUpdate(newCfm); // doesn't get 
set back here.
+        MigrationManager.announceColumnFamilyUpdate(newCfm, false); // doesn't 
get set back here.
 
         newCfm.readRepairChance(0.23);
-        MigrationManager.announceColumnFamilyUpdate(newCfm);
+        MigrationManager.announceColumnFamilyUpdate(newCfm, false);
 
         newCfm.gcGraceSeconds(12);
-        MigrationManager.announceColumnFamilyUpdate(newCfm);
+        MigrationManager.announceColumnFamilyUpdate(newCfm, false);
 
         newCfm.defaultValidator(UTF8Type.instance);
-        MigrationManager.announceColumnFamilyUpdate(newCfm);
+        MigrationManager.announceColumnFamilyUpdate(newCfm, false);
 
         newCfm.minCompactionThreshold(3);
-        MigrationManager.announceColumnFamilyUpdate(newCfm);
+        MigrationManager.announceColumnFamilyUpdate(newCfm, false);
 
         newCfm.maxCompactionThreshold(33);
-        MigrationManager.announceColumnFamilyUpdate(newCfm);
+        MigrationManager.announceColumnFamilyUpdate(newCfm, false);
 
         // can't test changing the reconciler because there is only one impl.
 
@@ -529,10 +521,10 @@ public class DefsTest extends SchemaLoader
 
         // drop the index
         CFMetaData meta = cfs.metadata.clone();
-        ColumnDefinition cdOld = 
meta.getColumn_metadata().values().iterator().next();
-        ColumnDefinition cdNew = new ColumnDefinition(cdOld.name, 
cdOld.getValidator(), null, null, null, null);
+        ColumnDefinition cdOld = meta.regularColumns().iterator().next();
+        ColumnDefinition cdNew = ColumnDefinition.regularDef(cdOld.name, 
cdOld.getValidator(), null);
         meta.columnMetadata(Collections.singletonMap(cdOld.name, cdNew));
-        MigrationManager.announceColumnFamilyUpdate(meta);
+        MigrationManager.announceColumnFamilyUpdate(meta, false);
 
         // check
         assert cfs.indexManager.getIndexes().isEmpty();

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a950b925/test/unit/org/apache/cassandra/db/ColumnFamilyStoreTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/db/ColumnFamilyStoreTest.java 
b/test/unit/org/apache/cassandra/db/ColumnFamilyStoreTest.java
index fc744b8..8ac0bae 100644
--- a/test/unit/org/apache/cassandra/db/ColumnFamilyStoreTest.java
+++ b/test/unit/org/apache/cassandra/db/ColumnFamilyStoreTest.java
@@ -597,8 +597,8 @@ public class ColumnFamilyStoreTest extends SchemaLoader
         rm.apply();
 
         ColumnFamilyStore cfs = table.getColumnFamilyStore("Indexed2");
-        ColumnDefinition old = 
cfs.metadata.getColumn_metadata().get(ByteBufferUtil.bytes("birthdate"));
-        ColumnDefinition cd = new ColumnDefinition(old.name, 
old.getValidator(), IndexType.KEYS, null, "birthdate_index", null);
+        ColumnDefinition old = 
cfs.metadata.getColumnDefinition(ByteBufferUtil.bytes("birthdate"));
+        ColumnDefinition cd = ColumnDefinition.regularDef(old.name, 
old.getValidator(), null).setIndex("birthdate_index", IndexType.KEYS, null);
         Future<?> future = cfs.indexManager.addIndexedColumn(cd);
         future.get();
         // we had a bug (CASSANDRA-2244) where index would get created but not 
flushed -- check for that

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a950b925/test/unit/org/apache/cassandra/thrift/ThriftValidationTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/thrift/ThriftValidationTest.java 
b/test/unit/org/apache/cassandra/thrift/ThriftValidationTest.java
index 45ab748..e4f058c 100644
--- a/test/unit/org/apache/cassandra/thrift/ThriftValidationTest.java
+++ b/test/unit/org/apache/cassandra/thrift/ThriftValidationTest.java
@@ -56,11 +56,10 @@ public class ThriftValidationTest extends SchemaLoader
         boolean gotException = false;
 
         // add a key_alias = "id"
-        
newMetadata.keyAliases(Collections.singletonList(AsciiType.instance.decompose("id")));
-
         // should not throw IRE here
         try
         {
+            
newMetadata.addColumnDefinition(ColumnDefinition.partitionKeyDef(AsciiType.instance.decompose("id"),
 UTF8Type.instance, null));
             newMetadata.validate();
         }
         catch (ConfigurationException e)
@@ -70,13 +69,13 @@ public class ThriftValidationTest extends SchemaLoader
 
         assert !gotException : "got unexpected ConfigurationException";
 
-        // add a column with name = "id"
-        newMetadata.addColumnDefinition(new 
ColumnDefinition(ByteBufferUtil.bytes("id"), UTF8Type.instance, null, null, 
null, null));
 
         gotException = false;
 
+        // add a column with name = "id"
         try
         {
+            
newMetadata.addColumnDefinition(ColumnDefinition.regularDef(ByteBufferUtil.bytes("id"),
 UTF8Type.instance, null));
             newMetadata.validate();
         }
         catch (ConfigurationException e)

Reply via email to