You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by sl...@apache.org on 2016/12/13 09:27:35 UTC

[11/26] cassandra git commit: Thrift removal

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/config/CFMetaData.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/config/CFMetaData.java b/src/java/org/apache/cassandra/config/CFMetaData.java
index 8f11089..bc92af0 100644
--- a/src/java/org/apache/cassandra/config/CFMetaData.java
+++ b/src/java/org/apache/cassandra/config/CFMetaData.java
@@ -121,9 +121,6 @@ public final class CFMetaData
 
     public final DataResource resource;
 
-    //For hot path serialization it's often easier to store this info here
-    private volatile ColumnFilter allColumnFilter;
-
     /*
      * All of these methods will go away once CFMetaData becomes completely immutable.
      */
@@ -327,8 +324,6 @@ public final class CFMetaData
 
         if (isCompactTable())
             this.compactValueColumn = CompactTables.getCompactValueColumn(partitionColumns, isSuper());
-
-        this.allColumnFilter = ColumnFilter.all(this);
     }
 
     public Indexes getIndexes()
@@ -336,11 +331,6 @@ public final class CFMetaData
         return indexes;
     }
 
-    public ColumnFilter getAllColumnFilter()
-    {
-        return allColumnFilter;
-    }
-
     public static CFMetaData create(String ksName,
                                     String name,
                                     UUID cfId,
@@ -565,15 +555,6 @@ public final class CFMetaData
         return columnMetadata;
     }
 
