use of org.apache.cassandra.cql3.statements.BatchStatement 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);
}
}
use of org.apache.cassandra.cql3.statements.BatchStatement 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);
}
}
use of org.apache.cassandra.cql3.statements.BatchStatement in project cassandra by apache.
the class UFIdentificationTest method testBatchStatementWithConditions.
@Test
public void testBatchStatementWithConditions() throws Throwable {
List<ModificationStatement> statements = new ArrayList<>();
statements.add(modificationStatement(cql("UPDATE %s SET i_val = %s WHERE key=0 AND i_cc=0 and t_cc='foo' IF l_val = %s", functionCall(iFunc, "0"), functionCall(lFunc, "[1]"))));
statements.add(modificationStatement(cql("UPDATE %s SET i_val = %s WHERE key=0 AND i_cc=1 and t_cc='foo' IF s_val = %s", functionCall(iFunc, "0"), functionCall(sFunc, "{1}"))));
BatchStatement batch = new BatchStatement(BatchStatement.Type.LOGGED, VariableSpecifications.empty(), statements, Attributes.none());
assertFunctions(batch, iFunc, lFunc, sFunc);
}
use of org.apache.cassandra.cql3.statements.BatchStatement in project cassandra by apache.
the class UFAuthTest method testBatchStatement.
@Test
public void testBatchStatement() throws Throwable {
List<ModificationStatement> statements = new ArrayList<>();
List<String> functions = new ArrayList<>();
for (int i = 0; i < 3; i++) {
String functionName = createSimpleFunction();
ModificationStatement stmt = (ModificationStatement) getStatement(String.format("INSERT INTO %s (k, v1, v2) " + "VALUES (%s, %s, %s)", KEYSPACE + "." + currentTable(), i, i, functionCall(functionName)));
functions.add(functionName);
statements.add(stmt);
}
BatchStatement batch = new BatchStatement(BatchStatement.Type.LOGGED, VariableSpecifications.empty(), statements, Attributes.none());
assertUnauthorized(batch, functions);
grantExecuteOnFunction(functions.get(0));
assertUnauthorized(batch, functions.subList(1, functions.size()));
grantExecuteOnFunction(functions.get(1));
assertUnauthorized(batch, functions.subList(2, functions.size()));
grantExecuteOnFunction(functions.get(2));
batch.authorize(clientState);
}
Aggregations