Search in sources :

Example 1 with MD5Digest

use of org.apache.cassandra.utils.MD5Digest 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 2 with MD5Digest

use of org.apache.cassandra.utils.MD5Digest in project cassandra by apache.

the class PstmtPersistenceTest method testCachedPreparedStatements.

@Test
public void testCachedPreparedStatements() throws Throwable {
    // need this for pstmt execution/validation tests
    requireNetwork();
    assertEquals(0, numberOfStatementsOnDisk());
    execute("CREATE KEYSPACE IF NOT EXISTS foo WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'}");
    execute("CREATE TABLE foo.bar (key text PRIMARY KEY, val int)");
    ClientState clientState = ClientState.forExternalCalls(InetSocketAddress.createUnresolved("127.0.0.1", 1234));
    createTable("CREATE TABLE %s (pk int PRIMARY KEY, val text)");
    List<MD5Digest> stmtIds = new ArrayList<>();
    String statement0 = "SELECT * FROM %s WHERE keyspace_name = ?";
    String statement1 = "SELECT * FROM %s WHERE pk = ?";
    String statement2 = "SELECT * FROM %s WHERE key = ?";
    String statement3 = "SELECT * FROM %S WHERE key = ?";
    stmtIds.add(prepareStatement(statement0, SchemaConstants.SCHEMA_KEYSPACE_NAME, SchemaKeyspaceTables.TABLES, clientState));
    stmtIds.add(prepareStatement(statement1, clientState));
    stmtIds.add(prepareStatement(statement2, "foo", "bar", clientState));
    clientState.setKeyspace("foo");
    stmtIds.add(prepareStatement(statement1, clientState));
    stmtIds.add(prepareStatement(statement3, "foo", "bar", clientState));
    assertEquals(5, stmtIds.size());
    // statement1 will have two statements prepared because of `setKeyspace` usage
    assertEquals(6, QueryProcessor.preparedStatementsCount());
    assertEquals(6, numberOfStatementsOnDisk());
    QueryHandler handler = ClientState.getCQLQueryHandler();
    validatePstmts(stmtIds, handler);
    // clear prepared statements cache
    QueryProcessor.clearPreparedStatements(true);
    assertEquals(0, QueryProcessor.preparedStatementsCount());
    for (MD5Digest stmtId : stmtIds) Assert.assertNull(handler.getPrepared(stmtId));
    // load prepared statements and validate that these still execute fine
    QueryProcessor.instance.preloadPreparedStatements();
    validatePstmts(stmtIds, handler);
    // validate that the prepared statements are in the system table
    String queryAll = "SELECT * FROM " + SchemaConstants.SYSTEM_KEYSPACE_NAME + '.' + SystemKeyspace.PREPARED_STATEMENTS;
    for (UntypedResultSet.Row row : QueryProcessor.executeOnceInternal(queryAll)) {
        MD5Digest digest = MD5Digest.wrap(ByteBufferUtil.getArray(row.getBytes("prepared_id")));
        QueryProcessor.Prepared prepared = QueryProcessor.instance.getPrepared(digest);
        Assert.assertNotNull(prepared);
    }
    // add anther prepared statement and sync it to table
    prepareStatement(statement2, "foo", "bar", clientState);
    // statement1 will have two statements prepared because of `setKeyspace` usage
    assertEquals(7, numberOfStatementsInMemory());
    assertEquals(7, numberOfStatementsOnDisk());
    // drop a keyspace (prepared statements are removed - syncPreparedStatements() remove should the rows, too)
    execute("DROP KEYSPACE foo");
    assertEquals(3, numberOfStatementsInMemory());
    assertEquals(3, numberOfStatementsOnDisk());
}
Also used : ClientState(org.apache.cassandra.service.ClientState) MD5Digest(org.apache.cassandra.utils.MD5Digest) ArrayList(java.util.ArrayList) Test(org.junit.Test)

Example 3 with MD5Digest

use of org.apache.cassandra.utils.MD5Digest in project cassandra by apache.

the class SecondaryIndexTest method droppingIndexInvalidatesPreparedStatements.

@Test
public void droppingIndexInvalidatesPreparedStatements() throws Throwable {
    createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY ((a), b))");
    String indexName = createIndex("CREATE INDEX ON %s(c)");
    MD5Digest cqlId = prepareStatement("SELECT * FROM %s.%s WHERE c=?").statementId;
    assertNotNull(QueryProcessor.instance.getPrepared(cqlId));
    dropIndex("DROP INDEX %s." + indexName);
    assertNull(QueryProcessor.instance.getPrepared(cqlId));
}
Also used : MD5Digest(org.apache.cassandra.utils.MD5Digest) Test(org.junit.Test)

Example 4 with MD5Digest

use of org.apache.cassandra.utils.MD5Digest in project cassandra by apache.

the class BatchMessage method execute.