-    /**
-     *
-     * @return The name of the parent cf if this is a seconday index
-     */
-    public String getParentColumnFamilyName()
-    {
-        return isIndex ? cfName.substring(0, cfName.indexOf('.')) : null;
-    }
-
     public ReadRepairDecision newReadRepairDecision()
     {
         double chance = ThreadLocalRandom.current().nextDouble();
@@ -589,7 +570,7 @@ public final class CFMetaData
     public AbstractType<?> getColumnDefinitionNameComparator(ColumnDefinition.Kind kind)
     {
         return (isSuper() && kind == ColumnDefinition.Kind.REGULAR) || (isStaticCompactTable() && kind == ColumnDefinition.Kind.STATIC)
-             ? thriftColumnNameType()
+             ? staticCompactOrSuperTableColumnNameType()
              : UTF8Type.instance;
     }
 
@@ -605,7 +586,7 @@ public final class CFMetaData
 
     // An iterator over all column definitions but that respect the order of a SELECT *.
     // This also "hide" the clustering/regular columns for a non-CQL3 non-dense table for backward compatibility
-    // sake (those are accessible through thrift but not through CQL currently).
+    // sake.
     public Iterator<ColumnDefinition> allColumnsInSelectOrder()
     {
         final boolean isStaticCompactTable = isStaticCompactTable();
@@ -779,9 +760,6 @@ public final class CFMetaData
 
         rebuild();
 
-        // compaction thresholds are checked by ThriftValidation. We shouldn't be doing
-        // validation on the apply path; it's too late for that.
-
         params = cfm.params;
 
         keyValidator = cfm.keyValidator;
@@ -919,10 +897,17 @@ public final class CFMetaData
         return this;
     }
 
-
-
-    // The comparator to validate the definition name with thrift.
-    public AbstractType<?> thriftColumnNameType()
+    /**
+     * The type to use to compare column names in "static compact"
+     * tables or superColum ones.
+     * <p>
+     * This exists because for historical reasons, "static compact" tables as
+     * well as super column ones can have non-UTF8 column names.
+     * <p>
+     * This method should only be called for superColumn tables and "static
+     * compact" ones. For any other table, all column names are UTF8.
+     */
+    public AbstractType<?> staticCompactOrSuperTableColumnNameType()
     {
         if (isSuper())
         {
@@ -1003,10 +988,8 @@ public final class CFMetaData
         if (getColumnDefinition(to) != null)
             throw new InvalidRequestException(String.format("Cannot rename column %s to %s in keyspace %s; another column of that name already exist", from, to, cfName));
 
-        if (def.isPartOfCellName(isCQLTable(), isSuper()))
-        {
+        if (!def.isPrimaryKeyColumn())
             throw new InvalidRequestException(String.format("Cannot rename non PRIMARY KEY part %s", from));
-        }
 
         if (!getIndexes().isEmpty())
         {
@@ -1032,6 +1015,19 @@ public final class CFMetaData
             removeColumnDefinition(def);
     }
 
+    /**
+     * Records a deprecated column for a system table.
+     */
+    public CFMetaData recordDeprecatedSystemColumn(String name, AbstractType<?> type)
+    {
+        // As we play fast and loose with the removal timestamp, make sure this is misued for a non system table.
+        assert SchemaConstants.isSystemKeyspace(ksName);
+        ByteBuffer bb = ByteBufferUtil.bytes(name);
+        recordColumnDrop(ColumnDefinition.regularDef(this, bb, type), Long.MAX_VALUE);
+        return this;
+    }
+
+
     public boolean isCQLTable()
     {
         return !isSuper() && !isDense() && isCompound();
@@ -1047,43 +1043,11 @@ public final class CFMetaData
         return !isSuper() && !isDense() && !isCompound();
     }
 
-    /**
-     * Returns whether this CFMetaData can be returned to thrift.
-     */
-    public boolean isThriftCompatible()
-    {
-        return isCompactTable();
-    }
-
     public boolean hasStaticColumns()
     {
         return !partitionColumns.statics.isEmpty();
     }
 
-    public boolean hasCollectionColumns()
-    {
-        for (ColumnDefinition def : partitionColumns())
-            if (def.type instanceof CollectionType && def.type.isMultiCell())
-                return true;
-        return false;
-    }
-
-    public boolean hasComplexColumns()
-    {
-        for (ColumnDefinition def : partitionColumns())
-            if (def.isComplex())
-                return true;
-        return false;
-    }
-
-    public boolean hasDroppedCollectionColumns()
-    {
-        for (DroppedColumn def : getDroppedColumns().values())
-            if (def.type instanceof CollectionType && def.type.isMultiCell())
-                return true;
-        return false;
-    }
-
     public boolean isSuper()
     {
         return isSuper;
@@ -1112,13 +1076,6 @@ public final class CFMetaData
         return isView;
     }
 
-    public AbstractType<?> makeLegacyDefaultValidator()
-    {
-        return isCounter()
-             ? CounterColumnType.instance
-             : (isCompactTable() ? compactValueColumn().type : BytesType.instance);
-    }
-
     public static Set<Flag> flagsFromStrings(Set<String> strings)
     {
         return strings.stream()

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/config/ColumnDefinition.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/config/ColumnDefinition.java b/src/java/org/apache/cassandra/config/ColumnDefinition.java
index efdea0d..65cf837 100644
--- a/src/java/org/apache/cassandra/config/ColumnDefinition.java
+++ b/src/java/org/apache/cassandra/config/ColumnDefinition.java
@@ -54,9 +54,6 @@ public class ColumnDefinition extends ColumnSpecification implements Selectable,
      * those parts of the clustering columns and amongst the others, regular and
      * static ones.
      *
-     * Note that thrift only knows about definitions of type REGULAR (and
-     * the ones whose position == NO_POSITION (-1)).
-     *
      * IMPORTANT: this enum is serialized as toString() and deserialized by calling
      * Kind.valueOf(), so do not override toString() or rename existing values.
      */
@@ -311,23 +308,6 @@ public class ColumnDefinition extends ColumnSpecification implements Selectable,
     }
 
     /**
-     * Whether the name of this definition is serialized in the cell nane, i.e. whether
-     * it's not just a non-stored CQL metadata.
-     */
-    public boolean isPartOfCellName(boolean isCQL3Table, boolean isSuper)
-    {
-        // When converting CQL3 tables to thrift, any regular or static column ends up in the cell name.
-        // When it's a compact table however, the REGULAR definition is the name for the cell value of "dynamic"
-        // column (so it's not part of the cell name) and it's static columns that ends up in the cell name.
-        if (isCQL3Table)
-            return kind == Kind.REGULAR || kind == Kind.STATIC;
-        else if (isSuper)
-            return kind == Kind.REGULAR;
-        else
-            return kind == Kind.STATIC;
-    }
-
-    /**
      * Converts the specified column definitions into column identifiers.
      *
      * @param definitions the column definitions to convert.
@@ -463,7 +443,7 @@ public class ColumnDefinition extends ColumnSpecification implements Selectable,
     }
 
     /**
-     * Because Thrift-created tables may have a non-text comparator, we cannot determine the proper 'key' until
+     * Because legacy-created tables may have a non-text comparator, we cannot determine the proper 'key' until
      * we know the comparator. ColumnDefinition.Raw is a placeholder that can be converted to a real ColumnIdentifier
      * once the comparator is known with prepare(). This should only be used with identifiers that are actual
      * column names. See CASSANDRA-8178 for more background.
@@ -543,19 +523,19 @@ public class ColumnDefinition extends ColumnSpecification implements Selectable,
                 if (!cfm.isStaticCompactTable())
                     return ColumnIdentifier.getInterned(text, true);
 
-                AbstractType<?> thriftColumnNameType = cfm.thriftColumnNameType();
-                if (thriftColumnNameType instanceof UTF8Type)
+                AbstractType<?> columnNameType = cfm.staticCompactOrSuperTableColumnNameType();
+                if (columnNameType instanceof UTF8Type)
                     return ColumnIdentifier.getInterned(text, true);
 
-                // We have a Thrift-created table with a non-text comparator. Check if we have a match column, otherwise assume we should use
-                // thriftColumnNameType
+                // We have a legacy-created table with a non-text comparator. Check if we have a matching column, otherwise assume we should use
+                // columnNameType
                 ByteBuffer bufferName = ByteBufferUtil.bytes(text);
                 for (ColumnDefinition def : cfm.allColumns())
                 {
                     if (def.name.bytes.equals(bufferName))
                         return def.name;
                 }
-                return ColumnIdentifier.getInterned(thriftColumnNameType, thriftColumnNameType.fromString(text), text);
+                return ColumnIdentifier.getInterned(columnNameType, columnNameType.fromString(text), text);
             }
 
             public ColumnDefinition prepare(CFMetaData cfm)
@@ -563,19 +543,19 @@ public class ColumnDefinition extends ColumnSpecification implements Selectable,
                 if (!cfm.isStaticCompactTable())
                     return find(cfm);
 
-                AbstractType<?> thriftColumnNameType = cfm.thriftColumnNameType();
-                if (thriftColumnNameType instanceof UTF8Type)
+                AbstractType<?> columnNameType = cfm.staticCompactOrSuperTableColumnNameType();
+                if (columnNameType instanceof UTF8Type)
                     return find(cfm);
 
-                // We have a Thrift-created table with a non-text comparator. Check if we have a match column, otherwise assume we should use
-                // thriftColumnNameType
+                // We have a legacy-created table with a non-text comparator. Check if we have a match column, otherwise assume we should use
+                // columnNameType
                 ByteBuffer bufferName = ByteBufferUtil.bytes(text);
                 for (ColumnDefinition def : cfm.allColumns())
                 {
                     if (def.name.bytes.equals(bufferName))
                         return def;
                 }
-                return find(thriftColumnNameType.fromString(text), cfm);
+                return find(columnNameType.fromString(text), cfm);
             }
 
             private ColumnDefinition find(CFMetaData cfm)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/config/Config.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/config/Config.java b/src/java/org/apache/cassandra/config/Config.java
index be0517f..f5a8722 100644
--- a/src/java/org/apache/cassandra/config/Config.java
+++ b/src/java/org/apache/cassandra/config/Config.java
@@ -131,21 +131,11 @@ public class Config
     public boolean listen_on_broadcast_address = false;
     public String internode_authenticator;
 
-    /* intentionally left set to true, despite being set to false in stock 2.2 cassandra.yaml
-       we don't want to surprise Thrift users who have the setting blank in the yaml during 2.1->2.2 upgrade */
-    public boolean start_rpc = true;
     public String rpc_address;
     public String rpc_interface;
     public boolean rpc_interface_prefer_ipv6 = false;
     public String broadcast_rpc_address;
-    public int rpc_port = 9160;
-    public int rpc_listen_backlog = 50;
-    public String rpc_server_type = "sync";
     public boolean rpc_keepalive = true;
-    public int rpc_min_threads = 16;
-    public int rpc_max_threads = Integer.MAX_VALUE;
-    public Integer rpc_send_buff_size_in_bytes;
-    public Integer rpc_recv_buff_size_in_bytes;
     public int internode_send_buff_size_in_bytes = 0;
     public int internode_recv_buff_size_in_bytes = 0;
 
@@ -157,8 +147,6 @@ public class Config
     public volatile long native_transport_max_concurrent_connections = -1L;
     public volatile long native_transport_max_concurrent_connections_per_ip = -1L;
 
-    @Deprecated
-    public int thrift_max_message_length_in_mb = 16;
     /**
      * Max size of values in SSTables, in MegaBytes.
      * Default is the same as the native protocol frame limit: 256Mb.
@@ -166,7 +154,6 @@ public class Config
      */
     public int max_value_size_in_mb = 256;
 
-    public int thrift_framed_transport_size_in_mb = 15;
     public boolean snapshot_before_compaction = false;
     public boolean auto_snapshot = true;
 
@@ -222,10 +209,6 @@ public class Config
     public int dynamic_snitch_reset_interval_in_ms = 600000;
     public double dynamic_snitch_badness_threshold = 0.1;
 
-    public String request_scheduler;
-    public RequestSchedulerId request_scheduler_id;
-    public RequestSchedulerOptions request_scheduler_options;
-
     public EncryptionOptions.ServerEncryptionOptions server_encryption_options = new EncryptionOptions.ServerEncryptionOptions();
     public EncryptionOptions.ClientEncryptionOptions client_encryption_options = new EncryptionOptions.ClientEncryptionOptions();
     // this encOptions is for backward compatibility (a warning is logged by DatabaseDescriptor)
@@ -313,11 +296,6 @@ public class Config
      * Defaults to 1/256th of the heap size or 10MB, whichever is greater.
      */
     public Long prepared_statements_cache_size_mb = null;
-    /**
-     * Size of the Thrift prepared statements cache in MB.
-     * Defaults to 1/256th of the heap size or 10MB, whichever is greater.
-     */
-    public Long thrift_prepared_statements_cache_size_mb = null;
 
     public boolean enable_user_defined_functions = false;
     public boolean enable_scripted_user_defined_functions = false;
@@ -426,11 +404,6 @@ public class Config
         die_immediate
     }
 
-    public enum RequestSchedulerId
-    {
-        keyspace
-    }
-
     public enum DiskOptimizationStrategy
     {
         ssd,

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
index 4261674..c43672a 100644
--- a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
+++ b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
@@ -42,7 +42,6 @@ import org.apache.cassandra.auth.IAuthorizer;
 import org.apache.cassandra.auth.IInternodeAuthenticator;
 import org.apache.cassandra.auth.IRoleManager;
 import org.apache.cassandra.config.Config.CommitLogSync;
-import org.apache.cassandra.config.Config.RequestSchedulerId;
 import org.apache.cassandra.dht.IPartitioner;
 import org.apache.cassandra.exceptions.ConfigurationException;
 import org.apache.cassandra.io.FSWriteError;
@@ -56,11 +55,8 @@ import org.apache.cassandra.locator.IEndpointSnitch;
 import org.apache.cassandra.locator.SeedProvider;
 import org.apache.cassandra.net.BackPressureStrategy;
 import org.apache.cassandra.net.RateBasedBackPressure;
-import org.apache.cassandra.scheduler.IRequestScheduler;
-import org.apache.cassandra.scheduler.NoScheduler;
 import org.apache.cassandra.security.EncryptionContext;
 import org.apache.cassandra.service.CacheService.CacheType;
-import org.apache.cassandra.thrift.ThriftServer.ThriftServerType;
 import org.apache.cassandra.utils.FBUtilities;
 
 import org.apache.commons.lang3.StringUtils;
@@ -97,12 +93,7 @@ public class DatabaseDescriptor
     // depend on the configured IAuthenticator, so defer creating it until that's been set.
     private static IRoleManager roleManager;
 
-    private static IRequestScheduler requestScheduler;
-    private static RequestSchedulerId requestSchedulerId;
-    private static RequestSchedulerOptions requestSchedulerOptions;
-
     private static long preparedStatementsCacheSizeInMB;
-    private static long thriftPreparedStatementsCacheSizeInMB;
 
     private static long keyCacheSizeInMB;
     private static long counterCacheSizeInMB;
@@ -312,12 +303,8 @@ public class DatabaseDescriptor
 
         applyAddressConfig();
 
-        applyThriftHSHA();
-
         applySnitch();
 
-        applyRequestScheduler();
-
         applyInitialTokens();
 
         applySeedProvider();
@@ -423,9 +410,6 @@ public class DatabaseDescriptor
         else
             logger.info("Global memtable off-heap threshold is enabled at {}MB", conf.memtable_offheap_space_in_mb);
 
-        if (conf.thrift_framed_transport_size_in_mb <= 0)
-            throw new ConfigurationException("thrift_framed_transport_size_in_mb must be positive, but was " + conf.thrift_framed_transport_size_in_mb, false);
-
         if (conf.native_transport_max_frame_size_in_mb <= 0)
             throw new ConfigurationException("native_transport_max_frame_size_in_mb must be positive, but was " + conf.native_transport_max_frame_size_in_mb, false);
 
@@ -599,22 +583,6 @@ public class DatabaseDescriptor
 
         try
         {
-            // if thrift_prepared_statements_cache_size_mb option was set to "auto" then size of the cache should be "max(1/256 of Heap (in MB), 10MB)"
-            thriftPreparedStatementsCacheSizeInMB = (conf.thrift_prepared_statements_cache_size_mb == null)
-                                                    ? Math.max(10, (int) (Runtime.getRuntime().maxMemory() / 1024 / 1024 / 256))
-                                                    : conf.thrift_prepared_statements_cache_size_mb;
-
-            if (thriftPreparedStatementsCacheSizeInMB <= 0)
-                throw new NumberFormatException(); // to escape duplicating error message
-        }
-        catch (NumberFormatException e)
-        {
-            throw new ConfigurationException("thrift_prepared_statements_cache_size_mb option was set incorrectly to '"
-                                             + conf.thrift_prepared_statements_cache_size_mb + "', supported values are <integer> >= 0.", false);
-        }
-
-        try
-        {
             // if key_cache_size_in_mb option was set to "auto" then size of the cache should be "min(5% of Heap (in MB), 100MB)
             keyCacheSizeInMB = (conf.key_cache_size_in_mb == null)
                                ? Math.min(Math.max(1, (int) (Runtime.getRuntime().totalMemory() * 0.05 / 1024 / 1024)), 100)
@@ -833,18 +801,6 @@ public class DatabaseDescriptor
         }
     }
 
-    public static void applyThriftHSHA()
-    {
-        // fail early instead of OOMing (see CASSANDRA-8116)
-        if (ThriftServerType.HSHA.equals(conf.rpc_server_type) && conf.rpc_max_threads == Integer.MAX_VALUE)
-            throw new ConfigurationException("The hsha rpc_server_type is not compatible with an rpc_max_threads " +
-                                             "setting of 'unlimited'.  Please see the comments in cassandra.yaml " +
-                                             "for rpc_server_type and rpc_max_threads.",
-                                             false);
-        if (ThriftServerType.HSHA.equals(conf.rpc_server_type) && conf.rpc_max_threads > (FBUtilities.getAvailableProcessors() * 2 + 1024))
-            logger.warn("rpc_max_threads setting of {} may be too high for the hsha server and cause unnecessary thread contention, reducing performance", conf.rpc_max_threads);
-    }
-
     public static void applyEncryptionContext()
     {
         // always attempt to load the cipher factory, as we could be in the situation where the user has disabled encryption,
@@ -886,47 +842,6 @@ public class DatabaseDescriptor
         }
     }
 
-    // Maybe safe for clients + tools
-    public static void applyRequestScheduler()
-    {
-        /* Request Scheduler setup */
-        requestSchedulerOptions = conf.request_scheduler_options;
-        if (conf.request_scheduler != null)
-        {
-            try
-            {
-                if (requestSchedulerOptions == null)
-                {
-                    requestSchedulerOptions = new RequestSchedulerOptions();
-                }
-                Class<?> cls = Class.forName(conf.request_scheduler);
-                requestScheduler = (IRequestScheduler) cls.getConstructor(RequestSchedulerOptions.class).newInstance(requestSchedulerOptions);
-            }
-            catch (ClassNotFoundException e)
-            {
-                throw new ConfigurationException("Invalid Request Scheduler class " + conf.request_scheduler, false);
-            }
-            catch (Exception e)
-            {
-                throw new ConfigurationException("Unable to instantiate request scheduler", e);
-            }
-        }
-        else
-        {
-            requestScheduler = new NoScheduler();
-        }
-
-        if (conf.request_scheduler_id == RequestSchedulerId.keyspace)
-        {
-            requestSchedulerId = conf.request_scheduler_id;
-        }
-        else
-        {
-            // Default to Keyspace
-            requestSchedulerId = RequestSchedulerId.keyspace;
-        }
-    }
-
     // definitely not safe for tools + clients - implicitly instantiates StorageService
     public static void applySnitch()
     {
@@ -1127,11 +1042,6 @@ public class DatabaseDescriptor
         return conf.credentials_cache_max_entries = maxEntries;
     }
 
-    public static int getThriftFramedTransportSize()
-    {
-        return conf.thrift_framed_transport_size_in_mb * 1024 * 1024;
-    }
-
     public static int getMaxValueSize()
     {
         return conf.max_value_size_in_mb * 1024 * 1024;
@@ -1211,21 +1121,6 @@ public class DatabaseDescriptor
         snitch = eps;
     }
 
-    public static IRequestScheduler getRequestScheduler()
-    {
-        return requestScheduler;
-    }
-
-    public static RequestSchedulerOptions getRequestSchedulerOptions()
-    {
-        return requestSchedulerOptions;
-    }
-
-    public static RequestSchedulerId getRequestSchedulerId()
-    {
-        return requestSchedulerId;
-    }
-
     public static int getColumnIndexSize()
     {
         return conf.column_index_size_in_kb * 1024;
@@ -1349,16 +1244,6 @@ public class DatabaseDescriptor
         return Integer.parseInt(System.getProperty(Config.PROPERTY_PREFIX + "ssl_storage_port", Integer.toString(conf.ssl_storage_port)));
     }
 
-    public static int getRpcPort()
-    {
-        return Integer.parseInt(System.getProperty(Config.PROPERTY_PREFIX + "rpc_port", Integer.toString(conf.rpc_port)));
-    }
-
-    public static int getRpcListenBacklog()
-    {
-        return conf.rpc_listen_backlog;
-    }
-
     public static long getRpcTimeout()
     {
         return conf.request_timeout_in_ms;
@@ -1658,11 +1543,6 @@ public class DatabaseDescriptor
         broadcastAddress = broadcastAdd;
     }
 
-    public static boolean startRpc()
-    {
-        return conf.start_rpc;
-    }
-
     public static InetAddress getRpcAddress()
     {
         return rpcAddress;
@@ -1681,36 +1561,11 @@ public class DatabaseDescriptor
         return broadcastRpcAddress;
     }
 
-    public static String getRpcServerType()
-    {
-        return conf.rpc_server_type;
-    }
-
     public static boolean getRpcKeepAlive()
     {
         return conf.rpc_keepalive;
     }
 
-    public static Integer getRpcMinThreads()
-    {
-        return conf.rpc_min_threads;
-    }
-
-    public static Integer getRpcMaxThreads()
-    {
-        return conf.rpc_max_threads;
-    }
-
-    public static Integer getRpcSendBufferSize()
-    {
-        return conf.rpc_send_buff_size_in_bytes;
-    }
-
-    public static Integer getRpcRecvBufferSize()
-    {
-        return conf.rpc_recv_buff_size_in_bytes;
-    }
-
     public static int getInternodeSendBufferSize()
     {
         return conf.internode_send_buff_size_in_bytes;
@@ -2266,11 +2121,6 @@ public class DatabaseDescriptor
         return preparedStatementsCacheSizeInMB;
     }
 
-    public static long getThriftPreparedStatementsCacheSizeMB()
-    {
-        return thriftPreparedStatementsCacheSizeInMB;
-    }
-
     public static boolean enableUserDefinedFunctions()
     {
         return conf.enable_user_defined_functions;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/config/RequestSchedulerOptions.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/config/RequestSchedulerOptions.java b/src/java/org/apache/cassandra/config/RequestSchedulerOptions.java
deleted file mode 100644
index dacf405..0000000
--- a/src/java/org/apache/cassandra/config/RequestSchedulerOptions.java
+++ /dev/null
@@ -1,33 +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.config;
-
-import java.util.Map;
-
-/**
- *
- */
-public class RequestSchedulerOptions
-{
-    public static final Integer DEFAULT_THROTTLE_LIMIT = 80;
-    public static final Integer DEFAULT_WEIGHT = 1;
-
-    public Integer throttle_limit = DEFAULT_THROTTLE_LIMIT;
-    public Integer default_weight = DEFAULT_WEIGHT;
-    public Map<String, Integer> weights;
-}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/cql3/CQL3Type.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/CQL3Type.java b/src/java/org/apache/cassandra/cql3/CQL3Type.java
index 20f3e2d..7e375bf 100644
--- a/src/java/org/apache/cassandra/cql3/CQL3Type.java
+++ b/src/java/org/apache/cassandra/cql3/CQL3Type.java
@@ -663,7 +663,7 @@ public interface CQL3Type
                 if (!frozen && values.supportsFreezing() && !values.frozen)
                     throwNestedNonFrozenError(values);
 
-                // we represent Thrift supercolumns as maps, internally, and we do allow counters in supercolumns. Thus,
+                // we represent supercolumns as maps, internally, and we do allow counters in supercolumns. Thus,
                 // for internal type parsing (think schema) we have to make an exception and allow counters as (map) values
                 if (values.isCounter() && !isInternal)
                     throw new InvalidRequestException("Counters are not allowed inside collections: " + this);

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/cql3/CustomPayloadMirroringQueryHandler.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/CustomPayloadMirroringQueryHandler.java b/src/java/org/apache/cassandra/cql3/CustomPayloadMirroringQueryHandler.java
index 643c54b..aa8ca48 100644
--- a/src/java/org/apache/cassandra/cql3/CustomPayloadMirroringQueryHandler.java
+++ b/src/java/org/apache/cassandra/cql3/CustomPayloadMirroringQueryHandler.java
@@ -58,11 +58,6 @@ public class CustomPayloadMirroringQueryHandler implements QueryHandler
         return queryProcessor.getPrepared(id);
     }
 
-    public ParsedStatement.Prepared getPreparedForThrift(Integer id)
-    {
-        return queryProcessor.getPreparedForThrift(id);
-    }
-
     public ResultMessage processPrepared(CQLStatement statement,
                                          QueryState state,
                                          QueryOptions options,

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/cql3/QueryHandler.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/QueryHandler.java b/src/java/org/apache/cassandra/cql3/QueryHandler.java
index 2108d4c..0339d26 100644
--- a/src/java/org/apache/cassandra/cql3/QueryHandler.java
+++ b/src/java/org/apache/cassandra/cql3/QueryHandler.java
@@ -42,8 +42,6 @@ public interface QueryHandler
 
     ParsedStatement.Prepared getPrepared(MD5Digest id);
 
-    ParsedStatement.Prepared getPreparedForThrift(Integer id);
-
     ResultMessage processPrepared(CQLStatement statement,
                                   QueryState state,
                                   QueryOptions options,

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/cql3/QueryOptions.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/QueryOptions.java b/src/java/org/apache/cassandra/cql3/QueryOptions.java
index 1ba8f89..57d5eac 100644
--- a/src/java/org/apache/cassandra/cql3/QueryOptions.java
+++ b/src/java/org/apache/cassandra/cql3/QueryOptions.java
@@ -52,11 +52,6 @@ public abstract class QueryOptions
     // A cache of bind values parsed as JSON, see getJsonColumnValue for details.
     private List<Map<ColumnIdentifier, Term>> jsonValuesCache;
 
-    public static QueryOptions fromThrift(ConsistencyLevel consistency, List<ByteBuffer> values)
-    {
-        return new DefaultQueryOptions(consistency, values, false, SpecificOptions.DEFAULT, ProtocolVersion.V3);
-    }
-
     public static QueryOptions forInternalCalls(ConsistencyLevel consistency, List<ByteBuffer> values)
     {
         return new DefaultQueryOptions(consistency, values, false, SpecificOptions.DEFAULT, ProtocolVersion.V3);
@@ -178,8 +173,7 @@ public abstract class QueryOptions
     }
 
     /**
-     * The protocol version for the query. Will be 3 if the object don't come from
-     * a native protocol request (i.e. it's been allocated locally or by CQL-over-thrift).
+     * The protocol version for the query.
      */
     public abstract ProtocolVersion getProtocolVersion();
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/cql3/QueryProcessor.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/QueryProcessor.java b/src/java/org/apache/cassandra/cql3/QueryProcessor.java
index 288fd4b..354ee72 100644
--- a/src/java/org/apache/cassandra/cql3/QueryProcessor.java
+++ b/src/java/org/apache/cassandra/cql3/QueryProcessor.java
@@ -50,7 +50,6 @@ import org.apache.cassandra.exceptions.*;
 import org.apache.cassandra.metrics.CQLMetrics;
 import org.apache.cassandra.service.*;
 import org.apache.cassandra.service.pager.QueryPager;
-import org.apache.cassandra.thrift.ThriftClientState;
 import org.apache.cassandra.tracing.Tracing;
 import org.apache.cassandra.transport.ProtocolVersion;
 import org.apache.cassandra.transport.messages.ResultMessage;
@@ -67,7 +66,6 @@ public class QueryProcessor implements QueryHandler
     private static final Logger logger = LoggerFactory.getLogger(QueryProcessor.class);
 
     private static final ConcurrentLinkedHashMap<MD5Digest, ParsedStatement.Prepared> preparedStatements;
-    private static final ConcurrentLinkedHashMap<Integer, ParsedStatement.Prepared> thriftPreparedStatements;
 
     // A map for prepared statements used internally (which we don't want to mix with user statement, in particular we don't
     // bother with expiration on those.
@@ -78,7 +76,6 @@ public class QueryProcessor implements QueryHandler
     public static final CQLMetrics metrics = new CQLMetrics();
 
     private static final AtomicInteger lastMinuteEvictionsCount = new AtomicInteger(0);
-    private static final AtomicInteger thriftLastMinuteEvictionsCount = new AtomicInteger(0);
 
     static
     {
@@ -90,31 +87,16 @@ public class QueryProcessor implements QueryHandler
                                  lastMinuteEvictionsCount.incrementAndGet();
                              }).build();
 
-        thriftPreparedStatements = new ConcurrentLinkedHashMap.Builder<Integer, ParsedStatement.Prepared>()
-                                   .maximumWeightedCapacity(capacityToBytes(DatabaseDescriptor.getThriftPreparedStatementsCacheSizeMB()))
-                                   .weigher(QueryProcessor::measure)
-                                   .listener((integer, prepared) -> {
-                                       metrics.preparedStatementsEvicted.inc();
-                                       thriftLastMinuteEvictionsCount.incrementAndGet();
-                                   })
-                                   .build();
-
         ScheduledExecutors.scheduledTasks.scheduleAtFixedRate(() -> {
             long count = lastMinuteEvictionsCount.getAndSet(0);
             if (count > 0)
                 logger.warn("{} prepared statements discarded in the last minute because cache limit reached ({} MB)",
                             count,
                             DatabaseDescriptor.getPreparedStatementsCacheSizeMB());
-            count = thriftLastMinuteEvictionsCount.getAndSet(0);
-            if (count > 0)
-                logger.warn("{} prepared Thrift statements discarded in the last minute because cache limit reached ({} MB)",
-                            count,
-                            DatabaseDescriptor.getThriftPreparedStatementsCacheSizeMB());
         }, 1, 1, TimeUnit.MINUTES);
 
-        logger.info("Initialized prepared statement caches with {} MB (native) and {} MB (Thrift)",
-                    DatabaseDescriptor.getPreparedStatementsCacheSizeMB(),
-                    DatabaseDescriptor.getThriftPreparedStatementsCacheSizeMB());
+        logger.info("Initialized prepared statement caches with {} MB",
+                    DatabaseDescriptor.getPreparedStatementsCacheSizeMB());
     }
 
     private static long capacityToBytes(long cacheSizeMB)
@@ -124,7 +106,7 @@ public class QueryProcessor implements QueryHandler
 
     public static int preparedStatementsCount()
     {
-        return preparedStatements.size() + thriftPreparedStatements.size();
+        return preparedStatements.size();
     }
 
     // Work around initialization dependency
@@ -151,7 +133,7 @@ public class QueryProcessor implements QueryHandler
             try
             {
                 clientState.setKeyspace(useKeyspaceAndCQL.left);
-                prepare(useKeyspaceAndCQL.right, clientState, false);
+                prepare(useKeyspaceAndCQL.right, clientState);
                 count++;
             }
             catch (RequestValidationException e)
@@ -166,7 +148,6 @@ public class QueryProcessor implements QueryHandler
     public static void clearPrepraredStatements()
     {
         preparedStatements.clear();
-        thriftPreparedStatements.clear();
     }
 
     private static QueryState internalQueryState()
@@ -184,11 +165,6 @@ public class QueryProcessor implements QueryHandler
         return preparedStatements.get(id);
     }
 
