Search in sources :

Example 1 with org.apache.cassandra.cql3.statements

use of org.apache.cassandra.cql3.statements in project cassandra by apache.

the class CassandraAuthorizer method revokeAllFrom.

// Called when deleting a role with DROP ROLE query.
// Internal hook, so no permission checks are needed here.
// Executes a logged batch removing the granted premissions
// for the role as well as the entries from the reverse index
// table
public void revokeAllFrom(RoleResource revokee) {
    try {
        UntypedResultSet rows = process(String.format("SELECT resource FROM %s.%s WHERE role = '%s'", SchemaConstants.AUTH_KEYSPACE_NAME, AuthKeyspace.ROLE_PERMISSIONS, escape(revokee.getRoleName())));
        List<CQLStatement> statements = new ArrayList<>();
        for (UntypedResultSet.Row row : rows) {
            statements.add(QueryProcessor.getStatement(String.format("DELETE FROM %s.%s WHERE resource = '%s' AND role = '%s'", SchemaConstants.AUTH_KEYSPACE_NAME, AuthKeyspace.RESOURCE_ROLE_INDEX, escape(row.getString("resource")), escape(revokee.getRoleName())), ClientState.forInternalCalls()).statement);
        }
        statements.add(QueryProcessor.getStatement(String.format("DELETE FROM %s.%s WHERE role = '%s'", SchemaConstants.AUTH_KEYSPACE_NAME, AuthKeyspace.ROLE_PERMISSIONS, escape(revokee.getRoleName())), ClientState.forInternalCalls()).statement);
        executeLoggedBatch(statements);
    } catch (RequestExecutionException | RequestValidationException e) {
        logger.warn("CassandraAuthorizer failed to revoke all permissions of {}: {}", revokee.getRoleName(), e);
    }
}
Also used : UntypedResultSet(org.apache.cassandra.cql3.UntypedResultSet)

Example 2 with org.apache.cassandra.cql3.statements

use of org.apache.cassandra.cql3.statements in project cassandra by apache.

the class CassandraAuthorizer method revokeAllOn.

// Called after a resource is removed (DROP KEYSPACE, DROP TABLE, etc.).
// Execute a logged batch removing all the permissions for the resource
// as well as the index table entry
public void revokeAllOn(IResource droppedResource) {
    try {
        UntypedResultSet rows = process(String.format("SELECT role FROM %s.%s WHERE resource = '%s'", SchemaConstants.AUTH_KEYSPACE_NAME, AuthKeyspace.RESOURCE_ROLE_INDEX, escape(droppedResource.getName())));
        List<CQLStatement> statements = new ArrayList<>();
        for (UntypedResultSet.Row row : rows) {
            statements.add(QueryProcessor.getStatement(String.format("DELETE FROM %s.%s WHERE role = '%s' AND resource = '%s'", SchemaConstants.AUTH_KEYSPACE_NAME, AuthKeyspace.ROLE_PERMISSIONS, escape(row.getString("role")), escape(droppedResource.getName())), ClientState.forInternalCalls()).statement);
        }
        statements.add(QueryProcessor.getStatement(String.format("DELETE FROM %s.%s WHERE resource = '%s'", SchemaConstants.AUTH_KEYSPACE_NAME, AuthKeyspace.RESOURCE_ROLE_INDEX, escape(droppedResource.getName())), ClientState.forInternalCalls()).statement);
        executeLoggedBatch(statements);
    } catch (RequestExecutionException | RequestValidationException e) {
        logger.warn("CassandraAuthorizer failed to revoke all permissions on {}: {}", droppedResource, e);
        return;
    }
}
Also used : UntypedResultSet(org.apache.cassandra.cql3.UntypedResultSet)

Example 3 with org.apache.cassandra.cql3.statements

use of org.apache.cassandra.cql3.statements in project cassandra by apache.

the class FunctionResolver method get.

