http://git-wip-us.apache.org/repos/asf/cassandra/blob/aaddbd49/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 deleted file mode 100644 index 87bfff8..0000000 --- a/src/java/org/apache/cassandra/cql3/statements/DropFunctionStatement.java +++ /dev/null @@ -1,189 +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.ArrayList; -import java.util.Collection; -import java.util.List; - -import com.google.common.base.Joiner; - -import org.apache.cassandra.auth.FunctionResource; -import org.apache.cassandra.auth.Permission; -import org.apache.cassandra.cql3.CQL3Type; -import org.apache.cassandra.cql3.functions.*; -import org.apache.cassandra.db.marshal.AbstractType; -import org.apache.cassandra.exceptions.InvalidRequestException; -import org.apache.cassandra.exceptions.RequestValidationException; -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.service.ClientState; -import org.apache.cassandra.service.QueryState; -import org.apache.cassandra.transport.Event; - -/** - * A {@code DROP FUNCTION} statement parsed from a CQL query. - */ -public final class DropFunctionStatement extends SchemaAlteringStatement -{ - private FunctionName functionName; - private final boolean ifExists; - private final List<CQL3Type.Raw> argRawTypes; - private final boolean argsPresent; - - private List<AbstractType<?>> argTypes; - - public DropFunctionStatement(FunctionName functionName, - List<CQL3Type.Raw> argRawTypes, - boolean argsPresent, - boolean ifExists) - { - this.functionName = functionName; - this.argRawTypes = argRawTypes; - this.argsPresent = argsPresent; - this.ifExists = ifExists; - } - - @Override - public Prepared prepare() throws InvalidRequestException - { - if (Schema.instance.getKeyspaceMetadata(functionName.keyspace) != null) - { - argTypes = new ArrayList<>(argRawTypes.size()); - for (CQL3Type.Raw rawType : argRawTypes) - { - if (rawType.isFrozen()) - throw new InvalidRequestException("The function arguments should not be frozen; remove the frozen<> modifier"); - - // UDT are not supported non frozen but we do not allow the frozen keyword for argument. So for the moment we - // freeze them here - if (!rawType.canBeNonFrozen()) - rawType.freeze(); - - argTypes.add(rawType.prepare(functionName.keyspace).getType()); - } - } - - return super.prepare(); - } - - @Override - public void prepareKeyspace(ClientState state) throws InvalidRequestException - { - if (!functionName.hasKeyspace() && state.getRawKeyspace() != null) - functionName = new FunctionName(state.getKeyspace(), functionName.name); - - if (!functionName.hasKeyspace()) - throw new InvalidRequestException("Functions must be fully qualified with a keyspace name if a keyspace is not set for the session"); - - Schema.validateKeyspaceNotSystem(functionName.keyspace); - } - - public void checkAccess(ClientState state) throws UnauthorizedException, InvalidRequestException - { - Function function = findFunction(); - if (function == null) - { - if (!ifExists) - throw new InvalidRequestException(String.format("Unconfigured function %s.%s(%s)", - functionName.keyspace, - functionName.name, - Joiner.on(",").join(argRawTypes))); - } - else - { - state.ensureHasPermission(Permission.DROP, FunctionResource.function(function.name().keyspace, - function.name().name, - function.argTypes())); - } - } - - public void validate(ClientState state) - { - Collection<Function> olds = Schema.instance.getFunctions(functionName); - - if (!argsPresent && olds != null && olds.size() > 1) - throw new InvalidRequestException(String.format("'DROP FUNCTION %s' matches multiple function definitions; " + - "specify the argument types by issuing a statement like " + - "'DROP FUNCTION %s (type, type, ...)'. Hint: use cqlsh " + - "'DESCRIBE FUNCTION %s' command to find all overloads", - functionName, functionName, functionName)); - } - - public Event.SchemaChange announceMigration(QueryState queryState, boolean isLocalOnly) throws RequestValidationException - { - Function old = findFunction(); - if (old == null) - { - if (ifExists) - return null; - else - throw new InvalidRequestException(getMissingFunctionError()); - } - - KeyspaceMetadata ksm = Schema.instance.getKeyspaceMetadata(old.name().keyspace); - Collection<UDAggregate> referrers = ksm.functions.aggregatesUsingFunction(old); - if (!referrers.isEmpty()) - throw new InvalidRequestException(String.format("Function '%s' still referenced by %s", old, referrers)); - - MigrationManager.announceFunctionDrop((UDFunction) old, isLocalOnly); - - return new Event.SchemaChange(Event.SchemaChange.Change.DROPPED, Event.SchemaChange.Target.FUNCTION, - old.name().keyspace, old.name().name, AbstractType.asCQLTypeStringList(old.argTypes())); - } - - private String getMissingFunctionError() - { - // just build a nicer error message - StringBuilder sb = new StringBuilder("Cannot drop non existing function '"); - sb.append(functionName); - if (argsPresent) - sb.append(Joiner.on(", ").join(argRawTypes)); - sb.append('\''); - return sb.toString(); - } - - private Function findFunction() - { - Function old; - if (argsPresent) - { - if (argTypes == null) - { - return null; - } - - old = Schema.instance.findFunction(functionName, argTypes).orElse(null); - if (old == null || !(old instanceof ScalarFunction)) - { - return null; - } - } - else - { - Collection<Function> olds = Schema.instance.getFunctions(functionName); - if (olds == null || olds.isEmpty() || !(olds.iterator().next() instanceof ScalarFunction)) - return null; - - old = olds.iterator().next(); - } - return old; - } -}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/aaddbd49/src/java/org/apache/cassandra/cql3/statements/DropIndexStatement.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/statements/DropIndexStatement.java b/src/java/org/apache/cassandra/cql3/statements/DropIndexStatement.java deleted file mode 100644 index 2420f3b..0000000 --- a/src/java/org/apache/cassandra/cql3/statements/DropIndexStatement.java +++ /dev/null @@ -1,116 +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.Permission; -import org.apache.cassandra.schema.TableMetadata; -import org.apache.cassandra.schema.Schema; -import org.apache.cassandra.cql3.IndexName; -import org.apache.cassandra.cql3.QueryOptions; -import org.apache.cassandra.db.KeyspaceNotDefinedException; -import org.apache.cassandra.exceptions.*; -import org.apache.cassandra.schema.KeyspaceMetadata; -import org.apache.cassandra.service.ClientState; -import org.apache.cassandra.schema.MigrationManager; -import org.apache.cassandra.service.QueryState; -import org.apache.cassandra.transport.Event; -import org.apache.cassandra.transport.messages.ResultMessage; - -public class DropIndexStatement extends SchemaAlteringStatement -{ - public final String indexName; - public final boolean ifExists; - - public DropIndexStatement(IndexName indexName, boolean ifExists) - { - super(indexName.getCfName()); - this.indexName = indexName.getIdx(); - this.ifExists = ifExists; - } - - public String columnFamily() - { - TableMetadata metadata = lookupIndexedTable(); - return metadata == null ? null : metadata.name; - } - - public void checkAccess(ClientState state) throws UnauthorizedException, InvalidRequestException - { - TableMetadata metadata = lookupIndexedTable(); - if (metadata == null) - return; - - state.hasColumnFamilyAccess(metadata.keyspace, metadata.name, Permission.ALTER); - } - - public void validate(ClientState state) - { - // validated in lookupIndexedTable() - } - - @Override - public ResultMessage execute(QueryState state, QueryOptions options, long queryStartNanoTime) throws RequestValidationException - { - Event.SchemaChange ce = announceMigration(state, false); - return ce == null ? null : new ResultMessage.SchemaChange(ce); - } - - public Event.SchemaChange announceMigration(QueryState queryState, boolean isLocalOnly) throws InvalidRequestException, ConfigurationException - { - TableMetadata current = lookupIndexedTable(); - if (current == null) - return null; - - TableMetadata updated = - current.unbuild() - .indexes(current.indexes.without(indexName)) - .build(); - - MigrationManager.announceTableUpdate(updated, isLocalOnly); - // Dropping an index is akin to updating the CF - // Note that we shouldn't call columnFamily() at this point because the index has been dropped and the call to lookupIndexedTable() - // in that method would now throw. - return new Event.SchemaChange(Event.SchemaChange.Change.UPDATED, Event.SchemaChange.Target.TABLE, current.keyspace, current.name); - } - - /** - * The table for which the index should be dropped, or null if the index doesn't exist - * - * @return the metadata for the table containing the dropped index, or {@code null} - * if the index to drop cannot be found but "IF EXISTS" is set on the statement. - * - * @throws InvalidRequestException if the index cannot be found and "IF EXISTS" is not - * set on the statement. - */ - private TableMetadata lookupIndexedTable() - { - KeyspaceMetadata ksm = Schema.instance.getKeyspaceMetadata(keyspace()); - if (ksm == null) - throw new KeyspaceNotDefinedException("Keyspace " + keyspace() + " does not exist"); - - return ksm.findIndexedTable(indexName) - .orElseGet(() -> { - if (ifExists) - return null; - else - throw new InvalidRequestException(String.format("Index '%s' could not be found in any " + - "of the tables of keyspace '%s'", - indexName, keyspace())); - }); - } -} http://git-wip-us.apache.org/repos/asf/cassandra/blob/aaddbd49/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 21040f9..0000000 --- a/src/java/org/apache/cassandra/cql3/statements/DropKeyspaceStatement.java +++ /dev/null @@ -1,73 +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.Permission; -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; - -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 - { - try - { - MigrationManager.announceKeyspaceDrop(keyspace, isLocalOnly); - return new Event.SchemaChange(Event.SchemaChange.Change.DROPPED, keyspace()); - } - catch(ConfigurationException e) - { - if (ifExists) - return null; - throw e; - } - } -} http://git-wip-us.apache.org/repos/asf/cassandra/blob/aaddbd49/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 55fa83a..77edad3 100644 --- a/src/java/org/apache/cassandra/cql3/statements/DropRoleStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/DropRoleStatement.java @@ -35,7 +35,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); @@ -49,7 +49,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/aaddbd49/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 83b787e..0000000 --- a/src/java/org/apache/cassandra/cql3/statements/DropTableStatement.java +++ /dev/null @@ -1,104 +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.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; - -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"); - - 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; - } - } -} http://git-wip-us.apache.org/repos/asf/cassandra/blob/aaddbd49/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 b9536fb..0000000 --- a/src/java/org/apache/cassandra/cql3/statements/DropTriggerStatement.java +++ /dev/null @@ -1,85 +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.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; - -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()); - } -} http://git-wip-us.apache.org/repos/asf/cassandra/blob/aaddbd49/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 5909888..0000000 --- a/src/java/org/apache/cassandra/cql3/statements/DropTypeStatement.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.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; - -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()); - } -} http://git-wip-us.apache.org/repos/asf/cassandra/blob/aaddbd49/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 1909e89..0000000 --- a/src/java/org/apache/cassandra/cql3/statements/DropViewStatement.java +++ /dev/null @@ -1,69 +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.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; - -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; - } - } -} http://git-wip-us.apache.org/repos/asf/cassandra/blob/aaddbd49/src/java/org/apache/cassandra/cql3/statements/IndexAttributes.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/statements/IndexAttributes.java b/src/java/org/apache/cassandra/cql3/statements/IndexAttributes.java new file mode 100644 index 0000000..27486c2 --- /dev/null +++ b/src/java/org/apache/cassandra/cql3/statements/IndexAttributes.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 java.util.*; + +import org.apache.cassandra.exceptions.InvalidRequestException; +import org.apache.cassandra.exceptions.RequestValidationException; +import org.apache.cassandra.exceptions.SyntaxException; + +public class IndexAttributes 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/aaddbd49/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/aaddbd49/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 be7fb5d..851a0c7 100644 --- a/src/java/org/apache/cassandra/cql3/statements/ListPermissionsStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/ListPermissionsStatement.java @@ -76,7 +76,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/aaddbd49/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 0c0822c..bc9c3c8 100644 --- a/src/java/org/apache/cassandra/cql3/statements/ListRolesStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/ListRolesStatement.java @@ -70,7 +70,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/aaddbd49/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 e82d840..335d356 100644 --- a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java @@ -28,7 +28,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; @@ -71,7 +70,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; @@ -88,7 +88,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, @@ -96,7 +96,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; @@ -141,6 +141,19 @@ public abstract class ModificationStatement implements CQLStatement this.requiresRead = requiresReadBuilder.build(); } + @Override + public List<ColumnSpecification> getBindVariables() + { + return bindVariables.getSpecifications(); + } + + @Override + public short[] getPartitionKeyBindVariableIndexes() + { + return bindVariables.getPartitionKeyBindIndexes(metadata); + } + + @Override public Iterable<Function> getFunctions() { List<Function> functions = new ArrayList<>(); @@ -173,11 +186,6 @@ public abstract class ModificationStatement implements CQLStatement public abstract void addUpdateForKey(PartitionUpdate update, Slice slice, UpdateParameters params); - public int getBoundTerms() - { - return boundTerms; - } - public String keyspace() { return metadata.keyspace; @@ -213,28 +221,28 @@ public abstract class ModificationStatement implements CQLStatement return attrs.getTimeToLive(options, metadata().params.defaultTimeToLive); } - 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 @@ -561,7 +569,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) @@ -768,7 +776,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; @@ -776,7 +784,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, @@ -786,39 +794,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. @@ -839,17 +844,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"); @@ -859,7 +864,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); @@ -868,7 +873,7 @@ public abstract class ModificationStatement implements CQLStatement } protected abstract ModificationStatement prepareInternal(TableMetadata metadata, - VariableSpecifications boundNames, + VariableSpecifications bindVariables, Conditions conditions, Attributes attrs); @@ -902,7 +907,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); } http://git-wip-us.apache.org/repos/asf/cassandra/blob/aaddbd49/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 e617ba7..0000000 --- a/src/java/org/apache/cassandra/cql3/statements/ParsedStatement.java +++ /dev/null @@ -1,86 +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.Collections; -import java.util.List; - -import org.apache.cassandra.cql3.*; -import org.apache.cassandra.cql3.functions.Function; -import org.apache.cassandra.exceptions.RequestValidationException; - -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 CQLStatement statement; - public final List<ColumnSpecification> boundNames; - public final short[] partitionKeyBindIndexes; - - protected Prepared(CQLStatement statement, List<ColumnSpecification> boundNames, short[] partitionKeyBindIndexes) - { - this.statement = statement; - this.boundNames = boundNames; - this.partitionKeyBindIndexes = partitionKeyBindIndexes; - 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/aaddbd49/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 70d6f54..0e11116 100644 --- a/src/java/org/apache/cassandra/cql3/statements/PermissionsManagementStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/PermissionsManagementStatement.java @@ -43,14 +43,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 @@ -64,16 +64,16 @@ 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); } } http://git-wip-us.apache.org/repos/asf/cassandra/blob/aaddbd49/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..e6216f0 --- /dev/null +++ b/src/java/org/apache/cassandra/cql3/statements/QualifiedStatement.java @@ -0,0 +1,67 @@ +/* + * 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.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(); + } +} http://git-wip-us.apache.org/repos/asf/cassandra/blob/aaddbd49/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 e12b626..e07aac9 100644 --- a/src/java/org/apache/cassandra/cql3/statements/RoleManagementStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/RoleManagementStatement.java @@ -37,7 +37,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/aaddbd49/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 index 4a20451..fd981f4 100644 --- a/src/java/org/apache/cassandra/cql3/statements/SchemaAlteringStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/SchemaAlteringStatement.java @@ -18,7 +18,7 @@ package org.apache.cassandra.cql3.statements; import org.apache.cassandra.auth.AuthenticatedUser; -import org.apache.cassandra.cql3.CFName; +import org.apache.cassandra.cql3.QualifiedName; import org.apache.cassandra.cql3.CQLStatement; import org.apache.cassandra.cql3.QueryOptions; import org.apache.cassandra.exceptions.InvalidRequestException; @@ -31,7 +31,7 @@ import org.apache.cassandra.transport.messages.ResultMessage; /** * Abstract class for statements that alter the schema. */ -public abstract class SchemaAlteringStatement extends CFStatement implements CQLStatement +public abstract class SchemaAlteringStatement extends QualifiedStatement implements CQLStatement { private final boolean isColumnFamilyLevel; @@ -41,28 +41,23 @@ public abstract class SchemaAlteringStatement extends CFStatement implements CQL this.isColumnFamilyLevel = false; } - protected SchemaAlteringStatement(CFName name) + protected SchemaAlteringStatement(QualifiedName name) { super(name); this.isColumnFamilyLevel = true; } - public int getBoundTerms() - { - return 0; - } - @Override - public void prepareKeyspace(ClientState state) throws InvalidRequestException + public void setKeyspace(ClientState state) throws InvalidRequestException { if (isColumnFamilyLevel) - super.prepareKeyspace(state); + super.setKeyspace(state); } @Override - public Prepared prepare() + public SchemaAlteringStatement prepare(ClientState state) { - return new Prepared(this); + return this; } /** @@ -115,7 +110,7 @@ public abstract class SchemaAlteringStatement extends CFStatement implements CQL return new ResultMessage.SchemaChange(ce); } - public ResultMessage executeInternal(QueryState state, QueryOptions options) + public ResultMessage executeLocally(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/aaddbd49/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 652b549..67deb2e 100644 --- a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java @@ -83,7 +83,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; @@ -113,8 +113,8 @@ public class SelectStatement implements CQLStatement false, false); - public SelectStatement(TableMetadata table, - int boundTerms, + public SelectStatement(VariableSpecifications bindVariables, + TableMetadata table, Parameters parameters, Selection selection, StatementRestrictions restrictions, @@ -124,8 +124,8 @@ public class SelectStatement implements CQLStatement Term limit, Term perPartitionLimit) { + this.bindVariables = bindVariables; this.table = table; - this.boundTerms = boundTerms; this.selection = selection; this.restrictions = restrictions; this.isReversed = isReversed; @@ -137,6 +137,19 @@ public class SelectStatement implements CQLStatement this.queriedColumns = gatherQueriedColumns(); } + @Override + public List<ColumnSpecification> getBindVariables() + { + return bindVariables.getSpecifications(); + } + + @Override + public short[] getPartitionKeyBindVariableIndexes() + { + return bindVariables.getPartitionKeyBindIndexes(table); + } + + @Override public Iterable<Function> getFunctions() { List<Function> functions = new ArrayList<>(); @@ -193,8 +206,8 @@ public class SelectStatement implements CQLStatement // queried data through processColumnFamily. static SelectStatement forSelection(TableMetadata table, Selection selection) { - return new SelectStatement(table, - 0, + return new SelectStatement(VariableSpecifications.empty(), + table, defaultParameters, selection, StatementRestrictions.empty(StatementType.SELECT, table), @@ -210,26 +223,21 @@ public class SelectStatement implements CQLStatement return selection.getResultMetadata(parameters.isJson); } - 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 @@ -408,7 +416,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()); } @@ -905,7 +913,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; @@ -913,7 +921,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, @@ -927,21 +936,20 @@ 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()); Selection selection = selectClause.isEmpty() ? Selection.wildcard(table) - : Selection.fromSelectors(table, selectClause, boundNames, !parameters.groups.isEmpty()); + : Selection.fromSelectors(table, selectClause, bindVariables, !parameters.groups.isEmpty()); - StatementRestrictions restrictions = prepareRestrictions(table, boundNames, selection, forView); + StatementRestrictions restrictions = prepareRestrictions(table, bindVariables, selection, forView); if (parameters.isDistinct) { @@ -972,18 +980,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(bindVariables, + table, + parameters, + selection, + restrictions, + isReversed, + aggregationSpec, + orderingComparator, + prepareLimit(bindVariables, limit, keyspace(), limitReceiver()), + prepareLimit(bindVariables, perPartitionLimit, keyspace(), perPartitionLimitReceiver())); } /** @@ -1202,19 +1208,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) http://git-wip-us.apache.org/repos/asf/cassandra/blob/aaddbd49/src/java/org/apache/cassandra/cql3/statements/TableAttributes.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/statements/TableAttributes.java b/src/java/org/apache/cassandra/cql3/statements/TableAttributes.java index 779b6c2..67d76f5 100644 --- a/src/java/org/apache/cassandra/cql3/statements/TableAttributes.java +++ b/src/java/org/apache/cassandra/cql3/statements/TableAttributes.java @@ -31,7 +31,7 @@ import static java.lang.String.format; public final class TableAttributes extends PropertyDefinitions { - private static final String KW_ID = "id"; + public static final String ID = "id"; private static final Set<String> validKeywords; private static final Set<String> obsoleteKeywords; @@ -40,7 +40,7 @@ public final class TableAttributes extends PropertyDefinitions ImmutableSet.Builder<String> validBuilder = ImmutableSet.builder(); for (Option option : Option.values()) validBuilder.add(option.toString()); - validBuilder.add(KW_ID); + validBuilder.add(ID); validKeywords = validBuilder.build(); obsoleteKeywords = ImmutableSet.of(); } @@ -65,7 +65,7 @@ public final class TableAttributes extends PropertyDefinitions public TableId getId() throws ConfigurationException { - String id = getSimple(KW_ID); + String id = getSimple(ID); try { return id != null ? TableId.fromString(id) : null; @@ -193,7 +193,7 @@ public final class TableAttributes extends PropertyDefinitions return value; } - private boolean hasOption(Option option) + public boolean hasOption(Option option) { return hasProperty(option.toString()); } http://git-wip-us.apache.org/repos/asf/cassandra/blob/aaddbd49/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 300d8f4..3c26506 100644 --- a/src/java/org/apache/cassandra/cql3/statements/TruncateStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/TruncateStatement.java @@ -31,42 +31,37 @@ import org.apache.cassandra.service.QueryState; import org.apache.cassandra.service.StorageProxy; import org.apache.cassandra.transport.messages.ResultMessage; -public class TruncateStatement extends CFStatement implements CQLStatement +public class TruncateStatement extends QualifiedStatement implements CQLStatement { - public TruncateStatement(CFName name) + public TruncateStatement(QualifiedName name) { super(name); } - public int getBoundTerms() + public TruncateStatement prepare(ClientState state) { - return 0; + return this; } - public Prepared prepare() throws InvalidRequestException + public void authorize(ClientState state) throws InvalidRequestException, UnauthorizedException { - return new Prepared(this); - } - - public void checkAccess(ClientState state) throws InvalidRequestException, UnauthorizedException - { - state.hasColumnFamilyAccess(keyspace(), columnFamily(), Permission.MODIFY); + state.ensureTablePermission(keyspace(), name(), Permission.MODIFY); } public void validate(ClientState state) throws InvalidRequestException { - Schema.instance.validateTable(keyspace(), columnFamily()); + Schema.instance.validateTable(keyspace(), name()); } public ResultMessage execute(QueryState state, QueryOptions options, long queryStartNanoTime) throws InvalidRequestException, TruncateException { try { - TableMetadata metaData = Schema.instance.getTableMetadata(keyspace(), columnFamily()); + TableMetadata metaData = Schema.instance.getTableMetadata(keyspace(), name()); if (metaData.isView()) throw new InvalidRequestException("Cannot TRUNCATE materialized view directly; must truncate base table instead"); - StorageProxy.truncateBlocking(keyspace(), columnFamily()); + StorageProxy.truncateBlocking(keyspace(), name()); } catch (UnavailableException | TimeoutException e) { @@ -75,11 +70,11 @@ public class TruncateStatement extends CFStatement implements CQLStatement return null; } - public ResultMessage executeInternal(QueryState state, QueryOptions options) + public ResultMessage executeLocally(QueryState state, QueryOptions options) { try { - ColumnFamilyStore cfs = Keyspace.open(keyspace()).getColumnFamilyStore(columnFamily()); + ColumnFamilyStore cfs = Keyspace.open(keyspace()).getColumnFamilyStore(name()); cfs.truncateBlocking(); } catch (Exception e) --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
