cassandra-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From slebre...@apache.org
Subject [48/51] [partial] cassandra git commit: Storage engine refactor, a.k.a CASSANDRA-8099
Date Tue, 30 Jun 2015 10:48:12 GMT
http://git-wip-us.apache.org/repos/asf/cassandra/blob/a991b648/src/java/org/apache/cassandra/cql3/UpdateParameters.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/UpdateParameters.java b/src/java/org/apache/cassandra/cql3/UpdateParameters.java
index e412585..66f6b43 100644
--- a/src/java/org/apache/cassandra/cql3/UpdateParameters.java
+++ b/src/java/org/apache/cassandra/cql3/UpdateParameters.java
@@ -18,15 +18,18 @@
 package org.apache.cassandra.cql3;
 
 import java.nio.ByteBuffer;
-import java.util.Collections;
-import java.util.List;
 import java.util.Map;
 
 import org.apache.cassandra.config.CFMetaData;
+import org.apache.cassandra.config.ColumnDefinition;
 import org.apache.cassandra.db.*;
-import org.apache.cassandra.db.composites.CellName;
-import org.apache.cassandra.db.filter.ColumnSlice;
+import org.apache.cassandra.db.filter.ColumnFilter;
+import org.apache.cassandra.db.rows.*;
+import org.apache.cassandra.db.context.CounterContext;
+import org.apache.cassandra.db.index.SecondaryIndexManager;
+import org.apache.cassandra.db.partitions.*;
 import org.apache.cassandra.exceptions.InvalidRequestException;
+import org.apache.cassandra.utils.ByteBufferUtil;
 import org.apache.cassandra.utils.FBUtilities;
 
 /**
@@ -36,22 +39,39 @@ public class UpdateParameters
 {
     public final CFMetaData metadata;
     public final QueryOptions options;
-    public final long timestamp;
-    private final int ttl;
-    public final int localDeletionTime;
+
+    private final LivenessInfo defaultLiveness;
+    private final LivenessInfo deletionLiveness;
+    private final DeletionTime deletionTime;
+
+    private final SecondaryIndexManager indexManager;
 
     // For lists operation that require a read-before-write. Will be null otherwise.
-    private final Map<ByteBuffer, CQL3Row> prefetchedLists;
+    private final Map<DecoratedKey, Partition> prefetchedRows;
 
-    public UpdateParameters(CFMetaData metadata, QueryOptions options, long timestamp, int ttl, Map<ByteBuffer, CQL3Row> prefetchedLists)
+    public UpdateParameters(CFMetaData metadata, QueryOptions options, long timestamp, int ttl, Map<DecoratedKey, Partition> prefetchedRows, boolean validateIndexedColumns)
     throws InvalidRequestException
     {
         this.metadata = metadata;
         this.options = options;
-        this.timestamp = timestamp;
-        this.ttl = ttl;
-        this.localDeletionTime = (int)(System.currentTimeMillis() / 1000);
-        this.prefetchedLists = prefetchedLists;
+
+        int nowInSec = FBUtilities.nowInSeconds();
+        this.defaultLiveness = SimpleLivenessInfo.forUpdate(timestamp, ttl, nowInSec, metadata);
+        this.deletionLiveness = SimpleLivenessInfo.forDeletion(timestamp, nowInSec);
+        this.deletionTime = new SimpleDeletionTime(timestamp, nowInSec);
+
+        this.prefetchedRows = prefetchedRows;
+
+        // Index column validation triggers a call to Keyspace.open() which we want to be able to avoid in some case (e.g. when using CQLSSTableWriter)
+        if (validateIndexedColumns)
+        {
+            SecondaryIndexManager manager = Keyspace.openAndGetStore(metadata).indexManager;
+            indexManager = manager.hasIndexes() ? manager : null;
+        }
+        else
+        {
+            indexManager = null;
+        }
 
         // We use MIN_VALUE internally to mean the absence of of timestamp (in Selection, in sstable stats, ...), so exclude
         // it to avoid potential confusion.
@@ -59,48 +79,106 @@ public class UpdateParameters
             throw new InvalidRequestException(String.format("Out of bound timestamp, must be in [%d, %d]", Long.MIN_VALUE + 1, Long.MAX_VALUE));
     }
 
-    public Cell makeColumn(CellName name, ByteBuffer value) throws InvalidRequestException
+    public void newPartition(DecoratedKey partitionKey) throws InvalidRequestException
+    {
+        if (indexManager != null)
+            indexManager.validate(partitionKey);
+    }
+
+    public void writeClustering(Clustering clustering, Row.Writer writer) throws InvalidRequestException
+    {
+        if (indexManager != null)
+            indexManager.validate(clustering);
+
+        if (metadata.isDense() && !metadata.isCompound())
+        {
+            // If it's a COMPACT STORAGE table with a single clustering column, the clustering value is
+            // translated in Thrift to the full Thrift column name, and for backward compatibility we
+            // don't want to allow that to be empty (even though this would be fine for the storage engine).
+            assert clustering.size() == 1;
+            ByteBuffer value = clustering.get(0);
+            if (value == null || !value.hasRemaining())
+                throw new InvalidRequestException("Invalid empty or null value for column " + metadata.clusteringColumns().get(0).name);
+        }
+
+        Rows.writeClustering(clustering, writer);
+    }
+
+    public void writePartitionKeyLivenessInfo(Row.Writer writer)
+    {
+        writer.writePartitionKeyLivenessInfo(defaultLiveness);
+    }
+
+    public void writeRowDeletion(Row.Writer writer)
+    {
+        writer.writeRowDeletion(deletionTime);
+    }
+
+    public void addTombstone(ColumnDefinition column, Row.Writer writer) throws InvalidRequestException
     {
-        QueryProcessor.validateCellName(name, metadata.comparator);
-        return AbstractCell.create(name, value, timestamp, ttl, metadata);
+        addTombstone(column, writer, null);
     }
 
-     public Cell makeCounter(CellName name, long delta) throws InvalidRequestException
-     {
-         QueryProcessor.validateCellName(name, metadata.comparator);
-         return new BufferCounterUpdateCell(name, delta, FBUtilities.timestampMicros());
-     }
+    public void addTombstone(ColumnDefinition column, Row.Writer writer, CellPath path) throws InvalidRequestException
+    {
+        writer.writeCell(column, false, ByteBufferUtil.EMPTY_BYTE_BUFFER, deletionLiveness, path);
+    }
 
-    public Cell makeTombstone(CellName name) throws InvalidRequestException
+    public void addCell(Clustering clustering, ColumnDefinition column, Row.Writer writer, ByteBuffer value) throws InvalidRequestException
     {
-        QueryProcessor.validateCellName(name, metadata.comparator);
-        return new BufferDeletedCell(name, localDeletionTime, timestamp);
+        addCell(clustering, column, writer, null, value);
     }
 
-    public RangeTombstone makeRangeTombstone(ColumnSlice slice) throws InvalidRequestException
+    public void addCell(Clustering clustering, ColumnDefinition column, Row.Writer writer, CellPath path, ByteBuffer value) throws InvalidRequestException
     {
-        QueryProcessor.validateComposite(slice.start, metadata.comparator);
-        QueryProcessor.validateComposite(slice.finish, metadata.comparator);
-        return new RangeTombstone(slice.start, slice.finish, timestamp, localDeletionTime);
+        if (indexManager != null)
+            indexManager.validate(column, value, path);
+
+        writer.writeCell(column, false, value, defaultLiveness, path);
     }
 
-    public RangeTombstone makeTombstoneForOverwrite(ColumnSlice slice) throws InvalidRequestException
+    public void addCounter(ColumnDefinition column, Row.Writer writer, long increment) throws InvalidRequestException
     {
-        QueryProcessor.validateComposite(slice.start, metadata.comparator);
-        QueryProcessor.validateComposite(slice.finish, metadata.comparator);
-        return new RangeTombstone(slice.start, slice.finish, timestamp - 1, localDeletionTime);
+        assert defaultLiveness.ttl() == LivenessInfo.NO_TTL;
+
+        // In practice, the actual CounterId (and clock really) that we use doesn't matter, because we will
+        // actually ignore it in CounterMutation when we do the read-before-write to create the actual value
+        // that is applied. In other words, this is not the actual value that will be written to the memtable
+        // because this will be replaced in CounterMutation.updateWithCurrentValue().
+        // As an aside, since we don't care about the CounterId/clock, we used to only send the incremement,
+        // but that makes things a bit more complex as this means we need to be able to distinguish inside
+        // PartitionUpdate between counter updates that has been processed by CounterMutation and those that
+        // haven't.
+        ByteBuffer value = CounterContext.instance().createLocal(increment);
+        writer.writeCell(column, true, value, defaultLiveness, null);
     }
 
-    public List<Cell> getPrefetchedList(ByteBuffer rowKey, ColumnIdentifier cql3ColumnName)
+    public void setComplexDeletionTime(ColumnDefinition column, Row.Writer writer)
     {
-        if (prefetchedLists == null)
-            return Collections.emptyList();
+        writer.writeComplexDeletion(column, deletionTime);
+    }
 
-        CQL3Row row = prefetchedLists.get(rowKey);
-        if (row == null)
-            return Collections.<Cell>emptyList();
+    public void setComplexDeletionTimeForOverwrite(ColumnDefinition column, Row.Writer writer)
+    {
+        writer.writeComplexDeletion(column, new SimpleDeletionTime(deletionTime.markedForDeleteAt() - 1, deletionTime.localDeletionTime()));
+    }
+
+    public DeletionTime deletionTime()
+    {
+        return deletionTime;
+    }
+
+    public RangeTombstone makeRangeTombstone(CBuilder cbuilder)
+    {
+        return new RangeTombstone(cbuilder.buildSlice(), deletionTime);
+    }
+
+    public Row getPrefetchedRow(DecoratedKey key, Clustering clustering)
+    {
+        if (prefetchedRows == null)
+            return null;
 
-        List<Cell> cql3List = row.getMultiCellColumn(cql3ColumnName);
-        return (cql3List == null) ? Collections.<Cell>emptyList() : cql3List;
+        Partition partition = prefetchedRows.get(key);
+        return partition == null ? null : partition.searchIterator(ColumnFilter.selection(partition.columns()), false).next(clustering);
     }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a991b648/src/java/org/apache/cassandra/cql3/functions/TokenFct.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/functions/TokenFct.java b/src/java/org/apache/cassandra/cql3/functions/TokenFct.java
index 9d50a97..c76b588 100644
--- a/src/java/org/apache/cassandra/cql3/functions/TokenFct.java
+++ b/src/java/org/apache/cassandra/cql3/functions/TokenFct.java
@@ -22,7 +22,8 @@ import java.util.List;
 
 import org.apache.cassandra.config.CFMetaData;
 import org.apache.cassandra.config.ColumnDefinition;
-import org.apache.cassandra.db.composites.CBuilder;
+import org.apache.cassandra.cql3.statements.SelectStatement;
+import org.apache.cassandra.db.CBuilder;
 import org.apache.cassandra.db.marshal.AbstractType;
 import org.apache.cassandra.dht.IPartitioner;
 import org.apache.cassandra.exceptions.InvalidRequestException;
@@ -52,7 +53,7 @@ public class TokenFct extends NativeScalarFunction
 
     public ByteBuffer execute(int protocolVersion, List<ByteBuffer> parameters) throws InvalidRequestException
     {
-        CBuilder builder = cfm.getKeyValidatorAsCType().builder();
+        CBuilder builder = CBuilder.create(cfm.getKeyValidatorAsClusteringComparator());
         for (int i = 0; i < parameters.size(); i++)
         {
             ByteBuffer bb = parameters.get(i);
@@ -60,6 +61,6 @@ public class TokenFct extends NativeScalarFunction
                 return null;
             builder.add(bb);
         }
-        return partitioner.getTokenFactory().toByteArray(partitioner.getToken(builder.build().toByteBuffer()));
+        return partitioner.getTokenFactory().toByteArray(partitioner.getToken(CFMetaData.serializePartitionKey(builder.build())));
     }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a991b648/src/java/org/apache/cassandra/cql3/restrictions/AbstractPrimaryKeyRestrictions.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/restrictions/AbstractPrimaryKeyRestrictions.java b/src/java/org/apache/cassandra/cql3/restrictions/AbstractPrimaryKeyRestrictions.java
index 2eaa386..f1b5a50 100644
--- a/src/java/org/apache/cassandra/cql3/restrictions/AbstractPrimaryKeyRestrictions.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/AbstractPrimaryKeyRestrictions.java
@@ -18,11 +18,12 @@
 package org.apache.cassandra.cql3.restrictions;
 
 import java.nio.ByteBuffer;
-import java.util.List;
+import java.util.*;
 
 import org.apache.cassandra.cql3.QueryOptions;
 import org.apache.cassandra.cql3.statements.Bound;
-import org.apache.cassandra.db.composites.CType;
+import org.apache.cassandra.db.ClusteringPrefix;
+import org.apache.cassandra.db.ClusteringComparator;
 import org.apache.cassandra.exceptions.InvalidRequestException;
 
 /**
@@ -33,11 +34,11 @@ abstract class AbstractPrimaryKeyRestrictions extends AbstractRestriction implem
     /**
      * The composite type.
      */