/**
     * @param keyspace the current keyspace
     * @param name the name of the function
     * @param providedArgs the arguments provided for the function call
     * @param receiverKs the receiver's keyspace
     * @param receiverCf the receiver's table
     * @param receiverType if the receiver type is known (during inserts, for example), this should be the type of
     *                     the receiver
     * @throws InvalidRequestException
     */
public static Function get(String keyspace, FunctionName name, List<? extends AssignmentTestable> providedArgs, String receiverKs, String receiverCf, AbstractType<?> receiverType) throws InvalidRequestException {
    if (name.equalsNativeFunction(TOKEN_FUNCTION_NAME))
        return new TokenFct(Schema.instance.getTableMetadata(receiverKs, receiverCf));
    // due to needing to know the argument types in advance).
    if (name.equalsNativeFunction(ToJsonFct.NAME))
        throw new InvalidRequestException("toJson() may only be used within the selection clause of SELECT statements");
    // Similarly, we can only use fromJson when we know the receiver type (such as inserts)
    if (name.equalsNativeFunction(FromJsonFct.NAME)) {
        if (receiverType == null)
            throw new InvalidRequestException("fromJson() cannot be used in the selection clause of a SELECT statement");
        return FromJsonFct.getInstance(receiverType);
    }
    Collection<Function> candidates;
    if (!name.hasKeyspace()) {
        // function name not fully qualified
        candidates = new ArrayList<>();
        // add 'SYSTEM' (native) candidates
        candidates.addAll(Schema.instance.getFunctions(name.asNativeFunction()));
        // add 'current keyspace' candidates
        candidates.addAll(Schema.instance.getFunctions(new FunctionName(keyspace, name.name)));
    } else {
        // function name is fully qualified (keyspace + name)
        candidates = Schema.instance.getFunctions(name);
    }
    if (candidates.isEmpty())
        return null;
    // Fast path if there is only one choice
    if (candidates.size() == 1) {
        Function fun = candidates.iterator().next();
        validateTypes(keyspace, fun, providedArgs, receiverKs, receiverCf);
        return fun;
    }
    List<Function> compatibles = null;
    for (Function toTest : candidates) {
        if (matchReturnType(toTest, receiverType)) {
            AssignmentTestable.TestResult r = matchAguments(keyspace, toTest, providedArgs, receiverKs, receiverCf);
            switch(r) {
                case EXACT_MATCH:
                    // We always favor exact matches
                    return toTest;
                case WEAKLY_ASSIGNABLE:
                    if (compatibles == null)
                        compatibles = new ArrayList<>();
                    compatibles.add(toTest);
                    break;
            }
        }
    }
    if (compatibles == null) {
        if (OperationFcts.isOperation(name))
            throw invalidRequest("the '%s' operation is not supported between %s and %s", OperationFcts.getOperator(name), providedArgs.get(0), providedArgs.get(1));
        throw invalidRequest("Invalid call to function %s, none of its type signatures match (known type signatures: %s)", name, format(candidates));
    }
    if (compatibles.size() > 1) {
        if (OperationFcts.isOperation(name)) {
            if (receiverType != null && !containsMarkers(providedArgs)) {
                for (Function toTest : compatibles) {
                    List<AbstractType<?>> argTypes = toTest.argTypes();
                    if (receiverType.equals(argTypes.get(0)) && receiverType.equals(argTypes.get(1)))
                        return toTest;
                }
            }
            throw invalidRequest("Ambiguous '%s' operation: use type casts to disambiguate", OperationFcts.getOperator(name), providedArgs.get(0), providedArgs.get(1));
        }
        if (OperationFcts.isNegation(name))
            throw invalidRequest("Ambiguous negation: use type casts to disambiguate");
        throw invalidRequest("Ambiguous call to function %s (can be matched by following signatures: %s): use type casts to disambiguate", name, format(compatibles));
    }
    return compatibles.get(0);
}
Also used : AssignmentTestable(org.apache.cassandra.cql3.AssignmentTestable) ArrayList(java.util.ArrayList) AbstractType(org.apache.cassandra.db.marshal.AbstractType) InvalidRequestException(org.apache.cassandra.exceptions.InvalidRequestException)

