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 2016/05/02 14:21:03 UTC

[2/2] cassandra git commit: Merge branch cassandra-3.0 into trunk

Merge branch cassandra-3.0 into trunk


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/4edd9ed5
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/4edd9ed5
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/4edd9ed5

Branch: refs/heads/trunk
Commit: 4edd9ed5e98dca9c8ebf52fa40a1f8abb0031689
Parents: 7b0c716 89464ea
Author: Benjamin Lerer <b....@gmail.com>
Authored: Mon May 2 14:17:48 2016 +0200
Committer: Benjamin Lerer <b....@gmail.com>
Committed: Mon May 2 14:20:31 2016 +0200

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../cassandra/cql3/AbstractConditions.java      |  5 ++-
 .../apache/cassandra/cql3/AbstractMarker.java   |  4 +--
 .../org/apache/cassandra/cql3/Attributes.java   | 15 ++++-----
 .../apache/cassandra/cql3/ColumnCondition.java  | 11 +++----
 .../apache/cassandra/cql3/ColumnConditions.java |  9 ++----
 .../org/apache/cassandra/cql3/Conditions.java   |  8 +++--
 src/java/org/apache/cassandra/cql3/Json.java    |  4 +--
 src/java/org/apache/cassandra/cql3/Lists.java   |  4 +--
 src/java/org/apache/cassandra/cql3/Maps.java    |  8 ++---
 .../org/apache/cassandra/cql3/Operation.java    |  7 ++--
 .../org/apache/cassandra/cql3/Operations.java   |  9 ++----
 src/java/org/apache/cassandra/cql3/Sets.java    |  6 ++--
 src/java/org/apache/cassandra/cql3/Term.java    |  5 ++-
 src/java/org/apache/cassandra/cql3/Terms.java   | 22 +++----------
 src/java/org/apache/cassandra/cql3/Tuples.java  |  4 +--
 .../org/apache/cassandra/cql3/UserTypes.java    |  4 +--
 .../cql3/functions/AbstractFunction.java        |  5 ++-
 .../cassandra/cql3/functions/Function.java      |  2 +-
 .../cassandra/cql3/functions/FunctionCall.java  |  7 ++--
 .../cassandra/cql3/functions/UDAggregate.java   | 18 ++++++-----
 .../restrictions/MultiColumnRestriction.java    | 18 +++++------
 .../cql3/restrictions/Restriction.java          |  8 ++---
 .../cql3/restrictions/RestrictionSet.java       | 18 +++++------
 .../restrictions/RestrictionSetWrapper.java     |  4 +--
 .../restrictions/SingleColumnRestriction.java   | 34 +++++++++-----------
 .../restrictions/StatementRestrictions.java     |  9 +++---
 .../cassandra/cql3/restrictions/TermSlice.java  | 19 ++++-------
 .../cql3/restrictions/TokenFilter.java          | 18 +++++------
 .../cql3/restrictions/TokenRestriction.java     |  8 ++---
 .../selection/AbstractFunctionSelector.java     |  7 ++--
 .../cassandra/cql3/selection/Selection.java     |  7 ++--
 .../cassandra/cql3/selection/Selector.java      |  5 ++-
 .../cql3/selection/SelectorFactories.java       |  9 ++----
 .../cql3/statements/BatchStatement.java         |  4 +--
 .../statements/CreateAggregateStatement.java    |  6 ++--
 .../cql3/statements/ModificationStatement.java  | 15 ++++++---
 .../cql3/statements/SelectStatement.java        | 19 ++++++++---
 38 files changed, 165 insertions(+), 201 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/4edd9ed5/CHANGES.txt