-    public ParsedStatement.Prepared getPreparedForThrift(Integer id)
-    {
-        return thriftPreparedStatements.get(id);
-    }
-
     public static void validateKey(ByteBuffer key) throws InvalidRequestException
     {
         if (key == null || key.remaining() == 0)
@@ -400,12 +376,12 @@ public class QueryProcessor implements QueryHandler
     public ResultMessage.Prepared prepare(String queryString, QueryState queryState)
     {
         ClientState cState = queryState.getClientState();
-        return prepare(queryString, cState, cState instanceof ThriftClientState);
+        return prepare(queryString, cState);
     }
 
-    public static ResultMessage.Prepared prepare(String queryString, ClientState clientState, boolean forThrift)
+    public static ResultMessage.Prepared prepare(String queryString, ClientState clientState)
     {
-        ResultMessage.Prepared existing = getStoredPreparedStatement(queryString, clientState.getRawKeyspace(), forThrift);
+        ResultMessage.Prepared existing = getStoredPreparedStatement(queryString, clientState.getRawKeyspace());
         if (existing != null)
             return existing;
 
@@ -416,7 +392,7 @@ public class QueryProcessor implements QueryHandler
             throw new InvalidRequestException(String.format("Too many markers(?). %d markers exceed the allowed maximum of %d", boundTerms, FBUtilities.MAX_UNSIGNED_SHORT));
         assert boundTerms == prepared.boundNames.size();
 
-        return storePreparedStatement(queryString, clientState.getRawKeyspace(), prepared, forThrift);
+        return storePreparedStatement(queryString, clientState.getRawKeyspace(), prepared);
     }
 
     private static MD5Digest computeId(String queryString, String keyspace)
@@ -425,69 +401,35 @@ public class QueryProcessor implements QueryHandler
         return MD5Digest.compute(toHash);
     }
 