-    protected final CType ctype;
+    protected final ClusteringComparator comparator;
 
-    public AbstractPrimaryKeyRestrictions(CType ctype)
+    public AbstractPrimaryKeyRestrictions(ClusteringComparator comparator)
     {
-        this.ctype = ctype;
+        this.comparator = comparator;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a991b648/src/java/org/apache/cassandra/cql3/restrictions/AbstractRestriction.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/restrictions/AbstractRestriction.java b/src/java/org/apache/cassandra/cql3/restrictions/AbstractRestriction.java
index 64c94f4..0f56fd9 100644
--- a/src/java/org/apache/cassandra/cql3/restrictions/AbstractRestriction.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/AbstractRestriction.java
@@ -22,7 +22,7 @@ import java.nio.ByteBuffer;
 import org.apache.cassandra.cql3.ColumnSpecification;
 import org.apache.cassandra.cql3.QueryOptions;
 import org.apache.cassandra.cql3.statements.Bound;
-import org.apache.cassandra.db.composites.CompositesBuilder;
+import org.apache.cassandra.db.MultiCBuilder;
 import org.apache.cassandra.exceptions.InvalidRequestException;
 
 import static org.apache.cassandra.cql3.statements.RequestValidations.checkBindValueSet;
@@ -77,7 +77,7 @@ abstract class AbstractRestriction  implements Restriction
     }
 
     @Override
-    public CompositesBuilder appendBoundTo(CompositesBuilder builder, Bound bound, QueryOptions options)
+    public MultiCBuilder appendBoundTo(MultiCBuilder builder, Bound bound, QueryOptions options)
     {
         return appendTo(builder, options);
     }
@@ -87,14 +87,4 @@ abstract class AbstractRestriction  implements Restriction
     {
         return true;
     }
-
-    protected static ByteBuffer validateIndexedValue(ColumnSpecification columnSpec,
-                                                     ByteBuffer value)
-                                                     throws InvalidRequestException
-    {
-        checkNotNull(value, "Unsupported null value for indexed column %s", columnSpec.name);
-        checkBindValueSet(value, "Unsupported unset value for indexed column %s", columnSpec.name);
-        checkFalse(value.remaining() > 0xFFFF, "Index expression values may not be larger than 64K");
-        return value;
-    }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a991b648/src/java/org/apache/cassandra/cql3/restrictions/ForwardingPrimaryKeyRestrictions.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/restrictions/ForwardingPrimaryKeyRestrictions.java b/src/java/org/apache/cassandra/cql3/restrictions/ForwardingPrimaryKeyRestrictions.java
index 03c6cbc..91359e6 100644
--- a/src/java/org/apache/cassandra/cql3/restrictions/ForwardingPrimaryKeyRestrictions.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/ForwardingPrimaryKeyRestrictions.java
@@ -18,16 +18,15 @@
 package org.apache.cassandra.cql3.restrictions;
 
 import java.nio.ByteBuffer;
-import java.util.Collection;
-import java.util.List;
+import java.util.*;
 
 import org.apache.cassandra.config.ColumnDefinition;
 import org.apache.cassandra.cql3.QueryOptions;
 import org.apache.cassandra.cql3.functions.Function;
 import org.apache.cassandra.cql3.statements.Bound;
-import org.apache.cassandra.db.IndexExpression;
-import org.apache.cassandra.db.composites.Composite;
-import org.apache.cassandra.db.composites.CompositesBuilder;
+import org.apache.cassandra.db.*;
+import org.apache.cassandra.db.Slice;
+import org.apache.cassandra.db.filter.RowFilter;
 import org.apache.cassandra.db.index.SecondaryIndexManager;
 import org.apache.cassandra.exceptions.InvalidRequestException;
 
@@ -87,15 +86,15 @@ abstract class ForwardingPrimaryKeyRestrictions implements PrimaryKeyRestriction
     }
 
     @Override
-    public CompositesBuilder appendTo(CompositesBuilder builder, QueryOptions options)
+    public MultiCBuilder appendTo(MultiCBuilder builder, QueryOptions options)
     {
         return getDelegate().appendTo(builder, options);
     }
 
     @Override
-    public List<Composite> valuesAsComposites(QueryOptions options) throws InvalidRequestException
+    public NavigableSet<Clustering> valuesAsClustering(QueryOptions options) throws InvalidRequestException
     {
-        return getDelegate().valuesAsComposites(options);
+        return getDelegate().valuesAsClustering(options);
     }
 
     @Override
@@ -105,13 +104,13 @@ abstract class ForwardingPrimaryKeyRestrictions implements PrimaryKeyRestriction
     }
 
     @Override
-    public List<Composite> boundsAsComposites(Bound bound, QueryOptions options) throws InvalidRequestException
+    public SortedSet<Slice.Bound> boundsAsClustering(Bound bound, QueryOptions options) throws InvalidRequestException
     {
-        return getDelegate().boundsAsComposites(bound, options);
+        return getDelegate().boundsAsClustering(bound, options);
     }
 
     @Override
-    public CompositesBuilder appendBoundTo(CompositesBuilder builder, Bound bound, QueryOptions options)
+    public MultiCBuilder appendBoundTo(MultiCBuilder builder, Bound bound, QueryOptions options)
     {
         return getDelegate().appendBoundTo(builder, bound, options);
     }
@@ -177,10 +176,8 @@ abstract class ForwardingPrimaryKeyRestrictions implements PrimaryKeyRestriction
     }
 
     @Override
-    public void addIndexExpressionTo(List<IndexExpression> expressions,
-                                     SecondaryIndexManager indexManager,
-                                     QueryOptions options) throws InvalidRequestException
+    public void addRowFilterTo(RowFilter filter, SecondaryIndexManager indexManager, QueryOptions options) throws InvalidRequestException
     {
-        getDelegate().addIndexExpressionTo(expressions, indexManager, options);
+        getDelegate().addRowFilterTo(filter, indexManager, options);
     }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a991b648/src/java/org/apache/cassandra/cql3/restrictions/MultiColumnRestriction.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/restrictions/MultiColumnRestriction.java b/src/java/org/apache/cassandra/cql3/restrictions/MultiColumnRestriction.java
index c4bce4c..e48a22b 100644
--- a/src/java/org/apache/cassandra/cql3/restrictions/MultiColumnRestriction.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/MultiColumnRestriction.java
@@ -24,8 +24,8 @@ import org.apache.cassandra.config.ColumnDefinition;
 import org.apache.cassandra.cql3.*;
 import org.apache.cassandra.cql3.functions.Function;
 import org.apache.cassandra.cql3.statements.Bound;
-import org.apache.cassandra.db.IndexExpression;
-import org.apache.cassandra.db.composites.CompositesBuilder;
+import org.apache.cassandra.db.*;
+import org.apache.cassandra.db.filter.RowFilter;
 import org.apache.cassandra.db.index.SecondaryIndex;
 import org.apache.cassandra.db.index.SecondaryIndexManager;
 import org.apache.cassandra.exceptions.InvalidRequestException;