----------------------------------------------------------------------
diff --cc CHANGES.txt
index 984ad55,95db7bc..c49249c
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@@ -1,68 -1,5 +1,69 @@@
 -3.0.6
 +3.6
 + * Integrated JMX authentication and authorization (CASSANDRA-10091)
 + * Add units to stress ouput (CASSANDRA-11352)
 + * Fix PER PARTITION LIMIT for single and multi partitions queries (CASSANDRA-11603)
 + * Add uncompressed chunk cache for RandomAccessReader (CASSANDRA-5863)
 + * Clarify ClusteringPrefix hierarchy (CASSANDRA-11213)
 + * Always perform collision check before joining ring (CASSANDRA-10134)
 + * SSTableWriter output discrepancy (CASSANDRA-11646)
 + * Fix potential timeout in NativeTransportService.testConcurrentDestroys (CASSANDRA-10756)
 + * Support large partitions on the 3.0 sstable format (CASSANDRA-11206)
 + * Add support to rebuild from specific range (CASSANDRA-10406)
 + * Optimize the overlapping lookup by calculating all the
 +   bounds in advance (CASSANDRA-11571)
 + * Support json/yaml output in noetool tablestats (CASSANDRA-5977)
 + * (stress) Add datacenter option to -node options (CASSANDRA-11591)
 + * Fix handling of empty slices (CASSANDRA-11513)
 + * Make number of cores used by cqlsh COPY visible to testing code (CASSANDRA-11437)
 + * Allow filtering on clustering columns for queries without secondary indexes (CASSANDRA-11310)
 + * Refactor Restriction hierarchy (CASSANDRA-11354)
 + * Eliminate allocations in R/W path (CASSANDRA-11421)
 + * Update Netty to 4.0.36 (CASSANDRA-11567)
 + * Fix PER PARTITION LIMIT for queries requiring post-query ordering (CASSANDRA-11556)
 + * Allow instantiation of UDTs and tuples in UDFs (CASSANDRA-10818)
 + * Support UDT in CQLSSTableWriter (CASSANDRA-10624)
 + * Support for non-frozen user-defined types, updating
 +   individual fields of user-defined types (CASSANDRA-7423)
 + * Make LZ4 compression level configurable (CASSANDRA-11051)
 + * Allow per-partition LIMIT clause in CQL (CASSANDRA-7017)
 + * Make custom filtering more extensible with UserExpression (CASSANDRA-11295)
 + * Improve field-checking and error reporting in cassandra.yaml (CASSANDRA-10649)
 + * Print CAS stats in nodetool proxyhistograms (CASSANDRA-11507)
 + * More user friendly error when providing an invalid token to nodetool (CASSANDRA-9348)
 + * Add static column support to SASI index (CASSANDRA-11183)
 + * Support EQ/PREFIX queries in SASI CONTAINS mode without tokenization (CASSANDRA-11434)
 + * Support LIKE operator in prepared statements (CASSANDRA-11456)
 + * Add a command to see if a Materialized View has finished building (CASSANDRA-9967)
 + * Log endpoint and port associated with streaming operation (CASSANDRA-8777)
 + * Print sensible units for all log messages (CASSANDRA-9692)
 + * Upgrade Netty to version 4.0.34 (CASSANDRA-11096)
 + * Break the CQL grammar into separate Parser and Lexer (CASSANDRA-11372)
 + * Compress only inter-dc traffic by default (CASSANDRA-8888)
 + * Add metrics to track write amplification (CASSANDRA-11420)
 + * cassandra-stress: cannot handle "value-less" tables (CASSANDRA-7739)
 + * Add/drop multiple columns in one ALTER TABLE statement (CASSANDRA-10411)
 + * Add require_endpoint_verification opt for internode encryption (CASSANDRA-9220)
 + * Add auto import java.util for UDF code block (CASSANDRA-11392)
 + * Add --hex-format option to nodetool getsstables (CASSANDRA-11337)
 + * sstablemetadata should print sstable min/max token (CASSANDRA-7159)
 + * Do not wrap CassandraException in TriggerExecutor (CASSANDRA-9421)
 + * COPY TO should have higher double precision (CASSANDRA-11255)
 + * Stress should exit with non-zero status after failure (CASSANDRA-10340)
 + * Add client to cqlsh SHOW_SESSION (CASSANDRA-8958)
 + * Fix nodetool tablestats keyspace level metrics (CASSANDRA-11226)
 + * Store repair options in parent_repair_history (CASSANDRA-11244)
 + * Print current leveling in sstableofflinerelevel (CASSANDRA-9588)
 + * Change repair message for keyspaces with RF 1 (CASSANDRA-11203)
 + * Remove hard-coded SSL cipher suites and protocols (CASSANDRA-10508)
 + * Improve concurrency in CompactionStrategyManager (CASSANDRA-10099)
 + * (cqlsh) interpret CQL type for formatting blobs (CASSANDRA-11274)
 + * Refuse to start and print txn log information in case of disk
 +   corruption (CASSANDRA-10112)
 + * Resolve some eclipse-warnings (CASSANDRA-11086)
 + * (cqlsh) Show static columns in a different color (CASSANDRA-11059)
 + * Allow to remove TTLs on table with default_time_to_live (CASSANDRA-11207)
 +Merged from 3.0:
