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: [email protected] For additional commands, e-mail: [email protected]
