use of herddb.model.StatementExecutionResult in project herddb by diennea.
the class DeleteOp method execute.
@Override
public StatementExecutionResult execute(TableSpaceManager tableSpaceManager, TransactionContext transactionContext, StatementEvaluationContext context, boolean lockRequired, boolean forWrite) {
StatementExecutionResult input = this.input.execute(tableSpaceManager, transactionContext, context, true, true);
ScanResult downstreamScanResult = (ScanResult) input;
final Table table = tableSpaceManager.getTableManager(tableName).getTable();
long transactionId = transactionContext.transactionId;
int updateCount = 0;
Bytes key = null;
try (DataScanner inputScanner = downstreamScanResult.dataScanner) {
while (inputScanner.hasNext()) {
DataAccessor row = inputScanner.next();
long transactionIdFromScanner = inputScanner.getTransactionId();
if (transactionIdFromScanner > 0 && transactionIdFromScanner != transactionId) {
transactionId = transactionIdFromScanner;
transactionContext = new TransactionContext(transactionId);
}
key = RecordSerializer.serializePrimaryKey(row, table, table.getPrimaryKey());
DMLStatement deleteStatement = new DeleteStatement(tableSpace, tableName, null, new RawKeyEquals(key));
DMLStatementExecutionResult _result = (DMLStatementExecutionResult) tableSpaceManager.executeStatement(deleteStatement, context, transactionContext);
updateCount += _result.getUpdateCount();
if (_result.transactionId > 0 && _result.transactionId != transactionId) {
transactionId = _result.transactionId;
transactionContext = new TransactionContext(transactionId);
}
key = _result.getKey();
}
return new DMLStatementExecutionResult(transactionId, updateCount, key, null);
} catch (DataScannerException err) {
throw new StatementExecutionException(err);
}
}
use of herddb.model.StatementExecutionResult in project herddb by diennea.
the class UpdateOp method execute.
@Override
public StatementExecutionResult execute(TableSpaceManager tableSpaceManager, TransactionContext transactionContext, StatementEvaluationContext context, boolean lockRequired, boolean forWrite) {
StatementExecutionResult input = this.input.execute(tableSpaceManager, transactionContext, context, true, true);
ScanResult downstreamScanResult = (ScanResult) input;
final Table table = tableSpaceManager.getTableManager(tableName).getTable();
long transactionId = transactionContext.transactionId;
int updateCount = 0;
Bytes key = null;
Bytes newValue = null;
try (DataScanner inputScanner = downstreamScanResult.dataScanner) {
while (inputScanner.hasNext()) {
DataAccessor row = inputScanner.next();
long transactionIdFromScanner = inputScanner.getTransactionId();
if (transactionIdFromScanner > 0 && transactionIdFromScanner != transactionId) {
transactionId = transactionIdFromScanner;
transactionContext = new TransactionContext(transactionId);
}
key = RecordSerializer.serializePrimaryKey(row, table, table.getPrimaryKey());
Predicate pred = new RawKeyEquals(key);
DMLStatement updateStatement = new UpdateStatement(tableSpace, tableName, null, this.recordFunction, pred).setReturnValues(returnValues);
DMLStatementExecutionResult _result = (DMLStatementExecutionResult) tableSpaceManager.executeStatement(updateStatement, context, transactionContext);
updateCount += _result.getUpdateCount();
if (_result.transactionId > 0 && _result.transactionId != transactionId) {
transactionId = _result.transactionId;
transactionContext = new TransactionContext(transactionId);
}
key = _result.getKey();
newValue = _result.getNewvalue();
}
return new DMLStatementExecutionResult(transactionId, updateCount, key, newValue);
} catch (DataScannerException err) {
throw new StatementExecutionException(err);
}
}
use of herddb.model.StatementExecutionResult in project herddb by diennea.
the class ServerSideConnectionPeer method handleExecuteStatement.
private void handleExecuteStatement(Message message, Channel _channel) {
Long tx = (Long) message.parameters.get("tx");
long txId = tx != null ? tx : TransactionContext.NOTRANSACTION_ID;
String query = (String) message.parameters.get("query");
String tableSpace = (String) message.parameters.get("tableSpace");
Boolean returnValues = (Boolean) message.parameters.get("returnValues");
if (returnValues == null) {
returnValues = Boolean.FALSE;
}
List<Object> parameters = (List<Object>) message.parameters.get("params");
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.log(Level.FINEST, "query " + query + " with " + parameters);
}
try {
TransactionContext transactionContext = new TransactionContext(txId);
TranslatedQuery translatedQuery = server.getManager().getPlanner().translate(tableSpace, query, parameters, false, true, returnValues, -1);
Statement statement = translatedQuery.plan.mainStatement;
// LOGGER.log(Level.SEVERE, "query " + query + ", " + parameters + ", plan: " + translatedQuery.plan);
StatementExecutionResult result = server.getManager().executePlan(translatedQuery.plan, translatedQuery.context, transactionContext);
// LOGGER.log(Level.SEVERE, "query " + query + ", " + parameters + ", result:" + result);
if (result instanceof DMLStatementExecutionResult) {
DMLStatementExecutionResult dml = (DMLStatementExecutionResult) result;
Map<String, Object> otherData = null;
if (returnValues && dml.getKey() != null) {
TableAwareStatement tableStatement = statement.unwrap(TableAwareStatement.class);
Table table = server.getManager().getTableSpaceManager(statement.getTableSpace()).getTableManager(tableStatement.getTable()).getTable();
otherData = new HashMap<>();
Object key = RecordSerializer.deserializePrimaryKey(dml.getKey().data, table);
otherData.put("key", key);
if (dml.getNewvalue() != null) {
Map<String, Object> newvalue = RecordSerializer.toBean(new Record(dml.getKey(), dml.getNewvalue()), table);
otherData.put("newvalue", newvalue);
}
}
_channel.sendReplyMessage(message, Message.EXECUTE_STATEMENT_RESULT(dml.getUpdateCount(), otherData, dml.transactionId));
} else if (result instanceof GetResult) {
GetResult get = (GetResult) result;
if (!get.found()) {
_channel.sendReplyMessage(message, Message.EXECUTE_STATEMENT_RESULT(0, null, get.transactionId));
} else {
Map<String, Object> record = get.getRecord().toBean(get.getTable());
_channel.sendReplyMessage(message, Message.EXECUTE_STATEMENT_RESULT(1, record, get.transactionId));
}
} else if (result instanceof TransactionResult) {
TransactionResult txresult = (TransactionResult) result;
Map<String, Object> data = new HashMap<>();
Set<Long> transactionsForTableSpace = openTransactions.computeIfAbsent(statement.getTableSpace(), k -> new ConcurrentSkipListSet<>());
switch(txresult.getOutcome()) {
case BEGIN:
{
transactionsForTableSpace.add(txresult.getTransactionId());
break;
}
case COMMIT:
case ROLLBACK:
transactionsForTableSpace.remove(txresult.getTransactionId());
break;
}
data.put("tx", txresult.getTransactionId());
_channel.sendReplyMessage(message, Message.EXECUTE_STATEMENT_RESULT(1, data, txresult.transactionId));
} else if (result instanceof DDLStatementExecutionResult) {
DDLStatementExecutionResult ddl = (DDLStatementExecutionResult) result;
_channel.sendReplyMessage(message, Message.EXECUTE_STATEMENT_RESULT(1, null, ddl.transactionId));
} else {
_channel.sendReplyMessage(message, Message.ERROR(null, new Exception("unknown result type " + result.getClass() + " (" + result + ")")));
}
} catch (DuplicatePrimaryKeyException err) {
LOGGER.log(Level.SEVERE, "error on query " + query + ", parameters: " + parameters + ": err", err);
Message error = Message.ERROR(null, err);
_channel.sendReplyMessage(message, error);
} catch (NotLeaderException err) {
Message error = Message.ERROR(null, err);
error.setParameter("notLeader", "true");
_channel.sendReplyMessage(message, error);
} catch (StatementExecutionException err) {
Message error = Message.ERROR(null, err);
_channel.sendReplyMessage(message, error);
} catch (RuntimeException err) {
LOGGER.log(Level.SEVERE, "unexpected error on query " + query + ", parameters: " + parameters + ": err", err);
Message error = Message.ERROR(null, err);
_channel.sendReplyMessage(message, error);
}
}
use of herddb.model.StatementExecutionResult in project herddb by diennea.
the class ServerSideConnectionPeer method handleExecuteStatements.
private void handleExecuteStatements(Message message, Channel _channel) {
Long tx = (Long) message.parameters.get("tx");
long txId = tx != null ? tx : TransactionContext.NOTRANSACTION_ID;
long transactionId = txId;
String query = (String) message.parameters.get("query");
String tableSpace = (String) message.parameters.get("tableSpace");
Boolean returnValues = (Boolean) message.parameters.get("returnValues");
if (returnValues == null) {
returnValues = Boolean.FALSE;
}
List<List<Object>> batch = (List<List<Object>>) message.parameters.get("params");
try {
List<Long> updateCounts = new ArrayList<>(batch.size());
List<Map<String, Object>> otherDatas = new ArrayList<>(batch.size());
for (int i = 0; i < batch.size(); i++) {
List<Object> parameters = batch.get(i);
TransactionContext transactionContext = new TransactionContext(transactionId);
TranslatedQuery translatedQuery = server.getManager().getPlanner().translate(tableSpace, query, parameters, false, true, returnValues, -1);
Statement statement = translatedQuery.plan.mainStatement;
StatementExecutionResult result = server.getManager().executePlan(translatedQuery.plan, translatedQuery.context, transactionContext);
if (transactionId > 0 && result.transactionId > 0 && transactionId != result.transactionId) {
throw new StatementExecutionException("transactionid changed during batch execution, " + transactionId + "<>" + result.transactionId);
}
transactionId = result.transactionId;
if (result instanceof DMLStatementExecutionResult) {
DMLStatementExecutionResult dml = (DMLStatementExecutionResult) result;
Map<String, Object> otherData = Collections.emptyMap();
if (returnValues && dml.getKey() != null) {
TableAwareStatement tableStatement = (TableAwareStatement) statement;
Table table = server.getManager().getTableSpaceManager(statement.getTableSpace()).getTableManager(tableStatement.getTable()).getTable();
Object key = RecordSerializer.deserializePrimaryKey(dml.getKey().data, 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.put("newvalue", newvalue);
}
}
updateCounts.add(Long.valueOf(dml.getUpdateCount()));
otherDatas.add(otherData);
} else {
_channel.sendReplyMessage(message, Message.ERROR(null, new Exception("bad result type " + result.getClass() + " (" + result + ")")));
}
}
_channel.sendReplyMessage(message, Message.EXECUTE_STATEMENT_RESULTS(updateCounts, otherDatas, transactionId));
} catch (HerdDBInternalException err) {
Message error = Message.ERROR(null, err);
if (err instanceof NotLeaderException) {
error.setParameter("notLeader", "true");
}
_channel.sendReplyMessage(message, error);
}
}
use of herddb.model.StatementExecutionResult in project herddb by diennea.
the class TableSpaceManager method commitTransaction.
private CompletableFuture<StatementExecutionResult> commitTransaction(CommitTransactionStatement statement, StatementEvaluationContext context) throws StatementExecutionException {
long txId = statement.getTransactionId();
validateTransactionBeforeTxCommand(txId);
LogEntry entry = LogEntryFactory.commitTransaction(txId);
long lockStamp = context.getTableSpaceLock();
boolean lockAcquired = false;
if (lockStamp == 0) {
lockStamp = acquireReadLock(statement);
context.setTableSpaceLock(lockStamp);
lockAcquired = true;
}
CommitLogResult pos = log.log(entry, true);
CompletableFuture<StatementExecutionResult> res = pos.logSequenceNumber.handleAsync((lsn, error) -> {
if (error == null) {
apply(pos, entry, false);
return new TransactionResult(txId, TransactionResult.OutcomeType.COMMIT);
} else {
// if the log is not able to write the commit
// apply a dummy "rollback", we are no more going to accept commands
// in the scope of this transaction
LogEntry rollback = LogEntryFactory.rollbackTransaction(txId);
apply(new CommitLogResult(LogSequenceNumber.START_OF_TIME, false, false), rollback, false);
throw new CompletionException(error);
}
}, callbacksExecutor);
if (lockAcquired) {
res = releaseReadLock(res, lockStamp, statement).thenApply(s -> {
context.setTableSpaceLock(0);
return s;
});
}
return res;
}
Aggregations