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();
}
}
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());
}
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));
}
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);
}
}
Aggregations