-    private static Integer computeThriftId(String queryString, String keyspace)
-    {
-        String toHash = keyspace == null ? queryString : keyspace + queryString;
-        return toHash.hashCode();
-    }
-
-    private static ResultMessage.Prepared getStoredPreparedStatement(String queryString, String keyspace, boolean forThrift)
+    private static ResultMessage.Prepared getStoredPreparedStatement(String queryString, String keyspace)
     throws InvalidRequestException
     {
-        if (forThrift)
-        {
-            Integer thriftStatementId = computeThriftId(queryString, keyspace);
-            ParsedStatement.Prepared existing = thriftPreparedStatements.get(thriftStatementId);
-            if (existing == null)
-                return null;
-
-            checkTrue(queryString.equals(existing.rawCQLStatement),
-                      String.format("MD5 hash collision: query with the same MD5 hash was already prepared. \n Existing: '%s'", existing.rawCQLStatement));
-            return ResultMessage.Prepared.forThrift(thriftStatementId, existing.boundNames);
-        }
-        else
-        {
-            MD5Digest statementId = computeId(queryString, keyspace);
-            ParsedStatement.Prepared existing = preparedStatements.get(statementId);
-            if (existing == null)
-                return null;
+        MD5Digest statementId = computeId(queryString, keyspace);
+        ParsedStatement.Prepared existing = preparedStatements.get(statementId);
+        if (existing == null)
+            return null;
 
-            checkTrue(queryString.equals(existing.rawCQLStatement),
-                      String.format("MD5 hash collision: query with the same MD5 hash was already prepared. \n Existing: '%s'", existing.rawCQLStatement));
-            return new ResultMessage.Prepared(statementId, existing);
-        }
+        checkTrue(queryString.equals(existing.rawCQLStatement),
+                String.format("MD5 hash collision: query with the same MD5 hash was already prepared. \n Existing: '%s'", existing.rawCQLStatement));
+        return new ResultMessage.Prepared(statementId, existing);
     }
 