+  * Reduce the amount of object allocations caused by the getFunctions methods (CASSANDRA-11593)
   * Potential error replaying commitlog with smallint/tinyint/date/time types (CASSANDRA-11618)
   * Fix queries with filtering on counter columns (CASSANDRA-11629)
   * Improve tombstone printing in sstabledump (CASSANDRA-11655)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4edd9ed5/src/java/org/apache/cassandra/cql3/AbstractMarker.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4edd9ed5/src/java/org/apache/cassandra/cql3/Attributes.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4edd9ed5/src/java/org/apache/cassandra/cql3/ColumnCondition.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/ColumnCondition.java
index 8db0ecc,b13e534..255dd0e
--- a/src/java/org/apache/cassandra/cql3/ColumnCondition.java
+++ b/src/java/org/apache/cassandra/cql3/ColumnCondition.java
@@@ -20,10 -20,8 +20,9 @@@ package org.apache.cassandra.cql3
  import java.nio.ByteBuffer;
  import java.util.*;
  
- import com.google.common.collect.Iterables;
  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.*;
@@@ -101,21 -86,15 +100,20 @@@ public class ColumnConditio
  
      public static ColumnCondition inCondition(ColumnDefinition column, Term collectionElement, Term inMarker)
      {
 -        return new ColumnCondition(column, collectionElement, inMarker, null, Operator.IN);
 +        return new ColumnCondition(column, collectionElement, null, inMarker, null, Operator.IN);
 +    }
 +
 +    public static ColumnCondition inCondition(ColumnDefinition column, ColumnIdentifier udtField, Term inMarker)
 +    {
 +        return new ColumnCondition(column, null, udtField, inMarker, null, Operator.IN);
      }
  
-     public Iterable<Function> getFunctions()
+     public void addFunctionsTo(List<Function> functions)
      {
-         Iterable<Function> iter = Collections.emptyList();
          if (collectionElement != null)
-            iter = Iterables.concat(iter, collectionElement.getFunctions());
+            collectionElement.addFunctionsTo(functions);
          if (value != null)
-             iter = Iterables.concat(iter, value.getFunctions());
+            value.addFunctionsTo(functions);
          if (inValues != null)
              for (Term value : inValues)
                  if (value != null)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4edd9ed5/src/java/org/apache/cassandra/cql3/Lists.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4edd9ed5/src/java/org/apache/cassandra/cql3/Operation.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/Operation.java
index bfb05e7,ecd37c4..0147859
--- a/src/java/org/apache/cassandra/cql3/Operation.java
+++ b/src/java/org/apache/cassandra/cql3/Operation.java
@@@ -17,9 -17,8 +17,9 @@@
   */
  package org.apache.cassandra.cql3;
  
- import java.util.Collections;
+ import java.util.List;
  
 +import org.apache.cassandra.config.CFMetaData;
  import org.apache.cassandra.config.ColumnDefinition;
  import org.apache.cassandra.cql3.functions.Function;
  import org.apache.cassandra.db.DecoratedKey;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4edd9ed5/src/java/org/apache/cassandra/cql3/Tuples.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4edd9ed5/src/java/org/apache/cassandra/cql3/UserTypes.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4edd9ed5/src/java/org/apache/cassandra/cql3/functions/AbstractFunction.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4edd9ed5/src/java/org/apache/cassandra/cql3/functions/Function.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/functions/Function.java
index f50657a,f93f14b..5d258af
--- a/src/java/org/apache/cassandra/cql3/functions/Function.java
+++ b/src/java/org/apache/cassandra/cql3/functions/Function.java
@@@ -44,15 -44,7 +44,15 @@@ public interface Function extends Assig
       */
      public boolean isAggregate();
  
-     public Iterable<Function> getFunctions();
+     public void addFunctionsTo(List<Function> functions);
  
      public boolean hasReferenceTo(Function function);
 +
 +    /**
 +     * Returns the name of the function to use within a ResultSet.
 +     *
 +     * @param columnNames the names of the columns used to call the function
 +     * @return the name of the function to use within a ResultSet
 +     */
 +    public String columnName(List<String> columnNames);
  }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4edd9ed5/src/java/org/apache/cassandra/cql3/functions/FunctionCall.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4edd9ed5/src/java/org/apache/cassandra/cql3/functions/UDAggregate.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4edd9ed5/src/java/org/apache/cassandra/cql3/restrictions/MultiColumnRestriction.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4edd9ed5/src/java/org/apache/cassandra/cql3/restrictions/Restriction.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/restrictions/Restriction.java
