Consolidate Relation.Type and IndexExpression.Operator Patch by Benjamin Lerer; reviewed by Tyler Hobbs for CASSANDRA-8147
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/5117a5d5 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/5117a5d5 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/5117a5d5 Branch: refs/heads/cassandra-2.1 Commit: 5117a5d5baca409a0510dac61d479827920cdfbc Parents: 52a701f Author: blerer <b_le...@hotmail.com> Authored: Tue Nov 4 10:31:12 2014 -0600 Committer: Tyler Hobbs <ty...@datastax.com> Committed: Tue Nov 4 10:31:12 2014 -0600 ---------------------------------------------------------------------- .../apache/cassandra/cql/QueryProcessor.java | 4 +- .../apache/cassandra/cql3/ColumnCondition.java | 98 ++++++++++---------- src/java/org/apache/cassandra/cql3/Cql.g | 18 ++-- .../cassandra/cql3/MultiColumnRelation.java | 14 +-- .../org/apache/cassandra/cql3/Operator.java | 93 +++++++++++++++++++ .../org/apache/cassandra/cql3/Relation.java | 82 +--------------- .../cassandra/cql3/SingleColumnRelation.java | 18 ++-- .../cql3/statements/ModificationStatement.java | 8 +- .../cassandra/cql3/statements/Restriction.java | 12 ++- .../cql3/statements/SelectStatement.java | 53 ++++++----- .../statements/SingleColumnRestriction.java | 17 ++-- .../apache/cassandra/db/IndexExpression.java | 95 +++++++------------ .../apache/cassandra/db/PagedRangeCommand.java | 10 +- .../apache/cassandra/db/RangeSliceCommand.java | 11 +-- .../cassandra/db/filter/ExtendedFilter.java | 31 ++++--- .../cassandra/db/index/SecondaryIndex.java | 12 +-- .../CompositesIndexOnCollectionKey.java | 7 +- .../CompositesIndexOnCollectionValue.java | 5 +- .../cassandra/db/marshal/CompositeType.java | 4 +- .../cassandra/thrift/ThriftConversion.java | 3 +- .../cassandra/cql3/ColumnConditionTest.java | 48 +++++----- .../org/apache/cassandra/db/CleanupTest.java | 11 ++- .../cassandra/db/ColumnFamilyStoreTest.java | 47 +++++----- .../cassandra/io/sstable/SSTableReaderTest.java | 3 +- .../streaming/StreamingTransferTest.java | 3 +- 25 files changed, 351 insertions(+), 356 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/5117a5d5/src/java/org/apache/cassandra/cql/QueryProcessor.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql/QueryProcessor.java b/src/java/org/apache/cassandra/cql/QueryProcessor.java index 0b9ba2e..d947cdb 100644 --- a/src/java/org/apache/cassandra/cql/QueryProcessor.java +++ b/src/java/org/apache/cassandra/cql/QueryProcessor.java @@ -33,7 +33,7 @@ import org.apache.cassandra.cql.hooks.ExecutionContext; import org.apache.cassandra.cql.hooks.PostPreparationHook; import org.apache.cassandra.cql.hooks.PreExecutionHook; import org.apache.cassandra.cql.hooks.PreparationContext; -import org.apache.cassandra.db.CounterCell; +import org.apache.cassandra.cql3.Operator; import org.apache.cassandra.db.*; import org.apache.cassandra.db.composites.CellName; import org.apache.cassandra.db.composites.CellNameType; @@ -193,7 +193,7 @@ public class QueryProcessor ByteBuffer value = columnRelation.getValue().getByteBuffer(metadata.getValueValidator(metadata.comparator.cellFromByteBuffer(entity)), variables); expressions.add(new IndexExpression(entity, - IndexExpression.Operator.valueOf(columnRelation.operator().toString()), + Operator.valueOf(columnRelation.operator().name()), value)); } http://git-wip-us.apache.org/repos/asf/cassandra/blob/5117a5d5/src/java/org/apache/cassandra/cql3/ColumnCondition.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/ColumnCondition.java b/src/java/org/apache/cassandra/cql3/ColumnCondition.java index 703ac5b..25cb07d 100644 --- a/src/java/org/apache/cassandra/cql3/ColumnCondition.java +++ b/src/java/org/apache/cassandra/cql3/ColumnCondition.java @@ -52,9 +52,9 @@ public class ColumnCondition private final Term value; // a single value or a marker for a list of IN values private final List<Term> inValues; - public final Relation.Type operator; + public final Operator operator; - private ColumnCondition(ColumnDefinition column, Term collectionElement, Term value, List<Term> inValues, Relation.Type op) + private ColumnCondition(ColumnDefinition column, Term collectionElement, Term value, List<Term> inValues, Operator op) { this.column = column; this.collectionElement = collectionElement; @@ -62,38 +62,38 @@ public class ColumnCondition this.inValues = inValues; this.operator = op; - if (!operator.equals(Relation.Type.IN)) + if (!operator.equals(Operator.IN)) assert this.inValues == null; } - public static ColumnCondition condition(ColumnDefinition column, Term value, Relation.Type op) + public static ColumnCondition condition(ColumnDefinition column, Term value, Operator op) { return new ColumnCondition(column, null, value, null, op); } - public static ColumnCondition condition(ColumnDefinition column, Term collectionElement, Term value, Relation.Type op) + public static ColumnCondition condition(ColumnDefinition column, Term collectionElement, Term value, Operator op) { return new ColumnCondition(column, collectionElement, value, null, op); } public static ColumnCondition inCondition(ColumnDefinition column, List<Term> inValues) { - return new ColumnCondition(column, null, null, inValues, Relation.Type.IN); + return new ColumnCondition(column, null, null, inValues, Operator.IN); } public static ColumnCondition inCondition(ColumnDefinition column, Term collectionElement, List<Term> inValues) { - return new ColumnCondition(column, collectionElement, null, inValues, Relation.Type.IN); + return new ColumnCondition(column, collectionElement, null, inValues, Operator.IN); } public static ColumnCondition inCondition(ColumnDefinition column, Term inMarker) { - return new ColumnCondition(column, null, inMarker, null, Relation.Type.IN); + return new ColumnCondition(column, null, inMarker, null, Operator.IN); } public static ColumnCondition inCondition(ColumnDefinition column, Term collectionElement, Term inMarker) { - return new ColumnCondition(column, collectionElement, inMarker, null, Relation.Type.IN); + return new ColumnCondition(column, collectionElement, inMarker, null, Operator.IN); } /** @@ -107,7 +107,7 @@ public class ColumnCondition if (collectionElement != null) collectionElement.collectMarkerSpecification(boundNames); - if (operator.equals(Relation.Type.IN) && inValues != null) + if (operator.equals(Operator.IN) && inValues != null) { for (Term value : inValues) value.collectMarkerSpecification(boundNames); @@ -120,7 +120,7 @@ public class ColumnCondition public ColumnCondition.Bound bind(QueryOptions options) throws InvalidRequestException { - boolean isInCondition = operator.equals(Relation.Type.IN); + boolean isInCondition = operator.equals(Operator.IN); if (column.type instanceof CollectionType) { if (collectionElement == null) @@ -134,9 +134,9 @@ public class ColumnCondition public static abstract class Bound { public final ColumnDefinition column; - public final Relation.Type operator; + public final Operator operator; - protected Bound(ColumnDefinition column, Relation.Type operator) + protected Bound(ColumnDefinition column, Operator operator) { this.column = column; this.operator = operator; @@ -152,14 +152,14 @@ public class ColumnCondition return null; } - protected boolean isSatisfiedByValue(ByteBuffer value, Cell c, AbstractType<?> type, Relation.Type operator, long now) throws InvalidRequestException + protected boolean isSatisfiedByValue(ByteBuffer value, Cell c, AbstractType<?> type, Operator operator, long now) throws InvalidRequestException { ByteBuffer columnValue = (c == null || !c.isLive(now)) ? null : c.value(); return compareWithOperator(operator, type, value, columnValue); } /** Returns true if the operator is satisfied (i.e. "value operator otherValue == true"), false otherwise. */ - protected boolean compareWithOperator(Relation.Type operator, AbstractType<?> type, ByteBuffer value, ByteBuffer otherValue) throws InvalidRequestException + protected boolean compareWithOperator(Operator operator, AbstractType<?> type, ByteBuffer value, ByteBuffer otherValue) throws InvalidRequestException { if (value == null) { @@ -176,7 +176,7 @@ public class ColumnCondition else if (otherValue == null) { // the condition value is not null, so only NEQ can return true - return operator.equals(Relation.Type.NEQ); + return operator.equals(Operator.NEQ); } int comparison = type.compare(otherValue, value); switch (operator) @@ -226,7 +226,7 @@ public class ColumnCondition { super(condition.column, condition.operator); assert !(column.type instanceof CollectionType) && condition.collectionElement == null; - assert !condition.operator.equals(Relation.Type.IN); + assert !condition.operator.equals(Operator.IN); this.value = condition.value.bindAndGet(options); } @@ -254,7 +254,7 @@ public class ColumnCondition { super(condition.column, condition.operator); assert !(column.type instanceof CollectionType) && condition.collectionElement == null; - assert condition.operator.equals(Relation.Type.IN); + assert condition.operator.equals(Operator.IN); if (condition.inValues == null) this.inValues = ((Lists.Marker) condition.value).bind(options).getElements(); else @@ -270,7 +270,7 @@ public class ColumnCondition CellName name = current.metadata().comparator.create(rowPrefix, column); for (ByteBuffer value : inValues) { - if (isSatisfiedByValue(value, current.getColumn(name), column.type, Relation.Type.EQ, now)) + if (isSatisfiedByValue(value, current.getColumn(name), column.type, Operator.EQ, now)) return true; } return false; @@ -293,7 +293,7 @@ public class ColumnCondition { super(condition.column, condition.operator); assert column.type instanceof CollectionType && condition.collectionElement != null; - assert !condition.operator.equals(Relation.Type.IN); + assert !condition.operator.equals(Operator.IN); this.collectionElement = condition.collectionElement.bindAndGet(options); this.value = condition.value.bindAndGet(options); } @@ -380,7 +380,7 @@ public class ColumnCondition AbstractType<?> valueType = ((MapType) column.type).values; for (ByteBuffer value : inValues) { - if (isSatisfiedByValue(value, item, valueType, Relation.Type.EQ, now)) + if (isSatisfiedByValue(value, item, valueType, Operator.EQ, now)) return true; } return false; @@ -394,7 +394,7 @@ public class ColumnCondition AbstractType<?> valueType = ((ListType) column.type).elements; for (ByteBuffer value : inValues) { - if (compareWithOperator(Relation.Type.EQ, valueType, value, columnValue)) + if (compareWithOperator(Operator.EQ, valueType, value, columnValue)) return true; } return false; @@ -416,7 +416,7 @@ public class ColumnCondition { super(condition.column, condition.operator); assert column.type instanceof CollectionType && condition.collectionElement == null; - assert !condition.operator.equals(Relation.Type.IN); + assert !condition.operator.equals(Operator.IN); this.value = condition.value.bind(options); } @@ -427,9 +427,9 @@ public class ColumnCondition Iterator<Cell> iter = collectionColumns(current.metadata().comparator.create(rowPrefix, column), current, now); if (value == null) { - if (operator.equals(Relation.Type.EQ)) + if (operator.equals(Operator.EQ)) return !iter.hasNext(); - else if (operator.equals(Relation.Type.NEQ)) + else if (operator.equals(Operator.NEQ)) return iter.hasNext(); else throw new InvalidRequestException(String.format("Invalid comparison with null for operator \"%s\"", operator)); @@ -438,7 +438,7 @@ public class ColumnCondition return valueAppliesTo(type, iter, value, operator); } - static boolean valueAppliesTo(CollectionType type, Iterator<Cell> iter, Term.Terminal value, Relation.Type operator) + static boolean valueAppliesTo(CollectionType type, Iterator<Cell> iter, Term.Terminal value, Operator operator) { if (value == null) return !iter.hasNext(); @@ -452,12 +452,12 @@ public class ColumnCondition throw new AssertionError(); } - private static boolean setOrListAppliesTo(AbstractType<?> type, Iterator<Cell> iter, Iterator<ByteBuffer> conditionIter, Relation.Type operator, boolean isSet) + private static boolean setOrListAppliesTo(AbstractType<?> type, Iterator<Cell> iter, Iterator<ByteBuffer> conditionIter, Operator operator, boolean isSet) { while(iter.hasNext()) { if (!conditionIter.hasNext()) - return operator.equals(Relation.Type.GT) || operator.equals(Relation.Type.GTE) || operator.equals(Relation.Type.NEQ); + return operator.equals(Operator.GT) || operator.equals(Operator.GTE) || operator.equals(Operator.NEQ); // for lists we use the cell value; for sets we use the cell name ByteBuffer cellValue = isSet? iter.next().name().collectionElement() : iter.next().value(); @@ -467,13 +467,13 @@ public class ColumnCondition } if (conditionIter.hasNext()) - return operator.equals(Relation.Type.LT) || operator.equals(Relation.Type.LTE) || operator.equals(Relation.Type.NEQ); + return operator.equals(Operator.LT) || operator.equals(Operator.LTE) || operator.equals(Operator.NEQ); // they're equal - return operator == Relation.Type.EQ || operator == Relation.Type.LTE || operator == Relation.Type.GTE; + return operator == Operator.EQ || operator == Operator.LTE || operator == Operator.GTE; } - private static boolean evaluateComparisonWithOperator(int comparison, Relation.Type operator) + private static boolean evaluateComparisonWithOperator(int comparison, Operator operator) { // called when comparison != 0 switch (operator) @@ -493,12 +493,12 @@ public class ColumnCondition } } - static boolean listAppliesTo(ListType type, Iterator<Cell> iter, List<ByteBuffer> elements, Relation.Type operator) + static boolean listAppliesTo(ListType type, Iterator<Cell> iter, List<ByteBuffer> elements, Operator operator) { return setOrListAppliesTo(type.elements, iter, elements.iterator(), operator, false); } - static boolean setAppliesTo(SetType type, Iterator<Cell> iter, Set<ByteBuffer> elements, Relation.Type operator) + static boolean setAppliesTo(SetType type, Iterator<Cell> iter, Set<ByteBuffer> elements, Operator operator) { ArrayList<ByteBuffer> sortedElements = new ArrayList<>(elements.size()); sortedElements.addAll(elements); @@ -506,13 +506,13 @@ public class ColumnCondition return setOrListAppliesTo(type.elements, iter, sortedElements.iterator(), operator, true); } - static boolean mapAppliesTo(MapType type, Iterator<Cell> iter, Map<ByteBuffer, ByteBuffer> elements, Relation.Type operator) + static boolean mapAppliesTo(MapType type, Iterator<Cell> iter, Map<ByteBuffer, ByteBuffer> elements, Operator operator) { Iterator<Map.Entry<ByteBuffer, ByteBuffer>> conditionIter = elements.entrySet().iterator(); while(iter.hasNext()) { if (!conditionIter.hasNext()) - return operator.equals(Relation.Type.GT) || operator.equals(Relation.Type.GTE) || operator.equals(Relation.Type.NEQ); + return operator.equals(Operator.GT) || operator.equals(Operator.GTE) || operator.equals(Operator.NEQ); Map.Entry<ByteBuffer, ByteBuffer> conditionEntry = conditionIter.next(); Cell c = iter.next(); @@ -529,10 +529,10 @@ public class ColumnCondition } if (conditionIter.hasNext()) - return operator.equals(Relation.Type.LT) || operator.equals(Relation.Type.LTE) || operator.equals(Relation.Type.NEQ); + return operator.equals(Operator.LT) || operator.equals(Operator.LTE) || operator.equals(Operator.NEQ); // they're equal - return operator == Relation.Type.EQ || operator == Relation.Type.LTE || operator == Relation.Type.GTE; + return operator == Operator.EQ || operator == Operator.LTE || operator == Operator.GTE; } @Override @@ -566,7 +566,7 @@ public class ColumnCondition { super(condition.column, condition.operator); assert column.type instanceof CollectionType && condition.collectionElement == null; - assert condition.operator.equals(Relation.Type.IN); + assert condition.operator.equals(Operator.IN); inValues = new ArrayList<>(); if (condition.inValues == null) { @@ -623,7 +623,7 @@ public class ColumnCondition List<Cell> cells = newArrayList(collectionColumns(name, current, now)); for (Term.Terminal value : inValues) { - if (CollectionBound.valueAppliesTo(type, cells.iterator(), value, Relation.Type.EQ)) + if (CollectionBound.valueAppliesTo(type, cells.iterator(), value, Operator.EQ)) return true; } return false; @@ -669,9 +669,9 @@ public class ColumnCondition // Can be null, only used with the syntax "IF m[e] = ..." (in which case it's 'e') private final Term.Raw collectionElement; - private final Relation.Type operator; + private final Operator operator; - private Raw(Term.Raw value, List<Term.Raw> inValues, AbstractMarker.INRaw inMarker, Term.Raw collectionElement, Relation.Type op) + private Raw(Term.Raw value, List<Term.Raw> inValues, AbstractMarker.INRaw inMarker, Term.Raw collectionElement, Operator op) { this.value = value; this.inValues = inValues; @@ -681,7 +681,7 @@ public class ColumnCondition } /** A condition on a column. For example: "IF col = 'foo'" */ - public static Raw simpleCondition(Term.Raw value, Relation.Type op) + public static Raw simpleCondition(Term.Raw value, Operator op) { return new Raw(value, null, null, null, op); } @@ -689,17 +689,17 @@ public class ColumnCondition /** An IN condition on a column. For example: "IF col IN ('foo', 'bar', ...)" */ public static Raw simpleInCondition(List<Term.Raw> inValues) { - return new Raw(null, inValues, null, null, Relation.Type.IN); + return new Raw(null, inValues, null, null, Operator.IN); } /** An IN condition on a column with a single marker. For example: "IF col IN ?" */ public static Raw simpleInCondition(AbstractMarker.INRaw inMarker) { - return new Raw(null, null, inMarker, null, Relation.Type.IN); + return new Raw(null, null, inMarker, null, Operator.IN); } /** A condition on a collection element. For example: "IF col['key'] = 'foo'" */ - public static Raw collectionCondition(Term.Raw value, Term.Raw collectionElement, Relation.Type op) + public static Raw collectionCondition(Term.Raw value, Term.Raw collectionElement, Operator op) { return new Raw(value, null, null, collectionElement, op); } @@ -707,13 +707,13 @@ public class ColumnCondition /** An IN condition on a collection element. For example: "IF col['key'] IN ('foo', 'bar', ...)" */ public static Raw collectionInCondition(Term.Raw collectionElement, List<Term.Raw> inValues) { - return new Raw(null, inValues, null, collectionElement, Relation.Type.IN); + return new Raw(null, inValues, null, collectionElement, Operator.IN); } /** An IN condition on a collection element with a single marker. For example: "IF col['key'] IN ?" */ public static Raw collectionInCondition(Term.Raw collectionElement, AbstractMarker.INRaw inMarker) { - return new Raw(null, null, inMarker, collectionElement, Relation.Type.IN); + return new Raw(null, null, inMarker, collectionElement, Operator.IN); } public ColumnCondition prepare(String keyspace, ColumnDefinition receiver) throws InvalidRequestException @@ -723,7 +723,7 @@ public class ColumnCondition if (collectionElement == null) { - if (operator.equals(Relation.Type.IN)) + if (operator.equals(Operator.IN)) { if (inValues == null) return ColumnCondition.inCondition(receiver, inMarker.prepare(keyspace, receiver)); @@ -757,7 +757,7 @@ public class ColumnCondition default: throw new AssertionError(); } - if (operator.equals(Relation.Type.IN)) + if (operator.equals(Operator.IN)) { if (inValues == null) return ColumnCondition.inCondition(receiver, collectionElement.prepare(keyspace, elementSpec), inMarker.prepare(keyspace, valueSpec)); http://git-wip-us.apache.org/repos/asf/cassandra/blob/5117a5d5/src/java/org/apache/cassandra/cql3/Cql.g ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/Cql.g b/src/java/org/apache/cassandra/cql3/Cql.g index 2c90c18..189ae7d 100644 --- a/src/java/org/apache/cassandra/cql3/Cql.g +++ b/src/java/org/apache/cassandra/cql3/Cql.g @@ -1013,13 +1013,13 @@ propertyValue returns [String str] | u=unreserved_keyword { $str = u; } ; -relationType returns [Relation.Type op] - : '=' { $op = Relation.Type.EQ; } - | '<' { $op = Relation.Type.LT; } - | '<=' { $op = Relation.Type.LTE; } - | '>' { $op = Relation.Type.GT; } - | '>=' { $op = Relation.Type.GTE; } - | '!=' { $op = Relation.Type.NEQ; } +relationType returns [Operator op] + : '=' { $op = Operator.EQ; } + | '<' { $op = Operator.LT; } + | '<=' { $op = Operator.LTE; } + | '>' { $op = Operator.GT; } + | '>=' { $op = Operator.GTE; } + | '!=' { $op = Operator.NEQ; } ; relation[List<Relation> clauses] @@ -1030,10 +1030,10 @@ relation[List<Relation> clauses] $clauses.add(new SingleColumnRelation(id, type, t, true)); } | name=cident K_IN marker=inMarker - { $clauses.add(new SingleColumnRelation(name, Relation.Type.IN, marker)); } + { $clauses.add(new SingleColumnRelation(name, Operator.IN, marker)); } | name=cident K_IN inValues=singleColumnInValues { $clauses.add(SingleColumnRelation.createInRelation($name.id, inValues)); } - | name=cident K_CONTAINS { Relation.Type rt = Relation.Type.CONTAINS; } (K_KEY { rt = Relation.Type.CONTAINS_KEY; })? + | name=cident K_CONTAINS { Operator rt = Operator.CONTAINS; } (K_KEY { rt = Operator.CONTAINS_KEY; })? t=term { $clauses.add(new SingleColumnRelation(name, rt, t)); } | ids=tupleOfIdentifiers ( K_IN http://git-wip-us.apache.org/repos/asf/cassandra/blob/5117a5d5/src/java/org/apache/cassandra/cql3/MultiColumnRelation.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/MultiColumnRelation.java b/src/java/org/apache/cassandra/cql3/MultiColumnRelation.java index fda60df..9c51d89 100644 --- a/src/java/org/apache/cassandra/cql3/MultiColumnRelation.java +++ b/src/java/org/apache/cassandra/cql3/MultiColumnRelation.java @@ -39,7 +39,7 @@ public class MultiColumnRelation extends Relation private final Tuples.INRaw inMarker; - private MultiColumnRelation(List<ColumnIdentifier> entities, Type relationType, Term.MultiColumnRaw valuesOrMarker, List<? extends Term.MultiColumnRaw> inValues, Tuples.INRaw inMarker) + private MultiColumnRelation(List<ColumnIdentifier> entities, Operator relationType, Term.MultiColumnRaw valuesOrMarker, List<? extends Term.MultiColumnRaw> inValues, Tuples.INRaw inMarker) { this.entities = entities; this.relationType = relationType; @@ -56,9 +56,9 @@ public class MultiColumnRelation extends Relation * @param relationType the relation operator * @param valuesOrMarker a Tuples.Literal instance or a Tuples.Raw marker */ - public static MultiColumnRelation createNonInRelation(List<ColumnIdentifier> entities, Type relationType, Term.MultiColumnRaw valuesOrMarker) + public static MultiColumnRelation createNonInRelation(List<ColumnIdentifier> entities, Operator relationType, Term.MultiColumnRaw valuesOrMarker) { - assert relationType != Relation.Type.IN; + assert relationType != Operator.IN; return new MultiColumnRelation(entities, relationType, valuesOrMarker, null, null); } @@ -70,7 +70,7 @@ public class MultiColumnRelation extends Relation */ public static MultiColumnRelation createInRelation(List<ColumnIdentifier> entities, List<? extends Term.MultiColumnRaw> inValues) { - return new MultiColumnRelation(entities, Relation.Type.IN, null, inValues, null); + return new MultiColumnRelation(entities, Operator.IN, null, inValues, null); } /** @@ -81,7 +81,7 @@ public class MultiColumnRelation extends Relation */ public static MultiColumnRelation createSingleMarkerInRelation(List<ColumnIdentifier> entities, Tuples.INRaw inMarker) { - return new MultiColumnRelation(entities, Relation.Type.IN, null, null, inMarker); + return new MultiColumnRelation(entities, Operator.IN, null, null, inMarker); } public List<ColumnIdentifier> getEntities() @@ -94,7 +94,7 @@ public class MultiColumnRelation extends Relation */ public Term.MultiColumnRaw getValue() { - assert relationType != Relation.Type.IN; + assert relationType != Operator.IN; return valuesOrMarker; } @@ -124,7 +124,7 @@ public class MultiColumnRelation extends Relation @Override public String toString() { - if (relationType == Type.IN) + if (relationType == Operator.IN) { StringBuilder sb = new StringBuilder(Tuples.tupleToString(entities)); sb.append(" IN "); http://git-wip-us.apache.org/repos/asf/cassandra/blob/5117a5d5/src/java/org/apache/cassandra/cql3/Operator.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/Operator.java b/src/java/org/apache/cassandra/cql3/Operator.java new file mode 100644 index 0000000..359fcb8 --- /dev/null +++ b/src/java/org/apache/cassandra/cql3/Operator.java @@ -0,0 +1,93 @@ +/* + * 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; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public enum Operator +{ + EQ(0), LT(4), LTE(3), GTE(1), GT(2), IN(7), CONTAINS(5), CONTAINS_KEY(6), NEQ(8); + + /** + * The binary representation of this <code>Enum</code> value. + */ + private final int b; + + /** + * Creates a new <code>Operator</code> with the specified binary representation. + * @param b the binary representation of this <code>Enum</code> value + */ + private Operator(int b) + { + this.b = b; + } + + /** + * Write the serialized version of this <code>Operator</code> to the specified output. + * + * @param output the output to write to + * @throws IOException if an I/O problem occurs while writing to the specified output + */ + public void writeTo(DataOutput output) throws IOException + { + output.writeInt(b); + } + + /** + * Deserializes a <code>Operator</code> instance from the specified input. + * + * @param input the input to read from + * @return the <code>Operator</code> instance deserialized + * @throws IOException if a problem occurs while deserializing the <code>Type</code> instance. + */ + public static Operator readFrom(DataInput input) throws IOException + { + int b = input.readInt(); + for (Operator operator : values()) + if (operator.b == b) + return operator; + + throw new IOException(String.format("Cannot resolve Relation.Type from binary representation: %s", b)); + } + + @Override + public String toString() + { + switch (this) + { + case EQ: + return "="; + case LT: + return "<"; + case LTE: + return "<="; + case GT: + return ">"; + case GTE: + return ">="; + case NEQ: + return "!="; + case CONTAINS_KEY: + return "CONTAINS KEY"; + default: + return this.name(); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/5117a5d5/src/java/org/apache/cassandra/cql3/Relation.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/Relation.java b/src/java/org/apache/cassandra/cql3/Relation.java index c6a7c65..91d4100 100644 --- a/src/java/org/apache/cassandra/cql3/Relation.java +++ b/src/java/org/apache/cassandra/cql3/Relation.java @@ -17,89 +17,11 @@ */ package org.apache.cassandra.cql3; -import org.apache.cassandra.config.ColumnDefinition; -import org.apache.cassandra.db.index.SecondaryIndex; -import org.apache.cassandra.db.marshal.CollectionType; - - public abstract class Relation { - protected Type relationType; - - public static enum Type - { - EQ - { - public boolean allowsIndexQueryOn(ColumnDefinition columnDef) - { - return columnDef.isIndexed(); - } - }, - LT, - LTE, - GTE, - GT, - IN, - CONTAINS - { - public boolean allowsIndexQueryOn(ColumnDefinition columnDef) - { - return columnDef.isIndexed() - && columnDef.type.isCollection() - && (!((CollectionType<?>) columnDef.type).isMap() - || columnDef.hasIndexOption(SecondaryIndex.INDEX_VALUES_OPTION_NAME)); - } - }, - CONTAINS_KEY - { - public boolean allowsIndexQueryOn(ColumnDefinition columnDef) - { - return columnDef.isIndexed() - && columnDef.type.isCollection() - && (!((CollectionType<?>) columnDef.type).isMap() - || columnDef.hasIndexOption(SecondaryIndex.INDEX_KEYS_OPTION_NAME)); - } - }, - NEQ; - - /** - * Checks if this relation type allow index queries on the specified column - * - * @param columnDef the column definition. - * @return <code>true</code> if this relation type allow index queries on the specified column, - * <code>false</code> otherwise. - */ - public boolean allowsIndexQueryOn(ColumnDefinition columnDef) - { - return false; - } - - @Override - public String toString() - { - switch (this) - { - case EQ: - return "="; - case LT: - return "<"; - case LTE: - return "<="; - case GT: - return ">"; - case GTE: - return ">="; - case NEQ: - return "!="; - case CONTAINS_KEY: - return "CONTAINS KEY"; - default: - return this.name(); - } - } - } + protected Operator relationType; - public Type operator() + public Operator operator() { return relationType; } http://git-wip-us.apache.org/repos/asf/cassandra/blob/5117a5d5/src/java/org/apache/cassandra/cql3/SingleColumnRelation.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/SingleColumnRelation.java b/src/java/org/apache/cassandra/cql3/SingleColumnRelation.java index ee95da0..fd427fd 100644 --- a/src/java/org/apache/cassandra/cql3/SingleColumnRelation.java +++ b/src/java/org/apache/cassandra/cql3/SingleColumnRelation.java @@ -31,7 +31,7 @@ public class SingleColumnRelation extends Relation private final List<Term.Raw> inValues; public final boolean onToken; - private SingleColumnRelation(ColumnIdentifier entity, Type type, Term.Raw value, List<Term.Raw> inValues, boolean onToken) + private SingleColumnRelation(ColumnIdentifier entity, Operator type, Term.Raw value, List<Term.Raw> inValues, boolean onToken) { this.entity = entity; this.relationType = type; @@ -47,19 +47,19 @@ public class SingleColumnRelation extends Relation * @param type the type that describes how this entity relates to the value. * @param value the value being compared. */ - public SingleColumnRelation(ColumnIdentifier entity, Type type, Term.Raw value) + public SingleColumnRelation(ColumnIdentifier entity, Operator type, Term.Raw value) { this(entity, type, value, null, false); } - public SingleColumnRelation(ColumnIdentifier entity, Type type, Term.Raw value, boolean onToken) + public SingleColumnRelation(ColumnIdentifier entity, Operator type, Term.Raw value, boolean onToken) { this(entity, type, value, null, onToken); } public static SingleColumnRelation createInRelation(ColumnIdentifier entity, List<Term.Raw> inValues) { - return new SingleColumnRelation(entity, Type.IN, null, inValues, false); + return new SingleColumnRelation(entity, Operator.IN, null, inValues, false); } public ColumnIdentifier getEntity() @@ -69,13 +69,13 @@ public class SingleColumnRelation extends Relation public Term.Raw getValue() { - assert relationType != Type.IN || value == null || value instanceof AbstractMarker.INRaw; + assert relationType != Operator.IN || value == null || value instanceof AbstractMarker.INRaw; return value; } public List<Term.Raw> getInValues() { - assert relationType == Type.IN; + assert relationType == Operator.IN; return inValues; } @@ -88,8 +88,8 @@ public class SingleColumnRelation extends Relation { switch (relationType) { - case GT: return new SingleColumnRelation(entity, Type.GTE, value); - case LT: return new SingleColumnRelation(entity, Type.LTE, value); + case GT: return new SingleColumnRelation(entity, Operator.GTE, value); + case LT: return new SingleColumnRelation(entity, Operator.LTE, value); default: return this; } } @@ -97,7 +97,7 @@ public class SingleColumnRelation extends Relation @Override public String toString() { - if (relationType == Type.IN) + if (relationType == Operator.IN) return String.format("%s IN %s", entity, inValues); else if (onToken) return String.format("token(%s) %s %s", entity, relationType, value); http://git-wip-us.apache.org/repos/asf/cassandra/blob/5117a5d5/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java index b8cb818..69984b6 100644 --- a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java @@ -33,8 +33,6 @@ import org.apache.cassandra.db.composites.CBuilder; import org.apache.cassandra.db.composites.Composite; import org.apache.cassandra.db.filter.ColumnSlice; import org.apache.cassandra.db.filter.SliceQueryFilter; -import org.apache.cassandra.db.marshal.CompositeType; -import org.apache.cassandra.db.marshal.UTF8Type; import org.apache.cassandra.db.marshal.BooleanType; import org.apache.cassandra.exceptions.*; import org.apache.cassandra.service.ClientState; @@ -180,7 +178,7 @@ public abstract class ModificationStatement implements CQLStatement, MeasurableF staticConditions == null ? Collections.<ColumnDefinition>emptyList() : Iterables.transform(staticConditions, getColumnForCondition)); } - public void addCondition(ColumnCondition cond) throws InvalidRequestException + public void addCondition(ColumnCondition cond) { List<ColumnCondition> conds = null; if (cond.column.isStatic()) @@ -257,13 +255,13 @@ public abstract class ModificationStatement implements CQLStatement, MeasurableF case CLUSTERING_COLUMN: Restriction restriction; - if (rel.operator() == Relation.Type.EQ) + if (rel.operator() == Operator.EQ) { Term t = rel.getValue().prepare(keyspace(), def); t.collectMarkerSpecification(names); restriction = new SingleColumnRestriction.EQ(t, false); } - else if (def.kind == ColumnDefinition.Kind.PARTITION_KEY && rel.operator() == Relation.Type.IN) + else if (def.kind == ColumnDefinition.Kind.PARTITION_KEY && rel.operator() == Operator.IN) { if (rel.getValue() != null) { http://git-wip-us.apache.org/repos/asf/cassandra/blob/5117a5d5/src/java/org/apache/cassandra/cql3/statements/Restriction.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/statements/Restriction.java b/src/java/org/apache/cassandra/cql3/statements/Restriction.java index c529a38..5307cbb 100644 --- a/src/java/org/apache/cassandra/cql3/statements/Restriction.java +++ b/src/java/org/apache/cassandra/cql3/statements/Restriction.java @@ -20,9 +20,11 @@ package org.apache.cassandra.cql3.statements; import java.nio.ByteBuffer; import java.util.List; +import org.apache.cassandra.cql3.ColumnIdentifier; +import org.apache.cassandra.cql3.Operator; +import org.apache.cassandra.cql3.QueryOptions; +import org.apache.cassandra.cql3.Term; import org.apache.cassandra.exceptions.InvalidRequestException; -import org.apache.cassandra.db.IndexExpression; -import org.apache.cassandra.cql3.*; /** * A restriction/clause on a column. @@ -60,10 +62,10 @@ public interface Restriction /** Returns true if the start or end bound (depending on the argument) is inclusive, false otherwise */ public boolean isInclusive(Bound b); - public Relation.Type getRelation(Bound eocBound, Bound inclusiveBound); + public Operator getRelation(Bound eocBound, Bound inclusiveBound); - public IndexExpression.Operator getIndexOperator(Bound b); + public Operator getIndexOperator(Bound b); - public void setBound(ColumnIdentifier name, Relation.Type type, Term t) throws InvalidRequestException; + public void setBound(ColumnIdentifier name, Operator type, Term t) throws InvalidRequestException; } } http://git-wip-us.apache.org/repos/asf/cassandra/blob/5117a5d5/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java index 3354c0b..aa01c93 100644 --- a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java @@ -38,6 +38,7 @@ import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.config.ColumnDefinition; import org.apache.cassandra.db.*; import org.apache.cassandra.db.filter.*; +import org.apache.cassandra.db.index.SecondaryIndex; import org.apache.cassandra.db.index.SecondaryIndexManager; import org.apache.cassandra.db.marshal.*; import org.apache.cassandra.dht.*; @@ -840,7 +841,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache if (r.isSlice()) { builder.add(getSliceValue(r, b, options)); - Relation.Type relType = ((Restriction.Slice)r).getRelation(eocBound, b); + Operator relType = ((Restriction.Slice)r).getRelation(eocBound, b); return Collections.singletonList(builder.build().withEOC(eocForRelation(relType))); } else @@ -880,7 +881,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache return Collections.singletonList(eocBound == Bound.END && builder.remainingCount() > 0 ? prefix.end() : prefix); } - private static Composite.EOC eocForRelation(Relation.Type op) + private static Composite.EOC eocForRelation(Operator op) { switch (op) { @@ -942,7 +943,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache throw new InvalidRequestException("Invalid null value in condition for column " + def.name); builder.add(v); } - Relation.Type relType = slice.getRelation(eocBound, firstComponentBound); + Operator relType = slice.getRelation(eocBound, firstComponentBound); return Collections.singletonList(builder.build().withEOC(eocForRelation(relType))); } @@ -1052,7 +1053,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache if (slice.hasBound(b)) { ByteBuffer value = validateIndexedValue(def, slice.bound(b, options)); - IndexExpression.Operator op = slice.getIndexOperator(b); + 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. @@ -1068,12 +1069,12 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache for (ByteBuffer value : contains.values(options)) { validateIndexedValue(def, value); - expressions.add(new IndexExpression(def.name.bytes, IndexExpression.Operator.CONTAINS, value)); + expressions.add(new IndexExpression(def.name.bytes, Operator.CONTAINS, value)); } for (ByteBuffer key : contains.keys(options)) { validateIndexedValue(def, key); - expressions.add(new IndexExpression(def.name.bytes, IndexExpression.Operator.CONTAINS_KEY, key)); + expressions.add(new IndexExpression(def.name.bytes, Operator.CONTAINS_KEY, key)); } } else @@ -1084,7 +1085,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache throw new InvalidRequestException("IN restrictions are not supported on indexed columns"); ByteBuffer value = validateIndexedValue(def, values.get(0)); - expressions.add(new IndexExpression(def.name.bytes, IndexExpression.Operator.EQ, value)); + expressions.add(new IndexExpression(def.name.bytes, Operator.EQ, value)); } } @@ -1136,14 +1137,14 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache }; } - private static IndexExpression.Operator reverse(IndexExpression.Operator op) + private static Operator reverse(Operator op) { switch (op) { - case LT: return IndexExpression.Operator.GT; - case LTE: return IndexExpression.Operator.GTE; - case GT: return IndexExpression.Operator.LT; - case GTE: return IndexExpression.Operator.LTE; + case LT: return Operator.GT; + case LTE: return Operator.GTE; + case GT: return Operator.LT; + case GTE: return Operator.LTE; default: return op; } } @@ -1414,6 +1415,10 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache boolean hasQueriableClusteringColumnIndex = false; boolean hasSingleColumnRelations = false; boolean hasMultiColumnRelations = false; + + ColumnFamilyStore cfs = Keyspace.open(keyspace()).getColumnFamilyStore(columnFamily()); + SecondaryIndexManager indexManager = cfs.indexManager; + for (Relation relation : whereClause) { if (relation.isMultiColumn()) @@ -1423,7 +1428,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache for (ColumnIdentifier entity : rel.getEntities()) { ColumnDefinition def = cfm.getColumnDefinition(entity); - boolean[] queriable = processRelationEntity(stmt, relation, entity, def); + boolean[] queriable = processRelationEntity(stmt, indexManager, relation, entity, def); hasQueriableIndex |= queriable[0]; hasQueriableClusteringColumnIndex |= queriable[1]; names.add(def); @@ -1436,7 +1441,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache SingleColumnRelation rel = (SingleColumnRelation) relation; ColumnIdentifier entity = rel.getEntity(); ColumnDefinition def = cfm.getColumnDefinition(entity); - boolean[] queriable = processRelationEntity(stmt, relation, entity, def); + boolean[] queriable = processRelationEntity(stmt, indexManager, relation, entity, def); hasQueriableIndex |= queriable[0]; hasQueriableClusteringColumnIndex |= queriable[1]; hasSingleColumnRelations |= ColumnDefinition.Kind.CLUSTERING_COLUMN.equals(def.kind); @@ -1490,13 +1495,19 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache } /** Returns a pair of (hasQueriableIndex, hasQueriableClusteringColumnIndex) */ - private boolean[] processRelationEntity(SelectStatement stmt, Relation relation, ColumnIdentifier entity, ColumnDefinition def) throws InvalidRequestException + private boolean[] processRelationEntity(SelectStatement stmt, + SecondaryIndexManager indexManager, + Relation relation, + ColumnIdentifier entity, + ColumnDefinition def) throws InvalidRequestException { if (def == null) handleUnrecognizedEntity(entity, relation); stmt.restrictedColumns.add(def); - if (relation.operator().allowsIndexQueryOn(def)) + + SecondaryIndex index = indexManager.getIndexForColumn(def.name.bytes); + if (index != null && index.supportsOperator(relation.operator())) return new boolean[]{true, def.kind == ColumnDefinition.Kind.CLUSTERING_COLUMN}; return new boolean[]{false, false}; } @@ -1551,10 +1562,10 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache previousPosition++; Restriction existing = getExistingRestriction(stmt, def); - Relation.Type operator = relation.operator(); + Operator operator = relation.operator(); if (existing != null) { - if (operator == Relation.Type.EQ || operator == Relation.Type.IN) + if (operator == Operator.EQ || operator == Operator.IN) throw new InvalidRequestException(String.format("Column \"%s\" cannot be restricted by more than one relation if it is in an %s relation", def, relation.operator())); else if (!existing.isSlice()) throw new InvalidRequestException(String.format("Column \"%s\" cannot be restricted by an equality relation and an inequality relation", def)); @@ -1681,7 +1692,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache } // We don't support relations against entire collections, like "numbers = {1, 2, 3}" - if (receiver.type.isCollection() && !(newRel.operator().equals(Relation.Type.CONTAINS_KEY) || newRel.operator() == Relation.Type.CONTAINS)) + if (receiver.type.isCollection() && !(newRel.operator().equals(Operator.CONTAINS_KEY) || newRel.operator() == Operator.CONTAINS)) { throw new InvalidRequestException(String.format("Collection column '%s' (%s) cannot be restricted by a '%s' relation", def.name, receiver.type.asCQL3Type(), newRel.operator())); @@ -1759,7 +1770,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache existingRestriction = new SingleColumnRestriction.Contains(); else if (!existingRestriction.isContains()) throw new InvalidRequestException(String.format("Collection column %s can only be restricted by CONTAINS or CONTAINS KEY", def.name)); - boolean isKey = newRel.operator() == Relation.Type.CONTAINS_KEY; + boolean isKey = newRel.operator() == Operator.CONTAINS_KEY; receiver = makeCollectionReceiver(receiver, isKey); Term t = newRel.getValue().prepare(keyspace(), receiver); t.collectMarkerSpecification(boundNames); @@ -2097,7 +2108,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache // so it can't be a MultiColumnRelation. SingleColumnRelation rel = (SingleColumnRelation)r; if (cfm.getColumnDefinition(rel.getEntity()).kind == ColumnDefinition.Kind.CLUSTERING_COLUMN - && (rel.operator() == Relation.Type.GT || rel.operator() == Relation.Type.LT)) + && (rel.operator() == Operator.GT || rel.operator() == Operator.LT)) return rel; } http://git-wip-us.apache.org/repos/asf/cassandra/blob/5117a5d5/src/java/org/apache/cassandra/cql3/statements/SingleColumnRestriction.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/statements/SingleColumnRestriction.java b/src/java/org/apache/cassandra/cql3/statements/SingleColumnRestriction.java index 1ee0ebe..7f8156e 100644 --- a/src/java/org/apache/cassandra/cql3/statements/SingleColumnRestriction.java +++ b/src/java/org/apache/cassandra/cql3/statements/SingleColumnRestriction.java @@ -18,7 +18,6 @@ package org.apache.cassandra.cql3.statements; import org.apache.cassandra.cql3.*; -import org.apache.cassandra.db.IndexExpression; import org.apache.cassandra.exceptions.InvalidRequestException; import java.nio.ByteBuffer; @@ -249,35 +248,35 @@ public abstract class SingleColumnRestriction implements Restriction return bounds[b.idx] == null || boundInclusive[b.idx]; } - public Relation.Type getRelation(Bound eocBound, Bound inclusiveBound) + public Operator getRelation(Bound eocBound, Bound inclusiveBound) { switch (eocBound) { case START: - return boundInclusive[inclusiveBound.idx] ? Relation.Type.GTE : Relation.Type.GT; + return boundInclusive[inclusiveBound.idx] ? Operator.GTE : Operator.GT; case END: - return boundInclusive[inclusiveBound.idx] ? Relation.Type.LTE : Relation.Type.LT; + return boundInclusive[inclusiveBound.idx] ? Operator.LTE : Operator.LT; } throw new AssertionError(); } - public IndexExpression.Operator getIndexOperator(Bound b) + public Operator getIndexOperator(Bound b) { switch (b) { case START: - return boundInclusive[b.idx] ? IndexExpression.Operator.GTE : IndexExpression.Operator.GT; + return boundInclusive[b.idx] ? Operator.GTE : Operator.GT; case END: - return boundInclusive[b.idx] ? IndexExpression.Operator.LTE : IndexExpression.Operator.LT; + return boundInclusive[b.idx] ? Operator.LTE : Operator.LT; } throw new AssertionError(); } - public void setBound(ColumnIdentifier name, Relation.Type type, Term t) throws InvalidRequestException + public void setBound(ColumnIdentifier name, Operator operator, Term t) throws InvalidRequestException { Bound b; boolean inclusive; - switch (type) + switch (operator) { case GT: b = Bound.START; http://git-wip-us.apache.org/repos/asf/cassandra/blob/5117a5d5/src/java/org/apache/cassandra/db/IndexExpression.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/IndexExpression.java b/src/java/org/apache/cassandra/db/IndexExpression.java index 910bfbc..bdb74ce 100644 --- a/src/java/org/apache/cassandra/db/IndexExpression.java +++ b/src/java/org/apache/cassandra/db/IndexExpression.java @@ -19,13 +19,17 @@ package org.apache.cassandra.db; +import java.io.DataInput; +import java.io.IOException; import java.nio.ByteBuffer; import com.google.common.base.Objects; +import org.apache.cassandra.cql3.Operator; +import org.apache.cassandra.io.util.DataOutputPlus; import org.apache.cassandra.utils.ByteBufferUtil; -public class IndexExpression +public final class IndexExpression { public final ByteBuffer column; public final Operator operator; @@ -38,68 +42,6 @@ public class IndexExpression this.value = value; } - public enum Operator - { - EQ, GTE, GT, LTE, LT, CONTAINS, CONTAINS_KEY; - - public static Operator findByOrdinal(int ordinal) - { - switch (ordinal) { - case 0: - return EQ; - case 1: - return GTE; - case 2: - return GT; - case 3: - return LTE; - case 4: - return LT; - case 5: - return CONTAINS; - case 6: - return CONTAINS_KEY; - default: - throw new AssertionError(); - } - } - - public boolean allowsIndexQuery() - { - switch (this) - { - case EQ: - case CONTAINS: - case CONTAINS_KEY: - return true; - default: - return false; - } - } - - @Override - public String toString() - { - switch (this) - { - case EQ: - return "="; - case LT: - return "<"; - case LTE: - return "<="; - case GT: - return ">"; - case GTE: - return ">="; - case CONTAINS_KEY: - return "CONTAINS KEY"; - default: - return this.name(); - } - } - } - /** * Checks if the operator of this <code>IndexExpression</code> is a <code>CONTAINS</code> operator. * @@ -149,4 +91,31 @@ public class IndexExpression { return Objects.hashCode(column, operator, value); } + + /** + * Write the serialized version of this <code>IndexExpression</code> to the specified output. + * + * @param output the output to write to + * @throws IOException if an I/O problem occurs while writing to the specified output + */ + public void writeTo(DataOutputPlus output) throws IOException + { + ByteBufferUtil.writeWithShortLength(column, output); + operator.writeTo(output); + ByteBufferUtil.writeWithShortLength(value, output); + } + + /** + * Deserializes an <code>IndexExpression</code> instance from the specified input. + * + * @param input the input to read from + * @return the <code>IndexExpression</code> instance deserialized + * @throws IOException if a problem occurs while deserializing the <code>IndexExpression</code> instance. + */ + public static IndexExpression readFrom(DataInput input) throws IOException + { + return new IndexExpression(ByteBufferUtil.readWithShortLength(input), + Operator.readFrom(input), + ByteBufferUtil.readWithShortLength(input)); + } } http://git-wip-us.apache.org/repos/asf/cassandra/blob/5117a5d5/src/java/org/apache/cassandra/db/PagedRangeCommand.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/PagedRangeCommand.java b/src/java/org/apache/cassandra/db/PagedRangeCommand.java index f2d81b9..614f0f7 100644 --- a/src/java/org/apache/cassandra/db/PagedRangeCommand.java +++ b/src/java/org/apache/cassandra/db/PagedRangeCommand.java @@ -31,7 +31,6 @@ import org.apache.cassandra.io.IVersionedSerializer; import org.apache.cassandra.io.util.DataOutputPlus; import org.apache.cassandra.net.MessageOut; import org.apache.cassandra.net.MessagingService; -import org.apache.cassandra.utils.ByteBufferUtil; public class PagedRangeCommand extends AbstractRangeCommand { @@ -145,9 +144,7 @@ public class PagedRangeCommand extends AbstractRangeCommand out.writeInt(cmd.rowFilter.size()); for (IndexExpression expr : cmd.rowFilter) { - ByteBufferUtil.writeWithShortLength(expr.column, out); - out.writeInt(expr.operator.ordinal()); - ByteBufferUtil.writeWithShortLength(expr.value, out); + expr.writeTo(out);; } out.writeInt(cmd.limit); @@ -174,10 +171,7 @@ public class PagedRangeCommand extends AbstractRangeCommand List<IndexExpression> rowFilter = new ArrayList<IndexExpression>(filterCount); for (int i = 0; i < filterCount; i++) { - IndexExpression expr = new IndexExpression(ByteBufferUtil.readWithShortLength(in), - IndexExpression.Operator.findByOrdinal(in.readInt()), - ByteBufferUtil.readWithShortLength(in)); - rowFilter.add(expr); + rowFilter.add(IndexExpression.readFrom(in)); } int limit = in.readInt(); http://git-wip-us.apache.org/repos/asf/cassandra/blob/5117a5d5/src/java/org/apache/cassandra/db/RangeSliceCommand.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/RangeSliceCommand.java b/src/java/org/apache/cassandra/db/RangeSliceCommand.java index 82e892c..4d2955b 100644 --- a/src/java/org/apache/cassandra/db/RangeSliceCommand.java +++ b/src/java/org/apache/cassandra/db/RangeSliceCommand.java @@ -34,7 +34,6 @@ import org.apache.cassandra.io.util.DataOutputPlus; import org.apache.cassandra.net.MessageOut; import org.apache.cassandra.net.MessagingService; import org.apache.cassandra.service.pager.Pageable; -import org.apache.cassandra.utils.ByteBufferUtil; public class RangeSliceCommand extends AbstractRangeCommand implements Pageable { @@ -170,9 +169,7 @@ class RangeSliceCommandSerializer implements IVersionedSerializer<RangeSliceComm out.writeInt(sliceCommand.rowFilter.size()); for (IndexExpression expr : sliceCommand.rowFilter) { - ByteBufferUtil.writeWithShortLength(expr.column, out); - out.writeInt(expr.operator.ordinal()); - ByteBufferUtil.writeWithShortLength(expr.value, out); + expr.writeTo(out); } } AbstractBounds.serializer.serialize(sliceCommand.keyRange, out, version); @@ -196,11 +193,7 @@ class RangeSliceCommandSerializer implements IVersionedSerializer<RangeSliceComm rowFilter = new ArrayList<>(filterCount); for (int i = 0; i < filterCount; i++) { - IndexExpression expr; - expr = new IndexExpression(ByteBufferUtil.readWithShortLength(in), - IndexExpression.Operator.findByOrdinal(in.readInt()), - ByteBufferUtil.readWithShortLength(in)); - rowFilter.add(expr); + rowFilter.add(IndexExpression.readFrom(in)); } AbstractBounds<RowPosition> range = AbstractBounds.serializer.deserialize(in, version).toRowBounds(); http://git-wip-us.apache.org/repos/asf/cassandra/blob/5117a5d5/src/java/org/apache/cassandra/db/filter/ExtendedFilter.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/filter/ExtendedFilter.java b/src/java/org/apache/cassandra/db/filter/ExtendedFilter.java index b152472..2d56bfa 100644 --- a/src/java/org/apache/cassandra/db/filter/ExtendedFilter.java +++ b/src/java/org/apache/cassandra/db/filter/ExtendedFilter.java @@ -18,15 +18,26 @@ package org.apache.cassandra.db.filter; import java.nio.ByteBuffer; -import java.util.*; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.SortedSet; +import java.util.TreeSet; import com.google.common.base.Objects; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.config.ColumnDefinition; -import org.apache.cassandra.db.*; +import org.apache.cassandra.config.DatabaseDescriptor; +import org.apache.cassandra.cql3.Operator; +import org.apache.cassandra.db.Cell; +import org.apache.cassandra.db.ColumnFamily; +import org.apache.cassandra.db.ColumnFamilyStore; +import org.apache.cassandra.db.DataRange; +import org.apache.cassandra.db.DecoratedKey; +import org.apache.cassandra.db.IndexExpression; import org.apache.cassandra.db.composites.CellName; import org.apache.cassandra.db.composites.Composite; import org.apache.cassandra.db.marshal.AbstractType; @@ -130,7 +141,7 @@ public abstract class ExtendedFilter */ public abstract boolean isSatisfiedBy(DecoratedKey rowKey, ColumnFamily data, Composite prefix, ByteBuffer collectionElement); - public static boolean satisfies(int comparison, IndexExpression.Operator op) + public static boolean satisfies(int comparison, Operator op) { switch (op) { @@ -339,7 +350,7 @@ public abstract class ExtendedFilter assert def.type.isCollection(); CollectionType type = (CollectionType)def.type; - if (expr.operator == IndexExpression.Operator.CONTAINS) + if (expr.isContains()) { // get a slice of the collection cells Iterator<Cell> iter = data.iterator(new ColumnSlice[]{ data.getComparator().create(prefix, def).slice() }); @@ -369,15 +380,13 @@ public abstract class ExtendedFilter case SET: return data.getColumn(data.getComparator().create(prefix, def, expr.value)) != null; case MAP: - if (expr.operator == IndexExpression.Operator.CONTAINS_KEY) + if (expr.isContainsKey()) { return data.getColumn(data.getComparator().create(prefix, def, expr.value)) != null; } - else - { - assert collectionElement != null; - return type.valueComparator().compare(data.getColumn(data.getComparator().create(prefix, def, collectionElement)).value(), expr.value) == 0; - } + + assert collectionElement != null; + return type.valueComparator().compare(data.getColumn(data.getComparator().create(prefix, def, collectionElement)).value(), expr.value) == 0; } throw new AssertionError(); } http://git-wip-us.apache.org/repos/asf/cassandra/blob/5117a5d5/src/java/org/apache/cassandra/db/index/SecondaryIndex.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/index/SecondaryIndex.java b/src/java/org/apache/cassandra/db/index/SecondaryIndex.java index e3ed73c..e2bafaa 100644 --- a/src/java/org/apache/cassandra/db/index/SecondaryIndex.java +++ b/src/java/org/apache/cassandra/db/index/SecondaryIndex.java @@ -27,19 +27,18 @@ import java.util.concurrent.Future; import java.util.concurrent.FutureTask; import org.apache.commons.lang3.StringUtils; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.config.ColumnDefinition; - +import org.apache.cassandra.cql3.Operator; import org.apache.cassandra.db.BufferDecoratedKey; import org.apache.cassandra.db.Cell; import org.apache.cassandra.db.ColumnFamilyStore; import org.apache.cassandra.db.DecoratedKey; -import org.apache.cassandra.db.IndexExpression; import org.apache.cassandra.db.SystemKeyspace; - import org.apache.cassandra.db.compaction.CompactionManager; import org.apache.cassandra.db.composites.CellName; import org.apache.cassandra.db.composites.CellNameType; @@ -48,7 +47,6 @@ import org.apache.cassandra.db.index.composites.CompositesIndex; import org.apache.cassandra.db.index.keys.KeysIndex; import org.apache.cassandra.db.marshal.AbstractType; import org.apache.cassandra.db.marshal.BytesType; -import org.apache.cassandra.db.marshal.CollectionType; import org.apache.cassandra.db.marshal.LocalByPartionerType; import org.apache.cassandra.dht.LocalToken; import org.apache.cassandra.exceptions.ConfigurationException; @@ -57,8 +55,6 @@ import org.apache.cassandra.io.sstable.SSTableReader; import org.apache.cassandra.service.StorageService; import org.apache.cassandra.utils.FBUtilities; -import com.google.common.collect.Iterables; - /** * Abstract base class for different types of secondary indexes. * @@ -297,9 +293,9 @@ public abstract class SecondaryIndex } /** Returns true if the index supports lookups for the given operator, false otherwise. */ - public boolean supportsOperator(IndexExpression.Operator operator) + public boolean supportsOperator(Operator operator) { - return operator == IndexExpression.Operator.EQ; + return operator == Operator.EQ; } /** http://git-wip-us.apache.org/repos/asf/cassandra/blob/5117a5d5/src/java/org/apache/cassandra/db/index/composites/CompositesIndexOnCollectionKey.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/index/composites/CompositesIndexOnCollectionKey.java b/src/java/org/apache/cassandra/db/index/composites/CompositesIndexOnCollectionKey.java index 1067a94..81982bb 100644 --- a/src/java/org/apache/cassandra/db/index/composites/CompositesIndexOnCollectionKey.java +++ b/src/java/org/apache/cassandra/db/index/composites/CompositesIndexOnCollectionKey.java @@ -23,6 +23,7 @@ import java.util.List; import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.config.ColumnDefinition; +import org.apache.cassandra.cql3.Operator; import org.apache.cassandra.db.*; import org.apache.cassandra.db.composites.CBuilder; import org.apache.cassandra.db.composites.CellName; @@ -89,10 +90,10 @@ public class CompositesIndexOnCollectionKey extends CompositesIndex } @Override - public boolean supportsOperator(IndexExpression.Operator operator) + public boolean supportsOperator(Operator operator) { - return operator == IndexExpression.Operator.CONTAINS_KEY || - operator == IndexExpression.Operator.CONTAINS && columnDef.type instanceof SetType; + return operator == Operator.CONTAINS_KEY || + operator == Operator.CONTAINS && columnDef.type instanceof SetType; } @Override http://git-wip-us.apache.org/repos/asf/cassandra/blob/5117a5d5/src/java/org/apache/cassandra/db/index/composites/CompositesIndexOnCollectionValue.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/index/composites/CompositesIndexOnCollectionValue.java b/src/java/org/apache/cassandra/db/index/composites/CompositesIndexOnCollectionValue.java index 5b4aa64..e69e656 100644 --- a/src/java/org/apache/cassandra/db/index/composites/CompositesIndexOnCollectionValue.java +++ b/src/java/org/apache/cassandra/db/index/composites/CompositesIndexOnCollectionValue.java @@ -23,6 +23,7 @@ import java.util.List; import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.config.ColumnDefinition; +import org.apache.cassandra.cql3.Operator; import org.apache.cassandra.db.*; import org.apache.cassandra.db.composites.CBuilder; import org.apache.cassandra.db.composites.CellName; @@ -95,9 +96,9 @@ public class CompositesIndexOnCollectionValue extends CompositesIndex } @Override - public boolean supportsOperator(IndexExpression.Operator operator) + public boolean supportsOperator(Operator operator) { - return operator == IndexExpression.Operator.CONTAINS; + return operator == Operator.CONTAINS; } @Override http://git-wip-us.apache.org/repos/asf/cassandra/blob/5117a5d5/src/java/org/apache/cassandra/db/marshal/CompositeType.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/marshal/CompositeType.java b/src/java/org/apache/cassandra/db/marshal/CompositeType.java index 1115dff..9ee9fb3 100644 --- a/src/java/org/apache/cassandra/db/marshal/CompositeType.java +++ b/src/java/org/apache/cassandra/db/marshal/CompositeType.java @@ -30,7 +30,7 @@ import com.google.common.collect.ImmutableList; import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.exceptions.SyntaxException; import org.apache.cassandra.cql3.ColumnIdentifier; -import org.apache.cassandra.cql3.Relation; +import org.apache.cassandra.cql3.Operator; import org.apache.cassandra.io.util.DataOutputBuffer; import org.apache.cassandra.serializers.MarshalException; import org.apache.cassandra.utils.ByteBufferUtil; @@ -430,7 +430,7 @@ public class CompositeType extends AbstractCompositeType return bb; } - public ByteBuffer buildForRelation(Relation.Type op) + public ByteBuffer buildForRelation(Operator op) { /* * Given the rules for eoc (end-of-component, see AbstractCompositeType.compare()), http://git-wip-us.apache.org/repos/asf/cassandra/blob/5117a5d5/src/java/org/apache/cassandra/thrift/ThriftConversion.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/thrift/ThriftConversion.java b/src/java/org/apache/cassandra/thrift/ThriftConversion.java index 0c75d2c..2aca45a 100644 --- a/src/java/org/apache/cassandra/thrift/ThriftConversion.java +++ b/src/java/org/apache/cassandra/thrift/ThriftConversion.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import org.apache.cassandra.cql3.Operator; import org.apache.cassandra.db.WriteType; import org.apache.cassandra.exceptions.RequestExecutionException; import org.apache.cassandra.exceptions.RequestTimeoutException; @@ -124,7 +125,7 @@ public class ThriftConversion for (IndexExpression expr : exprs) { converted.add(new org.apache.cassandra.db.IndexExpression(expr.column_name, - org.apache.cassandra.db.IndexExpression.Operator.findByOrdinal(expr.op.getValue()), + Operator.valueOf(expr.op.name()), expr.value)); } return converted;