@Override
protected Message.Response execute(QueryState state, long queryStartNanoTime, boolean traceRequest) {
    List<QueryHandler.Prepared> prepared = null;
    try {
        if (traceRequest)
            traceQuery(state);
        QueryHandler handler = ClientState.getCQLQueryHandler();
        prepared = new ArrayList<>(queryOrIdList.size());
        for (int i = 0; i < queryOrIdList.size(); i++) {
            Object query = queryOrIdList.get(i);
            QueryHandler.Prepared p;
            if (query instanceof String) {
                p = QueryProcessor.parseAndPrepare((String) query, state.getClientState().cloneWithKeyspaceIfSet(options.getKeyspace()), false);
            } else {
                p = handler.getPrepared((MD5Digest) query);
                if (null == p)
                    throw new PreparedQueryNotFoundException((MD5Digest) query);
            }
            List<ByteBuffer> queryValues = values.get(i);
            if (queryValues.size() != p.statement.getBindVariables().size())
                throw new InvalidRequestException(String.format("There were %d markers(?) in CQL but %d bound variables", p.statement.getBindVariables().size(), queryValues.size()));
            prepared.add(p);
        }
        BatchQueryOptions batchOptions = BatchQueryOptions.withPerStatementVariables(options, values, queryOrIdList);
        List<ModificationStatement> statements = new ArrayList<>(prepared.size());
        List<String> queries = QueryEvents.instance.hasListeners() ? new ArrayList<>(prepared.size()) : null;
        for (int i = 0; i < prepared.size(); i++) {
            CQLStatement statement = prepared.get(i).statement;
            if (queries != null)
                queries.add(prepared.get(i).rawCQLStatement);
            batchOptions.prepareStatement(i, statement.getBindVariables());
            if (!(statement instanceof ModificationStatement))
                throw new InvalidRequestException("Invalid statement in batch: only UPDATE, INSERT and DELETE statements are allowed.");
            statements.add((ModificationStatement) 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(batchType, VariableSpecifications.empty(), statements, Attributes.none());
        long queryTime = currentTimeMillis();
        Message.Response response = handler.processBatch(batch, state, batchOptions, getCustomPayload(), queryStartNanoTime);
        if (queries != null)
            QueryEvents.instance.notifyBatchSuccess(batchType, statements, queries, values, options, state, queryTime, response);
        return response;
    } catch (Exception e) {
        QueryEvents.instance.notifyBatchFailure(prepared, batchType, queryOrIdList, values, options, state, e);
        JVMStabilityInspector.inspectThrowable(e);
        return ErrorMessage.fromException(e);
    }
}
Also used : CQLStatement(org.apache.cassandra.cql3.CQLStatement) QueryHandler(org.apache.cassandra.cql3.QueryHandler) Message(org.apache.cassandra.transport.Message) BatchQueryOptions(org.apache.cassandra.cql3.BatchQueryOptions) ModificationStatement(org.apache.cassandra.cql3.statements.ModificationStatement) ArrayList(java.util.ArrayList) PreparedQueryNotFoundException(org.apache.cassandra.exceptions.PreparedQueryNotFoundException) ByteBuffer(java.nio.ByteBuffer) PreparedQueryNotFoundException(org.apache.cassandra.exceptions.PreparedQueryNotFoundException) InvalidRequestException(org.apache.cassandra.exceptions.InvalidRequestException) ProtocolException(org.apache.cassandra.transport.ProtocolException) MD5Digest(org.apache.cassandra.utils.MD5Digest) BatchStatement(org.apache.cassandra.cql3.statements.BatchStatement) InvalidRequestException(org.apache.cassandra.exceptions.InvalidRequestException)

Aggregations

MD5Digest (org.apache.cassandra.utils.MD5Digest)4 ArrayList (java.util.ArrayList)3 ByteBuffer (java.nio.ByteBuffer)2 BatchStatement (org.apache.cassandra.cql3.statements.BatchStatement)2 ModificationStatement (org.apache.cassandra.cql3.statements.ModificationStatement)2 InvalidRequestException (org.apache.cassandra.exceptions.InvalidRequestException)2 PreparedQueryNotFoundException (org.apache.cassandra.exceptions.PreparedQueryNotFoundException)2 Test (org.junit.Test)2 ImmutableMap (com.google.common.collect.ImmutableMap)1 UUID (java.util.UUID)1 BatchQueryOptions (org.apache.cassandra.cql3.BatchQueryOptions)1 CQLStatement (org.apache.cassandra.cql3.CQLStatement)1 QueryHandler (org.apache.cassandra.cql3.QueryHandler)1 ParsedStatement (org.apache.cassandra.cql3.statements.ParsedStatement)1 ClientState (org.apache.cassandra.service.ClientState)1 Message (org.apache.cassandra.transport.Message)1 ProtocolException (org.apache.cassandra.transport.ProtocolException)1