Example 4 with org.apache.cassandra.cql3.statements

use of org.apache.cassandra.cql3.statements in project cassandra by apache.

the class BatchMessage method execute.

public Message.Response execute(QueryState state, long queryStartNanoTime) {
    try {
        UUID tracingId = null;
        if (isTracingRequested()) {
            tracingId = UUIDGen.getTimeUUID();
            state.prepareTracingSession(tracingId);
        }
        if (state.traceNextQuery()) {
            state.createTracingSession();
            ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
            if (options.getConsistency() != null)
                builder.put("consistency_level", options.getConsistency().name());
            if (options.getSerialConsistency() != null)
                builder.put("serial_consistency_level", options.getSerialConsistency().name());
            // TODO we don't have [typed] access to CQL bind variables here.  CASSANDRA-4560 is open to add support.
            Tracing.instance.begin("Execute batch of CQL3 queries", state.getClientAddress(), builder.build());
        }
        QueryHandler handler = ClientState.getCQLQueryHandler();
        List<ParsedStatement.Prepared> prepared = new ArrayList<>(queryOrIdList.size());
        for (int i = 0; i < queryOrIdList.size(); i++) {
            Object query = queryOrIdList.get(i);
            ParsedStatement.Prepared p;
            if (query instanceof String) {
                p = QueryProcessor.parseStatement((String) query, state);
            } else {
                p = handler.getPrepared((MD5Digest) query);
                if (p == null)
                    throw new PreparedQueryNotFoundException((MD5Digest) query);
            }
            List<ByteBuffer> queryValues = values.get(i);
            if (queryValues.size() != p.statement.getBoundTerms())
                throw new InvalidRequestException(String.format("There were %d markers(?) in CQL but %d bound variables", p.statement.getBoundTerms(), queryValues.size()));
            prepared.add(p);
        }
        BatchQueryOptions batchOptions = BatchQueryOptions.withPerStatementVariables(options, values, queryOrIdList);
        List<ModificationStatement> statements = new ArrayList<>(prepared.size());
        for (int i = 0; i < prepared.size(); i++) {
            ParsedStatement.Prepared p = prepared.get(i);
            batchOptions.prepareStatement(i, p.boundNames);
            if (!(p.statement instanceof ModificationStatement))
                throw new InvalidRequestException("Invalid statement in batch: only UPDATE, INSERT and DELETE statements are allowed.");
            statements.add((ModificationStatement) p.statement);
        }
        // Note: It's ok at this point to pass a bogus value for the number of bound terms in the BatchState ctor
        // (and no value would be really correct, so we prefer passing a clearly wrong one).
        BatchStatement batch = new BatchStatement(-1, batchType, statements, Attributes.none());
        Message.Response response = handler.processBatch(batch, state, batchOptions, getCustomPayload(), queryStartNanoTime);
        if (tracingId != null)
            response.setTracingId(tracingId);
        return response;
    } catch (Exception e) {
        JVMStabilityInspector.inspectThrowable(e);
        return ErrorMessage.fromException(e);
    } finally {
        Tracing.instance.stopSession();
    }
}
Also used : ModificationStatement(org.apache.cassandra.cql3.statements.ModificationStatement) ArrayList(java.util.ArrayList) ParsedStatement(org.apache.cassandra.cql3.statements.ParsedStatement) PreparedQueryNotFoundException(org.apache.cassandra.exceptions.PreparedQueryNotFoundException) ByteBuffer(java.nio.ByteBuffer) ImmutableMap(com.google.common.collect.ImmutableMap) PreparedQueryNotFoundException(org.apache.cassandra.exceptions.PreparedQueryNotFoundException) InvalidRequestException(org.apache.cassandra.exceptions.InvalidRequestException) MD5Digest(org.apache.cassandra.utils.MD5Digest) BatchStatement(org.apache.cassandra.cql3.statements.BatchStatement) InvalidRequestException(org.apache.cassandra.exceptions.InvalidRequestException) UUID(java.util.UUID)

