http://git-wip-us.apache.org/repos/asf/cassandra/blob/831bebdb/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 4b82189..032a622 100644 --- a/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java +++ b/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java @@ -68,12 +68,12 @@ public final class StatementRestrictions /** * Restrictions on partitioning columns */ - private PrimaryKeyRestrictions partitionKeyRestrictions; + private PartitionKeyRestrictions partitionKeyRestrictions; /** * Restrictions on clustering columns */ - private PrimaryKeyRestrictions clusteringColumnsRestrictions; + private ClusteringColumnRestrictions clusteringColumnsRestrictions; /** * Restriction on non-primary key columns (i.e. secondary index restrictions) @@ -113,8 +113,8 @@ public final class StatementRestrictions { this.type = type; this.cfm = cfm; - this.partitionKeyRestrictions = new PrimaryKeyRestrictionSet(cfm.getKeyValidatorAsClusteringComparator(), true); - this.clusteringColumnsRestrictions = new PrimaryKeyRestrictionSet(cfm.comparator, false); + this.partitionKeyRestrictions = new PartitionKeySingleRestrictionSet(cfm.getKeyValidatorAsClusteringComparator()); + this.clusteringColumnsRestrictions = new ClusteringColumnRestrictions(cfm); this.nonPrimaryKeyRestrictions = new RestrictionSet(); this.notNullColumns = new HashSet<>(); } @@ -224,7 +224,7 @@ public final class StatementRestrictions if (isKeyRange && hasQueriableClusteringColumnIndex) usesSecondaryIndexing = true; - usesSecondaryIndexing = usesSecondaryIndexing || clusteringColumnsRestrictions.isContains(); + usesSecondaryIndexing = usesSecondaryIndexing || clusteringColumnsRestrictions.hasContains(); if (usesSecondaryIndexing) indexRestrictions.add(clusteringColumnsRestrictions); @@ -255,12 +255,13 @@ public final class StatementRestrictions private void addRestriction(Restriction restriction) { - if (restriction.isMultiColumn()) - clusteringColumnsRestrictions = clusteringColumnsRestrictions.mergeWith(restriction); - else if (restriction.isOnToken()) + ColumnDefinition def = restriction.getFirstColumn(); + if (def.isPartitionKey()) partitionKeyRestrictions = partitionKeyRestrictions.mergeWith(restriction); + else if (def.isClusteringColumn()) + clusteringColumnsRestrictions = clusteringColumnsRestrictions.mergeWith(restriction); else - addSingleColumnRestriction((SingleColumnRestriction) restriction); + nonPrimaryKeyRestrictions = nonPrimaryKeyRestrictions.addRestriction((SingleRestriction) restriction); } public Iterable<Function> getFunctions() @@ -276,17 +277,6 @@ public final class StatementRestrictions return indexRestrictions; } - private void addSingleColumnRestriction(SingleColumnRestriction restriction) - { - ColumnDefinition def = restriction.columnDef; - if (def.isPartitionKey()) - partitionKeyRestrictions = partitionKeyRestrictions.mergeWith(restriction); - else if (def.isClusteringColumn()) - clusteringColumnsRestrictions = clusteringColumnsRestrictions.mergeWith(restriction); - else - nonPrimaryKeyRestrictions = nonPrimaryKeyRestrictions.addRestriction(restriction); - } - /** * Returns the non-PK column that are restricted. If includeNotNullRestrictions is true, columns that are restricted * by an IS NOT NULL restriction will be included, otherwise they will not be included (unless another restriction @@ -338,14 +328,14 @@ public final class StatementRestrictions } /** - * Checks if the restrictions on the partition key is an IN restriction. + * Checks if the restrictions on the partition key has IN restrictions. * - * @return <code>true</code> the restrictions on the partition key is an IN restriction, <code>false</code> + * @return <code>true</code> the restrictions on the partition key has an IN restriction, <code>false</code> * otherwise. */ public boolean keyIsInRelation() { - return partitionKeyRestrictions.isIN(); + return partitionKeyRestrictions.hasIN(); } /** @@ -463,7 +453,7 @@ public final class StatementRestrictions boolean selectsComplexColumn, boolean forView) throws InvalidRequestException { - checkFalse(!type.allowClusteringColumnSlices() && clusteringColumnsRestrictions.isSlice(), + checkFalse(!type.allowClusteringColumnSlices() && clusteringColumnsRestrictions.hasSlice(), "Slice restrictions are not supported on the clustering columns in %s statements", type); if (!type.allowClusteringColumnSlices() @@ -475,9 +465,9 @@ public final class StatementRestrictions } else { - checkFalse(clusteringColumnsRestrictions.isIN() && selectsComplexColumn, + checkFalse(clusteringColumnsRestrictions.hasIN() && selectsComplexColumn, "Cannot restrict clustering columns by IN relations when a collection is selected by the query"); - checkFalse(clusteringColumnsRestrictions.isContains() && !hasQueriableIndex, + checkFalse(clusteringColumnsRestrictions.hasContains() && !hasQueriableIndex, "Cannot restrict clustering columns by a CONTAINS relation without a secondary index"); if (hasClusteringColumnsRestriction()) @@ -504,7 +494,7 @@ public final class StatementRestrictions } } - if (clusteringColumnsRestrictions.isContains()) + if (clusteringColumnsRestrictions.hasContains()) usesSecondaryIndexing = true; } @@ -732,18 +722,6 @@ public final class StatementRestrictions } /** - * Checks if the bounds (start or end) of the clustering columns are inclusive. - * - * @param bound the bound type - * @return <code>true</code> if the bounds (start or end) of the clustering columns are inclusive, - * <code>false</code> otherwise - */ - public boolean areRequestedBoundsInclusive(Bound bound) - { - return clusteringColumnsRestrictions.isInclusive(bound); - } - - /** * Checks if the query returns a range of columns. * * @return <code>true</code> if the query returns a range of columns, <code>false</code> otherwise. @@ -756,7 +734,7 @@ public final class StatementRestrictions int numberOfClusteringColumns = cfm.isStaticCompactTable() ? 0 : cfm.clusteringColumns().size(); // it is a range query if it has at least one the column alias for which no relation is defined or is not EQ or IN. return clusteringColumnsRestrictions.size() < numberOfClusteringColumns - || (!clusteringColumnsRestrictions.isEQ() && !clusteringColumnsRestrictions.isIN()); + || !clusteringColumnsRestrictions.hasOnlyEqualityRestrictions(); } /** @@ -796,9 +774,9 @@ public final class StatementRestrictions { return !isPartitionKeyRestrictionsOnToken() && !hasUnrestrictedPartitionKeyComponents() - && (partitionKeyRestrictions.isEQ() || partitionKeyRestrictions.isIN()) + && (partitionKeyRestrictions.hasOnlyEqualityRestrictions()) && !hasUnrestrictedClusteringColumns() - && (clusteringColumnsRestrictions.isEQ() || clusteringColumnsRestrictions.isIN()); + && (clusteringColumnsRestrictions.hasOnlyEqualityRestrictions()); } }
http://git-wip-us.apache.org/repos/asf/cassandra/blob/831bebdb/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 3258b26..9069501 100644 --- a/src/java/org/apache/cassandra/cql3/restrictions/TokenFilter.java +++ b/src/java/org/apache/cassandra/cql3/restrictions/TokenFilter.java @@ -25,12 +25,15 @@ import com.google.common.collect.ImmutableRangeSet; import com.google.common.collect.Range; import com.google.common.collect.RangeSet; +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.*; +import org.apache.cassandra.db.filter.RowFilter; import org.apache.cassandra.dht.IPartitioner; import org.apache.cassandra.dht.Token; import org.apache.cassandra.exceptions.InvalidRequestException; +import org.apache.cassandra.index.SecondaryIndexManager; import static org.apache.cassandra.cql3.statements.Bound.END; import static org.apache.cassandra.cql3.statements.Bound.START; @@ -38,12 +41,12 @@ import static org.apache.cassandra.cql3.statements.Bound.START; /** * <code>Restriction</code> decorator used to merge non-token restriction and token restriction on partition keys. */ -final class TokenFilter extends ForwardingPrimaryKeyRestrictions +final class TokenFilter implements PartitionKeyRestrictions { /** * The decorated restriction */ - private PrimaryKeyRestrictions restrictions; + private PartitionKeyRestrictions restrictions; /** * The restriction on the token @@ -55,10 +58,14 @@ final class TokenFilter extends ForwardingPrimaryKeyRestrictions */ private final IPartitioner partitioner; - @Override - protected PrimaryKeyRestrictions getDelegate() + public boolean hasIN() + { + return isOnToken() ? false : restrictions.hasIN(); + } + + public boolean hasOnlyEqualityRestrictions() { - return restrictions; + return isOnToken() ? false : restrictions.hasOnlyEqualityRestrictions(); } @Override @@ -69,7 +76,7 @@ final class TokenFilter extends ForwardingPrimaryKeyRestrictions return restrictions.size() < tokenRestriction.size(); } - public TokenFilter(PrimaryKeyRestrictions restrictions, TokenRestriction tokenRestriction) + public TokenFilter(PartitionKeyRestrictions restrictions, TokenRestriction tokenRestriction) { this.restrictions = restrictions; this.tokenRestriction = tokenRestriction; @@ -83,18 +90,12 @@ final class TokenFilter extends ForwardingPrimaryKeyRestrictions } @Override - public NavigableSet<Clustering> valuesAsClustering(QueryOptions options) throws InvalidRequestException - { - throw new UnsupportedOperationException(); - } - - @Override - public PrimaryKeyRestrictions mergeWith(Restriction restriction) throws InvalidRequestException + public PartitionKeyRestrictions mergeWith(Restriction restriction) throws InvalidRequestException { if (restriction.isOnToken()) return new TokenFilter(restrictions, (TokenRestriction) tokenRestriction.mergeWith(restriction)); - return new TokenFilter(super.mergeWith(restriction), tokenRestriction); + return new TokenFilter(restrictions.mergeWith(restriction), tokenRestriction); } @Override @@ -115,12 +116,6 @@ final class TokenFilter extends ForwardingPrimaryKeyRestrictions return tokenRestriction.bounds(bound, options); } - @Override - public NavigableSet<Slice.Bound> boundsAsClustering(Bound bound, QueryOptions options) throws InvalidRequestException - { - return tokenRestriction.boundsAsClustering(bound, options); - } - /** * Filter the values returned by the restriction. * @@ -233,4 +228,52 @@ final class TokenFilter extends ForwardingPrimaryKeyRestrictions { return inclusive ? BoundType.CLOSED : BoundType.OPEN; } + + @Override + public ColumnDefinition getFirstColumn() + { + return this.restrictions.getFirstColumn(); + } + + @Override + public ColumnDefinition getLastColumn() + { + return this.restrictions.getLastColumn(); + } + + @Override + public List<ColumnDefinition> getColumnDefs() + { + return this.restrictions.getColumnDefs(); + } + + @Override + public Iterable<Function> getFunctions() + { + return this.restrictions.getFunctions(); + } + + @Override + public boolean hasSupportingIndex(SecondaryIndexManager indexManager) + { + return this.restrictions.hasSupportingIndex(indexManager); + } + + @Override + public void addRowFilterTo(RowFilter filter, SecondaryIndexManager indexManager, QueryOptions options) + { + this.restrictions.addRowFilterTo(filter, indexManager, options); + } + + @Override + public boolean isEmpty() + { + return this.restrictions.isEmpty(); + } + + @Override + public int size() + { + return this.restrictions.size(); + } } http://git-wip-us.apache.org/repos/asf/cassandra/blob/831bebdb/src/java/org/apache/cassandra/cql3/restrictions/TokenRestriction.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/restrictions/TokenRestriction.java b/src/java/org/apache/cassandra/cql3/restrictions/TokenRestriction.java index eaaafca..66cdb80 100644 --- a/src/java/org/apache/cassandra/cql3/restrictions/TokenRestriction.java +++ b/src/java/org/apache/cassandra/cql3/restrictions/TokenRestriction.java @@ -28,9 +28,6 @@ import org.apache.cassandra.cql3.QueryOptions; import org.apache.cassandra.cql3.Term; import org.apache.cassandra.cql3.functions.Function; import org.apache.cassandra.cql3.statements.Bound; -import org.apache.cassandra.db.Clustering; -import org.apache.cassandra.db.MultiCBuilder; -import org.apache.cassandra.db.Slice; import org.apache.cassandra.db.filter.RowFilter; import org.apache.cassandra.exceptions.InvalidRequestException; import org.apache.cassandra.index.SecondaryIndexManager; @@ -40,14 +37,14 @@ import static org.apache.cassandra.cql3.statements.RequestValidations.invalidReq /** * <code>Restriction</code> using the token function. */ -public abstract class TokenRestriction extends AbstractPrimaryKeyRestrictions +public abstract class TokenRestriction implements PartitionKeyRestrictions { /** * The definition of the columns to which apply the token restriction. */ protected final List<ColumnDefinition> columnDefs; - final CFMetaData metadata; + protected final CFMetaData metadata; /** * Creates a new <code>TokenRestriction</code> that apply to the specified columns. @@ -56,11 +53,25 @@ public abstract class TokenRestriction extends AbstractPrimaryKeyRestrictions */ public TokenRestriction(CFMetaData metadata, List<ColumnDefinition> columnDefs) { - super(metadata.getKeyValidatorAsClusteringComparator()); this.columnDefs = columnDefs; this.metadata = metadata; } + public boolean isSlice() + { + return false; + } + + public boolean hasIN() + { + return false; + } + + public boolean hasOnlyEqualityRestrictions() + { + return false; + } + @Override public boolean isOnToken() { @@ -98,21 +109,15 @@ public abstract class TokenRestriction extends AbstractPrimaryKeyRestrictions } @Override - public MultiCBuilder appendTo(MultiCBuilder builder, QueryOptions options) + public final boolean isEmpty() { - throw new UnsupportedOperationException(); + return getColumnDefs().isEmpty(); } @Override - public NavigableSet<Clustering> valuesAsClustering(QueryOptions options) throws InvalidRequestException + public final int size() { - throw new UnsupportedOperationException(); - } - - @Override - public NavigableSet<Slice.Bound> boundsAsClustering(Bound bound, QueryOptions options) throws InvalidRequestException - { - throw new UnsupportedOperationException(); + return getColumnDefs().size(); } /** @@ -126,10 +131,10 @@ public abstract class TokenRestriction extends AbstractPrimaryKeyRestrictions } @Override - public final PrimaryKeyRestrictions mergeWith(Restriction otherRestriction) throws InvalidRequestException + public final PartitionKeyRestrictions mergeWith(Restriction otherRestriction) throws InvalidRequestException { if (!otherRestriction.isOnToken()) - return new TokenFilter(toPrimaryKeyRestriction(otherRestriction), this); + return new TokenFilter(toPartitionKeyRestrictions(otherRestriction), this); return doMergeWith((TokenRestriction) otherRestriction); } @@ -138,21 +143,21 @@ public abstract class TokenRestriction extends AbstractPrimaryKeyRestrictions * Merges this restriction with the specified <code>TokenRestriction</code>. * @param otherRestriction the <code>TokenRestriction</code> to merge with. */ - protected abstract PrimaryKeyRestrictions doMergeWith(TokenRestriction otherRestriction) throws InvalidRequestException; + protected abstract PartitionKeyRestrictions doMergeWith(TokenRestriction otherRestriction) throws InvalidRequestException; /** - * Converts the specified restriction into a <code>PrimaryKeyRestrictions</code>. + * Converts the specified restriction into a <code>PartitionKeyRestrictions</code>. * * @param restriction the restriction to convert - * @return a <code>PrimaryKeyRestrictions</code> + * @return a <code>PartitionKeyRestrictions</code> * @throws InvalidRequestException if a problem occurs while converting the restriction */ - private PrimaryKeyRestrictions toPrimaryKeyRestriction(Restriction restriction) throws InvalidRequestException + private PartitionKeyRestrictions toPartitionKeyRestrictions(Restriction restriction) throws InvalidRequestException { - if (restriction instanceof PrimaryKeyRestrictions) - return (PrimaryKeyRestrictions) restriction; + if (restriction instanceof PartitionKeyRestrictions) + return (PartitionKeyRestrictions) restriction; - return new PrimaryKeyRestrictionSet(comparator, true).mergeWith(restriction); + return new PartitionKeySingleRestrictionSet(metadata.getKeyValidatorAsClusteringComparator()).mergeWith(restriction); } public static final class EQRestriction extends TokenRestriction @@ -166,25 +171,37 @@ public abstract class TokenRestriction extends AbstractPrimaryKeyRestrictions } @Override - public boolean isEQ() - { - return true; - } - - @Override public Iterable<Function> getFunctions() { return value.getFunctions(); } @Override - protected PrimaryKeyRestrictions doMergeWith(TokenRestriction otherRestriction) throws InvalidRequestException + protected PartitionKeyRestrictions doMergeWith(TokenRestriction otherRestriction) throws InvalidRequestException { throw invalidRequest("%s cannot be restricted by more than one relation if it includes an Equal", Joiner.on(", ").join(ColumnDefinition.toIdentifiers(columnDefs))); } @Override + public List<ByteBuffer> bounds(Bound b, QueryOptions options) throws InvalidRequestException + { + return values(options); + } + + @Override + public boolean hasBound(Bound b) + { + return true; + } + + @Override + public boolean isInclusive(Bound b) + { + return true; + } + + @Override public List<ByteBuffer> values(QueryOptions options) throws InvalidRequestException { return Collections.singletonList(value.bindAndGet(options)); @@ -238,10 +255,10 @@ public abstract class TokenRestriction extends AbstractPrimaryKeyRestrictions } @Override - protected PrimaryKeyRestrictions doMergeWith(TokenRestriction otherRestriction) + protected PartitionKeyRestrictions doMergeWith(TokenRestriction otherRestriction) throws InvalidRequestException { - if (!otherRestriction.isSlice()) + if (!(otherRestriction instanceof SliceRestriction)) throw invalidRequest("Columns \"%s\" cannot be restricted by both an equality and an inequality relation", getColumnNamesAsString()); http://git-wip-us.apache.org/repos/asf/cassandra/blob/831bebdb/src/java/org/apache/cassandra/cql3/statements/Bound.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/statements/Bound.java b/src/java/org/apache/cassandra/cql3/statements/Bound.java index 7742642..824743c 100644 --- a/src/java/org/apache/cassandra/cql3/statements/Bound.java +++ b/src/java/org/apache/cassandra/cql3/statements/Bound.java @@ -17,6 +17,8 @@ */ package org.apache.cassandra.cql3.statements; +import org.apache.cassandra.config.ColumnDefinition; + public enum Bound { START(0), END(1); @@ -28,6 +30,17 @@ public enum Bound this.idx = idx; } + /** + * Reverses the bound if the column type is a reversed one. + * + * @param columnDefinition the column definition + * @return the bound reversed if the column type was a reversed one or the original bound + */ + public Bound reverseIfNeeded(ColumnDefinition columnDefinition) + { + return columnDefinition.isReversedType() ? reverse() : this; + } + public Bound reverse() { return isStart() ? END : START;
