You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by al...@apache.org on 2018/07/17 15:40:31 UTC

[09/13] cassandra git commit: Make all DDL statements idempotent and not dependent on global state

http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/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
deleted file mode 100644
index 2f302c0..0000000
--- a/src/java/org/apache/cassandra/cql3/statements/DropKeyspaceStatement.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.cassandra.cql3.statements;
-
-import org.apache.cassandra.audit.AuditLogEntryType;
-import org.apache.cassandra.auth.Permission;
-import org.apache.cassandra.db.virtual.VirtualKeyspaceRegistry;
-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.schema.MigrationManager;
-import org.apache.cassandra.schema.Schema;
-import org.apache.cassandra.service.ClientState;
-import org.apache.cassandra.service.QueryState;
-import org.apache.cassandra.transport.Event;
-import org.apache.commons.lang3.builder.ToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
-
-public class DropKeyspaceStatement extends SchemaAlteringStatement
-{
-    private final String keyspace;
-    private final boolean ifExists;
-
-    public DropKeyspaceStatement(String keyspace, boolean ifExists)
-    {
-        super();
-        this.keyspace = keyspace;
-        this.ifExists = ifExists;
-    }
-
-    public void checkAccess(ClientState state) throws UnauthorizedException, InvalidRequestException
-    {
-        state.hasKeyspaceAccess(keyspace, Permission.DROP);
-    }
-
-    public void validate(ClientState state) throws RequestValidationException
-    {
-        Schema.validateKeyspaceNotSystem(keyspace);
-    }
-
-    @Override
-    public String keyspace()
-    {
-        return keyspace;
-    }
-
-    public Event.SchemaChange announceMigration(QueryState queryState, boolean isLocalOnly) throws ConfigurationException
-    {
-        if (null != VirtualKeyspaceRegistry.instance.getKeyspaceNullable(keyspace))
-            throw new InvalidRequestException("Cannot drop virtual keyspaces");
-
-        try
-        {
-            MigrationManager.announceKeyspaceDrop(keyspace, isLocalOnly);
-            return new Event.SchemaChange(Event.SchemaChange.Change.DROPPED, keyspace());
-        }
-        catch(ConfigurationException e)
-        {
-            if (ifExists)
-                return null;
-            throw e;
-        }
-    }
-    
-    @Override
-    public String toString()
-    {
-        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
-    }
-
-    @Override
-    public AuditLogContext getAuditLogContext()
-    {
-        return new AuditLogContext(AuditLogEntryType.DROP_KEYSPACE, keyspace());
-    }
-}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/cql3/statements/DropRoleStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/DropRoleStatement.java b/src/java/org/apache/cassandra/cql3/statements/DropRoleStatement.java
index 88b8b1a..058ab01 100644
--- a/src/java/org/apache/cassandra/cql3/statements/DropRoleStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/DropRoleStatement.java
@@ -17,6 +17,7 @@
  */
 package org.apache.cassandra.cql3.statements;
 
+import org.apache.cassandra.audit.AuditLogContext;
 import org.apache.cassandra.audit.AuditLogEntryType;
 import org.apache.cassandra.auth.*;
 import org.apache.cassandra.config.DatabaseDescriptor;
@@ -38,7 +39,7 @@ public class DropRoleStatement extends AuthenticationStatement
         this.ifExists = ifExists;
     }
 