Example 5 with org.apache.cassandra.cql3.statements

use of org.apache.cassandra.cql3.statements in project cassandra by apache.

the class CustomNowInSecondsTest method testBatchMessage.

@Test
public void testBatchMessage() {
    // test BatchMessage path
    int now = (int) (System.currentTimeMillis() / 1000);
    int day = 86400;
    String ks = createKeyspace("CREATE KEYSPACE %s WITH replication={ 'class' : 'SimpleStrategy', 'replication_factor' : 1 }");
    String tbl = createTable(ks, "CREATE TABLE %s (id int primary key, val int)");
    List<String> queries = ImmutableList.of(format("INSERT INTO %s.%s (id, val) VALUES (0, 0) USING TTL %d;", ks, tbl, 1), format("INSERT INTO %s.%s (id, val) VALUES (1, 1) USING TTL %d;", ks, tbl, 1));
    ClientState cs = ClientState.forInternalCalls();
    QueryState qs = new QueryState(cs);
    List<ModificationStatement> statements = new ArrayList<>(queries.size());
    for (String query : queries) statements.add((ModificationStatement) QueryProcessor.parseStatement(query, cs));
    BatchStatement batch = new BatchStatement(BatchStatement.Type.UNLOGGED, VariableSpecifications.empty(), statements, Attributes.none());
    // execute an BATCH message with now set to [now + 1 day], with ttl = 1, making its effective ttl = 1 day + 1.
    QueryProcessor.instance.processBatch(batch, qs, batchQueryOptions(now + day), emptyMap(), nanoTime());
    // verify that despite TTL having passed at now + 1 the rows are still there.
    assertEquals(2, executeSelect(format("SELECT * FROM %s.%s", ks, tbl), now + 1, false).size());
    // jump in time by one day, make sure the row expired.
    assertEquals(0, executeSelect(format("SELECT * FROM %s.%s", ks, tbl), now + day + 1, false).size());
}
Also used : ClientState(org.apache.cassandra.service.ClientState) ModificationStatement(org.apache.cassandra.cql3.statements.ModificationStatement) BatchStatement(org.apache.cassandra.cql3.statements.BatchStatement) ArrayList(java.util.ArrayList) QueryState(org.apache.cassandra.service.QueryState) Test(org.junit.Test)

Aggregations

BatchStatement (org.apache.cassandra.cql3.statements.BatchStatement)8 ArrayList (java.util.ArrayList)6 ModificationStatement (org.apache.cassandra.cql3.statements.ModificationStatement)6 Test (org.junit.Test)6 InvalidRequestException (org.apache.cassandra.exceptions.InvalidRequestException)4 ByteBuffer (java.nio.ByteBuffer)3 UUID (java.util.UUID)2 CQLStatement (org.apache.cassandra.cql3.CQLStatement)2 UntypedResultSet (org.apache.cassandra.cql3.UntypedResultSet)2 PreparedQueryNotFoundException (org.apache.cassandra.exceptions.PreparedQueryNotFoundException)2 ClientState (org.apache.cassandra.service.ClientState)2 MD5Digest (org.apache.cassandra.utils.MD5Digest)2 SimpleStatement (com.datastax.driver.core.SimpleStatement)1 Statement (com.datastax.driver.core.Statement)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 List (java.util.List)1 AssignmentTestable (org.apache.cassandra.cql3.AssignmentTestable)1 BatchQueryOptions (org.apache.cassandra.cql3.BatchQueryOptions)1 QueryHandler (org.apache.cassandra.cql3.QueryHandler)1 FunctionName (org.apache.cassandra.cql3.functions.FunctionName)1