Search in sources :

Example 1 with PreparedQueryNotFoundException

use of org.apache.cassandra.exceptions.PreparedQueryNotFoundException 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 PreparedQueryNotFoundException

use of org.apache.cassandra.exceptions.PreparedQueryNotFoundException in project cassandra by apache.

the class ExecuteMessage method execute.

public Message.Response execute(QueryState state, long queryStartNanoTime) {
    try {
        QueryHandler handler = ClientState.getCQLQueryHandler();
        ParsedStatement.Prepared prepared = handler.getPrepared(statementId);
        if (prepared == null)
            throw new PreparedQueryNotFoundException(statementId);
        options.prepare(prepared.boundNames);
        CQLStatement statement = prepared.statement;
        if (options.getPageSize() == 0)
            throw new ProtocolException("The page size cannot be 0");
        UUID tracingId = null;
        if (isTracingRequested()) {
            tracingId = UUIDGen.getTimeUUID();
            state.prepareTracingSession(tracingId);
        }
        if (state.traceNextQuery()) {
            state.createTracingSession(getCustomPayload());
            ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
            if (options.getPageSize() > 0)
                builder.put("page_size", Integer.toString(options.getPageSize()));
            if (options.getConsistency() != null)
                builder.put("consistency_level", options.getConsistency().name());
            if (options.getSerialConsistency() != null)
                builder.put("serial_consistency_level", options.getSerialConsistency().name());
            builder.put("query", prepared.rawCQLStatement);
            for (int i = 0; i < prepared.boundNames.size(); i++) {
                ColumnSpecification cs = prepared.boundNames.get(i);
                String boundName = cs.name.toString();
                String boundValue = cs.type.asCQL3Type().toCQLLiteral(options.getValues().get(i), options.getProtocolVersion());
                if (boundValue.length() > 1000) {
                    boundValue = boundValue.substring(0, 1000) + "...'";
                }
                //Here we prefix boundName with the index to avoid possible collission in builder keys due to
                //having multiple boundValues for the same variable
                builder.put("bound_var_" + Integer.toString(i) + "_" + boundName, boundValue);
            }
            Tracing.instance.begin("Execute CQL3 prepared query", state.getClientAddress(), builder.build());
        }
        // Some custom QueryHandlers are interested by the bound names. We provide them this information
        // by wrapping the QueryOptions.
        QueryOptions queryOptions = QueryOptions.addColumnSpecifications(options, prepared.boundNames);
        Message.Response response = handler.processPrepared(statement, state, queryOptions, getCustomPayload(), queryStartNanoTime);
        if (options.skipMetadata() && response instanceof ResultMessage.Rows)
            ((ResultMessage.Rows) response).result.metadata.setSkipMetadata();
        if (tracingId != null)
            response.setTracingId(tracingId);
        return response;
    } catch (Exception e) {
        JVMStabilityInspector.inspectThrowable(e);
        return ErrorMessage.fromException(e);
    } finally {
        Tracing.instance.stopSession();
    }
}
Also used : CQLStatement(org.apache.cassandra.cql3.CQLStatement) QueryHandler(org.apache.cassandra.cql3.QueryHandler) ColumnSpecification(org.apache.cassandra.cql3.ColumnSpecification) ParsedStatement(org.apache.cassandra.cql3.statements.ParsedStatement) PreparedQueryNotFoundException(org.apache.cassandra.exceptions.PreparedQueryNotFoundException) QueryOptions(org.apache.cassandra.cql3.QueryOptions) ImmutableMap(com.google.common.collect.ImmutableMap) PreparedQueryNotFoundException(org.apache.cassandra.exceptions.PreparedQueryNotFoundException) UUID(java.util.UUID)

Example 3 with PreparedQueryNotFoundException

use of org.apache.cassandra.exceptions.PreparedQueryNotFoundException in project cassandra by apache.

the class PreparedStatementsTest method testMetadataFlagsWithLWTs.