index 8311220,987fd30..fc7f5bc
--- a/src/java/org/apache/cassandra/cql3/restrictions/Restriction.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/Restriction.java
@@@ -54,13 -63,40 +54,13 @@@ public interface Restrictio
      public List<ColumnDefinition> getColumnDefs();
  
      /**
-      * Return an Iterable over all of the functions (both native and user-defined) used by any component
-      * of the restriction
-      * @return functions all functions found (may contain duplicates)
+      * Adds all functions (native and user-defined) used by any component of the restriction
+      * to the specified list.
+      * @param functions the list to add to
       */
-     public Iterable<Function> getFunctions();
+     void addFunctionsTo(List<Function> functions);
  
      /**
 -     * Checks if the specified bound is set or not.
 -     * @param b the bound type
 -     * @return <code>true</code> if the specified bound is set, <code>false</code> otherwise
 -     */
 -    public boolean hasBound(Bound b);
 -
 -    /**
 -     * Checks if the specified bound is inclusive or not.
 -     * @param b the bound type
 -     * @return <code>true</code> if the specified bound is inclusive, <code>false</code> otherwise
 -     */
 -    public boolean isInclusive(Bound b);
 -
 -    /**
 -     * Merges this restriction with the specified one.
 -     *
 -     * <p>Restriction are immutable. Therefore merging two restrictions result in a new one.
 -     * The reason behind this choice is that it allow a great flexibility in the way the merging can done while
 -     * preventing any side effect.</p>
 -     *
 -     * @param otherRestriction the restriction to merge into this one
 -     * @return the restriction resulting of the merge
 -     * @throws InvalidRequestException if the restrictions cannot be merged
 -     */
 -    public Restriction mergeWith(Restriction otherRestriction) throws InvalidRequestException;
 -
 -    /**
       * Check if the restriction is on indexed columns.
       *
       * @param indexManager the index manager

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4edd9ed5/src/java/org/apache/cassandra/cql3/restrictions/RestrictionSet.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/restrictions/RestrictionSet.java
index 8011e92,9aeea69..2648f62
--- a/src/java/org/apache/cassandra/cql3/restrictions/RestrictionSet.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/RestrictionSet.java
@@@ -18,10 -18,7 +18,8 @@@
  package org.apache.cassandra.cql3.restrictions;
  
  import java.util.*;
 +import java.util.stream.Stream;
  
- import com.google.common.collect.Iterables;
- 
  import org.apache.cassandra.config.ColumnDefinition;
  import org.apache.cassandra.cql3.QueryOptions;
  import org.apache.cassandra.cql3.functions.Function;
@@@ -78,24 -76,19 +76,24 @@@ final class RestrictionSet implements R
          return new ArrayList<>(restrictions.keySet());
      }
  
 +    public Stream<SingleRestriction> stream()
 +    {
 +        return new LinkedHashSet<>(restrictions.values()).stream();
 +    }
 +
      @Override
-     public Iterable<Function> getFunctions()
+     public void addFunctionsTo(List<Function> functions)
      {
-         com.google.common.base.Function<Restriction, Iterable<Function>> transform =
-             new com.google.common.base.Function<Restriction, Iterable<Function>>()
+         Restriction previous = null;
+         for (Restriction restriction : restrictions.values())
          {
-             public Iterable<Function> apply(Restriction restriction)
+             // For muti-column restriction, we can have multiple time the same restriction.
+             if (!restriction.equals(previous))
              {
-                 return restriction.getFunctions();
+                 previous = restriction;
+                 restriction.addFunctionsTo(functions);
              }
-         };
- 
-         return Iterables.concat(Iterables.transform(restrictions.values(), transform));
+         }
      }
  
      @Override

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4edd9ed5/src/java/org/apache/cassandra/cql3/restrictions/RestrictionSetWrapper.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/restrictions/RestrictionSetWrapper.java
index b8ccb1c,0000000..6ad5fbb
mode 100644,000000..100644
--- a/src/java/org/apache/cassandra/cql3/restrictions/RestrictionSetWrapper.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/RestrictionSetWrapper.java
@@@ -1,95 -1,0 +1,95 @@@
 +/*
 + * Licensed to the Apache Software Foundation (ASF) under one
 + * or more contributor license agreements.  See the NOTICE file
 + * distributed with this work for additional information
 + * regarding copyright ownership.  The ASF licenses this file
 + * to you under the Apache License, Version 2.0 (the
 + * "License"); you may not use this file except in compliance
 + * with the License.  You may obtain a copy of the License at
 + *
 + *     http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +package org.apache.cassandra.cql3.restrictions;
 +
 +import java.util.List;
 +
 +import org.apache.cassandra.config.ColumnDefinition;
 +import org.apache.cassandra.cql3.QueryOptions;
 +import org.apache.cassandra.cql3.functions.Function;
 +import org.apache.cassandra.db.filter.RowFilter;
 +import org.apache.cassandra.index.SecondaryIndexManager;
 +
 +/**
 + * A <code>RestrictionSet</code> wrapper that can be extended to allow to modify the <code>RestrictionSet</code>
 + * behaviour without breaking its immutability. Sub-classes should be immutables.
 + */
 +class RestrictionSetWrapper implements Restrictions
 +{
 +    /**
 +     * The wrapped <code>RestrictionSet</code>.
 +     */
 +    protected final RestrictionSet restrictions;
 +
 +    public RestrictionSetWrapper(RestrictionSet restrictions)
 +    {
 +        this.restrictions = restrictions;
 +    }
 +
 +    public void addRowFilterTo(RowFilter filter,
 +                               SecondaryIndexManager indexManager,
 +                               QueryOptions options)
 +    {
 +        restrictions.addRowFilterTo(filter, indexManager, options);
 +    }
 +
 +    public List<ColumnDefinition> getColumnDefs()
 +    {
 +        return restrictions.getColumnDefs();
 +    }
 +
-     public Iterable<Function> getFunctions()
++    public void addFunctionsTo(List<Function> functions)
 +    {
-         return restrictions.getFunctions();
++        restrictions.addFunctionsTo(functions);
 +    }
 +
 +    public boolean isEmpty()
 +    {
 +        return restrictions.isEmpty();
 +    }
 +
 +    public int size()
 +    {
 +        return restrictions.size();
 +    }
 +
 +    public boolean hasSupportingIndex(SecondaryIndexManager indexManager)
 +    {
 +        return restrictions.hasSupportingIndex(indexManager);
 +    }
 +
 +    public ColumnDefinition getFirstColumn()
 +    {
 +        return restrictions.getFirstColumn();
 +    }
 +
 +    public ColumnDefinition getLastColumn()
 +    {
 +        return restrictions.getLastColumn();
 +    }
 +
 +    public boolean hasIN()
 +    {
 +        return restrictions.hasIN();
 +    }
 +
 +    public boolean hasOnlyEqualityRestrictions()
 +    {
 +        return restrictions.hasOnlyEqualityRestrictions();
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4edd9ed5/src/java/org/apache/cassandra/cql3/restrictions/SingleColumnRestriction.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/restrictions/SingleColumnRestriction.java
index 9c20bef,6296b97..ae883d1
--- a/src/java/org/apache/cassandra/cql3/restrictions/SingleColumnRestriction.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/SingleColumnRestriction.java
@@@ -18,12 -18,8 +18,10 @@@
  package org.apache.cassandra.cql3.restrictions;
  
  import java.nio.ByteBuffer;
 -import java.util.*;
 +import java.util.ArrayList;
 +import java.util.Collections;
 +import java.util.List;
  
- import com.google.common.collect.Iterables;
- 
  import org.apache.cassandra.config.ColumnDefinition;
  import org.apache.cassandra.cql3.*;
  import org.apache.cassandra.cql3.Term.Terminal;
@@@ -652,135 -646,4 +648,135 @@@ public abstract class SingleColumnRestr
              return index.supportsExpression(columnDef, Operator.IS_NOT);
          }
      }
 +
 +    public static final class LikeRestriction extends SingleColumnRestriction
 +    {
 +        private static final ByteBuffer LIKE_WILDCARD = ByteBufferUtil.bytes("%");
 +        private final Operator operator;
 +        private final Term value;
 +
 +        public LikeRestriction(ColumnDefinition columnDef, Operator operator, Term value)
 +        {
 +            super(columnDef);
 +            this.operator = operator;
 +            this.value = value;
 +        }
 +
 +        @Override
-         public Iterable<Function> getFunctions()
++        public void addFunctionsTo(List<Function> functions)
 +        {
-             return value.getFunctions();
++            value.addFunctionsTo(functions);
 +        }
 +
 +        @Override
 +        public boolean isEQ()
 +        {
 +            return false;
 +        }
 +
 +        @Override
 +        public boolean isLIKE()
 +        {
 +            return true;
 +        }
 +
 +        @Override
 +        public boolean canBeConvertedToMultiColumnRestriction()
 +        {
 +            return false;
 +        }
 +
 +        @Override
 +        MultiColumnRestriction toMultiColumnRestriction()
 +        {
 +            throw new UnsupportedOperationException();
 +        }
 +
 +        @Override
 +        public void addRowFilterTo(RowFilter filter,
 +                                   SecondaryIndexManager indexManager,
 +                                   QueryOptions options)
 +        {
 +            Pair<Operator, ByteBuffer> operation = makeSpecific(value.bindAndGet(options));
 +
 +            // there must be a suitable INDEX for LIKE_XXX expressions
 +            RowFilter.SimpleExpression expression = filter.add(columnDef, operation.left, operation.right);
 +            indexManager.getBestIndexFor(expression)
 +                        .orElseThrow(() -> invalidRequest("%s is only supported on properly indexed columns",
 +                                                          expression));
 +        }
 +
 +        @Override
 +        public MultiCBuilder appendTo(MultiCBuilder builder, QueryOptions options)
 +        {
 +            // LIKE can be used with clustering columns, but as it doesn't
 +            // represent an actual clustering value, it can't be used in a
 +            // clustering filter.
 +            throw new UnsupportedOperationException();
 +        }
 +
 +        @Override
 +        public String toString()
 +        {
 +            return operator.toString();
 +        }
 +
 +        @Override
 +        public SingleRestriction doMergeWith(SingleRestriction otherRestriction)
 +        {
 +            throw invalidRequest("%s cannot be restricted by more than one relation if it includes a %s", columnDef.name, operator);
 +        }
 +
 +        @Override
 +        protected boolean isSupportedBy(Index index)
 +        {
 +            return index.supportsExpression(columnDef, operator);
 +        }
 +
 +        /**
 +         * As the specific subtype of LIKE (LIKE_PREFIX, LIKE_SUFFIX, LIKE_CONTAINS, LIKE_MATCHES) can only be
 +         * determined by examining the value, which in turn can only be known after binding, all LIKE restrictions
 +         * are initially created with the generic LIKE operator. This function takes the bound value, trims the
 +         * wildcard '%' chars from it and returns a tuple of the inferred operator subtype and the final value
 +         * @param value the bound value for the LIKE operation
 +         * @return  Pair containing the inferred LIKE subtype and the value with wildcards removed
 +         */
 +        private static Pair<Operator, ByteBuffer> makeSpecific(ByteBuffer value)
 +        {
 +            Operator operator;
 +            int beginIndex = value.position();
 +            int endIndex = value.limit() - 1;
 +            if (ByteBufferUtil.endsWith(value, LIKE_WILDCARD))
 +            {
 +                if (ByteBufferUtil.startsWith(value, LIKE_WILDCARD))
 +                {
 +                    operator = Operator.LIKE_CONTAINS;
 +                    beginIndex =+ 1;
 +                }
 +                else
 +                {
 +                    operator = Operator.LIKE_PREFIX;
 +                }
 +            }
 +            else if (ByteBufferUtil.startsWith(value, LIKE_WILDCARD))
 +            {
 +                operator = Operator.LIKE_SUFFIX;
 +                beginIndex += 1;
 +                endIndex += 1;
 +            }
 +            else
 +            {
 +                operator = Operator.LIKE_MATCHES;
 +                endIndex += 1;
 +            }
 +
 +            if (endIndex == 0 || beginIndex == endIndex)
 +                throw invalidRequest("LIKE value can't be empty.");
 +
 +            ByteBuffer newValue = value.duplicate();
 +            newValue.position(beginIndex);
 +            newValue.limit(endIndex);
 +            return Pair.create(operator, newValue);
 +        }
 +    }
  }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4edd9ed5/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java