@@ -108,7 +108,7 @@ public abstract class MultiColumnRestriction extends AbstractRestriction
     {
         for (ColumnDefinition columnDef : columnDefs)
         {
-            SecondaryIndex index = indexManager.getIndexForColumn(columnDef.name.bytes);
+            SecondaryIndex index = indexManager.getIndexForColumn(columnDef);
             if (index != null && isSupportedBy(index))
                 return true;
         }
@@ -124,11 +124,11 @@ public abstract class MultiColumnRestriction extends AbstractRestriction
      */
     protected abstract boolean isSupportedBy(SecondaryIndex index);
 
-    public static class EQ  extends MultiColumnRestriction
+    public static class EQRestriction extends MultiColumnRestriction
     {
         protected final Term value;
 
-        public EQ(List<ColumnDefinition> columnDefs, Term value)
+        public EQRestriction(List<ColumnDefinition> columnDefs, Term value)
         {
             super(columnDefs);
             this.value = value;
@@ -160,7 +160,7 @@ public abstract class MultiColumnRestriction extends AbstractRestriction
         }
 
         @Override
-        public CompositesBuilder appendTo(CompositesBuilder builder, QueryOptions options)
+        public MultiCBuilder appendTo(MultiCBuilder builder, QueryOptions options)
         {
             Tuples.Value t = ((Tuples.Value) value.bind(options));
             List<ByteBuffer> values = t.getElements();
@@ -173,9 +173,7 @@ public abstract class MultiColumnRestriction extends AbstractRestriction
         }
 
         @Override
-        public final void addIndexExpressionTo(List<IndexExpression> expressions,
-                                               SecondaryIndexManager indexManager,
-                                               QueryOptions options) throws InvalidRequestException
+        public final void addRowFilterTo(RowFilter filter, SecondaryIndexManager indexMananger, QueryOptions options) throws InvalidRequestException
         {
             Tuples.Value t = ((Tuples.Value) value.bind(options));
             List<ByteBuffer> values = t.getElements();
@@ -183,19 +181,23 @@ public abstract class MultiColumnRestriction extends AbstractRestriction
             for (int i = 0, m = columnDefs.size(); i < m; i++)
             {
                 ColumnDefinition columnDef = columnDefs.get(i);
-                ByteBuffer component = validateIndexedValue(columnDef, values.get(i));
-                expressions.add(new IndexExpression(columnDef.name.bytes, Operator.EQ, component));
+                filter.add(columnDef, Operator.EQ, values.get(i));
             }
         }
     }
 
-    public abstract static class IN extends MultiColumnRestriction
+    public abstract static class INRestriction extends MultiColumnRestriction
     {
+        public INRestriction(List<ColumnDefinition> columnDefs)
+        {
+            super(columnDefs);
+        }
+
         /**
          * {@inheritDoc}
          */
         @Override
-        public CompositesBuilder appendTo(CompositesBuilder builder, QueryOptions options)
+        public MultiCBuilder appendTo(MultiCBuilder builder, QueryOptions options)
         {
             List<List<ByteBuffer>> splitInValues = splitValues(options);
             builder.addAllElementsToAll(splitInValues);
@@ -205,11 +207,6 @@ public abstract class MultiColumnRestriction extends AbstractRestriction
             return builder;
         }
 
-        public IN(List<ColumnDefinition> columnDefs)
-        {
-            super(columnDefs);
-        }
-
         @Override
         public boolean isIN()
         {
@@ -230,9 +227,9 @@ public abstract class MultiColumnRestriction extends AbstractRestriction
         }
 
         @Override
-        public final void addIndexExpressionTo(List<IndexExpression> expressions,
-                                               SecondaryIndexManager indexManager,
-                                               QueryOptions options) throws InvalidRequestException
+        public final void addRowFilterTo(RowFilter filter,
+                                         SecondaryIndexManager indexManager,
+                                         QueryOptions options) throws InvalidRequestException
         {
             List<List<ByteBuffer>> splitInValues = splitValues(options);
             checkTrue(splitInValues.size() == 1, "IN restrictions are not supported on indexed columns");
@@ -241,8 +238,7 @@ public abstract class MultiColumnRestriction extends AbstractRestriction
             for (int i = 0, m = columnDefs.size(); i < m; i++)
             {
                 ColumnDefinition columnDef = columnDefs.get(i);
-                ByteBuffer component = validateIndexedValue(columnDef, values.get(i));
-                expressions.add(new IndexExpression(columnDef.name.bytes, Operator.EQ, component));
+                filter.add(columnDef, Operator.EQ, values.get(i));
             }
         }
 
@@ -253,11 +249,11 @@ public abstract class MultiColumnRestriction extends AbstractRestriction
      * An IN restriction that has a set of terms for in values.
      * For example: "SELECT ... WHERE (a, b, c) IN ((1, 2, 3), (4, 5, 6))" or "WHERE (a, b, c) IN (?, ?)"
      */
-    public static class InWithValues extends MultiColumnRestriction.IN
+    public static class InRestrictionWithValues extends INRestriction
     {
         protected final List<Term> values;
 
-        public InWithValues(List<ColumnDefinition> columnDefs, List<Term> values)
+        public InRestrictionWithValues(List<ColumnDefinition> columnDefs, List<Term> values)
         {
             super(columnDefs);
             this.values = values;
@@ -292,11 +288,11 @@ public abstract class MultiColumnRestriction extends AbstractRestriction
      * An IN restriction that uses a single marker for a set of IN values that are tuples.
      * For example: "SELECT ... WHERE (a, b, c) IN ?"
      */
-    public static class InWithMarker extends MultiColumnRestriction.IN
+    public static class InRestrictionWithMarker extends INRestriction
     {
         protected final AbstractMarker marker;
 
-        public InWithMarker(List<ColumnDefinition> columnDefs, AbstractMarker marker)
+        public InRestrictionWithMarker(List<ColumnDefinition> columnDefs, AbstractMarker marker)
         {
             super(columnDefs);
             this.marker = marker;
@@ -324,16 +320,16 @@ public abstract class MultiColumnRestriction extends AbstractRestriction
         }
     }
 
-    public static class Slice extends MultiColumnRestriction
+    public static class SliceRestriction extends MultiColumnRestriction
     {
         private final TermSlice slice;
 
-        public Slice(List<ColumnDefinition> columnDefs, Bound bound, boolean inclusive, Term term)
+        public SliceRestriction(List<ColumnDefinition> columnDefs, Bound bound, boolean inclusive, Term term)
         {
             this(columnDefs, TermSlice.newInstance(bound, inclusive, term));
         }
 
-        private Slice(List<ColumnDefinition> columnDefs, TermSlice slice)
+        private SliceRestriction(List<ColumnDefinition> columnDefs, TermSlice slice)
         {
             super(columnDefs);
             this.slice = slice;
@@ -346,13 +342,13 @@ public abstract class MultiColumnRestriction extends AbstractRestriction
         }
 
         @Override
-        public CompositesBuilder appendTo(CompositesBuilder builder, QueryOptions options)
+        public MultiCBuilder appendTo(MultiCBuilder builder, QueryOptions options)
         {
             throw new UnsupportedOperationException();
         }
 
         @Override
-        public CompositesBuilder appendBoundTo(CompositesBuilder builder, Bound bound, QueryOptions options)
+        public MultiCBuilder appendBoundTo(MultiCBuilder builder, Bound bound, QueryOptions options)
         {
             List<ByteBuffer> vals = componentBounds(bound, options);
 
@@ -395,7 +391,7 @@ public abstract class MultiColumnRestriction extends AbstractRestriction
                       "Column \"%s\" cannot be restricted by both an equality and an inequality relation",
                       getColumnsInCommons(otherRestriction));
 
-            Slice otherSlice = (Slice) otherRestriction;
+            SliceRestriction otherSlice = (SliceRestriction) otherRestriction;
 
             if (!getFirstColumn().equals(otherRestriction.getFirstColumn()))
             {
@@ -414,13 +410,13 @@ public abstract class MultiColumnRestriction extends AbstractRestriction
                        getColumnsInCommons(otherRestriction));
 
             List<ColumnDefinition> newColumnDefs = columnDefs.size() >= otherSlice.columnDefs.size() ?  columnDefs : otherSlice.columnDefs;
-            return new Slice(newColumnDefs, slice.merge(otherSlice.slice));
+            return new SliceRestriction(newColumnDefs, slice.merge(otherSlice.slice));
         }
 
         @Override
-        public final void addIndexExpressionTo(List<IndexExpression> expressions,
-                                               SecondaryIndexManager indexManager,
-                                               QueryOptions options) throws InvalidRequestException
+        public final void addRowFilterTo(RowFilter filter,
+                                         SecondaryIndexManager indexManager,
+                                         QueryOptions options) throws InvalidRequestException
         {
             throw invalidRequest("Slice restrictions are not supported on indexed columns");
         }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a991b648/src/java/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSet.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSet.java b/src/java/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSet.java
index b49d774..39322ff 100644
--- a/src/java/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSet.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictionSet.java
@@ -18,19 +18,18 @@
 package org.apache.cassandra.cql3.restrictions;
 
 import java.nio.ByteBuffer;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
+import java.util.*;
 
+import org.apache.cassandra.config.CFMetaData;
 import org.apache.cassandra.config.ColumnDefinition;
 import org.apache.cassandra.cql3.QueryOptions;
 import org.apache.cassandra.cql3.functions.Function;
 import org.apache.cassandra.cql3.statements.Bound;
-import org.apache.cassandra.db.IndexExpression;
-import org.apache.cassandra.db.composites.*;
-import org.apache.cassandra.db.composites.Composite.EOC;
+import org.apache.cassandra.db.*;
+import org.apache.cassandra.db.filter.RowFilter;
 import org.apache.cassandra.db.index.SecondaryIndexManager;
 import org.apache.cassandra.exceptions.InvalidRequestException;
+import org.apache.cassandra.utils.FBUtilities;
 
 import static org.apache.cassandra.cql3.statements.RequestValidations.checkFalse;
 import static org.apache.cassandra.cql3.statements.RequestValidations.invalidRequest;
@@ -65,18 +64,25 @@ final class PrimaryKeyRestrictionSet extends AbstractPrimaryKeyRestrictions
      */
     private boolean contains;
 
-    public PrimaryKeyRestrictionSet(CType ctype)
+    /**
+     * <code>true</code> if the restrictions corresponding to a partition key, <code>false</code> if it's clustering columns.
+     */
+    private boolean isPartitionKey;
+
+    public PrimaryKeyRestrictionSet(ClusteringComparator comparator, boolean isPartitionKey)
     {
-        super(ctype);
+        super(comparator);
         this.restrictions = new RestrictionSet();
         this.eq = true;
+        this.isPartitionKey = isPartitionKey;
     }
 
     private PrimaryKeyRestrictionSet(PrimaryKeyRestrictionSet primaryKeyRestrictions,
                                                Restriction restriction) throws InvalidRequestException
     {
-        super(primaryKeyRestrictions.ctype);
+        super(primaryKeyRestrictions.comparator);
         this.restrictions = primaryKeyRestrictions.restrictions.addRestriction(restriction);
+        this.isPartitionKey = primaryKeyRestrictions.isPartitionKey;
 
         if (!primaryKeyRestrictions.isEmpty())
         {
@@ -104,6 +110,15 @@ final class PrimaryKeyRestrictionSet extends AbstractPrimaryKeyRestrictions
             this.eq = true;
     }
 
+    private List<ByteBuffer> toByteBuffers(SortedSet<? extends ClusteringPrefix> clusterings)
+    {
+        // It's currently a tad hard to follow that this is only called for partition key so we should fix that
+        List<ByteBuffer> l = new ArrayList<>(clusterings.size());
+        for (ClusteringPrefix clustering : clusterings)
+            l.add(CFMetaData.serializePartitionKey(clustering));
+        return l;
+    }
+
     @Override
     public boolean isSlice()
     {
@@ -161,13 +176,13 @@ final class PrimaryKeyRestrictionSet extends AbstractPrimaryKeyRestrictions
     }
 
     @Override
-    public List<Composite> valuesAsComposites(QueryOptions options) throws InvalidRequestException
+    public NavigableSet<Clustering> valuesAsClustering(QueryOptions options) throws InvalidRequestException
     {
-        return appendTo(new CompositesBuilder(ctype), options).build();
+        return appendTo(MultiCBuilder.create(comparator), options).build();
     }
 
     @Override
-    public CompositesBuilder appendTo(CompositesBuilder builder, QueryOptions options)
+    public MultiCBuilder appendTo(MultiCBuilder builder, QueryOptions options)
     {
         for (Restriction r : restrictions)
         {
@@ -179,27 +194,22 @@ final class PrimaryKeyRestrictionSet extends AbstractPrimaryKeyRestrictions
     }
 
     @Override
-    public CompositesBuilder appendBoundTo(CompositesBuilder builder, Bound bound, QueryOptions options)
+    public MultiCBuilder appendBoundTo(MultiCBuilder builder, Bound bound, QueryOptions options)
     {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public List<Composite> boundsAsComposites(Bound bound, QueryOptions options) throws InvalidRequestException
+    public SortedSet<Slice.Bound> boundsAsClustering(Bound bound, QueryOptions options) throws InvalidRequestException
     {
-        CompositesBuilder builder = new CompositesBuilder(ctype);
-        // The end-of-component of composite doesn't depend on whether the
-        // component type is reversed or not (i.e. the ReversedType is applied
-        // to the component comparator but not to the end-of-component itself),
-        // it only depends on whether the slice is reversed
+        MultiCBuilder builder = MultiCBuilder.create(comparator);
         int keyPosition = 0;
         for (Restriction r : restrictions)
         {
             ColumnDefinition def = r.getFirstColumn();
 
-            // In a restriction, we always have Bound.START < Bound.END for the "base" comparator.
-            // So if we're doing a reverse slice, we must inverse the bounds when giving them as start and end of the slice filter.
-            // But if the actual comparator itself is reversed, we must inversed the bounds too.
+            // The bound of this method is refering to the clustering order. So if said clustering order
+            // is reversed for this column, we should reverse the restriction we use.
             Bound b = !def.isReversedType() ? bound : bound.reverse();
             if (keyPosition != def.position() || r.isContains())
                 break;
@@ -211,49 +221,41 @@ final class PrimaryKeyRestrictionSet extends AbstractPrimaryKeyRestrictions
                     // There wasn't any non EQ relation on that key, we select all records having the preceding component as prefix.
                     // For composites, if there was preceding component and we're computing the end, we must change the last component
                     // End-Of-Component, otherwise we would be selecting only one record.
-                    return builder.buildWithEOC(bound.isEnd() ? EOC.END : EOC.START);
+                    return builder.buildBound(bound.isStart(), true);
                 }
 
                 r.appendBoundTo(builder, b, options);
-                Composite.EOC eoc = eocFor(r, bound, b);
-                return builder.buildWithEOC(eoc);
+                return builder.buildBound(bound.isStart(), r.isInclusive(b));
             }
 
             r.appendBoundTo(builder, b, options);
 
             if (builder.hasMissingElements())
-                return Collections.emptyList();
+                return FBUtilities.<Slice.Bound>emptySortedSet(comparator);
 
             keyPosition = r.getLastColumn().position() + 1;
         }
-        // Means no relation at all or everything was an equal
-        // Note: if the builder is "full", there is no need to use the end-of-component bit. For columns selection,
-        // it would be harmless to do it. However, we use this method got the partition key too. And when a query
-        // with 2ndary index is done, and with the the partition provided with an EQ, we'll end up here, and in that
-        // case using the eoc would be bad, since for the random partitioner we have no guarantee that
-        // prefix.end() will sort after prefix (see #5240).
-        EOC eoc = !builder.hasRemaining() ? EOC.NONE : (bound.isEnd() ? EOC.END : EOC.START);
-        return builder.buildWithEOC(eoc);
+
+        // Everything was an equal (or there was nothing)
+        return builder.buildBound(bound.isStart(), true);
     }
 
     @Override
     public List<ByteBuffer> values(QueryOptions options) throws InvalidRequestException
     {
-        return Composites.toByteBuffers(valuesAsComposites(options));
+        if (!isPartitionKey)
+            throw new UnsupportedOperationException();
+
+        return toByteBuffers(valuesAsClustering(options));
     }
 
     @Override
     public List<ByteBuffer> bounds(Bound b, QueryOptions options) throws InvalidRequestException
     {
-        return Composites.toByteBuffers(boundsAsComposites(b, options));
-    }
-
-    private static Composite.EOC eocFor(Restriction r, Bound eocBound, Bound inclusiveBound)
-    {
-        if (eocBound.isStart())
-            return r.isInclusive(inclusiveBound) ? Composite.EOC.NONE : Composite.EOC.END;
+        if (!isPartitionKey)
+            throw new UnsupportedOperationException();
 
-        return r.isInclusive(inclusiveBound) ? Composite.EOC.END : Composite.EOC.START;
+        return toByteBuffers(boundsAsClustering(b, options));
     }
 
     @Override
@@ -279,30 +281,24 @@ final class PrimaryKeyRestrictionSet extends AbstractPrimaryKeyRestrictions
     }
 
     @Override
-    public void addIndexExpressionTo(List<IndexExpression> expressions,
-                                     SecondaryIndexManager indexManager,
-                                     QueryOptions options) throws InvalidRequestException
+    public void addRowFilterTo(RowFilter filter,
+                               SecondaryIndexManager indexManager,
+                               QueryOptions options) throws InvalidRequestException
     {
-        Boolean clusteringColumns = null;
         int position = 0;
 
         for (Restriction restriction : restrictions)
         {
             ColumnDefinition columnDef = restriction.getFirstColumn();
 
-            // PrimaryKeyRestrictionSet contains only one kind of column, either partition key or clustering columns.
-            // Therefore we only need to check the column kind once. All the other columns will be of the same kind.
-            if (clusteringColumns == null)
-                clusteringColumns = columnDef.isClusteringColumn() ? Boolean.TRUE : Boolean.FALSE;
-
             // We ignore all the clustering columns that can be handled by slices.
-            if (clusteringColumns && !restriction.isContains()&& position == columnDef.position())
+            if (!isPartitionKey && !restriction.isContains()&& position == columnDef.position())
             {
                 position = restriction.getLastColumn().position() + 1;
                 if (!restriction.hasSupportingIndex(indexManager))
                     continue;
             }
-            restriction.addIndexExpressionTo(expressions, indexManager, options);
+            restriction.addRowFilterTo(filter, indexManager, options);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a991b648/src/java/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictions.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictions.java b/src/java/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictions.java
index 7d7b492..6a14182 100644
--- a/src/java/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictions.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/PrimaryKeyRestrictions.java
@@ -19,10 +19,13 @@ package org.apache.cassandra.cql3.restrictions;
 
 import java.nio.ByteBuffer;
 import java.util.List;
+import java.util.NavigableSet;
+import java.util.SortedSet;
 
 import org.apache.cassandra.cql3.QueryOptions;
 import org.apache.cassandra.cql3.statements.Bound;
-import org.apache.cassandra.db.composites.Composite;
+import org.apache.cassandra.db.Clustering;
+import org.apache.cassandra.db.Slice;
 import org.apache.cassandra.exceptions.InvalidRequestException;
 
 /**
@@ -36,9 +39,9 @@ interface PrimaryKeyRestrictions extends Restriction, Restrictions
 
     public List<ByteBuffer> values(QueryOptions options) throws InvalidRequestException;
 
-    public List<Composite> valuesAsComposites(QueryOptions options) throws InvalidRequestException;
+    public NavigableSet<Clustering> valuesAsClustering(QueryOptions options) throws InvalidRequestException;
 
     public List<ByteBuffer> bounds(Bound b, QueryOptions options) throws InvalidRequestException;
 
-    public List<Composite> boundsAsComposites(Bound bound, QueryOptions options) throws InvalidRequestException;
+    public SortedSet<Slice.Bound> boundsAsClustering(Bound bound, QueryOptions options) throws InvalidRequestException;
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a991b648/src/java/org/apache/cassandra/cql3/restrictions/Restriction.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/restrictions/Restriction.java b/src/java/org/apache/cassandra/cql3/restrictions/Restriction.java
index c115a3b..370a0f2 100644
--- a/src/java/org/apache/cassandra/cql3/restrictions/Restriction.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/Restriction.java
@@ -18,14 +18,13 @@
 package org.apache.cassandra.cql3.restrictions;
 
 import java.util.Collection;
-import java.util.List;
 
 import org.apache.cassandra.config.ColumnDefinition;
 import org.apache.cassandra.cql3.QueryOptions;
 import org.apache.cassandra.cql3.functions.Function;
 import org.apache.cassandra.cql3.statements.Bound;
-import org.apache.cassandra.db.IndexExpression;
-import org.apache.cassandra.db.composites.CompositesBuilder;
+import org.apache.cassandra.db.MultiCBuilder;
+import org.apache.cassandra.db.filter.RowFilter;
 import org.apache.cassandra.db.index.SecondaryIndexManager;
 import org.apache.cassandra.exceptions.InvalidRequestException;
 
@@ -105,35 +104,34 @@ public interface Restriction
     public boolean hasSupportingIndex(SecondaryIndexManager indexManager);
 
     /**
-     * Adds to the specified list the <code>IndexExpression</code>s corresponding to this <code>Restriction</code>.
+     * Adds to the specified row filter the expressions corresponding to this <code>Restriction</code>.
      *
-     * @param expressions the list to add the <code>IndexExpression</code>s to
+     * @param filter the row filter to add expressions to
      * @param indexManager the secondary index manager
      * @param options the query options
-     * @throws InvalidRequestException if this <code>Restriction</code> cannot be converted into 
-     * <code>IndexExpression</code>s
+     * @throws InvalidRequestException if this <code>Restriction</code> cannot be converted into a row filter
      */
-    public void addIndexExpressionTo(List<IndexExpression> expressions,
-                                     SecondaryIndexManager indexManager,
-                                     QueryOptions options)
-                                     throws InvalidRequestException;
+    public void addRowFilterTo(RowFilter filter,
+                               SecondaryIndexManager indexManager,
+                               QueryOptions options)
+                               throws InvalidRequestException;
 
     /**
      * Appends the values of this <code>Restriction</code> to the specified builder.
      *
-     * @param builder the <code>CompositesBuilder</code> to append to.
+     * @param builder the <code>MultiCBuilder</code> to append to.
      * @param options the query options
-     * @return the <code>CompositesBuilder</code>
+     * @return the <code>MultiCBuilder</code>
      */
-    public CompositesBuilder appendTo(CompositesBuilder builder, QueryOptions options);
+    public MultiCBuilder appendTo(MultiCBuilder builder, QueryOptions options);
 
     /**
      * Appends the values of the <code>Restriction</code> for the specified bound to the specified builder.
      *
-     * @param builder the <code>CompositesBuilder</code> to append to.
+     * @param builder the <code>MultiCBuilder</code> to append to.
      * @param bound the bound
      * @param options the query options
-     * @return the <code>CompositesBuilder</code>
+     * @return the <code>MultiCBuilder</code>
      */
-    public CompositesBuilder appendBoundTo(CompositesBuilder builder, Bound bound, QueryOptions options);
+    public MultiCBuilder appendBoundTo(MultiCBuilder builder, Bound bound, QueryOptions options);
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a991b648/src/java/org/apache/cassandra/cql3/restrictions/RestrictionSet.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/restrictions/RestrictionSet.java b/src/java/org/apache/cassandra/cql3/restrictions/RestrictionSet.java
index 6bf7666..10fae13 100644
--- a/src/java/org/apache/cassandra/cql3/restrictions/RestrictionSet.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/RestrictionSet.java
@@ -24,8 +24,8 @@ import com.google.common.collect.Iterables;
 import org.apache.cassandra.config.ColumnDefinition;
 import org.apache.cassandra.cql3.QueryOptions;
 import org.apache.cassandra.cql3.functions.Function;
-import org.apache.cassandra.cql3.restrictions.SingleColumnRestriction.Contains;
-import org.apache.cassandra.db.IndexExpression;
+import org.apache.cassandra.cql3.restrictions.SingleColumnRestriction.ContainsRestriction;
+import org.apache.cassandra.db.filter.RowFilter;
 import org.apache.cassandra.db.index.SecondaryIndexManager;
 import org.apache.cassandra.exceptions.InvalidRequestException;
 
@@ -66,12 +66,10 @@ final class RestrictionSet implements Restrictions, Iterable<Restriction>
     }
 
     @Override
-    public final void addIndexExpressionTo(List<IndexExpression> expressions,
-                                           SecondaryIndexManager indexManager,
-                                           QueryOptions options) throws InvalidRequestException
+    public final void addRowFilterTo(RowFilter filter, SecondaryIndexManager indexManager, QueryOptions options) throws InvalidRequestException
     {
         for (Restriction restriction : restrictions.values())
-            restriction.addIndexExpressionTo(expressions, indexManager, options);
+            restriction.addRowFilterTo(filter, indexManager, options);
     }
 
     @Override
@@ -245,7 +243,7 @@ final class RestrictionSet implements Restrictions, Iterable<Restriction>
         {
             if (restriction.isContains())
             {
-                Contains contains = (Contains) restriction;
+                ContainsRestriction contains = (ContainsRestriction) restriction;
                 numberOfContains += (contains.numberOfValues() + contains.numberOfKeys() + contains.numberOfEntries());
             }
         }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a991b648/src/java/org/apache/cassandra/cql3/restrictions/Restrictions.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/restrictions/Restrictions.java b/src/java/org/apache/cassandra/cql3/restrictions/Restrictions.java
index ab81bf7..88d0bb6 100644
--- a/src/java/org/apache/cassandra/cql3/restrictions/Restrictions.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/Restrictions.java
@@ -18,12 +18,11 @@
 package org.apache.cassandra.cql3.restrictions;
 
 import java.util.Collection;
-import java.util.List;
 
 import org.apache.cassandra.config.ColumnDefinition;
 import org.apache.cassandra.cql3.QueryOptions;
 import org.apache.cassandra.cql3.functions.Function;
-import org.apache.cassandra.db.IndexExpression;
+import org.apache.cassandra.db.filter.RowFilter;
 import org.apache.cassandra.db.index.SecondaryIndexManager;
 import org.apache.cassandra.exceptions.InvalidRequestException;
 
@@ -54,18 +53,14 @@ interface Restrictions
     public boolean hasSupportingIndex(SecondaryIndexManager indexManager);
 
     /**
-     * Adds to the specified list the <code>IndexExpression</code>s corresponding to this <code>Restriction</code>.
+     * Adds to the specified row filter the expressions corresponding to this <code>Restrictions</code>.
      *
-     * @param expressions the list to add the <code>IndexExpression</code>s to
+     * @param filter the row filter to add expressions to
      * @param indexManager the secondary index manager
      * @param options the query options
-     * @throws InvalidRequestException if this <code>Restriction</code> cannot be converted into
-     * <code>IndexExpression</code>s
+     * @throws InvalidRequestException if this <code>Restrictions</code> cannot be converted into a row filter
      */
-    public void addIndexExpressionTo(List<IndexExpression> expressions,
-                                     SecondaryIndexManager indexManager,
-                                     QueryOptions options)
-                                     throws InvalidRequestException;
+    public void addRowFilterTo(RowFilter filter, SecondaryIndexManager indexManager, QueryOptions options) throws InvalidRequestException;
 
     /**
      * Checks if this <code>PrimaryKeyRestrictionSet</code> is empty or not.

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a991b648/src/java/org/apache/cassandra/cql3/restrictions/ReversedPrimaryKeyRestrictions.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/restrictions/ReversedPrimaryKeyRestrictions.java b/src/java/org/apache/cassandra/cql3/restrictions/ReversedPrimaryKeyRestrictions.java
deleted file mode 100644
index 9b33161..0000000
--- a/src/java/org/apache/cassandra/cql3/restrictions/ReversedPrimaryKeyRestrictions.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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.cql3.restrictions;
-
-import java.nio.ByteBuffer;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.cassandra.cql3.QueryOptions;
-import org.apache.cassandra.cql3.statements.Bound;
-import org.apache.cassandra.db.composites.Composite;
-import org.apache.cassandra.exceptions.InvalidRequestException;
-
-/**
- * <code>PrimaryKeyRestrictions</code> decorator that reverse the slices.
- */
-final class ReversedPrimaryKeyRestrictions extends ForwardingPrimaryKeyRestrictions
-{
-    /**
-     * The decorated restrictions.
-     */
-    private PrimaryKeyRestrictions restrictions;
-
-    public ReversedPrimaryKeyRestrictions(PrimaryKeyRestrictions restrictions)
-    {
-        this.restrictions = restrictions;
-    }
-
-    @Override
-    public PrimaryKeyRestrictions mergeWith(Restriction restriction) throws InvalidRequestException
-    {
-        return new ReversedPrimaryKeyRestrictions(this.restrictions.mergeWith(restriction));
-    }
-
-    @Override
-    public List<ByteBuffer> bounds(Bound bound, QueryOptions options) throws InvalidRequestException
-    {
-        List<ByteBuffer> buffers = restrictions.bounds(bound.reverse(), options);
-        Collections.reverse(buffers);
-        return buffers;
-    }
-
-    @Override
-    public List<Composite> boundsAsComposites(Bound bound, QueryOptions options) throws InvalidRequestException
-    {
-        List<Composite> composites = restrictions.boundsAsComposites(bound.reverse(), options);
-        Collections.reverse(composites);
-        return composites;
-    }
-
-    @Override
-    public boolean isInclusive(Bound bound)
-    {
-        return this.restrictions.isInclusive(bound.reverse());
-    }
-
-    @Override
-    protected PrimaryKeyRestrictions getDelegate()
-    {
-        return this.restrictions;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a991b648/src/java/org/apache/cassandra/cql3/restrictions/SingleColumnRestriction.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/restrictions/SingleColumnRestriction.java b/src/java/org/apache/cassandra/cql3/restrictions/SingleColumnRestriction.java
index d32f585..f96b7a0 100644
--- a/src/java/org/apache/cassandra/cql3/restrictions/SingleColumnRestriction.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/SingleColumnRestriction.java
@@ -27,11 +27,10 @@ import org.apache.cassandra.cql3.*;
 import org.apache.cassandra.cql3.Term.Terminal;
 import org.apache.cassandra.cql3.functions.Function;
 import org.apache.cassandra.cql3.statements.Bound;
-import org.apache.cassandra.db.IndexExpression;
-import org.apache.cassandra.db.composites.CompositesBuilder;
+import org.apache.cassandra.db.MultiCBuilder;
+import org.apache.cassandra.db.filter.RowFilter;
 import org.apache.cassandra.db.index.SecondaryIndex;
 import org.apache.cassandra.db.index.SecondaryIndexManager;
-import org.apache.cassandra.db.marshal.CompositeType;
 import org.apache.cassandra.exceptions.InvalidRequestException;
 
 import static org.apache.cassandra.cql3.statements.RequestValidations.checkBindValueSet;
@@ -73,7 +72,7 @@ public abstract class SingleColumnRestriction extends AbstractRestriction
     @Override
     public boolean hasSupportingIndex(SecondaryIndexManager indexManager)
     {
-        SecondaryIndex index = indexManager.getIndexForColumn(columnDef.name.bytes);
+        SecondaryIndex index = indexManager.getIndexForColumn(columnDef);
         return index != null && isSupportedBy(index);
     }
 
@@ -97,11 +96,11 @@ public abstract class SingleColumnRestriction extends AbstractRestriction
      */
     protected abstract boolean isSupportedBy(SecondaryIndex index);
 
-    public static final class EQ extends SingleColumnRestriction
+    public static final class EQRestriction extends SingleColumnRestriction
     {
         private final Term value;
 
-        public EQ(ColumnDefinition columnDef, Term value)
+        public EQRestriction(ColumnDefinition columnDef, Term value)
         {
             super(columnDef);
             this.value = value;
@@ -120,16 +119,15 @@ public abstract class SingleColumnRestriction extends AbstractRestriction
         }
 
         @Override
-        public void addIndexExpressionTo(List<IndexExpression> expressions,
-                                         SecondaryIndexManager indexManager,
-                                         QueryOptions options) throws InvalidRequestException
+        public void addRowFilterTo(RowFilter filter,
+                                   SecondaryIndexManager indexManager,
+                                   QueryOptions options) throws InvalidRequestException
         {
-            ByteBuffer buffer = validateIndexedValue(columnDef, value.bindAndGet(options));
-            expressions.add(new IndexExpression(columnDef.name.bytes, Operator.EQ, buffer));
+            filter.add(columnDef, Operator.EQ, value.bindAndGet(options));
         }
 
         @Override
-        public CompositesBuilder appendTo(CompositesBuilder builder, QueryOptions options)
+        public MultiCBuilder appendTo(MultiCBuilder builder, QueryOptions options)
         {
             builder.addElementToAll(value.bindAndGet(options));
             checkFalse(builder.containsNull(), "Invalid null value in condition for column %s", columnDef.name);
@@ -156,9 +154,9 @@ public abstract class SingleColumnRestriction extends AbstractRestriction
         }
     }
 
-    public static abstract class IN extends SingleColumnRestriction
+    public static abstract class INRestriction extends SingleColumnRestriction
     {
-        public IN(ColumnDefinition columnDef)
+        public INRestriction(ColumnDefinition columnDef)
         {
             super(columnDef);
         }
@@ -176,7 +174,7 @@ public abstract class SingleColumnRestriction extends AbstractRestriction
         }
 
         @Override
-        public CompositesBuilder appendTo(CompositesBuilder builder, QueryOptions options)
+        public MultiCBuilder appendTo(MultiCBuilder builder, QueryOptions options)
         {
             builder.addEachElementToAll(getValues(options));
             checkFalse(builder.containsNull(), "Invalid null value in condition for column %s", columnDef.name);
@@ -185,15 +183,14 @@ public abstract class SingleColumnRestriction extends AbstractRestriction
         }
 
         @Override
-        public void addIndexExpressionTo(List<IndexExpression> expressions,
-                                         SecondaryIndexManager indexManager,
-                                         QueryOptions options) throws InvalidRequestException
+        public void addRowFilterTo(RowFilter filter,
+                                   SecondaryIndexManager indexManager,
+                                   QueryOptions options) throws InvalidRequestException
         {
             List<ByteBuffer> values = getValues(options);
             checkTrue(values.size() == 1, "IN restrictions are not supported on indexed columns");
 
-            ByteBuffer value = validateIndexedValue(columnDef, values.get(0));
-            expressions.add(new IndexExpression(columnDef.name.bytes, Operator.EQ, value));
+            filter.add(columnDef, Operator.EQ, values.get(0));
         }
 
         @Override
@@ -205,11 +202,11 @@ public abstract class SingleColumnRestriction extends AbstractRestriction
         protected abstract List<ByteBuffer> getValues(QueryOptions options) throws InvalidRequestException;
     }
 
-    public static class InWithValues extends IN
+    public static class InRestrictionWithValues extends INRestriction
     {
         protected final List<Term> values;
 
-        public InWithValues(ColumnDefinition columnDef, List<Term> values)
+        public InRestrictionWithValues(ColumnDefinition columnDef, List<Term> values)
         {
             super(columnDef);
             this.values = values;
@@ -237,11 +234,11 @@ public abstract class SingleColumnRestriction extends AbstractRestriction
         }
     }
 
-    public static class InWithMarker extends IN
+    public static class InRestrictionWithMarker extends INRestriction
     {
         protected final AbstractMarker marker;
 
-        public InWithMarker(ColumnDefinition columnDef, AbstractMarker marker)
+        public InRestrictionWithMarker(ColumnDefinition columnDef, AbstractMarker marker)
         {
             super(columnDef);
             this.marker = marker;
@@ -270,11 +267,11 @@ public abstract class SingleColumnRestriction extends AbstractRestriction
         }
     }
 
-    public static class Slice extends SingleColumnRestriction
+    public static class SliceRestriction extends SingleColumnRestriction
     {
         private final TermSlice slice;
 
-        public Slice(ColumnDefinition columnDef, Bound bound, boolean inclusive, Term term)
+        public SliceRestriction(ColumnDefinition columnDef, Bound bound, boolean inclusive, Term term)
         {
             super(columnDef);
             slice = TermSlice.newInstance(bound, inclusive, term);
@@ -293,7 +290,7 @@ public abstract class SingleColumnRestriction extends AbstractRestriction
         }
 
         @Override
-        public CompositesBuilder appendTo(CompositesBuilder builder, QueryOptions options)
+        public MultiCBuilder appendTo(MultiCBuilder builder, QueryOptions options)
         {
             throw new UnsupportedOperationException();
         }
@@ -305,7 +302,7 @@ public abstract class SingleColumnRestriction extends AbstractRestriction
         }
 
         @Override
-        public CompositesBuilder appendBoundTo(CompositesBuilder builder, Bound bound, QueryOptions options)
+        public MultiCBuilder appendBoundTo(MultiCBuilder builder, Bound bound, QueryOptions options)
         {
             ByteBuffer value = slice.bound(bound).bindAndGet(options);
             checkBindValueSet(value, "Invalid unset value for column %s", columnDef.name);
@@ -326,7 +323,7 @@ public abstract class SingleColumnRestriction extends AbstractRestriction
                       "Column \"%s\" cannot be restricted by both an equality and an inequality relation",
                       columnDef.name);
 
-            SingleColumnRestriction.Slice otherSlice = (SingleColumnRestriction.Slice) otherRestriction;
+            SingleColumnRestriction.SliceRestriction otherSlice = (SingleColumnRestriction.SliceRestriction) otherRestriction;
 
             checkFalse(hasBound(Bound.START) && otherSlice.hasBound(Bound.START),
                        "More than one restriction was found for the start bound on %s", columnDef.name);
@@ -334,27 +331,15 @@ public abstract class SingleColumnRestriction extends AbstractRestriction
             checkFalse(hasBound(Bound.END) && otherSlice.hasBound(Bound.END),
                        "More than one restriction was found for the end bound on %s", columnDef.name);
 
-            return new Slice(columnDef,  slice.merge(otherSlice.slice));
+            return new SliceRestriction(columnDef,  slice.merge(otherSlice.slice));
         }
 
         @Override
-        public void addIndexExpressionTo(List<IndexExpression> expressions,
-                                         SecondaryIndexManager indexManager,
-                                         QueryOptions options) throws InvalidRequestException
+        public void addRowFilterTo(RowFilter filter, SecondaryIndexManager indexManager, QueryOptions options) throws InvalidRequestException
         {
             for (Bound b : Bound.values())
-            {
                 if (hasBound(b))
-                {
-                    ByteBuffer value = validateIndexedValue(columnDef, slice.bound(b).bindAndGet(options));
-                    Operator op = slice.getIndexOperator(b);
-                    // If the underlying comparator for name is reversed, we need to reverse the IndexOperator: user operation
-                    // always refer to the "forward" sorting even if the clustering order is reversed, but the 2ndary code does
-                    // use the underlying comparator as is.
-                    op = columnDef.isReversedType() ? op.reverse() : op;
-                    expressions.add(new IndexExpression(columnDef.name.bytes, op, value));
-                }
-            }
+                    filter.add(columnDef, slice.getIndexOperator(b), slice.bound(b).bindAndGet(options));
         }
 
         @Override
@@ -369,7 +354,7 @@ public abstract class SingleColumnRestriction extends AbstractRestriction
             return String.format("SLICE%s", slice);
         }
 
-        private Slice(ColumnDefinition columnDef, TermSlice slice)
+        private SliceRestriction(ColumnDefinition columnDef, TermSlice slice)
         {
             super(columnDef);
             this.slice = slice;
@@ -377,14 +362,14 @@ public abstract class SingleColumnRestriction extends AbstractRestriction
     }
 
     // This holds CONTAINS, CONTAINS_KEY, and map[key] = value restrictions because we might want to have any combination of them.
-    public static final class Contains extends SingleColumnRestriction
+    public static final class ContainsRestriction extends SingleColumnRestriction
     {
         private List<Term> values = new ArrayList<>(); // for CONTAINS
         private List<Term> keys = new ArrayList<>(); // for CONTAINS_KEY
         private List<Term> entryKeys = new ArrayList<>(); // for map[key] = value
         private List<Term> entryValues = new ArrayList<>(); // for map[key] = value
 
-        public Contains(ColumnDefinition columnDef, Term t, boolean isKey)
+        public ContainsRestriction(ColumnDefinition columnDef, Term t, boolean isKey)
         {
             super(columnDef);
             if (isKey)
@@ -393,7 +378,7 @@ public abstract class SingleColumnRestriction extends AbstractRestriction
                 values.add(t);
         }
 
-        public Contains(ColumnDefinition columnDef, Term mapKey, Term mapValue)
+        public ContainsRestriction(ColumnDefinition columnDef, Term mapKey, Term mapValue)
         {
             super(columnDef);
             entryKeys.add(mapKey);
@@ -401,7 +386,7 @@ public abstract class SingleColumnRestriction extends AbstractRestriction
         }
 
         @Override
-        public CompositesBuilder appendTo(CompositesBuilder builder, QueryOptions options)
+        public MultiCBuilder appendTo(MultiCBuilder builder, QueryOptions options)
         {
             throw new UnsupportedOperationException();
         }
@@ -419,33 +404,27 @@ public abstract class SingleColumnRestriction extends AbstractRestriction
                       "Collection column %s can only be restricted by CONTAINS, CONTAINS KEY, or map-entry equality",
                       columnDef.name);
 
-            SingleColumnRestriction.Contains newContains = new Contains(columnDef);
+            SingleColumnRestriction.ContainsRestriction newContains = new ContainsRestriction(columnDef);
 
             copyKeysAndValues(this, newContains);
-            copyKeysAndValues((Contains) otherRestriction, newContains);
+            copyKeysAndValues((ContainsRestriction) otherRestriction, newContains);
 
             return newContains;
         }
 
         @Override
-        public void addIndexExpressionTo(List<IndexExpression> expressions,
-                                         SecondaryIndexManager indexManager,
-                                         QueryOptions options)
-                                         throws InvalidRequestException
+        public void addRowFilterTo(RowFilter filter, SecondaryIndexManager indexManager, QueryOptions options) throws InvalidRequestException
         {
-            addExpressionsFor(expressions, bindAndGet(values, options), Operator.CONTAINS);
-            addExpressionsFor(expressions, bindAndGet(keys, options), Operator.CONTAINS_KEY);
-            addExpressionsFor(expressions, entries(options), Operator.EQ);
-        }
+            for (ByteBuffer value : bindAndGet(values, options))
+                filter.add(columnDef, Operator.CONTAINS, value);
+            for (ByteBuffer key : bindAndGet(keys, options))
+                filter.add(columnDef, Operator.CONTAINS_KEY, key);
 
-        private void addExpressionsFor(List<IndexExpression> target, List<ByteBuffer> values,
-                                       Operator op) throws InvalidRequestException
-        {
-            for (ByteBuffer value : values)
-            {
-                validateIndexedValue(columnDef, value);
-                target.add(new IndexExpression(columnDef.name.bytes, op, value));
-            }
+            List<ByteBuffer> eks = bindAndGet(entryKeys, options);
+            List<ByteBuffer> evs = bindAndGet(entryValues, options);
+            assert eks.size() == evs.size();
+            for (int i = 0; i < eks.size(); i++)
+                filter.addMapEquality(columnDef, eks.get(i), Operator.EQ, evs.get(i));
         }
 
         @Override
@@ -502,7 +481,7 @@ public abstract class SingleColumnRestriction extends AbstractRestriction
         }
 
         @Override
-        public CompositesBuilder appendBoundTo(CompositesBuilder builder, Bound bound, QueryOptions options)
+        public MultiCBuilder appendBoundTo(MultiCBuilder builder, Bound bound, QueryOptions options)
         {
             throw new UnsupportedOperationException();
         }
@@ -513,20 +492,6 @@ public abstract class SingleColumnRestriction extends AbstractRestriction
             throw new UnsupportedOperationException();
         }
 
-        private List<ByteBuffer> entries(QueryOptions options) throws InvalidRequestException
-        {
-            List<ByteBuffer> entryBuffers = new ArrayList<>(entryKeys.size());
-            List<ByteBuffer> keyBuffers = bindAndGet(entryKeys, options);
-            List<ByteBuffer> valueBuffers = bindAndGet(entryValues, options);
-            for (int i = 0; i < entryKeys.size(); i++)
-            {
-                if (valueBuffers.get(i) == null)
-                    throw new InvalidRequestException("Unsupported null value for map-entry equality");
-                entryBuffers.add(CompositeType.build(keyBuffers.get(i), valueBuffers.get(i)));
-            }
-            return entryBuffers;
-        }
-
         /**
          * Binds the query options to the specified terms and returns the resulting values.
          *
@@ -549,7 +514,7 @@ public abstract class SingleColumnRestriction extends AbstractRestriction
          * @param from the <code>Contains</code> to copy from
          * @param to the <code>Contains</code> to copy to
          */
-        private static void copyKeysAndValues(Contains from, Contains to)
+        private static void copyKeysAndValues(ContainsRestriction from, ContainsRestriction to)
         {
             to.values.addAll(from.values);
             to.keys.addAll(from.keys);
@@ -557,7 +522,7 @@ public abstract class SingleColumnRestriction extends AbstractRestriction
             to.entryValues.addAll(from.entryValues);
         }
 
-        private Contains(ColumnDefinition columnDef)
+        private ContainsRestriction(ColumnDefinition columnDef)
         {
             super(columnDef);
         }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a991b648/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java b/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java
index c10a56a..7660c3e 100644
--- a/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java
@@ -29,7 +29,7 @@ import org.apache.cassandra.cql3.*;
 import org.apache.cassandra.cql3.functions.Function;
 import org.apache.cassandra.cql3.statements.Bound;
 import org.apache.cassandra.db.*;
-import org.apache.cassandra.db.composites.Composite;
+import org.apache.cassandra.db.filter.RowFilter;
 import org.apache.cassandra.db.index.SecondaryIndexManager;
 import org.apache.cassandra.dht.*;
 import org.apache.cassandra.exceptions.InvalidRequestException;
@@ -67,7 +67,7 @@ public final class StatementRestrictions
     private RestrictionSet nonPrimaryKeyRestrictions;
 
     /**
-     * The restrictions used to build the index expressions
+     * The restrictions used to build the row filter
      */
     private final List<Restrictions> indexRestrictions = new ArrayList<>();
 
@@ -95,28 +95,28 @@ public final class StatementRestrictions
     private StatementRestrictions(CFMetaData cfm)
     {
         this.cfm = cfm;
-        this.partitionKeyRestrictions = new PrimaryKeyRestrictionSet(cfm.getKeyValidatorAsCType());
-        this.clusteringColumnsRestrictions = new PrimaryKeyRestrictionSet(cfm.comparator);
+        this.partitionKeyRestrictions = new PrimaryKeyRestrictionSet(cfm.getKeyValidatorAsClusteringComparator(), true);
+        this.clusteringColumnsRestrictions = new PrimaryKeyRestrictionSet(cfm.comparator, false);
         this.nonPrimaryKeyRestrictions = new RestrictionSet();
     }
 
     public StatementRestrictions(CFMetaData cfm,
-            List<Relation> whereClause,
-            VariableSpecifications boundNames,
-            boolean selectsOnlyStaticColumns,
-            boolean selectACollection) throws InvalidRequestException
+                                 List<Relation> whereClause,
+                                 VariableSpecifications boundNames,
+                                 boolean selectsOnlyStaticColumns,
+                                 boolean selectACollection,
+                                 boolean useFiltering) throws InvalidRequestException
     {
-        this.cfm = cfm;
-        this.partitionKeyRestrictions = new PrimaryKeyRestrictionSet(cfm.getKeyValidatorAsCType());
-        this.clusteringColumnsRestrictions = new PrimaryKeyRestrictionSet(cfm.comparator);
-        this.nonPrimaryKeyRestrictions = new RestrictionSet();
+        this(cfm);
 
         /*
-         * WHERE clause. For a given entity, rules are: - EQ relation conflicts with anything else (including a 2nd EQ)
-         * - Can't have more than one LT(E) relation (resp. GT(E) relation) - IN relation are restricted to row keys
-         * (for now) and conflicts with anything else (we could allow two IN for the same entity but that doesn't seem
-         * very useful) - The value_alias cannot be restricted in any way (we don't support wide rows with indexed value
-         * in CQL so far)
+         * WHERE clause. For a given entity, rules are:
+         *   - EQ relation conflicts with anything else (including a 2nd EQ)
+         *   - Can't have more than one LT(E) relation (resp. GT(E) relation)
+         *   - IN relation are restricted to row keys (for now) and conflicts with anything else (we could
+         *     allow two IN for the same entity but that doesn't seem very useful)
+         *   - The value_alias cannot be restricted in any way (we don't support wide rows with indexed value
+         *     in CQL so far)
          */
         for (Relation relation : whereClause)
             addRestriction(relation.toRestriction(cfm, boundNames));
@@ -133,7 +133,7 @@ public final class StatementRestrictions
         processPartitionKeyRestrictions(hasQueriableIndex);
 
         // Some but not all of the partition key columns have been specified;
-        // hence we need turn these restrictions into index expressions.
+        // hence we need turn these restrictions into a row filter.
         if (usesSecondaryIndexing)
             indexRestrictions.add(partitionKeyRestrictions);
 
@@ -155,7 +155,11 @@ public final class StatementRestrictions
         // there is restrictions not covered by the PK.
         if (!nonPrimaryKeyRestrictions.isEmpty())
         {
-            usesSecondaryIndexing = true;
+            if (hasQueriableIndex)
+                usesSecondaryIndexing = true;
+            else if (!useFiltering)
+                throw new InvalidRequestException("No supported secondary index found for the non primary key columns restrictions");
+
             indexRestrictions.add(nonPrimaryKeyRestrictions);
         }
 
@@ -192,6 +196,19 @@ public final class StatementRestrictions
     }
 
     /**
+     * Returns the non-PK column that are restricted.
+     */
+    public Set<ColumnDefinition> nonPKRestrictedColumns()
+    {
+        Set<ColumnDefinition> columns = new HashSet<>();
+        for (Restrictions r : indexRestrictions)
+            for (ColumnDefinition def : r.getColumnDefs())
+                if (!def.isPrimaryKeyColumn())
+                    columns.add(def);
+        return columns;
+    }
+
+    /**
      * Checks if the restrictions on the partition key is an IN restriction.
      *
      * @return <code>true</code> the restrictions on the partition key is an IN restriction, <code>false</code>
@@ -309,17 +326,16 @@ public final class StatementRestrictions
             usesSecondaryIndexing = true;
     }
 
-    public List<IndexExpression> getIndexExpressions(SecondaryIndexManager indexManager,
-                                                     QueryOptions options) throws InvalidRequestException
+    public RowFilter getRowFilter(SecondaryIndexManager indexManager, QueryOptions options) throws InvalidRequestException
     {
-        if (!usesSecondaryIndexing || indexRestrictions.isEmpty())
-            return Collections.emptyList();
+        if (indexRestrictions.isEmpty())
+            return RowFilter.NONE;
 
-        List<IndexExpression> expressions = new ArrayList<>();
+        RowFilter filter = RowFilter.create();
         for (Restrictions restrictions : indexRestrictions)
-            restrictions.addIndexExpressionTo(expressions, indexManager, options);
+            restrictions.addRowFilterTo(filter, indexManager, options);
 
-        return expressions;
+        return filter;
     }
 
     /**
@@ -345,8 +361,7 @@ public final class StatementRestrictions
     private ByteBuffer getPartitionKeyBound(Bound b, QueryOptions options) throws InvalidRequestException
     {
         // Deal with unrestricted partition key components (special-casing is required to deal with 2i queries on the
-        // first
-        // component of a composite partition key).
+        // first component of a composite partition key).
         if (hasPartitionKeyUnrestrictedComponents())
             return ByteBufferUtil.EMPTY_BYTE_BUFFER;
 
@@ -361,7 +376,7 @@ public final class StatementRestrictions
      * @return the partition key bounds
      * @throws InvalidRequestException if the query is invalid
      */
