use of herddb.model.StatementExecutionResult in project herddb by diennea.
the class ServerSideConnectionPeer method executeUpdate.
/**
* This method is like {@link #handleExecuteStatement(herddb.proto.Pdu, herddb.network.Channel) } but in "local" mode,
* we do not want here to marshal/unmarshal values, in order to save resources
*/
public DMLResult executeUpdate(String tablespace, String query, long txId, boolean returnValues, List<Object> parameters) throws HDBException {
// ensure we are dealing with the same data types that we see when the request id coming from the wire
parameters = PduCodec.normalizeParametersList(parameters);
TransactionContext transactionContext = new TransactionContext(txId);
TranslatedQuery translatedQuery;
try {
translatedQuery = server.getManager().getPlanner().translate(tablespace, query, parameters, false, true, returnValues, -1);
Statement statement = translatedQuery.plan.mainStatement;
CompletableFuture<StatementExecutionResult> res = server.getManager().executePlanAsync(translatedQuery.plan, translatedQuery.context, transactionContext);
CompletableFuture<DMLResult> finalResult = res.handle((result, err) -> {
if (err != null) {
while (err instanceof CompletionException) {
err = err.getCause();
}
if (err instanceof DuplicatePrimaryKeyException) {
throw new CompletionException(new SQLIntegrityConstraintViolationException(err));
} else {
throw new CompletionException(new SQLException(err));
}
}
if (result instanceof DMLStatementExecutionResult) {
DMLStatementExecutionResult dml = (DMLStatementExecutionResult) result;
if (returnValues && dml.getKey() != null) {
TableAwareStatement tableStatement = statement.unwrap(TableAwareStatement.class);
Table table = server.getManager().getTableSpaceManager(statement.getTableSpace()).getTableManager(tableStatement.getTable()).getTable();
final Map<RawString, Object> newRecord = new HashMap<>();
Object newKey = RecordSerializer.deserializePrimaryKey(dml.getKey(), table);
newRecord.put(RAWSTRING_KEY, newKey);
if (dml.getNewvalue() != null) {
Map<String, Object> toBean = RecordSerializer.toBean(new Record(dml.getKey(), dml.getNewvalue()), table);
toBean.forEach((k, v) -> {
newRecord.put(RawString.of(k), v);
});
}
return new DMLResult(dml.getUpdateCount(), newKey, newRecord, dml.transactionId);
} else {
return new DMLResult(dml.getUpdateCount(), null, null, dml.transactionId);
}
} else if (result instanceof DDLStatementExecutionResult) {
return new DMLResult(1, null, null, result.transactionId);
} else {
throw new CompletionException(new SQLException("Unknown result type " + result.getClass() + ": " + result));
}
});
return finalResult.get();
} catch (Throwable err) {
while (err instanceof CompletionException) {
err = err.getCause();
}
throw new HDBException(err);
}
}
use of herddb.model.StatementExecutionResult in project herddb by diennea.
the class ServerSideConnectionPeer method handleTxCommand.
private void handleTxCommand(Pdu message, Channel channel) {
long txId = PduCodec.TxCommand.readTx(message);
int type = PduCodec.TxCommand.readCommand(message);
String tableSpace = PduCodec.TxCommand.readTablespace(message);
TransactionContext transactionContext = new TransactionContext(txId);
Statement statement;
switch(type) {
case TX_COMMAND_COMMIT_TRANSACTION:
statement = new CommitTransactionStatement(tableSpace, txId);
break;
case TX_COMMAND_ROLLBACK_TRANSACTION:
statement = new RollbackTransactionStatement(tableSpace, txId);
break;
case TX_COMMAND_BEGIN_TRANSACTION:
statement = new BeginTransactionStatement(tableSpace);
break;
default:
statement = null;
}
if (statement == null) {
ByteBuf error = PduCodec.ErrorResponse.write(message.messageId, "unknown txcommand type:" + type);
channel.sendReplyMessage(message.messageId, error);
message.close();
} else {
// LOGGER.log(Level.SEVERE, "statement " + statement);
CompletableFuture<StatementExecutionResult> res = server.getManager().executeStatementAsync(statement, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), transactionContext);
// LOGGER.log(Level.SEVERE, "query " + query + ", " + parameters + ", result:" + result);
res.whenComplete((result, err) -> {
try {
if (err != null) {
if (err instanceof NotLeaderException) {
ByteBuf error = composeErrorResponse(message.messageId, err);
channel.sendReplyMessage(message.messageId, error);
} else if (err instanceof StatementExecutionException) {
ByteBuf error = composeErrorResponse(message.messageId, err);
channel.sendReplyMessage(message.messageId, error);
} else {
LOGGER.log(Level.SEVERE, "unexpected error on tx command: ", err);
ByteBuf error = composeErrorResponse(message.messageId, err);
channel.sendReplyMessage(message.messageId, error);
}
} else {
if (result instanceof TransactionResult) {
TransactionResult txresult = (TransactionResult) result;
ByteBuf response = PduCodec.TxCommandResult.write(message.messageId, txresult.transactionId);
channel.sendReplyMessage(message.messageId, response);
} else {
ByteBuf error = PduCodec.ErrorResponse.write(message.messageId, "unknown result type:" + result);
channel.sendReplyMessage(message.messageId, error);
}
}
} finally {
message.close();
}
});
}
}
use of herddb.model.StatementExecutionResult in project herddb by diennea.
the class ServerSideConnectionPeer method handleExecuteStatements.
private void handleExecuteStatements(Pdu message, Channel channel) {
long transactionId = PduCodec.ExecuteStatements.readTx(message);
String tableSpace = PduCodec.ExecuteStatements.readTablespace(message);
long statementId = PduCodec.ExecuteStatements.readStatementId(message);
String query = statementId > 0 ? preparedStatements.resolveQuery(tableSpace, statementId) : PduCodec.ExecuteStatements.readQuery(message);
if (query == null) {
ByteBuf error = PduCodec.ErrorResponse.writeMissingPreparedStatementError(message.messageId, "bad statement id: " + statementId);
channel.sendReplyMessage(message.messageId, error);
message.close();
return;
}
boolean returnValues = PduCodec.ExecuteStatements.readReturnValues(message);
PduCodec.ListOfListsReader statementParameters = PduCodec.ExecuteStatements.startReadStatementsParameters(message);
int numStatements = statementParameters.getNumLists();
List<List<Object>> batch = new ArrayList<>(numStatements);
for (int i = 0; i < numStatements; i++) {
PduCodec.ObjectListReader parametersReader = statementParameters.nextList();
List<Object> batchParams = new ArrayList<>(parametersReader.getNumParams());
for (int j = 0; j < parametersReader.getNumParams(); j++) {
batchParams.add(parametersReader.nextObject());
}
batch.add(batchParams);
}
RunningStatementsStats runningStatements = server.getManager().getRunningStatements();
RunningStatementInfo statementInfo = new RunningStatementInfo(query, System.currentTimeMillis(), tableSpace, "", numStatements);
try {
List<TranslatedQuery> queries = new ArrayList<>();
for (int i = 0; i < numStatements; i++) {
List<Object> parameters = batch.get(i);
TranslatedQuery translatedQuery = server.getManager().getPlanner().translate(tableSpace, query, parameters, false, true, returnValues, -1);
queries.add(translatedQuery);
}
List<Long> updateCounts = new CopyOnWriteArrayList<>();
List<Map<String, Object>> otherDatas = new CopyOnWriteArrayList<>();
class ComputeNext implements BiConsumer<StatementExecutionResult, Throwable> {
int current;
public ComputeNext(int current) {
this.current = current;
}
@Override
public void accept(StatementExecutionResult result, Throwable error) {
if (error != null) {
ByteBuf errorMsg = composeErrorResponse(message.messageId, error);
channel.sendReplyMessage(message.messageId, errorMsg);
message.close();
runningStatements.unregisterRunningStatement(statementInfo);
return;
}
if (result instanceof DMLStatementExecutionResult) {
DMLStatementExecutionResult dml = (DMLStatementExecutionResult) result;
Map<String, Object> otherData = Collections.emptyMap();
if (returnValues && dml.getKey() != null) {
TranslatedQuery translatedQuery = queries.get(current - 1);
Statement statement = translatedQuery.plan.mainStatement;
TableAwareStatement tableStatement = (TableAwareStatement) statement;
Table table = server.getManager().getTableSpaceManager(statement.getTableSpace()).getTableManager(tableStatement.getTable()).getTable();
Object key = RecordSerializer.deserializePrimaryKey(dml.getKey(), table);
otherData = new HashMap<>();
otherData.put("_key", key);
if (dml.getNewvalue() != null) {
Map<String, Object> newvalue = RecordSerializer.toBean(new Record(dml.getKey(), dml.getNewvalue()), table);
otherData.putAll(newvalue);
}
}
updateCounts.add((long) dml.getUpdateCount());
otherDatas.add(otherData);
} else if (result instanceof DDLStatementExecutionResult) {
Map<String, Object> otherData = Collections.emptyMap();
updateCounts.add(1L);
otherDatas.add(otherData);
} else {
ByteBuf response = PduCodec.ErrorResponse.write(message.messageId, "bad result type " + result.getClass() + " (" + result + ")");
channel.sendReplyMessage(message.messageId, response);
message.close();
runningStatements.unregisterRunningStatement(statementInfo);
return;
}
long newTransactionId = result.transactionId;
if (current == queries.size()) {
try {
ByteBuf response = PduCodec.ExecuteStatementsResult.write(message.messageId, updateCounts, otherDatas, newTransactionId);
channel.sendReplyMessage(message.messageId, response);
message.close();
runningStatements.unregisterRunningStatement(statementInfo);
} catch (Throwable t) {
LOGGER.log(Level.SEVERE, "Internal error", t);
}
return;
}
TranslatedQuery nextPlannedQuery = queries.get(current);
TransactionContext transactionContext = new TransactionContext(newTransactionId);
CompletableFuture<StatementExecutionResult> nextPromise = server.getManager().executePlanAsync(nextPlannedQuery.plan, nextPlannedQuery.context, transactionContext);
nextPromise.whenComplete(new ComputeNext(current + 1));
}
}
TransactionContext transactionContext = new TransactionContext(transactionId);
TranslatedQuery firstTranslatedQuery = queries.get(0);
server.getManager().executePlanAsync(firstTranslatedQuery.plan, firstTranslatedQuery.context, transactionContext).whenComplete(new ComputeNext(1));
} catch (HerdDBInternalException err) {
ByteBuf response = composeErrorResponse(message.messageId, err);
channel.sendReplyMessage(message.messageId, response);
message.close();
runningStatements.unregisterRunningStatement(statementInfo);
}
}
use of herddb.model.StatementExecutionResult in project herddb by diennea.
the class FilterOp method execute.
@Override
public StatementExecutionResult execute(TableSpaceManager tableSpaceManager, TransactionContext transactionContext, StatementEvaluationContext context, boolean lockRequired, boolean forWrite) throws StatementExecutionException {
try {
// TODO merge projection + scan + sort + limit
StatementExecutionResult input = this.input.execute(tableSpaceManager, transactionContext, context, lockRequired, forWrite);
ScanResult downstreamScanResult = (ScanResult) input;
final DataScanner inputScanner = downstreamScanResult.dataScanner;
FilteredDataScanner filtered = new FilteredDataScanner(inputScanner, condition, context);
return new ScanResult(downstreamScanResult.transactionId, filtered);
} catch (DataScannerException ex) {
throw new StatementExecutionException(ex);
}
}
use of herddb.model.StatementExecutionResult in project herddb by diennea.
the class LimitOp method execute.
@Override
public StatementExecutionResult execute(TableSpaceManager tableSpaceManager, TransactionContext transactionContext, StatementEvaluationContext context, boolean lockRequired, boolean forWrite) throws StatementExecutionException {
try {
// TODO merge projection + scan + sort + limit
StatementExecutionResult input = this.input.execute(tableSpaceManager, transactionContext, context, lockRequired, forWrite);
ScanResult downstreamScanResult = (ScanResult) input;
final DataScanner inputScanner = downstreamScanResult.dataScanner;
int offset = computeOffset(context);
int maxrows = computeMaxRows(context);
if (maxrows <= 0 && offset == 0) {
return downstreamScanResult;
} else {
LimitedDataScanner limited = new LimitedDataScanner(inputScanner, maxrows, offset, context);
return new ScanResult(downstreamScanResult.transactionId, limited);
}
} catch (DataScannerException ex) {
throw new StatementExecutionException(ex);
}
}
Aggregations