-    private static ResultMessage.Prepared storePreparedStatement(String queryString, String keyspace, ParsedStatement.Prepared prepared, boolean forThrift)
+    private static ResultMessage.Prepared storePreparedStatement(String queryString, String keyspace, ParsedStatement.Prepared prepared)
     throws InvalidRequestException
     {
         // Concatenate the current keyspace so we don't mix prepared statements between keyspace (#5352).
         // (if the keyspace is null, queryString has to have a fully-qualified keyspace so it's fine.
         long statementSize = ObjectSizes.measureDeep(prepared.statement);
         // don't execute the statement if it's bigger than the allowed threshold
-        if (forThrift)
-        {
-            if (statementSize > capacityToBytes(DatabaseDescriptor.getThriftPreparedStatementsCacheSizeMB()))
-                throw new InvalidRequestException(String.format("Prepared statement of size %d bytes is larger than allowed maximum of %d MB: %s...",
-                                                                statementSize,
-                                                                DatabaseDescriptor.getThriftPreparedStatementsCacheSizeMB(),
-                                                                queryString.substring(0, 200)));
-            Integer statementId = computeThriftId(queryString, keyspace);
-            thriftPreparedStatements.put(statementId, prepared);
-            return ResultMessage.Prepared.forThrift(statementId, prepared.boundNames);
-        }
-        else
-        {
-            if (statementSize > capacityToBytes(DatabaseDescriptor.getPreparedStatementsCacheSizeMB()))
-                throw new InvalidRequestException(String.format("Prepared statement of size %d bytes is larger than allowed maximum of %d MB: %s...",
-                                                                statementSize,
-                                                                DatabaseDescriptor.getPreparedStatementsCacheSizeMB(),
-                                                                queryString.substring(0, 200)));
-            MD5Digest statementId = computeId(queryString, keyspace);
-            preparedStatements.put(statementId, prepared);
-            SystemKeyspace.writePreparedStatement(keyspace, statementId, queryString);
-            return new ResultMessage.Prepared(statementId, prepared);
-        }
+        if (statementSize > capacityToBytes(DatabaseDescriptor.getPreparedStatementsCacheSizeMB()))
+            throw new InvalidRequestException(String.format("Prepared statement of size %d bytes is larger than allowed maximum of %d MB: %s...",
+                                                            statementSize,
+                                                            DatabaseDescriptor.getPreparedStatementsCacheSizeMB(),
+                                                            queryString.substring(0, 200)));
+        MD5Digest statementId = computeId(queryString, keyspace);
+        preparedStatements.put(statementId, prepared);
+        SystemKeyspace.writePreparedStatement(keyspace, statementId, queryString);
+        return new ResultMessage.Prepared(statementId, prepared);
     }
 
     public ResultMessage processPrepared(CQLStatement statement,
@@ -617,7 +559,6 @@ public class QueryProcessor implements QueryHandler
         {
             removeInvalidPreparedStatements(internalStatements.values().iterator(), ksName, cfName);
             removeInvalidPersistentPreparedStatements(preparedStatements.entrySet().iterator(), ksName, cfName);
-            removeInvalidPreparedStatements(thriftPreparedStatements.values().iterator(), ksName, cfName);
         }
 
         private static void removeInvalidPreparedStatementsForFunction(String ksName, String functionName)
@@ -638,9 +579,6 @@ public class QueryProcessor implements QueryHandler
 
             Iterators.removeIf(internalStatements.values().iterator(),
                                statement -> Iterables.any(statement.statement.getFunctions(), matchesFunction));
-
-            Iterators.removeIf(thriftPreparedStatements.values().iterator(),
-                               statement -> Iterables.any(statement.statement.getFunctions(), matchesFunction));
         }
 
         private static void removeInvalidPersistentPreparedStatements(Iterator<Map.Entry<MD5Digest, ParsedStatement.Prepared>> iterator,

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/cql3/ResultSet.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/ResultSet.java b/src/java/org/apache/cassandra/cql3/ResultSet.java
index 9659509..f0692da 100644
--- a/src/java/org/apache/cassandra/cql3/ResultSet.java
+++ b/src/java/org/apache/cassandra/cql3/ResultSet.java
@@ -25,11 +25,6 @@ import io.netty.buffer.ByteBuf;
 import org.apache.cassandra.transport.*;
 import org.apache.cassandra.db.marshal.AbstractType;
 import org.apache.cassandra.db.marshal.ReversedType;
-import org.apache.cassandra.thrift.Column;
-import org.apache.cassandra.thrift.CqlMetadata;
-import org.apache.cassandra.thrift.CqlResult;
-import org.apache.cassandra.thrift.CqlResultType;
-import org.apache.cassandra.thrift.CqlRow;
 import org.apache.cassandra.utils.ByteBufferUtil;
 import org.apache.cassandra.service.pager.PagingState;
 
@@ -95,44 +90,6 @@ public class ResultSet
         }
     }
 