@Test
public void testMetadataFlagsWithLWTs() throws Throwable {
    // Verify the behavior of CASSANDRA-10786 (result metadata IDs) on the protocol level.
    // Tests are against an LWT statement and a "regular" SELECT statement.
    // The fundamental difference between a SELECT and an LWT statement is that the result metadata
    // of an LWT can change between invocations - therefore we always return the resultset metadata
    // for LWTs. For "normal" SELECTs, the resultset metadata can only change when DDLs happen
    // (aka the famous prepared 'SELECT * FROM ks.tab' stops working after the schema of that table
    // changes). In those cases, the Result.Rows message contains a METADATA_CHANGED flag to tell
    // clients that the cached metadata for this statement has changed and is included in the result,
    // whereas the resultset metadata is omitted, if the metadata ID sent with the EXECUTE message
    // matches the one for the (current) schema.
    // Note: this test does not cover all aspects of 10786 (yet) - it was intended to test the
    // changes for CASSANDRA-13992.
    createTable("CREATE TABLE %s (pk int, v1 int, v2 int, PRIMARY KEY (pk))");
    execute("INSERT INTO %s (pk, v1, v2) VALUES (1,1,1)");
    try (SimpleClient simpleClient = newSimpleClient(ProtocolVersion.BETA.orElse(ProtocolVersion.CURRENT))) {
        ResultMessage.Prepared prepUpdate = simpleClient.prepare(String.format("UPDATE %s.%s SET v1 = ?, v2 = ? WHERE pk = 1 IF v1 = ?", keyspace(), currentTable()));
        ResultMessage.Prepared prepSelect = simpleClient.prepare(String.format("SELECT * FROM %s.%s WHERE pk = ?", keyspace(), currentTable()));
        // This is a _successful_ LWT update
        verifyMetadataFlagsWithLWTsUpdate(simpleClient, prepUpdate, Arrays.asList(Int32Serializer.instance.serialize(10), Int32Serializer.instance.serialize(20), Int32Serializer.instance.serialize(1)), Arrays.asList("[applied]"), Arrays.asList(BooleanSerializer.instance.serialize(true)));
        prepSelect = verifyMetadataFlagsWithLWTsSelect(simpleClient, prepSelect, Arrays.asList("pk", "v1", "v2"), Arrays.asList(Int32Serializer.instance.serialize(1), Int32Serializer.instance.serialize(10), Int32Serializer.instance.serialize(20)), EnumSet.of(org.apache.cassandra.cql3.ResultSet.Flag.GLOBAL_TABLES_SPEC));
        // This is an _unsuccessful_ LWT update (as the condition fails)
        verifyMetadataFlagsWithLWTsUpdate(simpleClient, prepUpdate, Arrays.asList(Int32Serializer.instance.serialize(10), Int32Serializer.instance.serialize(20), Int32Serializer.instance.serialize(1)), Arrays.asList("[applied]", "v1"), Arrays.asList(BooleanSerializer.instance.serialize(false), Int32Serializer.instance.serialize(10)));
        prepSelect = verifyMetadataFlagsWithLWTsSelect(simpleClient, prepSelect, Arrays.asList("pk", "v1", "v2"), Arrays.asList(Int32Serializer.instance.serialize(1), Int32Serializer.instance.serialize(10), Int32Serializer.instance.serialize(20)), EnumSet.of(org.apache.cassandra.cql3.ResultSet.Flag.GLOBAL_TABLES_SPEC));
        // force a schema change on that table
        simpleClient.execute(String.format("ALTER TABLE %s.%s ADD v3 int", keyspace(), currentTable()), ConsistencyLevel.LOCAL_ONE);
        try {
            simpleClient.executePrepared(prepUpdate, Arrays.asList(Int32Serializer.instance.serialize(1), Int32Serializer.instance.serialize(30), Int32Serializer.instance.serialize(10)), ConsistencyLevel.LOCAL_ONE);
            fail();
        } catch (RuntimeException re) {
            assertTrue(re.getCause() instanceof PreparedQueryNotFoundException);
            // the prepared statement has been removed from the pstmt cache, need to re-prepare it
            // only prepare the statement on the server side but don't set the variable
            simpleClient.prepare(String.format("UPDATE %s.%s SET v1 = ?, v2 = ? WHERE pk = 1 IF v1 = ?", keyspace(), currentTable()));
        }
        try {
            simpleClient.executePrepared(prepSelect, Arrays.asList(Int32Serializer.instance.serialize(1)), ConsistencyLevel.LOCAL_ONE);
            fail();
        } catch (RuntimeException re) {
            assertTrue(re.getCause() instanceof PreparedQueryNotFoundException);
            // the prepared statement has been removed from the pstmt cache, need to re-prepare it
            // only prepare the statement on the server side but don't set the variable
            simpleClient.prepare(String.format("SELECT * FROM %s.%s WHERE pk = ?", keyspace(), currentTable()));
        }
        // This is a _successful_ LWT update
        verifyMetadataFlagsWithLWTsUpdate(simpleClient, prepUpdate, Arrays.asList(Int32Serializer.instance.serialize(1), Int32Serializer.instance.serialize(30), Int32Serializer.instance.serialize(10)), Arrays.asList("[applied]"), Arrays.asList(BooleanSerializer.instance.serialize(true)));
        // Re-assign prepSelect here, as the resultset metadata changed to submit the updated
        // resultset-metadata-ID in the next SELECT. This behavior does not apply to LWT statements.
        prepSelect = verifyMetadataFlagsWithLWTsSelect(simpleClient, prepSelect, Arrays.asList("pk", "v1", "v2", "v3"), Arrays.asList(Int32Serializer.instance.serialize(1), Int32Serializer.instance.serialize(1), Int32Serializer.instance.serialize(30), null), EnumSet.of(org.apache.cassandra.cql3.ResultSet.Flag.GLOBAL_TABLES_SPEC, org.apache.cassandra.cql3.ResultSet.Flag.METADATA_CHANGED));
        // This is an _unsuccessful_ LWT update (as the condition fails)
        verifyMetadataFlagsWithLWTsUpdate(simpleClient, prepUpdate, Arrays.asList(Int32Serializer.instance.serialize(1), Int32Serializer.instance.serialize(30), Int32Serializer.instance.serialize(10)), Arrays.asList("[applied]", "v1"), Arrays.asList(BooleanSerializer.instance.serialize(false), Int32Serializer.instance.serialize(1)));
        verifyMetadataFlagsWithLWTsSelect(simpleClient, prepSelect, Arrays.asList("pk", "v1", "v2", "v3"), Arrays.asList(Int32Serializer.instance.serialize(1), Int32Serializer.instance.serialize(1), Int32Serializer.instance.serialize(30), null), EnumSet.of(org.apache.cassandra.cql3.ResultSet.Flag.GLOBAL_TABLES_SPEC));
    }
}
Also used : SimpleClient(org.apache.cassandra.transport.SimpleClient) PreparedQueryNotFoundException(org.apache.cassandra.exceptions.PreparedQueryNotFoundException) ResultMessage(org.apache.cassandra.transport.messages.ResultMessage) Test(org.junit.Test)