-    public void checkAccess(ClientState state) throws UnauthorizedException
+    public void authorize(ClientState state) throws UnauthorizedException
     {
         super.checkPermission(state, Permission.DROP, role);
 
@@ -52,7 +53,7 @@ public class DropRoleStatement extends AuthenticationStatement
 
     public void validate(ClientState state) throws RequestValidationException
     {
-        // validate login here before checkAccess to avoid leaking user existence to anonymous users.
+        // validate login here before authorize to avoid leaking user existence to anonymous users.
         state.ensureNotAnonymous();
 
         if (!ifExists && !DatabaseDescriptor.getRoleManager().isExistingRole(role))

http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/cql3/statements/DropTableStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/DropTableStatement.java b/src/java/org/apache/cassandra/cql3/statements/DropTableStatement.java
deleted file mode 100644
index beb1002..0000000
--- a/src/java/org/apache/cassandra/cql3/statements/DropTableStatement.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.cassandra.cql3.statements;
-
-import org.apache.cassandra.audit.AuditLogEntryType;
-import org.apache.cassandra.auth.Permission;
-import org.apache.cassandra.cql3.CFName;
-import org.apache.cassandra.exceptions.ConfigurationException;
-import org.apache.cassandra.exceptions.InvalidRequestException;
-import org.apache.cassandra.exceptions.UnauthorizedException;
-import org.apache.cassandra.schema.KeyspaceMetadata;
-import org.apache.cassandra.schema.MigrationManager;
-import org.apache.cassandra.schema.Schema;
-import org.apache.cassandra.schema.TableMetadata;
-import org.apache.cassandra.schema.ViewMetadata;
-import org.apache.cassandra.service.ClientState;
-import org.apache.cassandra.service.QueryState;
-import org.apache.cassandra.transport.Event;
-import org.apache.commons.lang3.builder.ToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
-
-public class DropTableStatement extends SchemaAlteringStatement
-{
-    private final boolean ifExists;
-
-    public DropTableStatement(CFName name, boolean ifExists)
-    {
-        super(name);
-        this.ifExists = ifExists;
-    }
-
-    public void checkAccess(ClientState state) throws UnauthorizedException, InvalidRequestException
-    {
-        try
-        {
-            state.hasColumnFamilyAccess(keyspace(), columnFamily(), Permission.DROP);
-        }
-        catch (InvalidRequestException e)
-        {
-            if (!ifExists)
-                throw e;
-        }
-    }
-
-    public void validate(ClientState state)
-    {
-        // validated in announceMigration()
-    }
-
-    public Event.SchemaChange announceMigration(QueryState queryState, boolean isLocalOnly) throws ConfigurationException
-    {
-        try
-        {
-            KeyspaceMetadata ksm = Schema.instance.getKeyspaceMetadata(keyspace());
-            if (ksm == null)
-                throw new ConfigurationException(String.format("Cannot drop table in unknown keyspace '%s'", keyspace()));
-            TableMetadata metadata = ksm.getTableOrViewNullable(columnFamily());
-            if (metadata != null)
-            {
-                if (metadata.isView())
-                    throw new InvalidRequestException("Cannot use DROP TABLE on Materialized View");
-
-                if (metadata.isVirtual())
-                    throw new InvalidRequestException("Cannot drop virtual tables");
-
-                boolean rejectDrop = false;
-                StringBuilder messageBuilder = new StringBuilder();
-                for (ViewMetadata def : ksm.views)
-                {
-                    if (def.baseTableId.equals(metadata.id))
-                    {
-                        if (rejectDrop)
-                            messageBuilder.append(',');
-                        rejectDrop = true;
-                        messageBuilder.append(def.name);
-                    }
-                }
-                if (rejectDrop)
-                {
-                    throw new InvalidRequestException(String.format("Cannot drop table when materialized views still depend on it (%s.{%s})",
-                                                                    keyspace(),
-                                                                    messageBuilder.toString()));
-                }
-            }
-            MigrationManager.announceTableDrop(keyspace(), columnFamily(), isLocalOnly);
-            return new Event.SchemaChange(Event.SchemaChange.Change.DROPPED, Event.SchemaChange.Target.TABLE, keyspace(), columnFamily());
-        }
-        catch (ConfigurationException e)
-        {
-            if (ifExists)
-                return null;
-            throw e;
-        }
-    }
-    
-    @Override
-    public String toString()
-    {
-        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
-    }
-
-    @Override
-    public AuditLogContext getAuditLogContext()
-    {
-        return new AuditLogContext(AuditLogEntryType.DROP_TABLE, keyspace(), cfName.getColumnFamily());
-    }
-}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/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
deleted file mode 100644
index 1d9e3e4..0000000
--- a/src/java/org/apache/cassandra/cql3/statements/DropTriggerStatement.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.cassandra.cql3.statements;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.cassandra.audit.AuditLogEntryType;
-import org.apache.cassandra.cql3.CFName;
-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.schema.MigrationManager;
-import org.apache.cassandra.schema.Schema;
-import org.apache.cassandra.schema.TableMetadata;
-import org.apache.cassandra.schema.Triggers;
-import org.apache.cassandra.service.ClientState;
-import org.apache.cassandra.service.QueryState;
-import org.apache.cassandra.transport.Event;
-import org.apache.commons.lang3.builder.ToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
-
-public class DropTriggerStatement extends SchemaAlteringStatement
-{
-    private static final Logger logger = LoggerFactory.getLogger(DropTriggerStatement.class);
-
-    private final String triggerName;
-
-    private final boolean ifExists;
-
-    public DropTriggerStatement(CFName name, String triggerName, boolean ifExists)
-    {
-        super(name);
-        this.triggerName = triggerName;
-        this.ifExists = ifExists;
-    }
-
-    public void checkAccess(ClientState state) throws UnauthorizedException
-    {
-        state.ensureIsSuper("Only superusers are allowed to perfrom DROP TRIGGER queries");
-    }
-
-    public void validate(ClientState state) throws RequestValidationException
-    {
-        Schema.instance.validateTable(keyspace(), columnFamily());
-    }
-
-    public Event.SchemaChange announceMigration(QueryState queryState, boolean isLocalOnly) throws ConfigurationException, InvalidRequestException
-    {
-        TableMetadata current = Schema.instance.getTableMetadata(keyspace(), columnFamily());
-        Triggers triggers = current.triggers;
-
-        if (!triggers.get(triggerName).isPresent())
-        {
-            if (ifExists)
-                return null;
-            else
-                throw new InvalidRequestException(String.format("Trigger %s was not found", triggerName));
-        }
-
-        logger.info("Dropping trigger with name {}", triggerName);
-
-        TableMetadata updated =
-            current.unbuild()
-                   .triggers(triggers.without(triggerName))
-                   .build();
-
-        MigrationManager.announceTableUpdate(updated, isLocalOnly);
-
-        return new Event.SchemaChange(Event.SchemaChange.Change.UPDATED, Event.SchemaChange.Target.TABLE, keyspace(), columnFamily());
-    }
-    
-    @Override
-    public String toString()
-    {
-        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
-    }
-
-    @Override
-    public AuditLogContext getAuditLogContext()
-    {
-        return new AuditLogContext(AuditLogEntryType.DROP_TRIGGER, keyspace(), triggerName);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/cql3/statements/DropTypeStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/DropTypeStatement.java b/src/java/org/apache/cassandra/cql3/statements/DropTypeStatement.java
deleted file mode 100644
index cc4ca1c..0000000
--- a/src/java/org/apache/cassandra/cql3/statements/DropTypeStatement.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.cassandra.cql3.statements;
-
-import org.apache.cassandra.audit.AuditLogEntryType;
-import org.apache.cassandra.auth.Permission;
-import org.apache.cassandra.cql3.*;
-import org.apache.cassandra.cql3.functions.Function;
-import org.apache.cassandra.db.marshal.*;
-import org.apache.cassandra.exceptions.*;
-import org.apache.cassandra.schema.ColumnMetadata;
-import org.apache.cassandra.schema.KeyspaceMetadata;
-import org.apache.cassandra.schema.MigrationManager;
-import org.apache.cassandra.schema.Schema;
-import org.apache.cassandra.schema.TableMetadata;
-import org.apache.cassandra.service.ClientState;
-import org.apache.cassandra.service.QueryState;
-import org.apache.cassandra.transport.Event;
-import org.apache.commons.lang3.builder.ToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
-
-public class DropTypeStatement extends SchemaAlteringStatement
-{
-    private final UTName name;
-    private final boolean ifExists;
-
-    public DropTypeStatement(UTName name, boolean ifExists)
-    {
-        this.name = name;
-        this.ifExists = ifExists;
-    }
-
-    @Override
-    public void prepareKeyspace(ClientState state) throws InvalidRequestException
-    {
-        if (!name.hasKeyspace())
-            name.setKeyspace(state.getKeyspace());
-    }
-
-    public void checkAccess(ClientState state) throws UnauthorizedException, InvalidRequestException
-    {
-        state.hasKeyspaceAccess(keyspace(), Permission.DROP);
-    }
-
-    public void validate(ClientState state) throws RequestValidationException
-    {
-        KeyspaceMetadata ksm = Schema.instance.getKeyspaceMetadata(name.getKeyspace());
-        if (ksm == null)
-        {
-            if (ifExists)
-                return;
-            else
-                throw new InvalidRequestException(String.format("Cannot drop type in unknown keyspace %s", name.getKeyspace()));
-        }
-
-        if (!ksm.types.get(name.getUserTypeName()).isPresent())
-        {
-            if (ifExists)
-                return;
-            else
-                throw new InvalidRequestException(String.format("No user type named %s exists.", name));
-        }
-
-        // We don't want to drop a type unless it's not used anymore (mainly because
-        // if someone drops a type and recreates one with the same name but different
-        // definition with the previous name still in use, things can get messy).
-        // We have two places to check: 1) other user type that can nest the one
-        // we drop and 2) existing tables referencing the type (maybe in a nested
-        // way).
-
-        for (Function function : ksm.functions)
-        {
-            if (function.returnType().referencesUserType(name.getStringTypeName()))
-                throw new InvalidRequestException(String.format("Cannot drop user type %s as it is still used by function %s", name, function));
-
-            for (AbstractType<?> argType : function.argTypes())
-                if (argType.referencesUserType(name.getStringTypeName()))
-                    throw new InvalidRequestException(String.format("Cannot drop user type %s as it is still used by function %s", name, function));
-        }
-
-        for (UserType ut : ksm.types)
-            if (!ut.name.equals(name.getUserTypeName()) && ut.referencesUserType(name.getStringTypeName()))
-                throw new InvalidRequestException(String.format("Cannot drop user type %s as it is still used by user type %s", name, ut.getNameAsString()));
-
-        for (TableMetadata table : ksm.tablesAndViews())
-            for (ColumnMetadata def : table.columns())
-                if (def.type.referencesUserType(name.getStringTypeName()))
-                    throw new InvalidRequestException(String.format("Cannot drop user type %s as it is still used by table %s", name, table.toString()));
-    }
-
-    @Override
-    public String keyspace()
-    {
-        return name.getKeyspace();
-    }
-
-    public Event.SchemaChange announceMigration(QueryState queryState, boolean isLocalOnly) throws InvalidRequestException, ConfigurationException
-    {
-        KeyspaceMetadata ksm = Schema.instance.getKeyspaceMetadata(name.getKeyspace());
-        if (ksm == null)
-            return null; // do not assert (otherwise IF EXISTS case fails)
-
-        UserType toDrop = ksm.types.getNullable(name.getUserTypeName());
-        // Can be null with ifExists
-        if (toDrop == null)
-            return null;
-
-        MigrationManager.announceTypeDrop(toDrop, isLocalOnly);
-        return new Event.SchemaChange(Event.SchemaChange.Change.DROPPED, Event.SchemaChange.Target.TYPE, keyspace(), name.getStringTypeName());
-    }
-
-    @Override
-    public String toString()
-    {
-        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
-    }
-
-    @Override
-    public AuditLogContext getAuditLogContext()
-    {
-        return new AuditLogContext(AuditLogEntryType.DROP_TYPE, keyspace(), name.getStringTypeName());
-    }
-}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/cql3/statements/DropViewStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/DropViewStatement.java b/src/java/org/apache/cassandra/cql3/statements/DropViewStatement.java
deleted file mode 100644
index 218807f..0000000
--- a/src/java/org/apache/cassandra/cql3/statements/DropViewStatement.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.cassandra.cql3.statements;
-
-import org.apache.cassandra.audit.AuditLogEntryType;
-import org.apache.cassandra.auth.Permission;
-import org.apache.cassandra.cql3.CFName;
-import org.apache.cassandra.db.view.View;
-import org.apache.cassandra.exceptions.ConfigurationException;
-import org.apache.cassandra.exceptions.InvalidRequestException;
-import org.apache.cassandra.exceptions.UnauthorizedException;
-import org.apache.cassandra.schema.MigrationManager;
-import org.apache.cassandra.schema.TableMetadataRef;
-import org.apache.cassandra.service.ClientState;
-import org.apache.cassandra.service.QueryState;
-import org.apache.cassandra.transport.Event;
-import org.apache.commons.lang3.builder.ToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
-
-public class DropViewStatement extends SchemaAlteringStatement
-{
-    public final boolean ifExists;
-
-    public DropViewStatement(CFName cf, boolean ifExists)
-    {
-        super(cf);
-        this.ifExists = ifExists;
-    }
-
-    public void checkAccess(ClientState state) throws UnauthorizedException, InvalidRequestException
-    {
-        TableMetadataRef baseTable = View.findBaseTable(keyspace(), columnFamily());
-        if (baseTable != null)
-            state.hasColumnFamilyAccess(keyspace(), baseTable.name, Permission.ALTER);
-    }
-
-    public void validate(ClientState state)
-    {
-        // validated in findIndexedCf()
-    }
-
-    public Event.SchemaChange announceMigration(QueryState queryState, boolean isLocalOnly) throws InvalidRequestException, ConfigurationException
-    {
-        try
-        {
-            MigrationManager.announceViewDrop(keyspace(), columnFamily(), isLocalOnly);
-            return new Event.SchemaChange(Event.SchemaChange.Change.DROPPED, Event.SchemaChange.Target.TABLE, keyspace(), columnFamily());
-        }
-        catch (ConfigurationException e)
-        {
-            if (ifExists)
-                return null;
-            throw e;
-        }
-    }
-    
-    @Override
-    public String toString()
-    {
-        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
-    }
-
-    @Override
-    public AuditLogContext getAuditLogContext()
-    {
-        return new AuditLogContext(AuditLogEntryType.DROP_VIEW, keyspace(), cfName.getColumnFamily());
-    }
-}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/cql3/statements/GrantPermissionsStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/GrantPermissionsStatement.java b/src/java/org/apache/cassandra/cql3/statements/GrantPermissionsStatement.java
index f5ac5ca..3db20e3 100644
--- a/src/java/org/apache/cassandra/cql3/statements/GrantPermissionsStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/GrantPermissionsStatement.java
@@ -19,6 +19,7 @@ package org.apache.cassandra.cql3.statements;
 
 import java.util.Set;
 
+import org.apache.cassandra.audit.AuditLogContext;
 import org.apache.cassandra.audit.AuditLogEntryType;
 import org.apache.cassandra.auth.IResource;
 import org.apache.cassandra.auth.Permission;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/cql3/statements/GrantRoleStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/GrantRoleStatement.java b/src/java/org/apache/cassandra/cql3/statements/GrantRoleStatement.java
index f234237..d6240c5 100644
--- a/src/java/org/apache/cassandra/cql3/statements/GrantRoleStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/GrantRoleStatement.java
@@ -17,6 +17,7 @@
  */
 package org.apache.cassandra.cql3.statements;
 
+import org.apache.cassandra.audit.AuditLogContext;
 import org.apache.cassandra.audit.AuditLogEntryType;
 import org.apache.cassandra.config.DatabaseDescriptor;
 import org.apache.cassandra.cql3.RoleName;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/cql3/statements/IndexPropDefs.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/IndexPropDefs.java b/src/java/org/apache/cassandra/cql3/statements/IndexPropDefs.java
deleted file mode 100644
index b8ce7ec..0000000
--- a/src/java/org/apache/cassandra/cql3/statements/IndexPropDefs.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.cassandra.cql3.statements;
-
-import java.util.*;
-
-import org.apache.cassandra.exceptions.InvalidRequestException;
-import org.apache.cassandra.exceptions.RequestValidationException;
-import org.apache.cassandra.exceptions.SyntaxException;
-
-public class IndexPropDefs extends PropertyDefinitions
-{
-    public static final String KW_OPTIONS = "options";
-
-    public static final Set<String> keywords = new HashSet<>();
-    public static final Set<String> obsoleteKeywords = new HashSet<>();
-
-    public boolean isCustom;
-    public String customClass;
-
-    static
-    {
-        keywords.add(KW_OPTIONS);
-    }
-
-    public void validate() throws RequestValidationException
-    {
-        validate(keywords, obsoleteKeywords);
-
-        if (isCustom && customClass == null)
-            throw new InvalidRequestException("CUSTOM index requires specifiying the index class");
-
-        if (!isCustom && customClass != null)
-            throw new InvalidRequestException("Cannot specify index class for a non-CUSTOM index");
-
-        if (!isCustom && !properties.isEmpty())
-            throw new InvalidRequestException("Cannot specify options for a non-CUSTOM index");
-
-        if (getRawOptions().containsKey(IndexTarget.CUSTOM_INDEX_OPTION_NAME))
-            throw new InvalidRequestException(String.format("Cannot specify %s as a CUSTOM option",
-                                                            IndexTarget.CUSTOM_INDEX_OPTION_NAME));
-
-        if (getRawOptions().containsKey(IndexTarget.TARGET_OPTION_NAME))
-            throw new InvalidRequestException(String.format("Cannot specify %s as a CUSTOM option",
-                                                            IndexTarget.TARGET_OPTION_NAME));
-
-    }
-
-    public Map<String, String> getRawOptions() throws SyntaxException
-    {
-        Map<String, String> options = getMap(KW_OPTIONS);
-        return options == null ? Collections.<String, String>emptyMap() : options;
-    }
-
-    public Map<String, String> getOptions() throws SyntaxException
-    {
-        Map<String, String> options = new HashMap<>(getRawOptions());
-        options.put(IndexTarget.CUSTOM_INDEX_OPTION_NAME, customClass);
-        return options;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/cql3/statements/IndexTarget.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/IndexTarget.java b/src/java/org/apache/cassandra/cql3/statements/IndexTarget.java
deleted file mode 100644
index 26ca3df..0000000
--- a/src/java/org/apache/cassandra/cql3/statements/IndexTarget.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.cassandra.cql3.statements;
-
-import org.apache.cassandra.schema.ColumnMetadata;
-import org.apache.cassandra.schema.TableMetadata;
-import org.apache.cassandra.cql3.ColumnIdentifier;
-import org.apache.commons.lang3.builder.ToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
-
-public class IndexTarget
-{
-    public static final String TARGET_OPTION_NAME = "target";
-    public static final String CUSTOM_INDEX_OPTION_NAME = "class_name";
-
-    public final ColumnIdentifier column;
-    public final Type type;
-
-    public IndexTarget(ColumnIdentifier column, Type type)
-    {
-        this.column = column;
-        this.type = type;
-    }
-
-    public String asCqlString()
-    {
-        return type == Type.SIMPLE
-               ? column.toCQLString()
-               : String.format("%s(%s)", type.toString(), column.toCQLString());
-    }
-
-    public static class Raw
-    {
-        private final ColumnMetadata.Raw column;
-        private final Type type;
-
-        private Raw(ColumnMetadata.Raw column, Type type)
-        {
-            this.column = column;
-            this.type = type;
-        }
-
-        public static Raw simpleIndexOn(ColumnMetadata.Raw c)
-        {
-            return new Raw(c, Type.SIMPLE);
-        }
-
-        public static Raw valuesOf(ColumnMetadata.Raw c)
-        {
-            return new Raw(c, Type.VALUES);
-        }
-
-        public static Raw keysOf(ColumnMetadata.Raw c)
-        {
-            return new Raw(c, Type.KEYS);
-        }
-
-        public static Raw keysAndValuesOf(ColumnMetadata.Raw c)
-        {
-            return new Raw(c, Type.KEYS_AND_VALUES);
-        }
-
-        public static Raw fullCollection(ColumnMetadata.Raw c)
-        {
-            return new Raw(c, Type.FULL);
-        }
-
-        public IndexTarget prepare(TableMetadata table)
-        {
-            // Until we've prepared the target column, we can't be certain about the target type
-            // because (for backwards compatibility) an index on a collection's values uses the
-            // same syntax as an index on a regular column (i.e. the 'values' in
-            // 'CREATE INDEX on table(values(collection));' is optional). So we correct the target type
-            // when the target column is a collection & the target type is SIMPLE.
-            ColumnMetadata columnDef = column.prepare(table);
-            Type actualType = (type == Type.SIMPLE && columnDef.type.isCollection()) ? Type.VALUES : type;
-            return new IndexTarget(columnDef.name, actualType);
-        }
-    }
-
-    public enum Type
-    {
-        VALUES, KEYS, KEYS_AND_VALUES, FULL, SIMPLE;
-
-        public String toString()
-        {
-            switch (this)
-            {
-                case KEYS: return "keys";
-                case KEYS_AND_VALUES: return "entries";
-                case FULL: return "full";
-                case VALUES: return "values";
-                case SIMPLE: return "";
-                default: return "";
-            }
-        }
-
-        public static Type fromString(String s)
-        {
-            if ("".equals(s))
-                return SIMPLE;
-            else if ("values".equals(s))
-                return VALUES;
-            else if ("keys".equals(s))
-                return KEYS;
-            else if ("entries".equals(s))
-                return KEYS_AND_VALUES;
-            else if ("full".equals(s))
-                return FULL;
-
-            throw new AssertionError("Unrecognized index target type " + s);
-        }
-    }
-    
-    @Override
-    public String toString()
-    {
-        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/cql3/statements/KeyspaceAttributes.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/KeyspaceAttributes.java b/src/java/org/apache/cassandra/cql3/statements/KeyspaceAttributes.java
deleted file mode 100644
index d2280ce..0000000
--- a/src/java/org/apache/cassandra/cql3/statements/KeyspaceAttributes.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.cassandra.cql3.statements;
-
-import java.util.*;
-
-import com.google.common.collect.ImmutableSet;
-
-import org.apache.cassandra.exceptions.ConfigurationException;
-import org.apache.cassandra.schema.KeyspaceParams;
-import org.apache.cassandra.schema.KeyspaceParams.Option;
-import org.apache.cassandra.schema.ReplicationParams;
-
-public final class KeyspaceAttributes extends PropertyDefinitions
-{
-    private static final Set<String> validKeywords;
-    private static final Set<String> obsoleteKeywords;
-
-    static
-    {
-        ImmutableSet.Builder<String> validBuilder = ImmutableSet.builder();
-        for (Option option : Option.values())
-            validBuilder.add(option.toString());
-        validKeywords = validBuilder.build();
-        obsoleteKeywords = ImmutableSet.of();
-    }
-
-    public void validate()
-    {
-        validate(validKeywords, obsoleteKeywords);
-
-        Map<String, String> replicationOptions = getAllReplicationOptions();
-        if (!replicationOptions.isEmpty() && !replicationOptions.containsKey(ReplicationParams.CLASS))
-            throw new ConfigurationException("Missing replication strategy class");
-    }
-
-    public String getReplicationStrategyClass()
-    {
-        return getAllReplicationOptions().get(ReplicationParams.CLASS);
-    }
-
-    public Map<String, String> getReplicationOptions()
-    {
-        Map<String, String> replication = new HashMap<>(getAllReplicationOptions());
-        replication.remove(ReplicationParams.CLASS);
-        return replication;
-    }
-
-    public Map<String, String> getAllReplicationOptions()
-    {
-        Map<String, String> replication = getMap(Option.REPLICATION.toString());
-        return replication == null
-             ? Collections.emptyMap()
-             : replication;
-    }
-
-    public KeyspaceParams asNewKeyspaceParams()
-    {
-        boolean durableWrites = getBoolean(Option.DURABLE_WRITES.toString(), KeyspaceParams.DEFAULT_DURABLE_WRITES);
-        return KeyspaceParams.create(durableWrites, getAllReplicationOptions());
-    }
-
-    public KeyspaceParams asAlteredKeyspaceParams(KeyspaceParams previous)
-    {
-        boolean durableWrites = getBoolean(Option.DURABLE_WRITES.toString(), previous.durableWrites);
-        ReplicationParams replication = getReplicationStrategyClass() == null
-                                      ? previous.replication
-                                      : ReplicationParams.fromMap(getAllReplicationOptions());
-        return new KeyspaceParams(durableWrites, replication);
-    }
-
-    public boolean hasOption(Option option)
-    {
-        return hasProperty(option.toString());
-    }
-}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/cql3/statements/ListPermissionsStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/ListPermissionsStatement.java b/src/java/org/apache/cassandra/cql3/statements/ListPermissionsStatement.java
index 80195c0..4b5aa60 100644
--- a/src/java/org/apache/cassandra/cql3/statements/ListPermissionsStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/ListPermissionsStatement.java
@@ -19,6 +19,7 @@ package org.apache.cassandra.cql3.statements;
 
 import java.util.*;
 
+import org.apache.cassandra.audit.AuditLogContext;
 import org.apache.cassandra.audit.AuditLogEntryType;
 import org.apache.cassandra.auth.*;
 import org.apache.cassandra.config.DatabaseDescriptor;
@@ -79,7 +80,7 @@ public class ListPermissionsStatement extends AuthorizationStatement
             throw new InvalidRequestException(String.format("%s doesn't exist", grantee));
    }
 
-    public void checkAccess(ClientState state)
+    public void authorize(ClientState state)
     {
         // checked in validate
     }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/cql3/statements/ListRolesStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/ListRolesStatement.java b/src/java/org/apache/cassandra/cql3/statements/ListRolesStatement.java
index 8b51c59..8a75f8a 100644
--- a/src/java/org/apache/cassandra/cql3/statements/ListRolesStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/ListRolesStatement.java
@@ -24,6 +24,7 @@ import java.util.Set;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
 
+import org.apache.cassandra.audit.AuditLogContext;
 import org.apache.cassandra.audit.AuditLogEntryType;
 import org.apache.cassandra.auth.*;
 import org.apache.cassandra.config.DatabaseDescriptor;
@@ -74,7 +75,7 @@ public class ListRolesStatement extends AuthorizationStatement
             throw new InvalidRequestException(String.format("%s doesn't exist", grantee));
     }
 
-    public void checkAccess(ClientState state) throws InvalidRequestException
+    public void authorize(ClientState state) throws InvalidRequestException
     {
     }
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/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 65e1e2d..c388c48 100644
--- a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
@@ -29,7 +29,6 @@ import org.apache.cassandra.auth.Permission;
 import org.apache.cassandra.schema.ColumnMetadata;
 import org.apache.cassandra.schema.Schema;
 import org.apache.cassandra.schema.TableMetadata;
-import org.apache.cassandra.schema.ColumnMetadata.Raw;
 import org.apache.cassandra.schema.ViewMetadata;
 import org.apache.cassandra.cql3.*;
 import org.apache.cassandra.cql3.conditions.ColumnCondition;
@@ -77,7 +76,8 @@ public abstract class ModificationStatement implements CQLStatement
 
     protected final StatementType type;
 
-    private final int boundTerms;
+    protected final VariableSpecifications bindVariables;
+
     public final TableMetadata metadata;
     private final Attributes attrs;
 
@@ -94,7 +94,7 @@ public abstract class ModificationStatement implements CQLStatement
     private final RegularAndStaticColumns requiresRead;
 
     public ModificationStatement(StatementType type,
-                                 int boundTerms,
+                                 VariableSpecifications bindVariables,
                                  TableMetadata metadata,
                                  Operations operations,
                                  StatementRestrictions restrictions,
@@ -102,7 +102,7 @@ public abstract class ModificationStatement implements CQLStatement
                                  Attributes attrs)
     {
         this.type = type;
-        this.boundTerms = boundTerms;
+        this.bindVariables = bindVariables;
         this.metadata = metadata;
         this.restrictions = restrictions;
         this.operations = operations;
@@ -147,6 +147,19 @@ public abstract class ModificationStatement implements CQLStatement
         this.requiresRead = requiresReadBuilder.build();
     }
 
+    @Override
+    public List<ColumnSpecification> getBindVariables()
+    {
+        return bindVariables.getBindVariables();
+    }
+
+    @Override
+    public short[] getPartitionKeyBindVariableIndexes()
+    {
+        return bindVariables.getPartitionKeyBindVariableIndexes(metadata);
+    }
+
+    @Override
     public Iterable<Function> getFunctions()
     {
         List<Function> functions = new ArrayList<>();
@@ -179,11 +192,6 @@ public abstract class ModificationStatement implements CQLStatement
 
     public abstract void addUpdateForKey(PartitionUpdate.Builder updateBuilder, Slice slice, UpdateParameters params);
 
-    public int getBoundTerms()
-    {
-        return boundTerms;
-    }
-
     public String keyspace()
     {
         return metadata.keyspace;
@@ -224,28 +232,28 @@ public abstract class ModificationStatement implements CQLStatement
         return attrs.getTimeToLive(options, metadata);
     }
 
-    public void checkAccess(ClientState state) throws InvalidRequestException, UnauthorizedException
+    public void authorize(ClientState state) throws InvalidRequestException, UnauthorizedException
     {
-        state.hasColumnFamilyAccess(metadata, Permission.MODIFY);
+        state.ensureTablePermission(metadata, Permission.MODIFY);
 
         // CAS updates can be used to simulate a SELECT query, so should require Permission.SELECT as well.
         if (hasConditions())
-            state.hasColumnFamilyAccess(metadata, Permission.SELECT);
+            state.ensureTablePermission(metadata, Permission.SELECT);
 
         // MV updates need to get the current state from the table, and might update the views
         // Require Permission.SELECT on the base table, and Permission.MODIFY on the views
         Iterator<ViewMetadata> views = View.findAll(keyspace(), columnFamily()).iterator();
         if (views.hasNext())
         {
-            state.hasColumnFamilyAccess(metadata, Permission.SELECT);
+            state.ensureTablePermission(metadata, Permission.SELECT);
             do
             {
-                state.hasColumnFamilyAccess(views.next().metadata, Permission.MODIFY);
+                state.ensureTablePermission(views.next().metadata, Permission.MODIFY);
             } while (views.hasNext());
         }
 
         for (Function function : getFunctions())
-            state.ensureHasPermission(Permission.EXECUTE, function);
+            state.ensurePermission(Permission.EXECUTE, function);
     }
 
     public void validate(ClientState state) throws InvalidRequestException
@@ -597,7 +605,7 @@ public abstract class ModificationStatement implements CQLStatement
         return builder.build();
     }
 
-    public ResultMessage executeInternal(QueryState queryState, QueryOptions options) throws RequestValidationException, RequestExecutionException
+    public ResultMessage executeLocally(QueryState queryState, QueryOptions options) throws RequestValidationException, RequestExecutionException
     {
         return hasConditions()
                ? executeInternalWithCondition(queryState, options)
@@ -799,7 +807,7 @@ public abstract class ModificationStatement implements CQLStatement
         return builder.build();
     }
 
-    public static abstract class Parsed extends CFStatement
+    public static abstract class Parsed extends QualifiedStatement
     {
         protected final StatementType type;
         private final Attributes.Raw attrs;
@@ -807,7 +815,7 @@ public abstract class ModificationStatement implements CQLStatement
         private final boolean ifNotExists;
         private final boolean ifExists;
 
-        protected Parsed(CFName name,
+        protected Parsed(QualifiedName name,
                          StatementType type,
                          Attributes.Raw attrs,
                          List<Pair<ColumnMetadata.Raw, ColumnCondition.Raw>> conditions,
@@ -817,39 +825,36 @@ public abstract class ModificationStatement implements CQLStatement
             super(name);
             this.type = type;
             this.attrs = attrs;
-            this.conditions = conditions == null ? Collections.<Pair<ColumnMetadata.Raw, ColumnCondition.Raw>>emptyList() : conditions;
+            this.conditions = conditions == null ? Collections.emptyList() : conditions;
             this.ifNotExists = ifNotExists;
             this.ifExists = ifExists;
         }
 
-        public ParsedStatement.Prepared prepare()
+        public ModificationStatement prepare(ClientState state)
         {
-            VariableSpecifications boundNames = getBoundVariables();
-            ModificationStatement statement = prepare(boundNames);
-            TableMetadata metadata = Schema.instance.validateTable(keyspace(), columnFamily());
-            return new ParsedStatement.Prepared(statement, boundNames, boundNames.getPartitionKeyBindIndexes(metadata));
+            return prepare(bindVariables);
         }
 
-        public ModificationStatement prepare(VariableSpecifications boundNames)
+        public ModificationStatement prepare(VariableSpecifications bindVariables)
         {
-            TableMetadata metadata = Schema.instance.validateTable(keyspace(), columnFamily());
+            TableMetadata metadata = Schema.instance.validateTable(keyspace(), name());
 
-            Attributes preparedAttributes = attrs.prepare(keyspace(), columnFamily());
-            preparedAttributes.collectMarkerSpecification(boundNames);
+            Attributes preparedAttributes = attrs.prepare(keyspace(), name());
+            preparedAttributes.collectMarkerSpecification(bindVariables);
 
-            Conditions preparedConditions = prepareConditions(metadata, boundNames);
+            Conditions preparedConditions = prepareConditions(metadata, bindVariables);
 
-            return prepareInternal(metadata, boundNames, preparedConditions, preparedAttributes);
+            return prepareInternal(metadata, bindVariables, preparedConditions, preparedAttributes);
         }
 
         /**
          * Returns the column conditions.
          *
          * @param metadata the column family meta data
-         * @param boundNames the bound names
+         * @param bindVariables the bound names
          * @return the column conditions.
          */
-        private Conditions prepareConditions(TableMetadata metadata, VariableSpecifications boundNames)
+        private Conditions prepareConditions(TableMetadata metadata, VariableSpecifications bindVariables)
         {
             // To have both 'IF EXISTS'/'IF NOT EXISTS' and some other conditions doesn't make sense.
             // So far this is enforced by the parser, but let's assert it for sanity if ever the parse changes.
@@ -870,17 +875,17 @@ public abstract class ModificationStatement implements CQLStatement
             if (conditions.isEmpty())
                 return Conditions.EMPTY_CONDITION;
 
-            return prepareColumnConditions(metadata, boundNames);
+            return prepareColumnConditions(metadata, bindVariables);
         }
 
         /**
          * Returns the column conditions.
          *
          * @param metadata the column family meta data
-         * @param boundNames the bound names
+         * @param bindVariables the bound names
          * @return the column conditions.
          */
-        private ColumnConditions prepareColumnConditions(TableMetadata metadata, VariableSpecifications boundNames)
+        private ColumnConditions prepareColumnConditions(TableMetadata metadata, VariableSpecifications bindVariables)
         {
             checkNull(attrs.timestamp, "Cannot provide custom timestamp for conditional updates");
 
@@ -890,7 +895,7 @@ public abstract class ModificationStatement implements CQLStatement
             {
                 ColumnMetadata def = entry.left.prepare(metadata);
                 ColumnCondition condition = entry.right.prepare(keyspace(), def, metadata);
-                condition.collectMarkerSpecification(boundNames);
+                condition.collectMarkerSpecification(bindVariables);
 
                 checkFalse(def.isPrimaryKeyColumn(), "PRIMARY KEY column '%s' cannot have IF conditions", def.name);
                 builder.add(condition);
@@ -899,7 +904,7 @@ public abstract class ModificationStatement implements CQLStatement
         }
 
         protected abstract ModificationStatement prepareInternal(TableMetadata metadata,
-                                                                 VariableSpecifications boundNames,
+                                                                 VariableSpecifications bindVariables,
                                                                  Conditions conditions,
                                                                  Attributes attrs);
 
@@ -933,7 +938,7 @@ public abstract class ModificationStatement implements CQLStatement
          * @param rawId the raw <code>ColumnIdentifier</code>
          * @return the <code>ColumnMetadata</code> corresponding to the specified raw <code>ColumnIdentifier</code>
          */
-        protected static ColumnMetadata getColumnDefinition(TableMetadata metadata, Raw rawId)
+        protected static ColumnMetadata getColumnDefinition(TableMetadata metadata, ColumnMetadata.Raw rawId)
         {
             return rawId.prepare(metadata);
         }
@@ -942,7 +947,7 @@ public abstract class ModificationStatement implements CQLStatement
         {
             ImmutableList.Builder<Pair<ColumnMetadata.Raw, ColumnCondition.Raw>> builder = ImmutableList.builderWithExpectedSize(conditions.size());
 
-            for (Pair<Raw, ColumnCondition.Raw> condition : conditions)
+            for (Pair<ColumnMetadata.Raw, ColumnCondition.Raw> condition : conditions)
                 builder.add(Pair.create(condition.left, condition.right));
 
             return builder.build();

http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/cql3/statements/ParsedStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/ParsedStatement.java b/src/java/org/apache/cassandra/cql3/statements/ParsedStatement.java
deleted file mode 100644
index 34bfc3d..0000000
--- a/src/java/org/apache/cassandra/cql3/statements/ParsedStatement.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.cassandra.cql3.statements;
-
-import java.util.*;
-
-import org.apache.cassandra.cql3.*;
-import org.apache.cassandra.cql3.functions.Function;
-import org.apache.cassandra.exceptions.RequestValidationException;
-import org.apache.cassandra.utils.*;
-
-public abstract class ParsedStatement
-{
-    private VariableSpecifications variables;
-
-    public VariableSpecifications getBoundVariables()
-    {
-        return variables;
-    }
-
-    // Used by the parser and preparable statement
-    public void setBoundVariables(List<ColumnIdentifier> boundNames)
-    {
-        this.variables = new VariableSpecifications(boundNames);
-    }
-
-    public void setBoundVariables(VariableSpecifications variables)
-    {
-        this.variables = variables;
-    }
-
-    public abstract Prepared prepare() throws RequestValidationException;
-
-    public static class Prepared
-    {
-        /**
-         * Contains the CQL statement source if the statement has been "regularly" perpared via
-         * {@link org.apache.cassandra.cql3.QueryProcessor#prepare(java.lang.String, org.apache.cassandra.service.ClientState)} /
-         * {@link QueryHandler#prepare(java.lang.String, org.apache.cassandra.service.ClientState, java.util.Map)}.
-         * Other usages of this class may or may not contain the CQL statement source.
-         */
-        public String rawCQLStatement;
-
-        public final MD5Digest resultMetadataId;
-        public final List<ColumnSpecification> boundNames;
-        public final CQLStatement statement;
-        public final short[] partitionKeyBindIndexes;
-
-        protected Prepared(CQLStatement statement, List<ColumnSpecification> boundNames, short[] partitionKeyBindIndexes)
-        {
-            this.statement = statement;
-            this.boundNames = boundNames;
-            this.partitionKeyBindIndexes = partitionKeyBindIndexes;
-            this.resultMetadataId = ResultSet.ResultMetadata.fromPrepared(this).getResultMetadataId();
-            this.rawCQLStatement = "";
-        }
-
-        public Prepared(CQLStatement statement, VariableSpecifications names, short[] partitionKeyBindIndexes)
-        {
-            this(statement, names.getSpecifications(), partitionKeyBindIndexes);
-        }
-
-        public Prepared(CQLStatement statement)
-        {
-            this(statement, Collections.<ColumnSpecification>emptyList(), null);
-        }
-    }
-
-    public Iterable<Function> getFunctions()
-    {
-        return Collections.emptyList();
-    }
-}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/cql3/statements/PermissionsManagementStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/PermissionsManagementStatement.java b/src/java/org/apache/cassandra/cql3/statements/PermissionsManagementStatement.java
index 6c21012..aa7e85b 100644
--- a/src/java/org/apache/cassandra/cql3/statements/PermissionsManagementStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/PermissionsManagementStatement.java
@@ -45,14 +45,14 @@ public abstract class PermissionsManagementStatement extends AuthorizationStatem
 
     public void validate(ClientState state) throws RequestValidationException
     {
-        // validate login here before checkAccess to avoid leaking user existence to anonymous users.
+        // validate login here before authorize to avoid leaking user existence to anonymous users.
         state.ensureNotAnonymous();
 
         if (!DatabaseDescriptor.getRoleManager().isExistingRole(grantee))
             throw new InvalidRequestException(String.format("Role %s doesn't exist", grantee.getRoleName()));
 
         // if a keyspace is omitted when GRANT/REVOKE ON TABLE <table>, we need to correct the resource.
-        // called both here and in checkAccess(), as in some cases we do not call the latter.
+        // called both here and in authorize(), as in some cases we do not call the latter.
         resource = maybeCorrectResource(resource, state);
 
         // altering permissions on builtin functions is not supported
@@ -66,17 +66,17 @@ public abstract class PermissionsManagementStatement extends AuthorizationStatem
             throw new InvalidRequestException(String.format("Resource %s doesn't exist", resource));
     }
 
-    public void checkAccess(ClientState state) throws UnauthorizedException
+    public void authorize(ClientState state) throws UnauthorizedException
     {
         // if a keyspace is omitted when GRANT/REVOKE ON TABLE <table>, we need to correct the resource.
         resource = maybeCorrectResource(resource, state);
 
         // check that the user has AUTHORIZE permission on the resource or its parents, otherwise reject GRANT/REVOKE.
-        state.ensureHasPermission(Permission.AUTHORIZE, resource);
+        state.ensurePermission(Permission.AUTHORIZE, resource);
 
         // check that the user has [a single permission or all in case of ALL] on the resource or its parents.
         for (Permission p : permissions)
-            state.ensureHasPermission(p, resource);
+            state.ensurePermission(p, resource);
     }
     
     @Override

http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/cql3/statements/QualifiedStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/QualifiedStatement.java b/src/java/org/apache/cassandra/cql3/statements/QualifiedStatement.java
new file mode 100644
index 0000000..a9c1f19
--- /dev/null
+++ b/src/java/org/apache/cassandra/cql3/statements/QualifiedStatement.java
@@ -0,0 +1,76 @@
+/*
+ * 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.statements;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+
+import org.apache.cassandra.cql3.CQLStatement;
+import org.apache.cassandra.cql3.QualifiedName;
+import org.apache.cassandra.service.ClientState;
+
+/**
+ * Abstract class for statements that work on sub-keyspace level (tables, views, indexes, functions, etc.)
+ */
+public abstract class QualifiedStatement extends CQLStatement.Raw
+{
+    final QualifiedName qualifiedName;
+
+    QualifiedStatement(QualifiedName qualifiedName)
+    {
+        this.qualifiedName = qualifiedName;
+    }
+
+    public void setKeyspace(ClientState state)
+    {
+        if (!qualifiedName.hasKeyspace())
+        {
+            // XXX: We explicitly only want to call state.getKeyspace() in this case, as we don't want to throw
+            // if not logged in any keyspace but a keyspace is explicitly set on the statement. So don't move
+            // the call outside the 'if' or replace the method by 'setKeyspace(state.getKeyspace())'
+            qualifiedName.setKeyspace(state.getKeyspace(), true);
+        }
+    }
+
+    // Only for internal calls, use the version with ClientState for user queries. In particular, the
+    // version with ClientState throws an exception if the statement does not have keyspace set *and*
+    // ClientState has no keyspace
+    public void setKeyspace(String keyspace)
+    {
+        qualifiedName.setKeyspace(keyspace, true);
+    }
+
+    public String keyspace()
+    {
+        if (!qualifiedName.hasKeyspace())
+            throw new IllegalStateException("Statement must have keyspace set");
+
+        return qualifiedName.getKeyspace();
+    }
+
+    public String name()
+    {
+        return qualifiedName.getName();
+    }
+    
+    @Override
+    public String toString()
+    {
+        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/cql3/statements/RevokePermissionsStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/RevokePermissionsStatement.java b/src/java/org/apache/cassandra/cql3/statements/RevokePermissionsStatement.java
index eb528fc..57d0631 100644
--- a/src/java/org/apache/cassandra/cql3/statements/RevokePermissionsStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/RevokePermissionsStatement.java
@@ -19,6 +19,7 @@ package org.apache.cassandra.cql3.statements;
 
 import java.util.Set;
 
+import org.apache.cassandra.audit.AuditLogContext;
 import org.apache.cassandra.audit.AuditLogEntryType;
 import org.apache.cassandra.auth.IResource;
 import org.apache.cassandra.auth.Permission;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/cql3/statements/RevokeRoleStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/RevokeRoleStatement.java b/src/java/org/apache/cassandra/cql3/statements/RevokeRoleStatement.java
index c497121..651743f 100644
--- a/src/java/org/apache/cassandra/cql3/statements/RevokeRoleStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/RevokeRoleStatement.java
@@ -17,6 +17,7 @@
  */
 package org.apache.cassandra.cql3.statements;
 
+import org.apache.cassandra.audit.AuditLogContext;
 import org.apache.cassandra.audit.AuditLogEntryType;
 import org.apache.cassandra.config.DatabaseDescriptor;
 import org.apache.cassandra.cql3.RoleName;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/cql3/statements/RoleManagementStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/RoleManagementStatement.java b/src/java/org/apache/cassandra/cql3/statements/RoleManagementStatement.java
index 2c920bf..a5274dd 100644
--- a/src/java/org/apache/cassandra/cql3/statements/RoleManagementStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/RoleManagementStatement.java
@@ -39,7 +39,7 @@ public abstract class RoleManagementStatement extends AuthenticationStatement
         this.grantee = RoleResource.role(grantee.getName());
     }
 
-    public void checkAccess(ClientState state) throws UnauthorizedException
+    public void authorize(ClientState state) throws UnauthorizedException
     {
         super.checkPermission(state, Permission.AUTHORIZE, role);
     }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/src/java/org/apache/cassandra/cql3/statements/SchemaAlteringStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/SchemaAlteringStatement.java b/src/java/org/apache/cassandra/cql3/statements/SchemaAlteringStatement.java
deleted file mode 100644
index 4a20451..0000000
--- a/src/java/org/apache/cassandra/cql3/statements/SchemaAlteringStatement.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.cassandra.cql3.statements;
-
-import org.apache.cassandra.auth.AuthenticatedUser;
-import org.apache.cassandra.cql3.CFName;
-import org.apache.cassandra.cql3.CQLStatement;
-import org.apache.cassandra.cql3.QueryOptions;
-import org.apache.cassandra.exceptions.InvalidRequestException;
-import org.apache.cassandra.exceptions.RequestValidationException;
-import org.apache.cassandra.service.ClientState;
-import org.apache.cassandra.service.QueryState;
-import org.apache.cassandra.transport.Event;
-import org.apache.cassandra.transport.messages.ResultMessage;
-
-/**
- * Abstract class for statements that alter the schema.
- */
-public abstract class SchemaAlteringStatement extends CFStatement implements CQLStatement
-{
-    private final boolean isColumnFamilyLevel;
-
-    protected SchemaAlteringStatement()
-    {
-        super(null);
-        this.isColumnFamilyLevel = false;
-    }
-
-    protected SchemaAlteringStatement(CFName name)
-    {
-        super(name);
-        this.isColumnFamilyLevel = true;
-    }
-
-    public int getBoundTerms()
-    {
-        return 0;
-    }
-
-    @Override
-    public void prepareKeyspace(ClientState state) throws InvalidRequestException
-    {
-        if (isColumnFamilyLevel)
-            super.prepareKeyspace(state);
-    }
-
-    @Override
-    public Prepared prepare()
-    {
-        return new Prepared(this);
-    }
-
-    /**
-     * Schema alteration may result in a new database object (keyspace, table, role, function) being created capable of
-     * having permissions GRANTed on it. The creator of the object (the primary role assigned to the AuthenticatedUser
-     * performing the operation) is automatically granted ALL applicable permissions on the object. This is a hook for
-     * subclasses to override in order to perform that grant when the statement is executed.
-     */
-    protected void grantPermissionsToCreator(QueryState state)
-    {
-        // no-op by default
-    }
-
-    /**
-     * Announces the migration to other nodes in the cluster.
-     *
-     * @return the schema change event corresponding to the execution of this statement, or {@code null} if no schema change
-     * has occurred (when IF NOT EXISTS is used, for example)
-     *
-     * @throws RequestValidationException
-     */
-    protected abstract Event.SchemaChange announceMigration(QueryState queryState, boolean isLocalOnly) throws RequestValidationException;
-
-    public ResultMessage execute(QueryState state, QueryOptions options, long queryStartNanoTime) throws RequestValidationException
-    {
-        // If an IF [NOT] EXISTS clause was used, this may not result in an actual schema change.  To avoid doing
-        // extra work in the drivers to handle schema changes, we return an empty message in this case. (CASSANDRA-7600)
-        Event.SchemaChange ce = announceMigration(state, false);
-        if (ce == null)
-            return new ResultMessage.Void();
-
-        // when a schema alteration results in a new db object being created, we grant permissions on the new
-        // object to the user performing the request if:
-        // * the user is not anonymous
-        // * the configured IAuthorizer supports granting of permissions (not all do, AllowAllAuthorizer doesn't and
-        //   custom external implementations may not)
-        AuthenticatedUser user = state.getClientState().getUser();
-        if (user != null && !user.isAnonymous() && ce.change == Event.SchemaChange.Change.CREATED)
-        {
-            try
-            {
-                grantPermissionsToCreator(state);
-            }
-            catch (UnsupportedOperationException e)
-            {
-                // not a problem, grant is an optional method on IAuthorizer
-            }
-        }
-
-        return new ResultMessage.SchemaChange(ce);
-    }
-
-    public ResultMessage executeInternal(QueryState state, QueryOptions options)
-    {
-        Event.SchemaChange ce = announceMigration(state, true);
-        return ce == null ? new ResultMessage.Void() : new ResultMessage.SchemaChange(ce);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/207c80c1/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 ef3db51..a5105f2 100644
--- a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
@@ -25,8 +25,8 @@ import com.google.common.base.MoreObjects;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import org.apache.cassandra.audit.AuditLogContext;
 import org.apache.cassandra.audit.AuditLogEntryType;
-import org.apache.cassandra.audit.IAuditLogContext;
 import org.apache.cassandra.auth.Permission;
 import org.apache.cassandra.schema.ColumnMetadata;
 import org.apache.cassandra.schema.Schema;
@@ -91,7 +91,7 @@ public class SelectStatement implements CQLStatement
 
     public static final int DEFAULT_PAGE_SIZE = 10000;
 
-    private final int boundTerms;
+    public final VariableSpecifications bindVariables;
     public final TableMetadata table;
     public final Parameters parameters;
     private final Selection selection;
@@ -120,7 +120,7 @@ public class SelectStatement implements CQLStatement
                                                                        false);
 
     public SelectStatement(TableMetadata table,
-                           int boundTerms,
+                           VariableSpecifications bindVariables,
                            Parameters parameters,
                            Selection selection,
                            StatementRestrictions restrictions,
@@ -131,7 +131,7 @@ public class SelectStatement implements CQLStatement
                            Term perPartitionLimit)
     {
         this.table = table;
-        this.boundTerms = boundTerms;
+        this.bindVariables = bindVariables;
         this.selection = selection;
         this.restrictions = restrictions;
         this.isReversed = isReversed;
@@ -142,6 +142,19 @@ public class SelectStatement implements CQLStatement
         this.perPartitionLimit = perPartitionLimit;
     }
 
+    @Override
+    public List<ColumnSpecification> getBindVariables()
+    {
+        return bindVariables.getBindVariables();
+    }
+
+    @Override
+    public short[] getPartitionKeyBindVariableIndexes()
+    {
+        return bindVariables.getPartitionKeyBindVariableIndexes(table);
+    }
+
+    @Override
     public Iterable<Function> getFunctions()
     {
         List<Function> functions = new ArrayList<>();
@@ -176,7 +189,7 @@ public class SelectStatement implements CQLStatement
     static SelectStatement forSelection(TableMetadata table, Selection selection)
     {
         return new SelectStatement(table,
-                                   0,
+                                   VariableSpecifications.empty(),
                                    defaultParameters,
                                    selection,
                                    StatementRestrictions.empty(StatementType.SELECT, table),
@@ -192,26 +205,21 @@ public class SelectStatement implements CQLStatement
         return selection.getResultMetadata();
     }
 
-    public int getBoundTerms()
-    {
-        return boundTerms;
-    }
-
-    public void checkAccess(ClientState state) throws InvalidRequestException, UnauthorizedException
+    public void authorize(ClientState state) throws InvalidRequestException, UnauthorizedException
     {
         if (table.isView())
         {
             TableMetadataRef baseTable = View.findBaseTable(keyspace(), columnFamily());
             if (baseTable != null)
-                state.hasColumnFamilyAccess(baseTable, Permission.SELECT);
+                state.ensureTablePermission(baseTable, Permission.SELECT);
         }
         else
         {
-            state.hasColumnFamilyAccess(table, Permission.SELECT);
+            state.ensureTablePermission(table, Permission.SELECT);
         }
 
         for (Function function : getFunctions())
-            state.ensureHasPermission(Permission.EXECUTE, function);
+            state.ensurePermission(Permission.EXECUTE, function);
     }
 
     public void validate(ClientState state) throws InvalidRequestException
@@ -418,7 +426,7 @@ public class SelectStatement implements CQLStatement
         return new ResultMessage.Rows(rset);
     }
 
-    public ResultMessage.Rows executeInternal(QueryState state, QueryOptions options) throws RequestExecutionException, RequestValidationException
+    public ResultMessage.Rows executeLocally(QueryState state, QueryOptions options) throws RequestExecutionException, RequestValidationException
     {
         return executeInternal(state, options, FBUtilities.nowInSeconds(), System.nanoTime());
     }
@@ -911,7 +919,7 @@ public class SelectStatement implements CQLStatement
         Collections.sort(cqlRows.rows, orderingComparator);
     }
 
-    public static class RawStatement extends CFStatement
+    public static class RawStatement extends QualifiedStatement
     {
         public final Parameters parameters;
         public final List<RawSelector> selectClause;
@@ -919,7 +927,8 @@ public class SelectStatement implements CQLStatement
         public final Term.Raw limit;
         public final Term.Raw perPartitionLimit;
 
-        public RawStatement(CFName cfName, Parameters parameters,
+        public RawStatement(QualifiedName cfName,
+                            Parameters parameters,
                             List<RawSelector> selectClause,
                             WhereClause whereClause,
                             Term.Raw limit,
@@ -933,20 +942,19 @@ public class SelectStatement implements CQLStatement
             this.perPartitionLimit = perPartitionLimit;
         }
 
-        public ParsedStatement.Prepared prepare() throws InvalidRequestException
+        public SelectStatement prepare(ClientState state)
         {
             return prepare(false);
         }
 
-        public ParsedStatement.Prepared prepare(boolean forView) throws InvalidRequestException
+        public SelectStatement prepare(boolean forView) throws InvalidRequestException
         {
-            TableMetadata table = Schema.instance.validateTable(keyspace(), columnFamily());
-            VariableSpecifications boundNames = getBoundVariables();
+            TableMetadata table = Schema.instance.validateTable(keyspace(), name());
 
             List<Selectable> selectables = RawSelector.toSelectables(selectClause, table);
             boolean containsOnlyStaticColumns = selectOnlyStaticColumns(table, selectables);
 
-            StatementRestrictions restrictions = prepareRestrictions(table, boundNames, containsOnlyStaticColumns, forView);
+            StatementRestrictions restrictions = prepareRestrictions(table, bindVariables, containsOnlyStaticColumns, forView);
 
             // If we order post-query, the sorted column needs to be in the ResultSet for sorting,
             // even if we don't ultimately ship them to the client (CASSANDRA-4911).
@@ -956,7 +964,7 @@ public class SelectStatement implements CQLStatement
 
             Selection selection = prepareSelection(table,
                                                    selectables,
-                                                   boundNames,
+                                                   bindVariables,
                                                    resultSetOrderingColumns,
                                                    restrictions);
 
@@ -989,18 +997,16 @@ public class SelectStatement implements CQLStatement
 
             checkNeedsFiltering(restrictions);
 
-            SelectStatement stmt = new SelectStatement(table,
-                                                       boundNames.size(),
-                                                       parameters,
-                                                       selection,
-                                                       restrictions,
-                                                       isReversed,
-                                                       aggregationSpec,
-                                                       orderingComparator,
-                                                       prepareLimit(boundNames, limit, keyspace(), limitReceiver()),
-                                                       prepareLimit(boundNames, perPartitionLimit, keyspace(), perPartitionLimitReceiver()));
-
-            return new ParsedStatement.Prepared(stmt, boundNames, boundNames.getPartitionKeyBindIndexes(table));
+            return new SelectStatement(table,
+                                       bindVariables,
+                                       parameters,
+                                       selection,
+                                       restrictions,
+                                       isReversed,
+                                       aggregationSpec,
+                                       orderingComparator,
+                                       prepareLimit(bindVariables, limit, keyspace(), limitReceiver()),
+                                       prepareLimit(bindVariables, perPartitionLimit, keyspace(), perPartitionLimitReceiver()));
         }
 
         private Selection prepareSelection(TableMetadata table,
@@ -1258,19 +1264,19 @@ public class SelectStatement implements CQLStatement
 
         private ColumnSpecification limitReceiver()
         {
-            return new ColumnSpecification(keyspace(), columnFamily(), new ColumnIdentifier("[limit]", true), Int32Type.instance);
+            return new ColumnSpecification(keyspace(), name(), new ColumnIdentifier("[limit]", true), Int32Type.instance);
         }
 
         private ColumnSpecification perPartitionLimitReceiver()
         {
-            return new ColumnSpecification(keyspace(), columnFamily(), new ColumnIdentifier("[per_partition_limit]", true), Int32Type.instance);
+            return new ColumnSpecification(keyspace(), name(), new ColumnIdentifier("[per_partition_limit]", true), Int32Type.instance);
         }
 
         @Override
         public String toString()
         {
             return MoreObjects.toStringHelper(this)
-                              .add("name", cfName)
+                              .add("name", qualifiedName)
                               .add("selectClause", selectClause)
                               .add("whereClause", whereClause)
                               .add("isDistinct", parameters.isDistinct)


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cassandra.apache.org
For additional commands, e-mail: commits-help@cassandra.apache.org