-    public AbstractBounds<RowPosition> getPartitionKeyBounds(QueryOptions options) throws InvalidRequestException
+    public AbstractBounds<PartitionPosition> getPartitionKeyBounds(QueryOptions options) throws InvalidRequestException
     {
         IPartitioner p = StorageService.getPartitioner();
 
@@ -373,14 +388,14 @@ public final class StatementRestrictions
         return getPartitionKeyBounds(p, options);
     }
 
-    private AbstractBounds<RowPosition> getPartitionKeyBounds(IPartitioner p,
+    private AbstractBounds<PartitionPosition> getPartitionKeyBounds(IPartitioner p,
                                                               QueryOptions options) throws InvalidRequestException
     {
         ByteBuffer startKeyBytes = getPartitionKeyBound(Bound.START, options);
         ByteBuffer finishKeyBytes = getPartitionKeyBound(Bound.END, options);
 
-        RowPosition startKey = RowPosition.ForKey.get(startKeyBytes, p);
-        RowPosition finishKey = RowPosition.ForKey.get(finishKeyBytes, p);
+        PartitionPosition startKey = PartitionPosition.ForKey.get(startKeyBytes, p);
+        PartitionPosition finishKey = PartitionPosition.ForKey.get(finishKeyBytes, p);
 
         if (startKey.compareTo(finishKey) > 0 && !finishKey.isMinimum())
             return null;
@@ -397,7 +412,7 @@ public final class StatementRestrictions
                 : new ExcludingBounds<>(startKey, finishKey);
     }
 
-    private AbstractBounds<RowPosition> getPartitionKeyBoundsForTokenRestrictions(IPartitioner p,
+    private AbstractBounds<PartitionPosition> getPartitionKeyBoundsForTokenRestrictions(IPartitioner p,
                                                                                   QueryOptions options)
                                                                                           throws InvalidRequestException
     {
@@ -422,8 +437,8 @@ public final class StatementRestrictions
                 && (cmp > 0 || (cmp == 0 && (!includeStart || !includeEnd))))
             return null;
 
-        RowPosition start = includeStart ? startToken.minKeyBound() : startToken.maxKeyBound();
-        RowPosition end = includeEnd ? endToken.maxKeyBound() : endToken.minKeyBound();
+        PartitionPosition start = includeStart ? startToken.minKeyBound() : startToken.maxKeyBound();
+        PartitionPosition end = includeEnd ? endToken.maxKeyBound() : endToken.minKeyBound();
 
         return new Range<>(start, end);
     }
@@ -439,17 +454,6 @@ public final class StatementRestrictions
     }
 
     /**
-     * Checks if the query does not contains any restriction on the clustering columns.
-     *
-     * @return <code>true</code> if the query does not contains any restriction on the clustering columns,
-     * <code>false</code> otherwise.
-     */
-    public boolean hasNoClusteringColumnsRestriction()
-    {
-        return clusteringColumnsRestrictions.isEmpty();
-    }
-
-    /**
      * Checks if the query has some restrictions on the clustering columns.
      *
      * @return <code>true</code> if the query has some restrictions on the clustering columns,
@@ -460,39 +464,16 @@ public final class StatementRestrictions
         return !clusteringColumnsRestrictions.isEmpty();
     }
 
-    // For non-composite slices, we don't support internally the difference between exclusive and
-    // inclusive bounds, so we deal with it manually.
-    public boolean isNonCompositeSliceWithExclusiveBounds()
-    {
-        return !cfm.comparator.isCompound()
-                && clusteringColumnsRestrictions.isSlice()
-                && (!clusteringColumnsRestrictions.isInclusive(Bound.START) || !clusteringColumnsRestrictions.isInclusive(Bound.END));
-    }
-
     /**
-     * Returns the requested clustering columns as <code>Composite</code>s.
+     * Returns the requested clustering columns.
      *
      * @param options the query options
-     * @return the requested clustering columns as <code>Composite</code>s
+     * @return the requested clustering columns
      * @throws InvalidRequestException if the query is not valid
      */