Example 4 with PreparedQueryNotFoundException

use of org.apache.cassandra.exceptions.PreparedQueryNotFoundException 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)

Example 5 with PreparedQueryNotFoundException

use of org.apache.cassandra.exceptions.PreparedQueryNotFoundException in project cassandra by apache.

the class ExecuteMessage method execute.

@Override
protected Message.Response execute(QueryState state, long queryStartNanoTime, boolean traceRequest) {
    QueryHandler.Prepared prepared = null;
    try {
        QueryHandler handler = ClientState.getCQLQueryHandler();
        prepared = handler.getPrepared(statementId);
        if (prepared == null)
            throw new PreparedQueryNotFoundException(statementId);
        if (!prepared.fullyQualified && !Objects.equals(state.getClientState().getRawKeyspace(), prepared.keyspace) && // We can not reliably detect inconsistencies for batches yet
        !(prepared.statement instanceof BatchStatement)) {
            state.getClientState().warnAboutUseWithPreparedStatements(statementId, prepared.keyspace);
            String msg = String.format("Tried to execute a prepared unqalified statement on a keyspace it was not prepared on. " + " Executing the resulting prepared statement will return unexpected results: %s (on keyspace %s, previously prepared on %s)", statementId, state.getClientState().getRawKeyspace(), prepared.keyspace);
            nospam.error(msg);
        }
        CQLStatement statement = prepared.statement;
        options.prepare(statement.getBindVariables());
        if (options.getPageSize() == 0)
            throw new ProtocolException("The page size cannot be 0");
        if (traceRequest)
            traceQuery(state, prepared);
        // Some custom QueryHandlers are interested by the bound names. We provide them this information
        // by wrapping the QueryOptions.
        QueryOptions queryOptions = QueryOptions.addColumnSpecifications(options, prepared.statement.getBindVariables());
        long requestStartTime = currentTimeMillis();
        Message.Response response = handler.processPrepared(statement, state, queryOptions, getCustomPayload(), queryStartNanoTime);
        QueryEvents.instance.notifyExecuteSuccess(prepared.statement, prepared.rawCQLStatement, options, state, requestStartTime, response);
        if (response instanceof ResultMessage.Rows) {
            ResultMessage.Rows rows = (ResultMessage.Rows) response;
            ResultSet.ResultMetadata resultMetadata = rows.result.metadata;
            if (options.getProtocolVersion().isGreaterOrEqualTo(ProtocolVersion.V5)) {
                // for details.
                if (!statement.hasConditions()) {
                    // check if there was a change, comparing it with metadata that's about to be returned to client.
                    if (!resultMetadata.getResultMetadataId().equals(resultMetadataId))
                        resultMetadata.setMetadataChanged();
                    else if (options.skipMetadata())
                        resultMetadata.setSkipMetadata();
                }
            } else {
                // and compare it with the metadata to be returned to client.
                if (options.skipMetadata() && prepared.resultMetadataId.equals(resultMetadata.getResultMetadataId()))
                    resultMetadata.setSkipMetadata();
            }
        }
        return response;
    } catch (Exception e) {
        QueryEvents.instance.notifyExecuteFailure(prepared, options, state, e);
        JVMStabilityInspector.inspectThrowable(e);
        return ErrorMessage.fromException(e);
    }
}
Also used : CQLStatement(org.apache.cassandra.cql3.CQLStatement) ProtocolException(org.apache.cassandra.transport.ProtocolException) QueryHandler(org.apache.cassandra.cql3.QueryHandler) Message(org.apache.cassandra.transport.Message) PreparedQueryNotFoundException(org.apache.cassandra.exceptions.PreparedQueryNotFoundException) QueryOptions(org.apache.cassandra.cql3.QueryOptions) PreparedQueryNotFoundException(org.apache.cassandra.exceptions.PreparedQueryNotFoundException) ProtocolException(org.apache.cassandra.transport.ProtocolException) BatchStatement(org.apache.cassandra.cql3.statements.BatchStatement) ResultSet(org.apache.cassandra.cql3.ResultSet)