-    public CqlResult toThriftResult()
-    {
-        assert metadata.names != null;
-
-        String UTF8 = "UTF8Type";
-        CqlMetadata schema = new CqlMetadata(new HashMap<ByteBuffer, String>(),
-                new HashMap<ByteBuffer, String>(),
-                // The 2 following ones shouldn't be needed in CQL3
-                UTF8, UTF8);
-
-        for (int i = 0; i < metadata.columnCount; i++)
-        {
-            ColumnSpecification spec = metadata.names.get(i);
-            ByteBuffer colName = ByteBufferUtil.bytes(spec.name.toString());
-            schema.name_types.put(colName, UTF8);
-            AbstractType<?> normalizedType = spec.type instanceof ReversedType ? ((ReversedType)spec.type).baseType : spec.type;
-            schema.value_types.put(colName, normalizedType.toString());
-
-        }
-
-        List<CqlRow> cqlRows = new ArrayList<CqlRow>(rows.size());
-        for (List<ByteBuffer> row : rows)
-        {
-            List<Column> thriftCols = new ArrayList<Column>(metadata.columnCount);
-            for (int i = 0; i < metadata.columnCount; i++)
-            {
-                Column col = new Column(ByteBufferUtil.bytes(metadata.names.get(i).name.toString()));
-                col.setValue(row.get(i));
-                thriftCols.add(col);
-            }
-            // The key of CqlRow shoudn't be needed in CQL3
-            cqlRows.add(new CqlRow(ByteBufferUtil.EMPTY_BYTE_BUFFER, thriftCols));
-        }
-        CqlResult res = new CqlResult(CqlResultType.ROWS);
-        res.setRows(cqlRows).setSchema(schema);
-        return res;
-    }
-
     @Override
     public String toString()
     {

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/cql3/UpdateParameters.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/UpdateParameters.java b/src/java/org/apache/cassandra/cql3/UpdateParameters.java
index d2c01c8..d065269 100644
--- a/src/java/org/apache/cassandra/cql3/UpdateParameters.java
+++ b/src/java/org/apache/cassandra/cql3/UpdateParameters.java
@@ -84,8 +84,7 @@ public class UpdateParameters
     {
         if (metadata.isDense() && !metadata.isCompound())
         {
-            // If it's a COMPACT STORAGE table with a single clustering column, the clustering value is
-            // translated in Thrift to the full Thrift column name, and for backward compatibility we
+            // If it's a COMPACT STORAGE table with a single clustering column and for backward compatibility we
             // don't want to allow that to be empty (even though this would be fine for the storage engine).
             assert clustering.size() == 1;
             ByteBuffer value = clustering.get(0);
@@ -122,9 +121,8 @@ public class UpdateParameters
     public void addRowDeletion()
     {
         // For compact tables, at the exclusion of the static row (of static compact tables), each row ever has a single column,
-        // the "compact" one. As such, deleting the row or deleting that single cell is equivalent. We favor the later however
-        // because that makes it easier when translating back to the old format layout (for thrift and pre-3.0 backward
-        // compatibility) as we don't have to special case for the row deletion. This is also in line with what we used to do pre-3.0.
+        // the "compact" one. As such, deleting the row or deleting that single cell is equivalent. We favor the later
+        // for backward compatibility (thought it doesn't truly matter anymore).
         if (metadata.isCompactTable() && builder.clustering() != Clustering.STATIC_CLUSTERING)
             addTombstone(metadata.compactValueColumn());
         else

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/cql3/Validation.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/Validation.java b/src/java/org/apache/cassandra/cql3/Validation.java
new file mode 100644
index 0000000..3f388eb
--- /dev/null
+++ b/src/java/org/apache/cassandra/cql3/Validation.java
@@ -0,0 +1,117 @@
+/*
+ * 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 org.apache.cassandra.config.CFMetaData;
+import org.apache.cassandra.config.Schema;
+import org.apache.cassandra.config.SchemaConstants;
+import org.apache.cassandra.db.KeyspaceNotDefinedException;
+import org.apache.cassandra.serializers.MarshalException;
+import org.apache.cassandra.exceptions.InvalidRequestException;
+import org.apache.cassandra.utils.FBUtilities;
+
+/**
+ * A collection of static validation functions reused across statements.
+ *
+ * Note: this hosts functions that were historically in ThriftValidation, but
+ * it's not necessary clear that this is the best place to have this (this is
+ * certainly not horrible either though).
+ */
+public abstract class Validation
+{
+    /**
+     * Retrieves the metadata for the provided keyspace and table name, throwing
+     * a meaningful user exception if those doen't exist.
+     *
+     * @param keyspaceName the keyspace name.
+     * @param tableName the table name.
+     * @return the metadata for table {@code keyspaceName.tableName} if it
+     * exists (otherwise an {@code InvalidRequestException} is thrown).
+     *
+     * @throws InvalidRequestException if the table requested doesn't exist.
+     */
+    public static CFMetaData validateColumnFamily(String keyspaceName, String tableName)
+    throws InvalidRequestException
+    {
+        validateKeyspace(keyspaceName);
+        if (tableName.isEmpty())
+            throw new InvalidRequestException("non-empty table is required");
+
+        CFMetaData metadata = Schema.instance.getCFMetaData(keyspaceName, tableName);
+        if (metadata == null)
+            throw new InvalidRequestException("unconfigured table " + tableName);
+
+        return metadata;
+    }
+
+    private static void validateKeyspace(String keyspaceName)
+    throws KeyspaceNotDefinedException
+    {
+        if (!Schema.instance.getKeyspaces().contains(keyspaceName))
+            throw new KeyspaceNotDefinedException("Keyspace " + keyspaceName + " does not exist");
+    }
+
+    /**
+     * Validates a (full serialized) partition key.
+     *
+     * @param metadata the metadata for the table of which to check the key.
+     * @param key the serialized partition key to check.
+     *
+     * @throws InvalidRequestException if the provided {@code key} is invalid.
+     */
+    public static void validateKey(CFMetaData metadata, ByteBuffer key)
+    throws InvalidRequestException
+    {
+        if (key == null || key.remaining() == 0)
+            throw new InvalidRequestException("Key may not be empty");
+
+        // check that key can be handled by FBUtilities.writeShortByteArray
+        if (key.remaining() > FBUtilities.MAX_UNSIGNED_SHORT)
+        {
+            throw new InvalidRequestException("Key length of " + key.remaining() +
+                                              " is longer than maximum of " +
+                                              FBUtilities.MAX_UNSIGNED_SHORT);
+        }
+
+        try
+        {
+            metadata.getKeyValidator().validate(key);
+        }
+        catch (MarshalException e)
+        {
+            throw new InvalidRequestException(e.getMessage());
+        }
+    }
+
+    /**
+     * Validates that the provided keyspace is not one of the system keyspace.
+     *
+     * @param keyspace the keyspace name to validate.
+     *
+     * @throws InvalidRequestException if {@code keyspace} is the name of a
+     * system keyspace.
+     */
+    public static void validateKeyspaceNotSystem(String keyspace)
+    throws InvalidRequestException
+    {
+        if (SchemaConstants.isSystemKeyspace(keyspace))
+            throw new InvalidRequestException(String.format("%s keyspace is not user-modifiable", keyspace));
+    }
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java b/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java
index 48666be..b0fe64d 100644
--- a/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java
@@ -41,8 +41,6 @@ import org.apache.cassandra.service.MigrationManager;
 import org.apache.cassandra.transport.Event;
 import org.apache.cassandra.utils.*;
 
-import static org.apache.cassandra.thrift.ThriftValidation.validateColumnFamily;
-
 public class AlterTableStatement extends SchemaAlteringStatement
 {
     public enum Type
@@ -83,7 +81,7 @@ public class AlterTableStatement extends SchemaAlteringStatement
 
     public Event.SchemaChange announceMigration(boolean isLocalOnly) throws RequestValidationException
     {
-        CFMetaData meta = validateColumnFamily(keyspace(), columnFamily());
+        CFMetaData meta = Validation.validateColumnFamily(keyspace(), columnFamily());
         if (meta.isView())
             throw new InvalidRequestException("Cannot use ALTER TABLE on Materialized View");
 
@@ -378,11 +376,10 @@ public class AlterTableStatement extends SchemaAlteringStatement
                 break;
             case REGULAR:
             case STATIC:
-                // Thrift allows to change a column validator so CFMetaData.validateCompatibility will let it slide
-                // if we change to an incompatible type (contrarily to the comparator case). But we don't want to
-                // allow it for CQL3 (see #5882) so validating it explicitly here. We only care about value compatibility
-                // though since we won't compare values (except when there is an index, but that is validated by
-                // ColumnDefinition already).
+                // As above, we want a clear error message, but in this case it happens that  CFMetaData.validateCompatibility *does not*
+                // validate this for historical reasons so it's doubtly important. Note that we only care about value compatibility
+                // though since we won't compare values (except when there is an index, but that is validated by ColumnDefinition already).
+                // TODO: we could clear out where validation is done and do it only once.
                 if (!validatorType.isValueCompatibleWith(def.type))
                     throw new ConfigurationException(String.format("Cannot change %s from type %s to type %s: types are incompatible.",
                                                                    def.name,

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/cql3/statements/AlterViewStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/AlterViewStatement.java b/src/java/org/apache/cassandra/cql3/statements/AlterViewStatement.java
index ba077c7..e507aed 100644
--- a/src/java/org/apache/cassandra/cql3/statements/AlterViewStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/AlterViewStatement.java
@@ -22,6 +22,7 @@ import org.apache.cassandra.config.CFMetaData;
 import org.apache.cassandra.config.Schema;
 import org.apache.cassandra.config.ViewDefinition;
 import org.apache.cassandra.cql3.CFName;
+import org.apache.cassandra.cql3.Validation;
 import org.apache.cassandra.db.view.View;
 import org.apache.cassandra.exceptions.InvalidRequestException;
 import org.apache.cassandra.exceptions.RequestValidationException;
@@ -31,8 +32,6 @@ import org.apache.cassandra.service.ClientState;
 import org.apache.cassandra.service.MigrationManager;
 import org.apache.cassandra.transport.Event;
 
-import static org.apache.cassandra.thrift.ThriftValidation.validateColumnFamily;
-
 public class AlterViewStatement extends SchemaAlteringStatement
 {
     private final TableAttributes attrs;
@@ -57,7 +56,7 @@ public class AlterViewStatement extends SchemaAlteringStatement
 
     public Event.SchemaChange announceMigration(boolean isLocalOnly) throws RequestValidationException
     {
-        CFMetaData meta = validateColumnFamily(keyspace(), columnFamily());
+        CFMetaData meta = Validation.validateColumnFamily(keyspace(), columnFamily());
         if (!meta.isView())
             throw new InvalidRequestException("Cannot use ALTER MATERIALIZED VIEW on Table");
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java b/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java
index 60a8df5..3b86ab4 100644
--- a/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java
@@ -83,11 +83,10 @@ public class BatchStatement implements CQLStatement
     public static final BatchMetrics metrics = new BatchMetrics();
 
     /**
-     * Creates a new BatchStatement from a list of statements and a
-     * Thrift consistency level.
+     * Creates a new BatchStatement.
      *
      * @param type       type of the batch
-     * @param statements a list of UpdateStatements
+     * @param statements the list of statements in the batch
      * @param attrs      additional attributes for statement (CL, timestamp, timeToLive)
      */
     public BatchStatement(int boundTerms, Type type, List<ModificationStatement> statements, Attributes attrs)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/cql3/statements/CreateAggregateStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/CreateAggregateStatement.java b/src/java/org/apache/cassandra/cql3/statements/CreateAggregateStatement.java
index eaba03b..1d57dd8 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CreateAggregateStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CreateAggregateStatement.java
@@ -34,7 +34,6 @@ import org.apache.cassandra.serializers.MarshalException;
 import org.apache.cassandra.service.ClientState;
 import org.apache.cassandra.service.MigrationManager;
 import org.apache.cassandra.service.QueryState;
-import org.apache.cassandra.thrift.ThriftValidation;
 import org.apache.cassandra.transport.Event;
 import org.apache.cassandra.transport.ProtocolVersion;
 
@@ -161,7 +160,7 @@ public final class CreateAggregateStatement extends SchemaAlteringStatement
         if (!functionName.hasKeyspace())
             throw new InvalidRequestException("Functions must be fully qualified with a keyspace name if a keyspace is not set for the session");
 
-        ThriftValidation.validateKeyspaceNotSystem(functionName.keyspace);
+        Validation.validateKeyspaceNotSystem(functionName.keyspace);
 
         stateFunc = new FunctionName(functionName.keyspace, stateFunc.name);
         if (finalFunc != null)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/cql3/statements/CreateFunctionStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/CreateFunctionStatement.java b/src/java/org/apache/cassandra/cql3/statements/CreateFunctionStatement.java
index a54c49e..e0a1e6b 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CreateFunctionStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CreateFunctionStatement.java
@@ -26,6 +26,7 @@ import org.apache.cassandra.config.DatabaseDescriptor;
 import org.apache.cassandra.config.Schema;
 import org.apache.cassandra.cql3.CQL3Type;
 import org.apache.cassandra.cql3.ColumnIdentifier;
+import org.apache.cassandra.cql3.Validation;
 import org.apache.cassandra.cql3.functions.*;
 import org.apache.cassandra.db.marshal.AbstractType;
 import org.apache.cassandra.exceptions.*;
@@ -33,7 +34,6 @@ import org.apache.cassandra.schema.Functions;
 import org.apache.cassandra.service.ClientState;
 import org.apache.cassandra.service.MigrationManager;
 import org.apache.cassandra.service.QueryState;
-import org.apache.cassandra.thrift.ThriftValidation;
 import org.apache.cassandra.transport.Event;
 
 /**
@@ -98,7 +98,7 @@ public final class CreateFunctionStatement extends SchemaAlteringStatement
         if (!functionName.hasKeyspace())
             throw new InvalidRequestException("Functions must be fully qualified with a keyspace name if a keyspace is not set for the session");
 
-        ThriftValidation.validateKeyspaceNotSystem(functionName.keyspace);
+        Validation.validateKeyspaceNotSystem(functionName.keyspace);
     }
 
     protected void grantPermissionsToCreator(QueryState state)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/cql3/statements/CreateIndexStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/CreateIndexStatement.java b/src/java/org/apache/cassandra/cql3/statements/CreateIndexStatement.java
index 2526f79..2019577 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CreateIndexStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CreateIndexStatement.java
@@ -33,6 +33,7 @@ import org.apache.cassandra.config.Schema;
 import org.apache.cassandra.cql3.CFName;
 import org.apache.cassandra.cql3.ColumnIdentifier;
 import org.apache.cassandra.cql3.IndexName;
+import org.apache.cassandra.cql3.Validation;
 import org.apache.cassandra.db.marshal.MapType;
 import org.apache.cassandra.exceptions.InvalidRequestException;
 import org.apache.cassandra.exceptions.RequestValidationException;
@@ -41,7 +42,6 @@ import org.apache.cassandra.schema.IndexMetadata;
 import org.apache.cassandra.schema.Indexes;
 import org.apache.cassandra.service.ClientState;
 import org.apache.cassandra.service.MigrationManager;
-import org.apache.cassandra.thrift.ThriftValidation;
 import org.apache.cassandra.transport.Event;
 
 /** A <code>CREATE INDEX</code> statement parsed from a CQL query. */
@@ -74,7 +74,7 @@ public class CreateIndexStatement extends SchemaAlteringStatement
 
     public void validate(ClientState state) throws RequestValidationException
     {
-        CFMetaData cfm = ThriftValidation.validateColumnFamily(keyspace(), columnFamily());
+        CFMetaData cfm = Validation.validateColumnFamily(keyspace(), columnFamily());
 
         if (cfm.isCounter())
             throw new InvalidRequestException("Secondary indexes are not supported on counter tables");

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java b/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java
index 33d2ce4..17dedf0 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java
@@ -20,6 +20,7 @@ package org.apache.cassandra.cql3.statements;
 import java.util.regex.Pattern;
 
 import org.apache.cassandra.auth.*;
+import org.apache.cassandra.cql3.Validation;
 import org.apache.cassandra.config.DatabaseDescriptor;
 import org.apache.cassandra.config.SchemaConstants;
 import org.apache.cassandra.exceptions.*;
@@ -27,7 +28,6 @@ import org.apache.cassandra.locator.LocalStrategy;
 import org.apache.cassandra.schema.KeyspaceMetadata;
 import org.apache.cassandra.schema.KeyspaceParams;
 import org.apache.cassandra.service.*;
-import org.apache.cassandra.thrift.ThriftValidation;
 import org.apache.cassandra.transport.Event;
 
 /** A <code>CREATE KEYSPACE</code> statement parsed from a CQL query. */
@@ -74,7 +74,7 @@ public class CreateKeyspaceStatement extends SchemaAlteringStatement
      */
     public void validate(ClientState state) throws RequestValidationException
     {
-        ThriftValidation.validateKeyspaceNotSystem(name);
+        Validation.validateKeyspaceNotSystem(name);
 
         // keyspace name
         if (!PATTERN_WORD_CHARS.matcher(name).matches())

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/cql3/statements/CreateTableStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/CreateTableStatement.java b/src/java/org/apache/cassandra/cql3/statements/CreateTableStatement.java
index 7f8eebc..7d5ebaf 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CreateTableStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CreateTableStatement.java
@@ -292,11 +292,11 @@ public class CreateTableStatement extends SchemaAlteringStatement
             }
 
             boolean useCompactStorage = properties.useCompactStorage;
-            // Dense means that on the thrift side, no part of the "thrift column name" stores a "CQL/metadata column name".
-            // This means COMPACT STORAGE with at least one clustering type (otherwise it's a thrift "static" CF).
+            // Dense meant, back with thrift, that no part of the "thrift column name" stores a "CQL/metadata column name".
+            // This means COMPACT STORAGE with at least one clustering type (otherwise it's a "static" CF).
             stmt.isDense = useCompactStorage && !stmt.clusteringTypes.isEmpty();
-            // Compound means that on the thrift side, the "thrift column name" is a composite one. It's the case unless
-            // we use compact storage COMPACT STORAGE and we have either no clustering columns (thrift "static" CF) or
+            // Compound meant the "thrift column name" was a composite one. It's the case unless
+            // we use compact storage COMPACT STORAGE and we have either no clustering columns ("static" CF) or
             // only one of them (if more than one, it's a "dense composite").
             stmt.isCompound = !(useCompactStorage && stmt.clusteringTypes.size() <= 1);
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/cql3/statements/CreateTriggerStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/CreateTriggerStatement.java b/src/java/org/apache/cassandra/cql3/statements/CreateTriggerStatement.java
index 94cfc15..c43dd0e 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CreateTriggerStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CreateTriggerStatement.java
@@ -23,6 +23,7 @@ import org.slf4j.LoggerFactory;
 import org.apache.cassandra.config.CFMetaData;
 import org.apache.cassandra.config.Schema;
 import org.apache.cassandra.cql3.CFName;
+import org.apache.cassandra.cql3.Validation;
 import org.apache.cassandra.exceptions.ConfigurationException;
 import org.apache.cassandra.exceptions.InvalidRequestException;
 import org.apache.cassandra.exceptions.RequestValidationException;
@@ -31,7 +32,6 @@ import org.apache.cassandra.schema.TriggerMetadata;
 import org.apache.cassandra.schema.Triggers;
 import org.apache.cassandra.service.ClientState;
 import org.apache.cassandra.service.MigrationManager;
-import org.apache.cassandra.thrift.ThriftValidation;
 import org.apache.cassandra.transport.Event;
 import org.apache.cassandra.triggers.TriggerExecutor;
 
@@ -58,7 +58,7 @@ public class CreateTriggerStatement extends SchemaAlteringStatement
 
     public void validate(ClientState state) throws RequestValidationException
     {
-        CFMetaData cfm = ThriftValidation.validateColumnFamily(keyspace(), columnFamily());
+        CFMetaData cfm = Validation.validateColumnFamily(keyspace(), columnFamily());
         if (cfm.isView())
             throw new InvalidRequestException("Cannot CREATE TRIGGER against a materialized view");
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/cql3/statements/CreateViewStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/CreateViewStatement.java b/src/java/org/apache/cassandra/cql3/statements/CreateViewStatement.java
index 3cc0d97..ad5e251 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CreateViewStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CreateViewStatement.java
@@ -43,7 +43,6 @@ import org.apache.cassandra.exceptions.UnauthorizedException;
 import org.apache.cassandra.schema.TableParams;
 import org.apache.cassandra.service.ClientState;
 import org.apache.cassandra.service.MigrationManager;
-import org.apache.cassandra.thrift.ThriftValidation;
 import org.apache.cassandra.transport.Event;
 
 public class CreateViewStatement extends SchemaAlteringStatement
@@ -133,7 +132,7 @@ public class CreateViewStatement extends SchemaAlteringStatement
         if (!baseName.getKeyspace().equals(keyspace()))
             throw new InvalidRequestException("Cannot create a materialized view on a table in a separate keyspace");
 
-        CFMetaData cfm = ThriftValidation.validateColumnFamily(baseName.getKeyspace(), baseName.getColumnFamily());
+        CFMetaData cfm = Validation.validateColumnFamily(baseName.getKeyspace(), baseName.getColumnFamily());
 
         if (cfm.isCounter())
             throw new InvalidRequestException("Materialized views are not supported on counter tables");

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/cql3/statements/DropAggregateStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/DropAggregateStatement.java b/src/java/org/apache/cassandra/cql3/statements/DropAggregateStatement.java
index 2b1432b..c770805 100644
--- a/src/java/org/apache/cassandra/cql3/statements/DropAggregateStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/DropAggregateStatement.java
@@ -24,6 +24,7 @@ import java.util.List;
 import org.apache.cassandra.auth.Permission;
 import org.apache.cassandra.config.Schema;
 import org.apache.cassandra.cql3.CQL3Type;
+import org.apache.cassandra.cql3.Validation;
 import org.apache.cassandra.cql3.functions.*;
 import org.apache.cassandra.db.marshal.AbstractType;
 import org.apache.cassandra.exceptions.InvalidRequestException;
@@ -31,7 +32,6 @@ import org.apache.cassandra.exceptions.RequestValidationException;
 import org.apache.cassandra.exceptions.UnauthorizedException;
 import org.apache.cassandra.service.ClientState;
 import org.apache.cassandra.service.MigrationManager;
-import org.apache.cassandra.thrift.ThriftValidation;
 import org.apache.cassandra.transport.Event;
 
 /**
@@ -63,7 +63,7 @@ public final class DropAggregateStatement extends SchemaAlteringStatement
         if (!functionName.hasKeyspace())
             throw new InvalidRequestException("Functions must be fully qualified with a keyspace name if a keyspace is not set for the session");
 
-        ThriftValidation.validateKeyspaceNotSystem(functionName.keyspace);
+        Validation.validateKeyspaceNotSystem(functionName.keyspace);
     }
 
     public void checkAccess(ClientState state) throws UnauthorizedException, InvalidRequestException

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/cql3/statements/DropFunctionStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/DropFunctionStatement.java b/src/java/org/apache/cassandra/cql3/statements/DropFunctionStatement.java
index 6f11f9c..6ab4189 100644
--- a/src/java/org/apache/cassandra/cql3/statements/DropFunctionStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/DropFunctionStatement.java
@@ -27,6 +27,7 @@ import org.apache.cassandra.auth.FunctionResource;
 import org.apache.cassandra.auth.Permission;
 import org.apache.cassandra.config.Schema;
 import org.apache.cassandra.cql3.CQL3Type;
+import org.apache.cassandra.cql3.Validation;
 import org.apache.cassandra.cql3.functions.*;
 import org.apache.cassandra.db.marshal.AbstractType;
 import org.apache.cassandra.exceptions.InvalidRequestException;
@@ -35,7 +36,6 @@ import org.apache.cassandra.exceptions.UnauthorizedException;
 import org.apache.cassandra.schema.KeyspaceMetadata;
 import org.apache.cassandra.service.ClientState;
 import org.apache.cassandra.service.MigrationManager;
-import org.apache.cassandra.thrift.ThriftValidation;
 import org.apache.cassandra.transport.Event;
 
 /**
@@ -93,7 +93,7 @@ public final class DropFunctionStatement extends SchemaAlteringStatement
         if (!functionName.hasKeyspace())
             throw new InvalidRequestException("Functions must be fully qualified with a keyspace name if a keyspace is not set for the session");
 
-        ThriftValidation.validateKeyspaceNotSystem(functionName.keyspace);
+        Validation.validateKeyspaceNotSystem(functionName.keyspace);
     }
 
     public void checkAccess(ClientState state) throws UnauthorizedException, InvalidRequestException

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/cql3/statements/DropKeyspaceStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/DropKeyspaceStatement.java b/src/java/org/apache/cassandra/cql3/statements/DropKeyspaceStatement.java
index a08b193..5119462 100644
--- a/src/java/org/apache/cassandra/cql3/statements/DropKeyspaceStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/DropKeyspaceStatement.java
@@ -18,13 +18,13 @@
 package org.apache.cassandra.cql3.statements;
 
 import org.apache.cassandra.auth.Permission;
+import org.apache.cassandra.cql3.Validation;
 import org.apache.cassandra.exceptions.ConfigurationException;
 import org.apache.cassandra.exceptions.InvalidRequestException;
 import org.apache.cassandra.exceptions.RequestValidationException;
 import org.apache.cassandra.exceptions.UnauthorizedException;
 import org.apache.cassandra.service.ClientState;
 import org.apache.cassandra.service.MigrationManager;
-import org.apache.cassandra.thrift.ThriftValidation;
 import org.apache.cassandra.transport.Event;
 
 public class DropKeyspaceStatement extends SchemaAlteringStatement
@@ -46,7 +46,7 @@ public class DropKeyspaceStatement extends SchemaAlteringStatement
 
     public void validate(ClientState state) throws RequestValidationException
     {
-        ThriftValidation.validateKeyspaceNotSystem(keyspace);
+        Validation.validateKeyspaceNotSystem(keyspace);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/cql3/statements/DropTriggerStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/DropTriggerStatement.java b/src/java/org/apache/cassandra/cql3/statements/DropTriggerStatement.java
index 3f61e01..26a1c00 100644
--- a/src/java/org/apache/cassandra/cql3/statements/DropTriggerStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/DropTriggerStatement.java
@@ -23,6 +23,7 @@ import org.slf4j.LoggerFactory;
 import org.apache.cassandra.config.CFMetaData;
 import org.apache.cassandra.config.Schema;
 import org.apache.cassandra.cql3.CFName;
+import org.apache.cassandra.cql3.Validation;
 import org.apache.cassandra.exceptions.ConfigurationException;
 import org.apache.cassandra.exceptions.InvalidRequestException;
 import org.apache.cassandra.exceptions.RequestValidationException;
@@ -30,7 +31,6 @@ import org.apache.cassandra.exceptions.UnauthorizedException;
 import org.apache.cassandra.schema.Triggers;
 import org.apache.cassandra.service.ClientState;
 import org.apache.cassandra.service.MigrationManager;
-import org.apache.cassandra.thrift.ThriftValidation;
 import org.apache.cassandra.transport.Event;
 
 public class DropTriggerStatement extends SchemaAlteringStatement
@@ -55,7 +55,7 @@ public class DropTriggerStatement extends SchemaAlteringStatement
 
     public void validate(ClientState state) throws RequestValidationException
     {
-        ThriftValidation.validateColumnFamily(keyspace(), columnFamily());
+        Validation.validateColumnFamily(keyspace(), columnFamily());
     }
 
     public Event.SchemaChange announceMigration(boolean isLocalOnly) throws ConfigurationException, InvalidRequestException

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
index d32a689..4569ec8 100644
--- a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
@@ -44,7 +44,6 @@ import org.apache.cassandra.service.ClientState;
 import org.apache.cassandra.service.QueryState;
 import org.apache.cassandra.service.StorageProxy;
 import org.apache.cassandra.service.paxos.Commit;
-import org.apache.cassandra.thrift.ThriftValidation;
 import org.apache.cassandra.transport.messages.ResultMessage;
 import org.apache.cassandra.triggers.TriggerExecutor;
 import org.apache.cassandra.utils.FBUtilities;
@@ -650,7 +649,7 @@ public abstract class ModificationStatement implements CQLStatement
                                                            queryStartNanoTime);
             for (ByteBuffer key : keys)
             {
-                ThriftValidation.validateKey(cfm, key);
+                Validation.validateKey(cfm, key);
                 DecoratedKey dk = cfm.decorateKey(key);
 
                 PartitionUpdate upd = collector.getPartitionUpdate(cfm, dk, options.getConsistency());
@@ -667,7 +666,7 @@ public abstract class ModificationStatement implements CQLStatement
 
             for (ByteBuffer key : keys)
             {
-                ThriftValidation.validateKey(cfm, key);
+                Validation.validateKey(cfm, key);
                 DecoratedKey dk = cfm.decorateKey(key);
 
                 PartitionUpdate upd = collector.getPartitionUpdate(cfm, dk, options.getConsistency());
@@ -789,13 +788,13 @@ public abstract class ModificationStatement implements CQLStatement
         {
             VariableSpecifications boundNames = getBoundVariables();
             ModificationStatement statement = prepare(boundNames);
-            CFMetaData cfm = ThriftValidation.validateColumnFamily(keyspace(), columnFamily());
+            CFMetaData cfm = Validation.validateColumnFamily(keyspace(), columnFamily());
             return new ParsedStatement.Prepared(statement, boundNames, boundNames.getPartitionKeyBindIndexes(cfm));
         }
 
         public ModificationStatement prepare(VariableSpecifications boundNames)
         {
-            CFMetaData metadata = ThriftValidation.validateColumnFamily(keyspace(), columnFamily());
+            CFMetaData metadata = Validation.validateColumnFamily(keyspace(), columnFamily());
 
             Attributes preparedAttributes = attrs.prepare(keyspace(), columnFamily());
             preparedAttributes.collectMarkerSpecification(boundNames);

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
index 1744e70..508e92a 100644
--- a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
@@ -55,7 +55,6 @@ import org.apache.cassandra.service.QueryState;
 import org.apache.cassandra.service.pager.AggregationQueryPager;
 import org.apache.cassandra.service.pager.PagingState;
 import org.apache.cassandra.service.pager.QueryPager;
-import org.apache.cassandra.thrift.ThriftValidation;
 import org.apache.cassandra.transport.ProtocolVersion;
 import org.apache.cassandra.transport.messages.ResultMessage;
 import org.apache.cassandra.utils.ByteBufferUtil;
@@ -924,7 +923,7 @@ public class SelectStatement implements CQLStatement
 
         public ParsedStatement.Prepared prepare(boolean forView) throws InvalidRequestException
         {
-            CFMetaData cfm = ThriftValidation.validateColumnFamily(keyspace(), columnFamily());
+            CFMetaData cfm = Validation.validateColumnFamily(keyspace(), columnFamily());
             VariableSpecifications boundNames = getBoundVariables();
 
             Selection selection = selectClause.isEmpty()

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/cql3/statements/TruncateStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/TruncateStatement.java b/src/java/org/apache/cassandra/cql3/statements/TruncateStatement.java
index 1478efd..927cdda 100644
--- a/src/java/org/apache/cassandra/cql3/statements/TruncateStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/TruncateStatement.java
@@ -30,7 +30,6 @@ import org.apache.cassandra.transport.messages.ResultMessage;
 import org.apache.cassandra.service.ClientState;
 import org.apache.cassandra.service.QueryState;
 import org.apache.cassandra.service.StorageProxy;
-import org.apache.cassandra.thrift.ThriftValidation;
 
 public class TruncateStatement extends CFStatement implements CQLStatement
 {
@@ -56,7 +55,7 @@ public class TruncateStatement extends CFStatement implements CQLStatement
 
     public void validate(ClientState state) throws InvalidRequestException
     {
-        ThriftValidation.validateColumnFamily(keyspace(), columnFamily());
+        Validation.validateColumnFamily(keyspace(), columnFamily());
     }
 
     public ResultMessage execute(QueryState state, QueryOptions options, long queryStartNanoTime) throws InvalidRequestException, TruncateException

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/cql3/statements/UpdateStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/UpdateStatement.java b/src/java/org/apache/cassandra/cql3/statements/UpdateStatement.java
index 6bcfd9c..9817c24 100644
--- a/src/java/org/apache/cassandra/cql3/statements/UpdateStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/UpdateStatement.java
@@ -75,12 +75,9 @@ public class UpdateStatement extends ModificationStatement
 
             List<Operation> updates = getRegularOperations();
 
-            // For compact table, when we translate it to thrift, we don't have a row marker. So we don't accept an insert/update
-            // that only sets the PK unless the is no declared non-PK columns (in the latter we just set the value empty).
-
-            // For a dense layout, when we translate it to thrift, we don't have a row marker. So we don't accept an insert/update
-            // that only sets the PK unless the is no declared non-PK columns (which we recognize because in that case the compact
-            // value is of type "EmptyType").
+            // For compact table, we don't accept an insert/update that only sets the PK unless the is no
+            // declared non-PK columns (which we recognize because in that case
+            // the compact value is of type "EmptyType").
             if (cfm.isCompactTable() && updates.isEmpty())
             {
                 checkTrue(CompactTables.hasEmptyCompactValue(cfm),

http://git-wip-us.apache.org/repos/asf/cassandra/blob/4881d9c3/src/java/org/apache/cassandra/db/BufferClustering.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/BufferClustering.java b/src/java/org/apache/cassandra/db/BufferClustering.java
index df6a473..0c2ecbc 100644
--- a/src/java/org/apache/cassandra/db/BufferClustering.java
+++ b/src/java/org/apache/cassandra/db/BufferClustering.java
@@ -27,9 +27,8 @@ import java.nio.ByteBuffer;
  * prefix used by rows.
  * <p>
  * Note however that while it's size must be equal to the table clustering size, a clustering can have
- * {@code null} values, and this mostly for thrift backward compatibility (in practice, if a value is null,
- * all of the following ones will be too because that's what thrift allows, but it's never assumed by the
- * code so we could start generally allowing nulls for clustering columns if we wanted to).
+ * {@code null} values (this is currently only allowed in COMPACT table for historical reasons, but we
+ * could imagine lifting that limitation if we decide it make sense from a CQL point of view).
  */
 public class BufferClustering extends AbstractBufferClusteringPrefix implements Clustering
 {