-    public List<Composite> getClusteringColumnsAsComposites(QueryOptions options) throws InvalidRequestException
-    {
-        return clusteringColumnsRestrictions.valuesAsComposites(options);
-    }
-
-    /**
-     * Returns the bounds (start or end) of the clustering columns as <code>Composites</code>.
-     *
-     * @param b the bound type
-     * @param options the query options
-     * @return the bounds (start or end) of the clustering columns as <code>Composites</code>
-     * @throws InvalidRequestException if the request is not valid
-     */
-    public List<Composite> getClusteringColumnsBoundsAsComposites(Bound b,
-                                                                  QueryOptions options) throws InvalidRequestException
+    public NavigableSet<Clustering> getClusteringColumns(QueryOptions options) throws InvalidRequestException
     {
-        return clusteringColumnsRestrictions.boundsAsComposites(b, options);
+        return clusteringColumnsRestrictions.valuesAsClustering(options);
     }
 
     /**
@@ -503,9 +484,9 @@ public final class StatementRestrictions
      * @return the bounds (start or end) of the clustering columns
      * @throws InvalidRequestException if the request is not valid
      */
-    public List<ByteBuffer> getClusteringColumnsBounds(Bound b, QueryOptions options) throws InvalidRequestException
+    public SortedSet<Slice.Bound> getClusteringColumnsBounds(Bound b, QueryOptions options) throws InvalidRequestException
     {
-        return clusteringColumnsRestrictions.bounds(b, options);
+        return clusteringColumnsRestrictions.boundsAsClustering(b, options);
     }
 
     /**
@@ -527,15 +508,9 @@ public final class StatementRestrictions
      */
     public boolean isColumnRange()
     {
-        // Due to CASSANDRA-5762, we always do a slice for CQL3 tables (not dense, composite).
-        // Static CF (non dense but non composite) never entails a column slice however
-        if (!cfm.comparator.isDense())
-            return cfm.comparator.isCompound();
-
-        // Otherwise (i.e. for compact table where we don't have a row marker anyway and thus don't care about
-        // CASSANDRA-5762),
         // it is a range query if it has at least one the column alias for which no relation is defined or is not EQ.
-        return clusteringColumnsRestrictions.size() < cfm.clusteringColumns().size() || clusteringColumnsRestrictions.isSlice();
+        return clusteringColumnsRestrictions.size() < cfm.clusteringColumns().size()
+            || (!clusteringColumnsRestrictions.isEQ() && !clusteringColumnsRestrictions.isIN());
     }
 
     /**
@@ -564,9 +539,4 @@ public final class StatementRestrictions
         // so far, 2i means that you've restricted a non static column, so the query is somewhat non-sensical.
         checkFalse(selectsOnlyStaticColumns, "Queries using 2ndary indexes don't support selecting only static columns");
     }
-
-    public void reverse()
-    {
-        clusteringColumnsRestrictions = new ReversedPrimaryKeyRestrictions(clusteringColumnsRestrictions);
-    }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a991b648/src/java/org/apache/cassandra/cql3/restrictions/TokenFilter.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/restrictions/TokenFilter.java b/src/java/org/apache/cassandra/cql3/restrictions/TokenFilter.java
index bd04610..2ab54ce 100644
--- a/src/java/org/apache/cassandra/cql3/restrictions/TokenFilter.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/TokenFilter.java
@@ -18,8 +18,7 @@
 package org.apache.cassandra.cql3.restrictions;
 
 import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.*;
 
 import com.google.common.collect.BoundType;
 import com.google.common.collect.ImmutableRangeSet;
@@ -28,7 +27,7 @@ import com.google.common.collect.RangeSet;
 
 import org.apache.cassandra.cql3.QueryOptions;
 import org.apache.cassandra.cql3.statements.Bound;
-import org.apache.cassandra.db.composites.Composite;
+import org.apache.cassandra.db.*;
 import org.apache.cassandra.dht.IPartitioner;
 import org.apache.cassandra.dht.Token;
 import org.apache.cassandra.exceptions.InvalidRequestException;
@@ -84,7 +83,7 @@ final class TokenFilter extends ForwardingPrimaryKeyRestrictions
     }
 
     @Override
-    public List<Composite> valuesAsComposites(QueryOptions options) throws InvalidRequestException
+    public NavigableSet<Clustering> valuesAsClustering(QueryOptions options) throws InvalidRequestException
     {
         throw new UnsupportedOperationException();
     }
@@ -117,9 +116,9 @@ final class TokenFilter extends ForwardingPrimaryKeyRestrictions
     }
 
     @Override
-    public List<Composite> boundsAsComposites(Bound bound, QueryOptions options) throws InvalidRequestException
+    public SortedSet<Slice.Bound> boundsAsClustering(Bound bound, QueryOptions options) throws InvalidRequestException
     {
-        return tokenRestriction.boundsAsComposites(bound, options);
+        return tokenRestriction.boundsAsClustering(bound, options);
     }
 
     /**


Mime
View raw message