Aggregations

PreparedQueryNotFoundException (org.apache.cassandra.exceptions.PreparedQueryNotFoundException)5 CQLStatement (org.apache.cassandra.cql3.CQLStatement)3 QueryHandler (org.apache.cassandra.cql3.QueryHandler)3 BatchStatement (org.apache.cassandra.cql3.statements.BatchStatement)3 ImmutableMap (com.google.common.collect.ImmutableMap)2 ByteBuffer (java.nio.ByteBuffer)2 ArrayList (java.util.ArrayList)2 UUID (java.util.UUID)2 QueryOptions (org.apache.cassandra.cql3.QueryOptions)2 ModificationStatement (org.apache.cassandra.cql3.statements.ModificationStatement)2 ParsedStatement (org.apache.cassandra.cql3.statements.ParsedStatement)2 InvalidRequestException (org.apache.cassandra.exceptions.InvalidRequestException)2 Message (org.apache.cassandra.transport.Message)2 ProtocolException (org.apache.cassandra.transport.ProtocolException)2 MD5Digest (org.apache.cassandra.utils.MD5Digest)2 BatchQueryOptions (org.apache.cassandra.cql3.BatchQueryOptions)1 ColumnSpecification (org.apache.cassandra.cql3.ColumnSpecification)1 ResultSet (org.apache.cassandra.cql3.ResultSet)1 SimpleClient (org.apache.cassandra.transport.SimpleClient)1 ResultMessage (org.apache.cassandra.transport.messages.ResultMessage)1