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); } /**