index 43a912d,6ee554e..f8a39ee
--- a/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java
@@@ -256,26 -242,30 +255,26 @@@ public final class StatementRestriction
  
      private void addRestriction(Restriction restriction)
      {
 -        if (restriction.isMultiColumn())
 -            clusteringColumnsRestrictions = clusteringColumnsRestrictions.mergeWith(restriction);
 -        else if (restriction.isOnToken())
 +        ColumnDefinition def = restriction.getFirstColumn();
 +        if (def.isPartitionKey())
              partitionKeyRestrictions = partitionKeyRestrictions.mergeWith(restriction);
 +        else if (def.isClusteringColumn())
 +            clusteringColumnsRestrictions = clusteringColumnsRestrictions.mergeWith(restriction);
          else
 -            addSingleColumnRestriction((SingleColumnRestriction) restriction);
 +            nonPrimaryKeyRestrictions = nonPrimaryKeyRestrictions.addRestriction((SingleRestriction) restriction);
      }
  
-     public Iterable<Function> getFunctions()
+     public void addFunctionsTo(List<Function> functions)
      {
-         return Iterables.concat(partitionKeyRestrictions.getFunctions(),
-                                 clusteringColumnsRestrictions.getFunctions(),
-                                 nonPrimaryKeyRestrictions.getFunctions());
+         partitionKeyRestrictions.addFunctionsTo(functions);
+         clusteringColumnsRestrictions.addFunctionsTo(functions);
+         nonPrimaryKeyRestrictions.addFunctionsTo(functions);
      }
  
 -    private void addSingleColumnRestriction(SingleColumnRestriction restriction)
 +    // may be used by QueryHandler implementations
 +    public IndexRestrictions getIndexRestrictions()
      {
 -        ColumnDefinition def = restriction.columnDef;
 -        if (def.isPartitionKey())
 -            partitionKeyRestrictions = partitionKeyRestrictions.mergeWith(restriction);
 -        else if (def.isClusteringColumn())
 -            clusteringColumnsRestrictions = clusteringColumnsRestrictions.mergeWith(restriction);
 -        else
 -            nonPrimaryKeyRestrictions = nonPrimaryKeyRestrictions.addRestriction(restriction);
 +        return filterRestrictions;
      }
  
      /**

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4edd9ed5/src/java/org/apache/cassandra/cql3/restrictions/TokenFilter.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/restrictions/TokenFilter.java
index 9069501,3258b26..66e0cfb
--- a/src/java/org/apache/cassandra/cql3/restrictions/TokenFilter.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/TokenFilter.java
@@@ -228,52 -233,4 +228,52 @@@ final class TokenFilter implements Part
      {
          return inclusive ? BoundType.CLOSED : BoundType.OPEN;
      }
 +
 +    @Override
 +    public ColumnDefinition getFirstColumn()
 +    {
-         return this.restrictions.getFirstColumn();
++        return restrictions.getFirstColumn();
 +    }
 +
 +    @Override
 +    public ColumnDefinition getLastColumn()
 +    {
-         return this.restrictions.getLastColumn();
++        return restrictions.getLastColumn();
 +    }
 +
 +    @Override
 +    public List<ColumnDefinition> getColumnDefs()
 +    {
-         return this.restrictions.getColumnDefs();
++        return restrictions.getColumnDefs();
 +    }
 +
 +    @Override
-     public Iterable<Function> getFunctions()
++    public void addFunctionsTo(List<Function> functions)
 +    {
-         return this.restrictions.getFunctions();
++        restrictions.addFunctionsTo(functions);
 +    }
 +
 +    @Override
 +    public boolean hasSupportingIndex(SecondaryIndexManager indexManager)
 +    {
-         return this.restrictions.hasSupportingIndex(indexManager);
++        return restrictions.hasSupportingIndex(indexManager);
 +    }
 +
 +    @Override
 +    public void addRowFilterTo(RowFilter filter, SecondaryIndexManager indexManager, QueryOptions options)
 +    {
-         this.restrictions.addRowFilterTo(filter, indexManager, options);
++        restrictions.addRowFilterTo(filter, indexManager, options);
 +    }
 +
 +    @Override
 +    public boolean isEmpty()
 +    {
-         return this.restrictions.isEmpty();
++        return restrictions.isEmpty();
 +    }
 +
 +    @Override
 +    public int size()
 +    {
-         return this.restrictions.size();
++        return restrictions.size();
 +    }
  }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4edd9ed5/src/java/org/apache/cassandra/cql3/restrictions/TokenRestriction.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/restrictions/TokenRestriction.java
index 66cdb80,14d2cb7..a71c64c
--- a/src/java/org/apache/cassandra/cql3/restrictions/TokenRestriction.java
+++ b/src/java/org/apache/cassandra/cql3/restrictions/TokenRestriction.java
@@@ -171,9 -166,15 +171,9 @@@ public abstract class TokenRestriction 
          }
  
          @Override
-         public Iterable<Function> getFunctions()
 -        public boolean isEQ()
 -        {
 -            return true;
 -        }
 -
 -        @Override
+         public void addFunctionsTo(List<Function> functions)
          {
-             return value.getFunctions();
+             value.addFunctionsTo(functions);
          }
  
          @Override

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4edd9ed5/src/java/org/apache/cassandra/cql3/selection/AbstractFunctionSelector.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/selection/AbstractFunctionSelector.java
index 0ccff6b,c48b93c..868f752
--- a/src/java/org/apache/cassandra/cql3/selection/AbstractFunctionSelector.java
+++ b/src/java/org/apache/cassandra/cql3/selection/AbstractFunctionSelector.java
@@@ -21,9 -21,10 +21,7 @@@ import java.nio.ByteBuffer
  import java.util.Arrays;
  import java.util.List;
  
- import com.google.common.collect.Iterables;
- 
  import org.apache.commons.lang3.text.StrBuilder;
 -
 -import org.apache.cassandra.cql3.functions.AggregateFcts;
 -
  import org.apache.cassandra.config.ColumnDefinition;
  import org.apache.cassandra.cql3.ColumnSpecification;
  import org.apache.cassandra.cql3.functions.Function;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4edd9ed5/src/java/org/apache/cassandra/cql3/selection/Selection.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4edd9ed5/src/java/org/apache/cassandra/cql3/selection/Selector.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4edd9ed5/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4edd9ed5/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
index 6224457,12bade5..af89ba8
--- a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
@@@ -141,20 -141,19 +141,27 @@@ public abstract class ModificationState
  
      public Iterable<Function> getFunctions()
      {
-         return Iterables.concat(attrs.getFunctions(),
-                                 restrictions.getFunctions(),
-                                 operations.getFunctions(),
-                                 conditions.getFunctions());
+         List<Function> functions = new ArrayList<>();
+         addFunctionsTo(functions);
+         return functions;
+     }
+ 
+     public void addFunctionsTo(List<Function> functions)
+     {
+         attrs.addFunctionsTo(functions);
+         restrictions.addFunctionsTo(functions);
+         operations.addFunctionsTo(functions);
+         conditions.addFunctionsTo(functions);
      }
  
 +    /*
 +     * May be used by QueryHandler implementations
 +     */
 +    public StatementRestrictions getRestrictions()
 +    {
 +        return restrictions;
 +    }
 +
      public abstract void addUpdateForKey(PartitionUpdate update, Clustering clustering, UpdateParameters params);
  
      public abstract void addUpdateForKey(PartitionUpdate update, Slice slice, UpdateParameters params);

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4edd9ed5/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
index 3f72bd8,c3e13f4..36df69a
--- a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
@@@ -125,10 -120,18 +125,21 @@@ public class SelectStatement implement
  
      public Iterable<Function> getFunctions()
      {
-         return Iterables.concat(selection.getFunctions(),
-                                 restrictions.getFunctions(),
-                                 limit != null ? limit.getFunctions() : Collections.<Function>emptySet(),
-                                 perPartitionLimit != null ? perPartitionLimit.getFunctions() : Collections.<Function>emptySet());
+         List<Function> functions = new ArrayList<>();
+         addFunctionsTo(functions);
+         return functions;
+     }
+ 
+     private void addFunctionsTo(List<Function> functions)
+     {
+         selection.addFunctionsTo(functions);
+         restrictions.addFunctionsTo(functions);
+ 
+         if (limit != null)
+             limit.addFunctionsTo(functions);
++
++        if (perPartitionLimit != null)
++            perPartitionLimit.addFunctionsTo(functions);
      }
  
      // Note that the queried columns internally is different from the one selected by the