You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by bl...@apache.org on 2017/01/27 14:51:44 UTC
[7/7] cassandra git commit: Refactor ColumnCondition
Refactor ColumnCondition
patch by Benjamin Lerer; reviewed by Alex Petrov for CASSANDRA-12981
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/e71a49e8
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/e71a49e8
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/e71a49e8
Branch: refs/heads/trunk
Commit: e71a49e81f97864641f406461425a74ca4c56df1
Parents: 36375f9
Author: Benjamin Lerer <b....@gmail.com>
Authored: Fri Jan 27 15:50:06 2017 +0100
Committer: Benjamin Lerer <b....@gmail.com>
Committed: Fri Jan 27 15:50:06 2017 +0100
----------------------------------------------------------------------
CHANGES.txt | 4 +-
src/antlr/Cql.g | 1 +
.../cassandra/cql3/AbstractConditions.java | 64 --
.../apache/cassandra/cql3/AbstractMarker.java | 4 +-
.../apache/cassandra/cql3/ColumnCondition.java | 1042 ------------------
.../apache/cassandra/cql3/ColumnConditions.java | 164 ---
.../org/apache/cassandra/cql3/Conditions.java | 102 --
.../cassandra/cql3/IfExistsCondition.java | 36 -
.../cassandra/cql3/IfNotExistsCondition.java | 36 -
.../org/apache/cassandra/cql3/Operator.java | 180 ++-
src/java/org/apache/cassandra/cql3/Terms.java | 241 +++-
.../cql3/conditions/AbstractConditions.java | 64 ++
.../cql3/conditions/ColumnCondition.java | 825 ++++++++++++++
.../cql3/conditions/ColumnConditions.java | 165 +++
.../cassandra/cql3/conditions/Conditions.java | 103 ++
.../cql3/conditions/IfExistsCondition.java | 37 +
.../cql3/conditions/IfNotExistsCondition.java | 37 +
.../cql3/statements/CQL3CasRequest.java | 1 +
.../cql3/statements/DeleteStatement.java | 2 +
.../cql3/statements/ModificationStatement.java | 3 +
.../cql3/statements/UpdateStatement.java | 2 +
.../cassandra/cql3/ColumnConditionTest.java | 589 ----------
.../cql3/conditions/ColumnConditionTest.java | 557 ++++++++++
.../operations/InsertUpdateIfConditionTest.java | 192 +++-
24 files changed, 2356 insertions(+), 2095 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/e71a49e8/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index ee2196d..d113645 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,5 +1,6 @@
4.0
- * Parallelize streaming of different keyspaces (4663)
+ * Refactor ColumnCondition (CASSANDRA-12981)
+ * Parallelize streaming of different keyspaces (CASSANDRA-4663)
* Improved compactions metrics (CASSANDRA-13015)
* Speed-up start-up sequence by avoiding un-needed flushes (CASSANDRA-13031)
* Use Caffeine (W-TinyLFU) for on-heap caches (CASSANDRA-10855)
@@ -216,6 +217,7 @@ Merged from 3.0:
* Correct log message for statistics of offheap memtable flush (CASSANDRA-12776)
* Explicitly set locale for string validation (CASSANDRA-12541,CASSANDRA-12542,CASSANDRA-12543,CASSANDRA-12545)
Merged from 2.2:
+ * Fix handling of nulls and unsets in IN conditions (CASSANDRA-12981)
* Fix race causing infinite loop if Thrift server is stopped before it starts listening (CASSANDRA-12856)
* CompactionTasks now correctly drops sstables out of compaction when not enough disk space is available (CASSANDRA-12979)
* Fix DynamicEndpointSnitch noop in multi-datacenter situations (CASSANDRA-13074)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/e71a49e8/src/antlr/Cql.g
----------------------------------------------------------------------
diff --git a/src/antlr/Cql.g b/src/antlr/Cql.g
index a11f2fd..8b26426 100644
--- a/src/antlr/Cql.g
+++ b/src/antlr/Cql.g
@@ -46,6 +46,7 @@ import Parser,Lexer;
import org.apache.cassandra.cql3.statements.*;
import org.apache.cassandra.cql3.selection.*;
import org.apache.cassandra.cql3.functions.*;
+ import org.apache.cassandra.cql3.conditions.*;
import org.apache.cassandra.db.marshal.CollectionType;
import org.apache.cassandra.exceptions.ConfigurationException;
import org.apache.cassandra.exceptions.InvalidRequestException;
http://git-wip-us.apache.org/repos/asf/cassandra/blob/e71a49e8/src/java/org/apache/cassandra/cql3/AbstractConditions.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/AbstractConditions.java b/src/java/org/apache/cassandra/cql3/AbstractConditions.java
deleted file mode 100644
index 530d2b1..0000000
--- a/src/java/org/apache/cassandra/cql3/AbstractConditions.java
+++ /dev/null
@@ -1,64 +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;
-
-import java.util.List;
-
-import org.apache.cassandra.config.ColumnDefinition;
-import org.apache.cassandra.cql3.functions.Function;
-
-/**
- * Base class for <code>Conditions</code> classes.
- *
- */
-abstract class AbstractConditions implements Conditions
-{
- public void addFunctionsTo(List<Function> functions)
- {
- }
-
- public Iterable<ColumnDefinition> getColumns()
- {
- return null;
- }
-
- public boolean isEmpty()
- {
- return false;
- }
-
- public boolean appliesToStaticColumns()
- {
- return false;
- }
-
- public boolean appliesToRegularColumns()
- {
- return false;
- }
-
- public boolean isIfExists()
- {
- return false;
- }
-
- public boolean isIfNotExists()
- {
- return false;
- }
-}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/e71a49e8/src/java/org/apache/cassandra/cql3/AbstractMarker.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/AbstractMarker.java b/src/java/org/apache/cassandra/cql3/AbstractMarker.java
index 7ffedef..19ce26c 100644
--- a/src/java/org/apache/cassandra/cql3/AbstractMarker.java
+++ b/src/java/org/apache/cassandra/cql3/AbstractMarker.java
@@ -140,7 +140,7 @@ public abstract class AbstractMarker extends Term.NonTerminal
*
* Because a single type is used, a List is used to represent the values.
*/
- public static class INRaw extends Raw
+ public static final class INRaw extends Raw
{
public INRaw(int bindIndex)
{
@@ -154,7 +154,7 @@ public abstract class AbstractMarker extends Term.NonTerminal
}
@Override
- public AbstractMarker prepare(String keyspace, ColumnSpecification receiver) throws InvalidRequestException
+ public Lists.Marker prepare(String keyspace, ColumnSpecification receiver) throws InvalidRequestException
{
return new Lists.Marker(bindIndex, makeInReceiver(receiver));
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/e71a49e8/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
deleted file mode 100644
index 07f9f60..0000000
--- a/src/java/org/apache/cassandra/cql3/ColumnCondition.java
+++ /dev/null
@@ -1,1042 +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;
-
-import java.nio.ByteBuffer;
-import java.util.*;
-
-import com.google.common.collect.Iterators;
-
-import org.apache.cassandra.config.CFMetaData;
-import org.apache.cassandra.config.ColumnDefinition;
-import org.apache.cassandra.cql3.functions.Function;
-import org.apache.cassandra.db.rows.*;
-import org.apache.cassandra.db.marshal.*;
-import org.apache.cassandra.exceptions.InvalidRequestException;
-import org.apache.cassandra.transport.ProtocolVersion;
-import org.apache.cassandra.utils.ByteBufferUtil;
-
-/**
- * A CQL3 condition on the value of a column or collection element. For example, "UPDATE .. IF a = 0".
- */
-public class ColumnCondition
-{
- public final ColumnDefinition column;
-
- // For collection, when testing the equality of a specific element, null otherwise.
- private final Term collectionElement;
-
- // For UDT, when testing the equality of a specific field, null otherwise.
- private final FieldIdentifier field;
-
- private final Term value; // a single value or a marker for a list of IN values
- private final List<Term> inValues;
-
- public final Operator operator;
-
- private ColumnCondition(ColumnDefinition column, Term collectionElement, FieldIdentifier field, Term value, List<Term> inValues, Operator op)
- {
- this.column = column;
- this.collectionElement = collectionElement;
- this.field = field;
- this.value = value;
- this.inValues = inValues;
- this.operator = op;
-
- assert field == null || collectionElement == null;
- if (operator != Operator.IN)
- assert this.inValues == null;
- }
-
- public static ColumnCondition condition(ColumnDefinition column, Term value, Operator op)
- {
- return new ColumnCondition(column, null, null, value, null, op);
- }
-
- public static ColumnCondition condition(ColumnDefinition column, Term collectionElement, Term value, Operator op)
- {
- return new ColumnCondition(column, collectionElement, null, value, null, op);
- }
-
- public static ColumnCondition condition(ColumnDefinition column, FieldIdentifier udtField, Term value, Operator op)
- {
- return new ColumnCondition(column, null, udtField, value, null, op);
- }
-
- public static ColumnCondition inCondition(ColumnDefinition column, List<Term> inValues)
- {
- return new ColumnCondition(column, null, null, null, inValues, Operator.IN);
- }
-
- public static ColumnCondition inCondition(ColumnDefinition column, Term collectionElement, List<Term> inValues)
- {
- return new ColumnCondition(column, collectionElement, null, null, inValues, Operator.IN);
- }
-
- public static ColumnCondition inCondition(ColumnDefinition column, FieldIdentifier udtField, List<Term> inValues)
- {
- return new ColumnCondition(column, null, udtField, null, inValues, Operator.IN);
- }
-
- public static ColumnCondition inCondition(ColumnDefinition column, Term inMarker)
- {
- return new ColumnCondition(column, null, null, inMarker, null, Operator.IN);
- }
-
- public static ColumnCondition inCondition(ColumnDefinition column, Term collectionElement, Term inMarker)
- {
- return new ColumnCondition(column, collectionElement, null, inMarker, null, Operator.IN);
- }
-
- public static ColumnCondition inCondition(ColumnDefinition column, FieldIdentifier udtField, Term inMarker)
- {
- return new ColumnCondition(column, null, udtField, inMarker, null, Operator.IN);
- }
-
- public void addFunctionsTo(List<Function> functions)
- {
- if (collectionElement != null)
- collectionElement.addFunctionsTo(functions);
- if (value != null)
- value.addFunctionsTo(functions);
- if (inValues != null)
- for (Term value : inValues)
- if (value != null)
- value.addFunctionsTo(functions);
- }
-
- /**
- * Collects the column specification for the bind variables of this operation.
- *
- * @param boundNames the list of column specification where to collect the
- * bind variables of this term in.
- */
- public void collectMarkerSpecification(VariableSpecifications boundNames)
- {
- if (collectionElement != null)
- collectionElement.collectMarkerSpecification(boundNames);
-
- if ((operator == Operator.IN) && inValues != null)
- {
- for (Term value : inValues)
- value.collectMarkerSpecification(boundNames);
- }
- else
- {
- value.collectMarkerSpecification(boundNames);
- }
- }
-
- public ColumnCondition.Bound bind(QueryOptions options) throws InvalidRequestException
- {
- boolean isInCondition = operator == Operator.IN;
- if (column.type instanceof CollectionType)
- {
- if (collectionElement != null)
- return isInCondition ? new ElementAccessInBound(this, options) : new ElementAccessBound(this, options);
- else
- return isInCondition ? new CollectionInBound(this, options) : new CollectionBound(this, options);
- }
- else if (column.type.isUDT())
- {
- if (field != null)
- return isInCondition ? new UDTFieldAccessInBound(this, options) : new UDTFieldAccessBound(this, options);
- else
- return isInCondition ? new UDTInBound(this, options) : new UDTBound(this, options);
- }
-
- return isInCondition ? new SimpleInBound(this, options) : new SimpleBound(this, options);
- }
-
- public static abstract class Bound
- {
- public final ColumnDefinition column;
- public final Operator operator;
-
- protected Bound(ColumnDefinition column, Operator operator)
- {
- this.column = column;
- this.operator = operator;
- }
-
- /**
- * Validates whether this condition applies to {@code current}.
- */
- public abstract boolean appliesTo(Row row) throws InvalidRequestException;
-
- public ByteBuffer getCollectionElementValue()
- {
- return null;
- }
-
- protected boolean isSatisfiedByValue(ByteBuffer value, Cell c, AbstractType<?> type, Operator operator) throws InvalidRequestException
- {
- return compareWithOperator(operator, type, value, c == null ? null : c.value());
- }
-
- /** Returns true if the operator is satisfied (i.e. "otherValue operator value == true"), false otherwise. */
- protected boolean compareWithOperator(Operator operator, AbstractType<?> type, ByteBuffer value, ByteBuffer otherValue) throws InvalidRequestException
- {
- if (value == ByteBufferUtil.UNSET_BYTE_BUFFER)
- throw new InvalidRequestException("Invalid 'unset' value in condition");
- if (value == null)
- {
- switch (operator)
- {
- case EQ:
- return otherValue == null;
- case NEQ:
- return otherValue != null;
- default:
- throw new InvalidRequestException(String.format("Invalid comparison with null for operator \"%s\"", operator));
- }
- }
- else if (otherValue == null)
- {
- // the condition value is not null, so only NEQ can return true
- return operator == Operator.NEQ;
- }
- return operator.isSatisfiedBy(type, otherValue, value);
- }
- }
-
- private static Cell getCell(Row row, ColumnDefinition column)
- {
- // If we're asking for a given cell, and we didn't got any row from our read, it's
- // the same as not having said cell.
- return row == null ? null : row.getCell(column);
- }
-
- private static Cell getCell(Row row, ColumnDefinition column, CellPath path)
- {
- // If we're asking for a given cell, and we didn't got any row from our read, it's
- // the same as not having said cell.
- return row == null ? null : row.getCell(column, path);
- }
-
- private static Iterator<Cell> getCells(Row row, ColumnDefinition column)
- {
- // If we're asking for a complex cells, and we didn't got any row from our read, it's
- // the same as not having any cells for that column.
- if (row == null)
- return Collections.<Cell>emptyIterator();
-
- ComplexColumnData complexData = row.getComplexColumnData(column);
- return complexData == null ? Collections.<Cell>emptyIterator() : complexData.iterator();
- }
-
- private static boolean evaluateComparisonWithOperator(int comparison, Operator operator)
- {
- // called when comparison != 0
- switch (operator)
- {
- case EQ:
- return false;
- case LT:
- case LTE:
- return comparison < 0;
- case GT:
- case GTE:
- return comparison > 0;
- case NEQ:
- return true;
- default:
- throw new AssertionError();
- }
- }
-
- private static ByteBuffer cellValueAtIndex(Iterator<Cell> iter, int index)
- {
- int adv = Iterators.advance(iter, index);
- if (adv == index && iter.hasNext())
- return iter.next().value();
- else
- return null;
- }
-
- /**
- * A condition on a single non-collection column. This does not support IN operators (see SimpleInBound).
- */
- static class SimpleBound extends Bound
- {
- public final ByteBuffer value;
-
- private SimpleBound(ColumnCondition condition, QueryOptions options) throws InvalidRequestException
- {
- super(condition.column, condition.operator);
- assert !(column.type instanceof CollectionType) && condition.field == null;
- assert condition.operator != Operator.IN;
- this.value = condition.value.bindAndGet(options);
- }
-
- public boolean appliesTo(Row row) throws InvalidRequestException
- {
- return isSatisfiedByValue(value, getCell(row, column), column.type, operator);
- }
- }
-
- /**
- * An IN condition on a single non-collection column.
- */
- static class SimpleInBound extends Bound
- {
- public final List<ByteBuffer> inValues;
-
- private SimpleInBound(ColumnCondition condition, QueryOptions options) throws InvalidRequestException
- {
- super(condition.column, condition.operator);
- assert !(column.type instanceof CollectionType) && condition.field == null;
- assert condition.operator == Operator.IN;
- if (condition.inValues == null)
- this.inValues = ((Lists.Value) condition.value.bind(options)).getElements();
- else
- {
- this.inValues = new ArrayList<>(condition.inValues.size());
- for (Term value : condition.inValues)
- this.inValues.add(value.bindAndGet(options));
- }
- }
-
- public boolean appliesTo(Row row) throws InvalidRequestException
- {
- Cell c = getCell(row, column);
- for (ByteBuffer value : inValues)
- {
- if (isSatisfiedByValue(value, c, column.type, Operator.EQ))
- return true;
- }
- return false;
- }
- }
-
- /** A condition on an element of a collection column. IN operators are not supported here, see ElementAccessInBound. */
- static class ElementAccessBound extends Bound
- {
- public final ByteBuffer collectionElement;
- public final ByteBuffer value;
-
- private ElementAccessBound(ColumnCondition condition, QueryOptions options) throws InvalidRequestException
- {
- super(condition.column, condition.operator);
- assert column.type instanceof CollectionType && condition.collectionElement != null;
- assert condition.operator != Operator.IN;
- this.collectionElement = condition.collectionElement.bindAndGet(options);
- this.value = condition.value.bindAndGet(options);
- }
-
- public boolean appliesTo(Row row) throws InvalidRequestException
- {
- if (collectionElement == null)
- throw new InvalidRequestException("Invalid null value for " + (column.type instanceof MapType ? "map" : "list") + " element access");
-
- if (column.type instanceof MapType)
- {
- MapType mapType = (MapType) column.type;
- if (column.type.isMultiCell())
- {
- Cell cell = getCell(row, column, CellPath.create(collectionElement));
- return isSatisfiedByValue(value, cell, ((MapType) column.type).getValuesType(), operator);
- }
- else
- {
- Cell cell = getCell(row, column);
- ByteBuffer mapElementValue = mapType.getSerializer().getSerializedValue(cell.value(), collectionElement, mapType.getKeysType());
- return compareWithOperator(operator, mapType.getValuesType(), value, mapElementValue);
- }
- }
-
- // sets don't have element access, so it's a list
- ListType listType = (ListType) column.type;
- if (column.type.isMultiCell())
- {
- ByteBuffer columnValue = cellValueAtIndex(getCells(row, column), getListIndex(collectionElement));
- return compareWithOperator(operator, ((ListType)column.type).getElementsType(), value, columnValue);
- }
- else
- {
- Cell cell = getCell(row, column);
- ByteBuffer listElementValue = listType.getSerializer().getElement(cell.value(), getListIndex(collectionElement));
- return compareWithOperator(operator, listType.getElementsType(), value, listElementValue);
- }
- }
-
- static int getListIndex(ByteBuffer collectionElement) throws InvalidRequestException
- {
- int idx = ByteBufferUtil.toInt(collectionElement);
- if (idx < 0)
- throw new InvalidRequestException(String.format("Invalid negative list index %d", idx));
- return idx;
- }
-
- public ByteBuffer getCollectionElementValue()
- {
- return collectionElement;
- }
- }
-
- static class ElementAccessInBound extends Bound
- {
- public final ByteBuffer collectionElement;
- public final List<ByteBuffer> inValues;
-
- private ElementAccessInBound(ColumnCondition condition, QueryOptions options) throws InvalidRequestException
- {
- super(condition.column, condition.operator);
- assert column.type instanceof CollectionType && condition.collectionElement != null;
- this.collectionElement = condition.collectionElement.bindAndGet(options);
-
- if (condition.inValues == null)
- this.inValues = ((Lists.Value) condition.value.bind(options)).getElements();
- else
- {
- this.inValues = new ArrayList<>(condition.inValues.size());
- for (Term value : condition.inValues)
- this.inValues.add(value.bindAndGet(options));
- }
- }
-
- public boolean appliesTo(Row row) throws InvalidRequestException
- {
- if (collectionElement == null)
- throw new InvalidRequestException("Invalid null value for " + (column.type instanceof MapType ? "map" : "list") + " element access");
-
- ByteBuffer cellValue;
- AbstractType<?> valueType;
- if (column.type instanceof MapType)
- {
- MapType mapType = (MapType) column.type;
- valueType = mapType.getValuesType();
- if (column.type.isMultiCell())
- {
- Cell cell = getCell(row, column, CellPath.create(collectionElement));
- cellValue = cell == null ? null : cell.value();
- }
- else
- {
- Cell cell = getCell(row, column);
- cellValue = cell == null
- ? null
- : mapType.getSerializer().getSerializedValue(cell.value(), collectionElement, mapType.getKeysType());
- }
- }
- else // ListType
- {
- ListType listType = (ListType) column.type;
- valueType = listType.getElementsType();
- if (column.type.isMultiCell())
- {
- cellValue = cellValueAtIndex(getCells(row, column), ElementAccessBound.getListIndex(collectionElement));
- }
- else
- {
- Cell cell = getCell(row, column);
- cellValue = cell == null
- ? null
- : listType.getSerializer().getElement(cell.value(), ElementAccessBound.getListIndex(collectionElement));
- }
- }
-
- for (ByteBuffer value : inValues)
- {
- if (compareWithOperator(Operator.EQ, valueType, value, cellValue))
- return true;
- }
- return false;
- }
- }
-
- /** A condition on an entire collection column. IN operators are not supported here, see CollectionInBound. */
- static class CollectionBound extends Bound
- {
- private final Term.Terminal value;
-
- private CollectionBound(ColumnCondition condition, QueryOptions options) throws InvalidRequestException
- {
- super(condition.column, condition.operator);
- assert column.type.isCollection() && condition.collectionElement == null;
- assert condition.operator != Operator.IN;
- this.value = condition.value.bind(options);
- }
-
- public boolean appliesTo(Row row) throws InvalidRequestException
- {
- CollectionType type = (CollectionType)column.type;
-
- if (type.isMultiCell())
- {
- Iterator<Cell> iter = getCells(row, column);
- if (value == null)
- {
- if (operator == Operator.EQ)
- return !iter.hasNext();
- else if (operator == Operator.NEQ)
- return iter.hasNext();
- else
- throw new InvalidRequestException(String.format("Invalid comparison with null for operator \"%s\"", operator));
- }
-
- return valueAppliesTo(type, iter, value, operator);
- }
-
- // frozen collections
- Cell cell = getCell(row, column);
- if (value == null)
- {
- if (operator == Operator.EQ)
- return cell == null;
- else if (operator == Operator.NEQ)
- return cell != null;
- else
- throw new InvalidRequestException(String.format("Invalid comparison with null for operator \"%s\"", operator));
- }
-
- // make sure we use v3 serialization format for comparison
- ByteBuffer conditionValue;
- if (type.kind == CollectionType.Kind.LIST)
- conditionValue = ((Lists.Value) value).get(ProtocolVersion.V3);
- else if (type.kind == CollectionType.Kind.SET)
- conditionValue = ((Sets.Value) value).get(ProtocolVersion.V3);
- else
- conditionValue = ((Maps.Value) value).get(ProtocolVersion.V3);
-
- return compareWithOperator(operator, type, conditionValue, cell.value());
- }
-
- static boolean valueAppliesTo(CollectionType type, Iterator<Cell> iter, Term.Terminal value, Operator operator)
- {
- if (value == null)
- return !iter.hasNext();
-
- switch (type.kind)
- {
- case LIST:
- List<ByteBuffer> valueList = ((Lists.Value) value).elements;
- return listAppliesTo((ListType)type, iter, valueList, operator);
- case SET:
- Set<ByteBuffer> valueSet = ((Sets.Value) value).elements;
- return setAppliesTo((SetType)type, iter, valueSet, operator);
- case MAP:
- Map<ByteBuffer, ByteBuffer> valueMap = ((Maps.Value) value).map;
- return mapAppliesTo((MapType)type, iter, valueMap, operator);
- }
- throw new AssertionError();
- }
-
- private static boolean setOrListAppliesTo(AbstractType<?> type, Iterator<Cell> iter, Iterator<ByteBuffer> conditionIter, Operator operator, boolean isSet)
- {
- while(iter.hasNext())
- {
- if (!conditionIter.hasNext())
- return (operator == Operator.GT) || (operator == Operator.GTE) || (operator == Operator.NEQ);
-
- // for lists we use the cell value; for sets we use the cell name
- ByteBuffer cellValue = isSet ? iter.next().path().get(0) : iter.next().value();
- int comparison = type.compare(cellValue, conditionIter.next());
- if (comparison != 0)
- return evaluateComparisonWithOperator(comparison, operator);
- }
-
- if (conditionIter.hasNext())
- return (operator == Operator.LT) || (operator == Operator.LTE) || (operator == Operator.NEQ);
-
- // they're equal
- return operator == Operator.EQ || operator == Operator.LTE || operator == Operator.GTE;
- }
-
- static boolean listAppliesTo(ListType type, Iterator<Cell> iter, List<ByteBuffer> elements, Operator operator)
- {
- return setOrListAppliesTo(type.getElementsType(), iter, elements.iterator(), operator, false);
- }
-
- static boolean setAppliesTo(SetType type, Iterator<Cell> iter, Set<ByteBuffer> elements, Operator operator)
- {
- ArrayList<ByteBuffer> sortedElements = new ArrayList<>(elements.size());
- sortedElements.addAll(elements);
- Collections.sort(sortedElements, type.getElementsType());
- return setOrListAppliesTo(type.getElementsType(), iter, sortedElements.iterator(), operator, true);
- }
-
- 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 == Operator.GT) || (operator == Operator.GTE) || (operator == Operator.NEQ);
-
- Map.Entry<ByteBuffer, ByteBuffer> conditionEntry = conditionIter.next();
- Cell c = iter.next();
-
- // compare the keys
- int comparison = type.getKeysType().compare(c.path().get(0), conditionEntry.getKey());
- if (comparison != 0)
- return evaluateComparisonWithOperator(comparison, operator);
-
- // compare the values
- comparison = type.getValuesType().compare(c.value(), conditionEntry.getValue());
- if (comparison != 0)
- return evaluateComparisonWithOperator(comparison, operator);
- }
-
- if (conditionIter.hasNext())
- return (operator == Operator.LT) || (operator == Operator.LTE) || (operator == Operator.NEQ);
-
- // they're equal
- return operator == Operator.EQ || operator == Operator.LTE || operator == Operator.GTE;
- }
- }
-
- public static class CollectionInBound extends Bound
- {
- private final List<Term.Terminal> inValues;
-
- private CollectionInBound(ColumnCondition condition, QueryOptions options) throws InvalidRequestException
- {
- super(condition.column, condition.operator);
- assert column.type instanceof CollectionType && condition.collectionElement == null;
- assert condition.operator == Operator.IN;
- inValues = new ArrayList<>();
- if (condition.inValues == null)
- {
- // We have a list of serialized collections that need to be deserialized for later comparisons
- CollectionType collectionType = (CollectionType) column.type;
- Lists.Marker inValuesMarker = (Lists.Marker) condition.value;
- if (column.type instanceof ListType)
- {
- ListType deserializer = ListType.getInstance(collectionType.valueComparator(), false);
- for (ByteBuffer buffer : ((Lists.Value)inValuesMarker.bind(options)).elements)
- {
- if (buffer == null)
- this.inValues.add(null);
- else
- this.inValues.add(Lists.Value.fromSerialized(buffer, deserializer, options.getProtocolVersion()));
- }
- }
- else if (column.type instanceof MapType)
- {
- MapType deserializer = MapType.getInstance(collectionType.nameComparator(), collectionType.valueComparator(), false);
- for (ByteBuffer buffer : ((Lists.Value)inValuesMarker.bind(options)).elements)
- {
- if (buffer == null)
- this.inValues.add(null);
- else
- this.inValues.add(Maps.Value.fromSerialized(buffer, deserializer, options.getProtocolVersion()));
- }
- }
- else if (column.type instanceof SetType)
- {
- SetType deserializer = SetType.getInstance(collectionType.valueComparator(), false);
- for (ByteBuffer buffer : ((Lists.Value)inValuesMarker.bind(options)).elements)
- {
- if (buffer == null)
- this.inValues.add(null);
- else
- this.inValues.add(Sets.Value.fromSerialized(buffer, deserializer, options.getProtocolVersion()));
- }
- }
- }
- else
- {
- for (Term value : condition.inValues)
- this.inValues.add(value.bind(options));
- }
- }
-
- public boolean appliesTo(Row row) throws InvalidRequestException
- {
- CollectionType type = (CollectionType)column.type;
- if (type.isMultiCell())
- {
- // copy iterator contents so that we can properly reuse them for each comparison with an IN value
- for (Term.Terminal value : inValues)
- {
- if (CollectionBound.valueAppliesTo(type, getCells(row, column), value, Operator.EQ))
- return true;
- }
- return false;
- }
- else
- {
- Cell cell = getCell(row, column);
- for (Term.Terminal value : inValues)
- {
- if (value == null)
- {
- if (cell == null)
- return true;
- }
- else if (type.compare(value.get(ProtocolVersion.V3), cell.value()) == 0)
- {
- return true;
- }
- }
- return false;
- }
- }
- }
-
- /** A condition on a UDT field. IN operators are not supported here, see UDTFieldAccessInBound. */
- static class UDTFieldAccessBound extends Bound
- {
- public final FieldIdentifier field;
- public final ByteBuffer value;
-
- private UDTFieldAccessBound(ColumnCondition condition, QueryOptions options) throws InvalidRequestException
- {
- super(condition.column, condition.operator);
- assert column.type.isUDT() && condition.field != null;
- assert condition.operator != Operator.IN;
- this.field = condition.field;
- this.value = condition.value.bindAndGet(options);
- }
-
- public boolean appliesTo(Row row) throws InvalidRequestException
- {
- UserType userType = (UserType) column.type;
- int fieldPosition = userType.fieldPosition(field);
- assert fieldPosition >= 0;
-
- ByteBuffer cellValue;
- if (column.type.isMultiCell())
- {
- Cell cell = getCell(row, column, userType.cellPathForField(field));
- cellValue = cell == null ? null : cell.value();
- }
- else
- {
- Cell cell = getCell(row, column);
- cellValue = cell == null
- ? null
- : userType.split(cell.value())[fieldPosition];
- }
- return compareWithOperator(operator, userType.fieldType(fieldPosition), value, cellValue);
- }
- }
-
- /** An IN condition on a UDT field. For example: IF user.name IN ('a', 'b') */
- static class UDTFieldAccessInBound extends Bound
- {
- public final FieldIdentifier field;
- public final List<ByteBuffer> inValues;
-
- private UDTFieldAccessInBound(ColumnCondition condition, QueryOptions options) throws InvalidRequestException
- {
- super(condition.column, condition.operator);
- assert column.type.isUDT() && condition.field != null;
- this.field = condition.field;
-
- if (condition.inValues == null)
- this.inValues = ((Lists.Value) condition.value.bind(options)).getElements();
- else
- {
- this.inValues = new ArrayList<>(condition.inValues.size());
- for (Term value : condition.inValues)
- this.inValues.add(value.bindAndGet(options));
- }
- }
-
- public boolean appliesTo(Row row) throws InvalidRequestException
- {
- UserType userType = (UserType) column.type;
- int fieldPosition = userType.fieldPosition(field);
- assert fieldPosition >= 0;
-
- ByteBuffer cellValue;
- if (column.type.isMultiCell())
- {
- Cell cell = getCell(row, column, userType.cellPathForField(field));
- cellValue = cell == null ? null : cell.value();
- }
- else
- {
- Cell cell = getCell(row, column);
- cellValue = cell == null ? null : userType.split(getCell(row, column).value())[fieldPosition];
- }
-
- AbstractType<?> valueType = userType.fieldType(fieldPosition);
- for (ByteBuffer value : inValues)
- {
- if (compareWithOperator(Operator.EQ, valueType, value, cellValue))
- return true;
- }
- return false;
- }
- }
-
- /** A non-IN condition on an entire UDT. For example: IF user = {name: 'joe', age: 42}). */
- static class UDTBound extends Bound
- {
- private final ByteBuffer value;
- private final ProtocolVersion protocolVersion;
-
- private UDTBound(ColumnCondition condition, QueryOptions options) throws InvalidRequestException
- {
- super(condition.column, condition.operator);
- assert column.type.isUDT() && condition.field == null;
- assert condition.operator != Operator.IN;
- protocolVersion = options.getProtocolVersion();
- value = condition.value.bindAndGet(options);
- }
-
- public boolean appliesTo(Row row) throws InvalidRequestException
- {
- UserType userType = (UserType) column.type;
- ByteBuffer rowValue;
- if (userType.isMultiCell())
- {
- Iterator<Cell> iter = getCells(row, column);
- rowValue = iter.hasNext() ? userType.serializeForNativeProtocol(iter, protocolVersion) : null;
- }
- else
- {
- Cell cell = getCell(row, column);
- rowValue = cell == null ? null : cell.value();
- }
-
- if (value == null)
- {
- if (operator == Operator.EQ)
- return rowValue == null;
- else if (operator == Operator.NEQ)
- return rowValue != null;
- else
- throw new InvalidRequestException(String.format("Invalid comparison with null for operator \"%s\"", operator));
- }
-
- return compareWithOperator(operator, userType, value, rowValue);
- }
- }
-
- /** An IN condition on an entire UDT. For example: IF user IN ({name: 'joe', age: 42}, {name: 'bob', age: 23}). */
- public static class UDTInBound extends Bound
- {
- private final List<ByteBuffer> inValues;
- private final ProtocolVersion protocolVersion;
-
- private UDTInBound(ColumnCondition condition, QueryOptions options) throws InvalidRequestException
- {
- super(condition.column, condition.operator);
- assert column.type.isUDT() && condition.field == null;
- assert condition.operator == Operator.IN;
- protocolVersion = options.getProtocolVersion();
- inValues = new ArrayList<>();
- if (condition.inValues == null)
- {
- Lists.Marker inValuesMarker = (Lists.Marker) condition.value;
- for (ByteBuffer buffer : ((Lists.Value)inValuesMarker.bind(options)).elements)
- this.inValues.add(buffer);
- }
- else
- {
- for (Term value : condition.inValues)
- this.inValues.add(value.bindAndGet(options));
- }
- }
-
- public boolean appliesTo(Row row) throws InvalidRequestException
- {
- UserType userType = (UserType) column.type;
- ByteBuffer rowValue;
- if (userType.isMultiCell())
- {
- Iterator<Cell> cells = getCells(row, column);
- rowValue = cells.hasNext() ? userType.serializeForNativeProtocol(cells, protocolVersion) : null;
- }
- else
- {
- Cell cell = getCell(row, column);
- rowValue = cell == null ? null : cell.value();
- }
-
- for (ByteBuffer value : inValues)
- {
- if (value == null || rowValue == null)
- {
- if (value == rowValue) // both null
- return true;
- }
- else if (userType.compare(value, rowValue) == 0)
- {
- return true;
- }
- }
- return false;
- }
- }
-
- public static class Raw
- {
- private final Term.Raw value;
- private final List<Term.Raw> inValues;
- private final AbstractMarker.INRaw inMarker;
-
- // Can be null, only used with the syntax "IF m[e] = ..." (in which case it's 'e')
- private final Term.Raw collectionElement;
-
- // Can be null, only used with the syntax "IF udt.field = ..." (in which case it's 'field')
- private final FieldIdentifier udtField;
-
- private final Operator operator;
-
- private Raw(Term.Raw value, List<Term.Raw> inValues, AbstractMarker.INRaw inMarker, Term.Raw collectionElement,
- FieldIdentifier udtField, Operator op)
- {
- this.value = value;
- this.inValues = inValues;
- this.inMarker = inMarker;
- this.collectionElement = collectionElement;
- this.udtField = udtField;
- this.operator = op;
- }
-
- /** A condition on a column. For example: "IF col = 'foo'" */
- public static Raw simpleCondition(Term.Raw value, Operator op)
- {
- return new Raw(value, null, null, null, null, op);
- }
-
- /** 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, 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, 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, Operator op)
- {
- return new Raw(value, null, null, collectionElement, null, op);
- }
-
- /** 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, null, 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, null, Operator.IN);
- }
-
- /** A condition on a UDT field. For example: "IF col.field = 'foo'" */
- public static Raw udtFieldCondition(Term.Raw value, FieldIdentifier udtField, Operator op)
- {
- return new Raw(value, null, null, null, udtField, op);
- }
-
- /** An IN condition on a collection element. For example: "IF col.field IN ('foo', 'bar', ...)" */
- public static Raw udtFieldInCondition(FieldIdentifier udtField, List<Term.Raw> inValues)
- {
- return new Raw(null, inValues, null, null, udtField, Operator.IN);
- }
-
- /** An IN condition on a collection element with a single marker. For example: "IF col.field IN ?" */
- public static Raw udtFieldInCondition(FieldIdentifier udtField, AbstractMarker.INRaw inMarker)
- {
- return new Raw(null, null, inMarker, null, udtField, Operator.IN);
- }
-
- public ColumnCondition prepare(String keyspace, ColumnDefinition receiver, CFMetaData cfm) throws InvalidRequestException
- {
- if (receiver.type instanceof CounterColumnType)
- throw new InvalidRequestException("Conditions on counters are not supported");
-
- if (collectionElement != null)
- {
- if (!(receiver.type.isCollection()))
- throw new InvalidRequestException(String.format("Invalid element access syntax for non-collection column %s", receiver.name));
-
- ColumnSpecification elementSpec, valueSpec;
- switch ((((CollectionType) receiver.type).kind))
- {
- case LIST:
- elementSpec = Lists.indexSpecOf(receiver);
- valueSpec = Lists.valueSpecOf(receiver);
- break;
- case MAP:
- elementSpec = Maps.keySpecOf(receiver);
- valueSpec = Maps.valueSpecOf(receiver);
- break;
- case SET:
- throw new InvalidRequestException(String.format("Invalid element access syntax for set column %s", receiver.name));
- default:
- throw new AssertionError();
- }
- if (operator == Operator.IN)
- {
- if (inValues == null)
- return ColumnCondition.inCondition(receiver, collectionElement.prepare(keyspace, elementSpec), inMarker.prepare(keyspace, valueSpec));
- List<Term> terms = new ArrayList<>(inValues.size());
- for (Term.Raw value : inValues)
- terms.add(value.prepare(keyspace, valueSpec));
- return ColumnCondition.inCondition(receiver, collectionElement.prepare(keyspace, elementSpec), terms);
- }
- else
- {
- return ColumnCondition.condition(receiver, collectionElement.prepare(keyspace, elementSpec), value.prepare(keyspace, valueSpec), operator);
- }
- }
- else if (udtField != null)
- {
- UserType userType = (UserType) receiver.type;
- int fieldPosition = userType.fieldPosition(udtField);
- if (fieldPosition == -1)
- throw new InvalidRequestException(String.format("Unknown field %s for column %s", udtField, receiver.name));
-
- ColumnSpecification fieldReceiver = UserTypes.fieldSpecOf(receiver, fieldPosition);
- if (operator == Operator.IN)
- {
- if (inValues == null)
- return ColumnCondition.inCondition(receiver, udtField, inMarker.prepare(keyspace, fieldReceiver));
-
- List<Term> terms = new ArrayList<>(inValues.size());
- for (Term.Raw value : inValues)
- terms.add(value.prepare(keyspace, fieldReceiver));
- return ColumnCondition.inCondition(receiver, udtField, terms);
- }
- else
- {
- return ColumnCondition.condition(receiver, udtField, value.prepare(keyspace, fieldReceiver), operator);
- }
- }
- else
- {
- if (operator == Operator.IN)
- {
- if (inValues == null)
- return ColumnCondition.inCondition(receiver, inMarker.prepare(keyspace, receiver));
- List<Term> terms = new ArrayList<>(inValues.size());
- for (Term.Raw value : inValues)
- terms.add(value.prepare(keyspace, receiver));
- return ColumnCondition.inCondition(receiver, terms);
- }
- else
- {
- return ColumnCondition.condition(receiver, value.prepare(keyspace, receiver), operator);
- }
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/e71a49e8/src/java/org/apache/cassandra/cql3/ColumnConditions.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/ColumnConditions.java b/src/java/org/apache/cassandra/cql3/ColumnConditions.java
deleted file mode 100644
index cb09b1a..0000000
--- a/src/java/org/apache/cassandra/cql3/ColumnConditions.java
+++ /dev/null
@@ -1,164 +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;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import org.apache.cassandra.config.ColumnDefinition;
-import org.apache.cassandra.cql3.functions.Function;
-import org.apache.cassandra.cql3.statements.CQL3CasRequest;
-import org.apache.cassandra.db.Clustering;
-
-/**
- * A set of <code>ColumnCondition</code>s.
- *
- */
-public final class ColumnConditions extends AbstractConditions
-{
- /**
- * The conditions on regular columns.
- */
- private final List<ColumnCondition> columnConditions;
-
- /**
- * The conditions on static columns
- */
- private final List<ColumnCondition> staticConditions;
-
- /**
- * Creates a new <code>ColumnConditions</code> instance for the specified builder.
- */
- private ColumnConditions(Builder builder)
- {
- this.columnConditions = builder.columnConditions;
- this.staticConditions = builder.staticConditions;
- }
-
- @Override
- public boolean appliesToStaticColumns()
- {
- return !staticConditions.isEmpty();
- }
-
- @Override
- public boolean appliesToRegularColumns()
- {
- return !columnConditions.isEmpty();
- }
-
- @Override
- public Collection<ColumnDefinition> getColumns()
- {
- return Stream.concat(columnConditions.stream(), staticConditions.stream())
- .map(e -> e.column)
- .collect(Collectors.toList());
- }
-
- @Override
- public boolean isEmpty()
- {
- return columnConditions.isEmpty() && staticConditions.isEmpty();
- }
-
- /**
- * Adds the conditions to the specified CAS request.
- *
- * @param request the request
- * @param clustering the clustering prefix
- * @param options the query options
- */
- public void addConditionsTo(CQL3CasRequest request,
- Clustering clustering,
- QueryOptions options)
- {
- if (!columnConditions.isEmpty())
- request.addConditions(clustering, columnConditions, options);
- if (!staticConditions.isEmpty())
- request.addConditions(Clustering.STATIC_CLUSTERING, staticConditions, options);
- }
-
- @Override
- public void addFunctionsTo(List<Function> functions)
- {
- columnConditions.forEach(p -> p.addFunctionsTo(functions));
- staticConditions.forEach(p -> p.addFunctionsTo(functions));
- }
-
- /**
- * Creates a new <code>Builder</code> for <code>ColumnConditions</code>.
- * @return a new <code>Builder</code> for <code>ColumnConditions</code>
- */
- public static Builder newBuilder()
- {
- return new Builder();
- }
-
- /**
- * A <code>Builder</code> for <code>ColumnConditions</code>.
- *
- */
- public static final class Builder
- {
- /**
- * The conditions on regular columns.
- */
- private List<ColumnCondition> columnConditions = Collections.emptyList();
-
- /**
- * The conditions on static columns
- */
- private List<ColumnCondition> staticConditions = Collections.emptyList();
-
- /**
- * Adds the specified <code>ColumnCondition</code> to this set of conditions.
- * @param condition the condition to add
- */
- public Builder add(ColumnCondition condition)
- {
- List<ColumnCondition> conds = null;
- if (condition.column.isStatic())
- {
- if (staticConditions.isEmpty())
- staticConditions = new ArrayList<>();
- conds = staticConditions;
- }
- else
- {
- if (columnConditions.isEmpty())
- columnConditions = new ArrayList<>();
- conds = columnConditions;
- }
- conds.add(condition);
- return this;
- }
-
- public ColumnConditions build()
- {
- return new ColumnConditions(this);
- }
-
- private Builder()
- {
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/e71a49e8/src/java/org/apache/cassandra/cql3/Conditions.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/Conditions.java b/src/java/org/apache/cassandra/cql3/Conditions.java
deleted file mode 100644
index 16fa4aa..0000000
--- a/src/java/org/apache/cassandra/cql3/Conditions.java
+++ /dev/null
@@ -1,102 +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;
-
-import java.util.List;
-
-import org.apache.cassandra.config.ColumnDefinition;
-import org.apache.cassandra.cql3.functions.Function;
-import org.apache.cassandra.cql3.statements.CQL3CasRequest;
-import org.apache.cassandra.db.Clustering;
-
-/**
- * Conditions that can be applied to a mutation statement.
- *
- */
-public interface Conditions
-{
- /**
- * An EMPTY condition
- */
- static final Conditions EMPTY_CONDITION = ColumnConditions.newBuilder().build();
-
- /**
- * IF EXISTS condition
- */
- static final Conditions IF_EXISTS_CONDITION = new IfExistsCondition();
-
- /**
- * IF NOT EXISTS condition
- */
- static final Conditions IF_NOT_EXISTS_CONDITION = new IfNotExistsCondition();
-
- /**
- * Adds the functions used by the conditions to the specified list.
- * @param functions the list to add to
- */
- void addFunctionsTo(List<Function> functions);
-
- /**
- * Returns the column definitions to which apply the conditions.
- * @return the column definitions to which apply the conditions.
- */
- Iterable<ColumnDefinition> getColumns();
-
- /**
- * Checks if this <code>Conditions</code> is empty.
- * @return <code>true</code> if this <code>Conditions</code> is empty, <code>false</code> otherwise.
- */
- boolean isEmpty();
-
- /**
- * Checks if this is a IF EXIST condition.
- * @return <code>true</code> if this is a IF EXIST condition, <code>false</code> otherwise.
- */
- boolean isIfExists();
-
- /**
- * Checks if this is a IF NOT EXIST condition.
- * @return <code>true</code> if this is a IF NOT EXIST condition, <code>false</code> otherwise.
- */
- boolean isIfNotExists();
-
- /**
- * Checks if some of the conditions apply to static columns.
- *
- * @return <code>true</code> if some of the conditions apply to static columns, <code>false</code> otherwise.
- */
- boolean appliesToStaticColumns();
-
- /**
- * Checks if some of the conditions apply to regular columns.
- *
- * @return <code>true</code> if some of the conditions apply to regular columns, <code>false</code> otherwise.
- */
- boolean appliesToRegularColumns();
-
- /**
- * Adds the conditions to the specified CAS request.
- *
- * @param request the request
- * @param clustering the clustering prefix
- * @param options the query options
- */
- public void addConditionsTo(CQL3CasRequest request,
- Clustering clustering,
- QueryOptions options);
-}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/e71a49e8/src/java/org/apache/cassandra/cql3/IfExistsCondition.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/IfExistsCondition.java b/src/java/org/apache/cassandra/cql3/IfExistsCondition.java
deleted file mode 100644
index a24d8c0..0000000
--- a/src/java/org/apache/cassandra/cql3/IfExistsCondition.java
+++ /dev/null
@@ -1,36 +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;
-
-import org.apache.cassandra.cql3.statements.CQL3CasRequest;
-import org.apache.cassandra.db.Clustering;
-
-final class IfExistsCondition extends AbstractConditions
-{
- @Override
- public void addConditionsTo(CQL3CasRequest request, Clustering clustering, QueryOptions options)
- {
- request.addExist(clustering);
- }
-
- @Override
- public boolean isIfExists()
- {
- return true;
- }
-}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/e71a49e8/src/java/org/apache/cassandra/cql3/IfNotExistsCondition.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/IfNotExistsCondition.java b/src/java/org/apache/cassandra/cql3/IfNotExistsCondition.java
deleted file mode 100644
index 05cb864..0000000
--- a/src/java/org/apache/cassandra/cql3/IfNotExistsCondition.java
+++ /dev/null
@@ -1,36 +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;
-
-import org.apache.cassandra.cql3.statements.CQL3CasRequest;
-import org.apache.cassandra.db.Clustering;
-
-final class IfNotExistsCondition extends AbstractConditions
-{
- @Override
- public void addConditionsTo(CQL3CasRequest request, Clustering clustering, QueryOptions options)
- {
- request.addNotExist(clustering);
- }
-
- @Override
- public boolean isIfNotExists()
- {
- return true;
- }
-}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/e71a49e8/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
index 07c92f0..f2a6c6b 100644
--- a/src/java/org/apache/cassandra/cql3/Operator.java
+++ b/src/java/org/apache/cassandra/cql3/Operator.java
@@ -37,6 +37,12 @@ public enum Operator
{
return "=";
}
+
+ @Override
+ public boolean isSatisfiedBy(AbstractType<?> type, ByteBuffer leftOperand, ByteBuffer rightOperand)
+ {
+ return type.compareForCQL(leftOperand, rightOperand) == 0;
+ }
},
LT(4)
{
@@ -45,6 +51,12 @@ public enum Operator
{
return "<";
}
+
+ @Override
+ public boolean isSatisfiedBy(AbstractType<?> type, ByteBuffer leftOperand, ByteBuffer rightOperand)
+ {
+ return type.compareForCQL(leftOperand, rightOperand) < 0;
+ }
},
LTE(3)
{
@@ -53,6 +65,12 @@ public enum Operator
{
return "<=";
}
+
+ @Override
+ public boolean isSatisfiedBy(AbstractType<?> type, ByteBuffer leftOperand, ByteBuffer rightOperand)
+ {
+ return type.compareForCQL(leftOperand, rightOperand) <= 0;
+ }
},
GTE(1)
{
@@ -61,6 +79,12 @@ public enum Operator
{
return ">=";
}
+
+ @Override
+ public boolean isSatisfiedBy(AbstractType<?> type, ByteBuffer leftOperand, ByteBuffer rightOperand)
+ {
+ return type.compareForCQL(leftOperand, rightOperand) >= 0;
+ }
},
GT(2)
{
@@ -69,12 +93,56 @@ public enum Operator
{
return ">";
}
+
+ @Override
+ public boolean isSatisfiedBy(AbstractType<?> type, ByteBuffer leftOperand, ByteBuffer rightOperand)
+ {
+ return type.compareForCQL(leftOperand, rightOperand) > 0;
+ }
},
IN(7)
{
+ @Override
+ public String toString()
+ {
+ return "IN";
+ }
+
+ public boolean isSatisfiedBy(AbstractType<?> type, ByteBuffer leftOperand, ByteBuffer rightOperand)
+ {
+ List<?> inValues = ListType.getInstance(type, false).getSerializer().deserialize(rightOperand);
+ return inValues.contains(type.getSerializer().deserialize(leftOperand));
+ }
},
CONTAINS(5)
{
+ @Override
+ public String toString()
+ {
+ return "CONTAINS";
+ }
+
+ @Override
+ public boolean isSatisfiedBy(AbstractType<?> type, ByteBuffer leftOperand, ByteBuffer rightOperand)
+ {
+ switch(((CollectionType<?>) type).kind)
+ {
+ case LIST :
+ ListType<?> listType = (ListType<?>) type;
+ List<?> list = listType.getSerializer().deserialize(leftOperand);
+ return list.contains(listType.getElementsType().getSerializer().deserialize(rightOperand));
+ case SET:
+ SetType<?> setType = (SetType<?>) type;
+ Set<?> set = setType.getSerializer().deserialize(leftOperand);
+ return set.contains(setType.getElementsType().getSerializer().deserialize(rightOperand));
+ case MAP:
+ MapType<?, ?> mapType = (MapType<?, ?>) type;
+ Map<?, ?> map = mapType.getSerializer().deserialize(leftOperand);
+ return map.containsValue(mapType.getValuesType().getSerializer().deserialize(rightOperand));
+ default:
+ throw new AssertionError();
+ }
+ }
},
CONTAINS_KEY(6)
{
@@ -83,6 +151,14 @@ public enum Operator
{
return "CONTAINS KEY";
}
+
+ @Override
+ public boolean isSatisfiedBy(AbstractType<?> type, ByteBuffer leftOperand, ByteBuffer rightOperand)
+ {
+ MapType<?, ?> mapType = (MapType<?, ?>) type;
+ Map<?, ?> map = mapType.getSerializer().deserialize(leftOperand);
+ return map.containsKey(mapType.getKeysType().getSerializer().deserialize(rightOperand));
+ }
},
NEQ(8)
{
@@ -91,6 +167,13 @@ public enum Operator
{
return "!=";
}
+
+ @Override
+ public boolean isSatisfiedBy(AbstractType<?> type, ByteBuffer leftOperand, ByteBuffer rightOperand)
+ {
+ return type.compareForCQL(leftOperand, rightOperand) != 0;
+
+ }
},
IS_NOT(9)
{
@@ -99,6 +182,12 @@ public enum Operator
{
return "IS NOT";
}
+
+ @Override
+ public boolean isSatisfiedBy(AbstractType<?> type, ByteBuffer leftOperand, ByteBuffer rightOperand)
+ {
+ throw new UnsupportedOperationException();
+ }
},
LIKE_PREFIX(10)
{
@@ -107,6 +196,12 @@ public enum Operator
{
return "LIKE '<term>%'";
}
+
+ @Override
+ public boolean isSatisfiedBy(AbstractType<?> type, ByteBuffer leftOperand, ByteBuffer rightOperand)
+ {
+ return ByteBufferUtil.startsWith(leftOperand, rightOperand);
+ }
},
LIKE_SUFFIX(11)
{
@@ -115,6 +210,12 @@ public enum Operator
{
return "LIKE '%<term>'";
}
+
+ @Override
+ public boolean isSatisfiedBy(AbstractType<?> type, ByteBuffer leftOperand, ByteBuffer rightOperand)
+ {
+ return ByteBufferUtil.endsWith(leftOperand, rightOperand);
+ }
},
LIKE_CONTAINS(12)
{
@@ -123,6 +224,12 @@ public enum Operator
{
return "LIKE '%<term>%'";
}
+
+ @Override
+ public boolean isSatisfiedBy(AbstractType<?> type, ByteBuffer leftOperand, ByteBuffer rightOperand)
+ {
+ return ByteBufferUtil.contains(leftOperand, rightOperand);
+ }
},
LIKE_MATCHES(13)
{
@@ -131,6 +238,11 @@ public enum Operator
{
return "LIKE '<term>'";
}
+
+ public boolean isSatisfiedBy(AbstractType<?> type, ByteBuffer leftOperand, ByteBuffer rightOperand)
+ {
+ return ByteBufferUtil.contains(leftOperand, rightOperand);
+ }
},
LIKE(14)
{
@@ -139,6 +251,12 @@ public enum Operator
{
return "LIKE";
}
+
+ @Override
+ public boolean isSatisfiedBy(AbstractType<?> type, ByteBuffer leftOperand, ByteBuffer rightOperand)
+ {
+ throw new UnsupportedOperationException();
+ }
};
/**
@@ -190,59 +308,8 @@ public enum Operator
/**
* Whether 2 values satisfy this operator (given the type they should be compared with).
- *
- * @throws AssertionError for CONTAINS and CONTAINS_KEY as this doesn't support those operators yet
*/
- public boolean isSatisfiedBy(AbstractType<?> type, ByteBuffer leftOperand, ByteBuffer rightOperand)
- {
- switch (this)
- {
- case EQ:
- return type.compareForCQL(leftOperand, rightOperand) == 0;
- case LT:
- return type.compareForCQL(leftOperand, rightOperand) < 0;
- case LTE:
- return type.compareForCQL(leftOperand, rightOperand) <= 0;
- case GT:
- return type.compareForCQL(leftOperand, rightOperand) > 0;
- case GTE:
- return type.compareForCQL(leftOperand, rightOperand) >= 0;
- case NEQ:
- return type.compareForCQL(leftOperand, rightOperand) != 0;
- case IN:
- List inValues = ((List) ListType.getInstance(type, false).getSerializer().deserialize(rightOperand));
- return inValues.contains(type.getSerializer().deserialize(leftOperand));
- case CONTAINS:
- if (type instanceof ListType)
- {
- List list = (List) type.getSerializer().deserialize(leftOperand);
- return list.contains(((ListType) type).getElementsType().getSerializer().deserialize(rightOperand));
- }
- else if (type instanceof SetType)
- {
- Set set = (Set) type.getSerializer().deserialize(leftOperand);
- return set.contains(((SetType) type).getElementsType().getSerializer().deserialize(rightOperand));
- }
- else // MapType
- {
- Map map = (Map) type.getSerializer().deserialize(leftOperand);
- return map.containsValue(((MapType) type).getValuesType().getSerializer().deserialize(rightOperand));
- }
- case CONTAINS_KEY:
- Map map = (Map) type.getSerializer().deserialize(leftOperand);
- return map.containsKey(((MapType) type).getKeysType().getSerializer().deserialize(rightOperand));
- case LIKE_PREFIX:
- return ByteBufferUtil.startsWith(leftOperand, rightOperand);
- case LIKE_SUFFIX:
- return ByteBufferUtil.endsWith(leftOperand, rightOperand);
- case LIKE_MATCHES:
- case LIKE_CONTAINS:
- return ByteBufferUtil.contains(leftOperand, rightOperand);
- default:
- // we shouldn't get LIKE, CONTAINS, CONTAINS KEY, or IS NOT here
- throw new AssertionError();
- }
- }
+ public abstract boolean isSatisfiedBy(AbstractType<?> type, ByteBuffer leftOperand, ByteBuffer rightOperand);
public int serializedSize()
{
@@ -254,4 +321,13 @@ public enum Operator
{
return this.name();
}
+
+ /**
+ * Checks if this operator is an IN operator.
+ * @return {@code true} if this operator is an IN operator, {@code false} otherwise.
+ */
+ public boolean isIN()
+ {
+ return this == IN;
+ }
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/e71a49e8/src/java/org/apache/cassandra/cql3/Terms.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/Terms.java b/src/java/org/apache/cassandra/cql3/Terms.java
index 7d3948a..7478366 100644
--- a/src/java/org/apache/cassandra/cql3/Terms.java
+++ b/src/java/org/apache/cassandra/cql3/Terms.java
@@ -18,17 +18,248 @@
package org.apache.cassandra.cql3;
import java.nio.ByteBuffer;
-import java.util.List;
+import java.util.*;
+import org.apache.cassandra.cql3.Term.MultiItemTerminal;
+import org.apache.cassandra.cql3.Term.Terminal;
import org.apache.cassandra.cql3.functions.Function;
-import org.apache.cassandra.db.marshal.AbstractType;
+import org.apache.cassandra.db.marshal.*;
+import org.apache.cassandra.transport.ProtocolVersion;
-public class Terms
+/**
+ * A set of {@code Terms}
+ */
+public interface Terms
{
+ /**
+ * The {@code List} returned when the list was not set.
+ */
+ @SuppressWarnings("rawtypes")
+ public static final List UNSET_LIST = new AbstractList()
+ {
+ @Override
+ public Object get(int index)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int size()
+ {
+ return 0;
+ }
+ };
+
+ /**
+ * Adds all functions (native and user-defined) used by any of the terms to the specified list.
+ * @param functions the list to add to
+ */
+ public void addFunctionsTo(List<Function> functions);
+
+ /**
+ * Collects the column specifications for the bind variables in the terms.
+ * This is obviously a no-op if the terms are Terminal.
+ *
+ * @param boundNames the variables specification where to collect the
+ * bind variables of the terms in.
+ */
+ public void collectMarkerSpecification(VariableSpecifications boundNames);
+
+ /**
+ * Bind the values in these terms to the values contained in {@code options}.
+ * This is obviously a no-op if the term is Terminal.
+ *
+ * @param options the values to bind markers to.
+ * @return the result of binding all the variables of these NonTerminals or an {@code UNSET_LIST} if the term
+ * was unset.
+ */
+ public List<Terminal> bind(QueryOptions options);
+
+
+ public List<ByteBuffer> bindAndGet(QueryOptions options);
+
+ /**
+ * Creates a {@code Terms} for the specified list marker.
+ *
+ * @param marker the list marker
+ * @param type the element type
+ * @return a {@code Terms} for the specified list marker
+ */
+ public static Terms ofListMarker(final Lists.Marker marker, final AbstractType<?> type)
+ {
+ return new Terms()
+ {
+ @Override
+ public void addFunctionsTo(List<Function> functions)
+ {
+ }
+
+ @Override
+ public void collectMarkerSpecification(VariableSpecifications boundNames)
+ {
+ marker.collectMarkerSpecification(boundNames);
+ }
+
+ @Override
+ public List<ByteBuffer> bindAndGet(QueryOptions options)
+ {
+ Terminal terminal = marker.bind(options);
+
+ if (terminal == null)
+ return null;
+
+ if (terminal == Constants.UNSET_VALUE)
+ return UNSET_LIST;
+
+ return ((MultiItemTerminal) terminal).getElements();
+ }
+
+ @Override
+ public List<Terminal> bind(QueryOptions options)
+ {
+ Terminal terminal = marker.bind(options);
+
+ if (terminal == null)
+ return null;
+
+ if (terminal == Constants.UNSET_VALUE)
+ return UNSET_LIST;
+
+ java.util.function.Function<ByteBuffer, Term.Terminal> deserializer = deserializer(options.getProtocolVersion());
+
+ List<ByteBuffer> boundValues = ((MultiItemTerminal) terminal).getElements();
+ List<Term.Terminal> values = new ArrayList<>(boundValues.size());
+ for (int i = 0, m = boundValues.size(); i < m; i++)
+ {
+ ByteBuffer buffer = boundValues.get(i);
+ Term.Terminal value = buffer == null ? null : deserializer.apply(buffer);
+ values.add(value);
+ }
+ return values;
+ }
+
+ public java.util.function.Function<ByteBuffer, Term.Terminal> deserializer(ProtocolVersion version)
+ {
+ if (type.isCollection())
+ {
+ switch (((CollectionType<?>) type).kind)
+ {
+ case LIST:
+ return e -> Lists.Value.fromSerialized(e, (ListType<?>) type, version);
+ case SET:
+ return e -> Sets.Value.fromSerialized(e, (SetType<?>) type, version);
+ case MAP:
+ return e -> Maps.Value.fromSerialized(e, (MapType<?, ?>) type, version);
+ }
+ throw new AssertionError();
+ }
+ return e -> new Constants.Value(e);
+ }
+ };
+ }
+
+ /**
+ * Creates a {@code Terms} containing a single {@code Term}.
+ *
+ * @param term the {@code Term}
+ * @return a {@code Terms} containing a single {@code Term}.
+ */
+ public static Terms of(final Term term)
+ {
+ assert !(term instanceof Lists.Marker);
+ return new Terms()
+ {
+ @Override
+ public void addFunctionsTo(List<Function> functions)
+ {
+ term.addFunctionsTo(functions);
+ }
+
+ @Override
+ public void collectMarkerSpecification(VariableSpecifications boundNames)
+ {
+ term.collectMarkerSpecification(boundNames);
+ }
+
+ @Override
+ public List<ByteBuffer> bindAndGet(QueryOptions options)
+ {
+ return Collections.singletonList(term.bindAndGet(options));
+ }
+
+ @Override
+ public List<Terminal> bind(QueryOptions options)
+ {
+ return Collections.singletonList(term.bind(options));
+ }
+ };
+ }
+
+ /**
+ * Creates a {@code Terms} containing a set of {@code Term}.
+ *
+ * @param term the {@code Term}
+ * @return a {@code Terms} containing a set of {@code Term}.
+ */
+ public static Terms of(final List<Term> terms)
+ {
+ return new Terms()
+ {
+ @Override
+ public void addFunctionsTo(List<Function> functions)
+ {
+ addFunctions(terms, functions);
+ }
+
+ @Override
+ public void collectMarkerSpecification(VariableSpecifications boundNames)
+ {
+ for (int i = 0, m = terms.size(); i <m; i++)
+ {
+ Term term = terms.get(i);
+ term.collectMarkerSpecification(boundNames);
+ }
+ }
+
+ @Override
+ public List<Terminal> bind(QueryOptions options)
+ {
+ int size = terms.size();
+ List<Terminal> terminals = new ArrayList<>(size);
+ for (int i = 0; i < size; i++)
+ {
+ Term term = terms.get(i);
+ terminals.add(term.bind(options));
+ }
+ return terminals;
+ }
+
+ @Override
+ public List<ByteBuffer> bindAndGet(QueryOptions options)
+ {
+ int size = terms.size();
+ List<ByteBuffer> buffers = new ArrayList<>(size);
+ for (int i = 0; i < size; i++)
+ {
+ Term term = terms.get(i);
+ buffers.add(term.bindAndGet(options));
+ }
+ return buffers;
+ }
+ };
+ }
+
+ /**
+ * Adds all functions (native and user-defined) of the specified terms to the list.
+ * @param functions the list to add to
+ */
public static void addFunctions(Iterable<Term> terms, List<Function> functions)
{
- if (terms != null)
- terms.forEach(t -> t.addFunctionsTo(functions));
+ for (Term term : terms)
+ {
+ if (term != null)
+ term.addFunctionsTo(functions);
+ }
}
public static ByteBuffer asBytes(String keyspace, String term, AbstractType type)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/e71a49e8/src/java/org/apache/cassandra/cql3/conditions/AbstractConditions.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/conditions/AbstractConditions.java b/src/java/org/apache/cassandra/cql3/conditions/AbstractConditions.java
new file mode 100644
index 0000000..9b6dd7e
--- /dev/null
+++ b/src/java/org/apache/cassandra/cql3/conditions/AbstractConditions.java
@@ -0,0 +1,64 @@
+/*
+ * 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.conditions;
+
+import java.util.List;
+
+import org.apache.cassandra.config.ColumnDefinition;
+import org.apache.cassandra.cql3.functions.Function;
+
+/**
+ * Base class for <code>Conditions</code> classes.
+ *
+ */
+abstract class AbstractConditions implements Conditions
+{
+ public void addFunctionsTo(List<Function> functions)
+ {
+ }
+
+ public Iterable<ColumnDefinition> getColumns()
+ {
+ return null;
+ }
+
+ public boolean isEmpty()
+ {
+ return false;
+ }
+
+ public boolean appliesToStaticColumns()
+ {
+ return false;
+ }
+
+ public boolean appliesToRegularColumns()
+ {
+ return false;
+ }
+
+ public boolean isIfExists()
+ {
+ return false;
+ }
+
+ public boolean isIfNotExists()
+ {
+ return false;
+ }
+}