use of herddb.model.TransactionContext in project herddb by diennea.
the class InsertOp 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);
}
int index = 0;
List<CompiledSQLExpression> keyValueExpression = new ArrayList<>();
List<String> keyExpressionToColumn = new ArrayList<>();
List<CompiledSQLExpression> valuesExpressions = new ArrayList<>();
List<String> valuesColumns = new ArrayList<>();
for (Column column : table.getColumns()) {
Object value = row.get(index++);
if (value != null) {
ConstantExpression exp = new ConstantExpression(value);
if (table.isPrimaryKeyColumn(column.name)) {
keyExpressionToColumn.add(column.name);
keyValueExpression.add(exp);
}
valuesColumns.add(column.name);
valuesExpressions.add(exp);
}
}
RecordFunction keyfunction;
if (keyValueExpression.isEmpty() && table.auto_increment) {
keyfunction = new AutoIncrementPrimaryKeyRecordFunction();
} else {
if (keyValueExpression.size() != table.primaryKey.length) {
throw new StatementExecutionException("you must set a value for the primary key (expressions=" + keyValueExpression.size() + ")");
}
keyfunction = new SQLRecordKeyFunction(keyExpressionToColumn, keyValueExpression, table);
}
RecordFunction valuesfunction = new SQLRecordFunction(valuesColumns, table, valuesExpressions);
DMLStatement insertStatement = new InsertStatement(tableSpace, tableName, keyfunction, valuesfunction).setReturnValues(returnValues);
DMLStatementExecutionResult _result = (DMLStatementExecutionResult) tableSpaceManager.executeStatement(insertStatement, 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();
}
if (updateCount > 1 && returnValues) {
if (transactionId > 0) {
// usually the first record will be rolledback with transaction failure
throw new StatementExecutionException("cannot 'return values' on multi-values insert");
} else {
throw new StatementExecutionException("cannot 'return values' on multi-values insert, at least record could have been written because autocommit=true");
}
}
return new DMLStatementExecutionResult(transactionId, updateCount, key, newValue);
} catch (DataScannerException err) {
throw new StatementExecutionException(err);
}
}
use of herddb.model.TransactionContext in project herddb by diennea.
the class ServerSideConnectionPeer method handleOpenScanner.
private void handleOpenScanner(Message message, Channel _channel) {
String tableSpace = (String) message.parameters.get("tableSpace");
Long tx = (Long) message.parameters.get("tx");
long txId = tx != null ? tx : 0;
String query = (String) message.parameters.get("query");
String scannerId = (String) message.parameters.get("scannerId");
int fetchSize = 10;
if (message.parameters.containsKey("fetchSize")) {
fetchSize = (Integer) message.parameters.get("fetchSize");
}
int maxRows = 0;
if (message.parameters.containsKey("maxRows")) {
maxRows = (Integer) message.parameters.get("maxRows");
}
List<Object> parameters = (List<Object>) message.parameters.get("params");
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.log(Level.FINEST, "openScanner txId+" + txId + ", fetchSize " + fetchSize + ", maxRows " + maxRows + "," + query + " with " + parameters);
}
try {
TranslatedQuery translatedQuery = server.getManager().getPlanner().translate(tableSpace, query, parameters, true, true, false, maxRows);
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.log(Level.FINEST, query + " -> " + translatedQuery.plan.mainStatement);
}
TransactionContext transactionContext = new TransactionContext(txId);
if (translatedQuery.plan.mainStatement instanceof SQLPlannedOperationStatement || translatedQuery.plan.mainStatement instanceof ScanStatement || translatedQuery.plan.joinStatements != null) {
ScanResult scanResult = (ScanResult) server.getManager().executePlan(translatedQuery.plan, translatedQuery.context, transactionContext);
DataScanner dataScanner = scanResult.dataScanner;
ServerSideScannerPeer scanner = new ServerSideScannerPeer(dataScanner);
String[] columns = dataScanner.getFieldNames();
List<DataAccessor> records = dataScanner.consume(fetchSize);
TuplesList tuplesList = new TuplesList(columns, records);
boolean last = dataScanner.isFinished();
LOGGER.log(Level.FINEST, "sending first {0} records to scanner {1} query {2}", new Object[] { records.size(), scannerId, query });
if (!last) {
scanners.put(scannerId, scanner);
}
_channel.sendReplyMessage(message, Message.RESULTSET_CHUNK(null, scannerId, tuplesList, last, dataScanner.transactionId));
} else {
_channel.sendReplyMessage(message, Message.ERROR(null, new Exception("unsupported query type for scan " + query + ": PLAN is " + translatedQuery.plan)));
}
} catch (DataScannerException | RuntimeException err) {
LOGGER.log(Level.SEVERE, "error on scanner " + scannerId + ": " + err, err);
scanners.remove(scannerId);
Message error = Message.ERROR(null, err);
if (err instanceof NotLeaderException) {
error.setParameter("notLeader", "true");
}
_channel.sendReplyMessage(message, error);
}
}
use of herddb.model.TransactionContext in project herddb by diennea.
the class ThetaJoinOp method execute.
@Override
public StatementExecutionResult execute(TableSpaceManager tableSpaceManager, TransactionContext transactionContext, StatementEvaluationContext context, boolean lockRequired, boolean forWrite) throws StatementExecutionException {
ScanResult resLeft = (ScanResult) left.execute(tableSpaceManager, transactionContext, context, lockRequired, forWrite);
transactionContext = new TransactionContext(resLeft.transactionId);
ScanResult resRight = (ScanResult) right.execute(tableSpaceManager, transactionContext, context, lockRequired, forWrite);
final long resTransactionId = resRight.transactionId;
final String[] fieldNamesFromLeft = resLeft.dataScanner.getFieldNames();
final String[] fieldNamesFromRight = resRight.dataScanner.getFieldNames();
final Function2<DataAccessor, DataAccessor, DataAccessor> resultProjection = resultProjection(fieldNamesFromLeft, fieldNamesFromRight);
Enumerable<DataAccessor> result = EnumerableDefaults.thetaJoin(resLeft.dataScanner.createEnumerable(), resRight.dataScanner.createEnumerable(), predicate(resultProjection, context), resultProjection, generateNullsOnLeft, generateNullsOnRight);
EnumerableDataScanner joinedScanner = new EnumerableDataScanner(resTransactionId, fieldNames, columns, result);
return new ScanResult(resTransactionId, joinedScanner);
}
use of herddb.model.TransactionContext in project herddb by diennea.
the class RawSQLTest method multiInsert.
@Test
public void multiInsert() throws Exception {
String nodeId = "localhost";
try (DBManager manager = new DBManager("localhost", new MemoryMetadataStorageManager(), new MemoryDataStorageManager(), new MemoryCommitLogManager(), null, null)) {
manager.start();
CreateTableSpaceStatement st1 = new CreateTableSpaceStatement("tblspace1", Collections.singleton(nodeId), nodeId, 1, 0, 0);
manager.executeStatement(st1, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
manager.waitForTablespace("tblspace1", 10000);
execute(manager, "CREATE TABLE tblspace1.tsql (k1 string primary key,n1 int,s1 string,t1 timestamp)", Collections.emptyList());
java.sql.Timestamp tt1 = new java.sql.Timestamp(System.currentTimeMillis());
java.sql.Timestamp tt2 = new java.sql.Timestamp(System.currentTimeMillis() + 60000);
assertEquals(2, executeUpdate(manager, "INSERT INTO tblspace1.tsql(k1,n1,t1) values(?,?,?),(?,?,?)", Arrays.asList("mykey", Integer.valueOf(1234), tt1, "mykey2", Integer.valueOf(1235), tt2)).getUpdateCount());
try (DataScanner scan = scan(manager, "SELECT k1,n1,t1 FROM tblspace1.tsql ORDER BY n1 desc", Collections.emptyList())) {
List<DataAccessor> res = scan.consume();
assertEquals(RawString.of("mykey2"), res.get(0).get("k1"));
assertEquals(RawString.of("mykey"), res.get(1).get("k1"));
assertEquals(Integer.valueOf(1235), res.get(0).get("n1"));
assertEquals(Integer.valueOf(1234), res.get(1).get("n1"));
assertEquals(tt2, res.get(0).get("t1"));
assertEquals(tt1, res.get(1).get("t1"));
}
execute(manager, "CREATE TABLE tblspace1.tsql2 (a1 integer auto_increment primary key, k1 string ,n1 int,s1 string,t1 timestamp)", Collections.emptyList());
assertEquals(2, executeUpdate(manager, "INSERT INTO tblspace1.tsql2(k1,n1,t1) values(?,?,?),(?,?,?)", Arrays.asList("mykey", Integer.valueOf(1234), tt1, "mykey2", Integer.valueOf(1235), tt2)).getUpdateCount());
try (DataScanner scan = scan(manager, "SELECT a1,k1,n1,t1 FROM tblspace1.tsql2 ORDER BY n1 desc", Collections.emptyList())) {
List<DataAccessor> res = scan.consume();
assertEquals(RawString.of("mykey2"), res.get(0).get("k1"));
assertEquals(RawString.of("mykey"), res.get(1).get("k1"));
assertEquals(Integer.valueOf(1235), res.get(0).get("n1"));
assertEquals(Integer.valueOf(1234), res.get(1).get("n1"));
assertEquals(tt2, res.get(0).get("t1"));
assertEquals(tt1, res.get(1).get("t1"));
assertEquals(2, res.get(0).get("a1"));
assertEquals(1, res.get(1).get("a1"));
}
// auto-transaction
execute(manager, "CREATE TABLE tblspace1.tsql3 (a1 integer auto_increment primary key, k1 string ,n1 int,s1 string,t1 timestamp)", Collections.emptyList());
DMLStatementExecutionResult resInsert = executeUpdate(manager, "INSERT INTO tblspace1.tsql3(k1,n1,t1) values(?,?,?),(?,?,?)", Arrays.asList("mykey", Integer.valueOf(1234), tt1, "mykey2", Integer.valueOf(1235), tt2), TransactionContext.AUTOTRANSACTION_TRANSACTION);
assertEquals(2, resInsert.getUpdateCount());
assertTrue(resInsert.transactionId > 0);
try (DataScanner scan = scan(manager, "SELECT a1,k1,n1,t1 FROM tblspace1.tsql3 ORDER BY n1 desc", Collections.emptyList(), 0, new TransactionContext(resInsert.transactionId))) {
List<DataAccessor> res = scan.consume();
assertEquals(RawString.of("mykey2"), res.get(0).get("k1"));
assertEquals(RawString.of("mykey"), res.get(1).get("k1"));
assertEquals(Integer.valueOf(1235), res.get(0).get("n1"));
assertEquals(Integer.valueOf(1234), res.get(1).get("n1"));
assertEquals(tt2, res.get(0).get("t1"));
assertEquals(tt1, res.get(1).get("t1"));
assertEquals(2, res.get(0).get("a1"));
assertEquals(1, res.get(1).get("a1"));
}
}
}
use of herddb.model.TransactionContext in project herddb by diennea.
the class RestartPendingTransactionTest method recoverUpdate.
@Test
public void recoverUpdate() throws Exception {
Path dataPath = folder.newFolder("data").toPath();
Path logsPath = folder.newFolder("logs").toPath();
Path metadataPath = folder.newFolder("metadata").toPath();
Path tmoDir = folder.newFolder("tmoDir").toPath();
Bytes key1 = Bytes.from_string("k1");
Bytes key2 = Bytes.from_string("k2");
Bytes key3 = Bytes.from_string("k3");
String nodeId = "localhost";
try (DBManager manager = new DBManager("localhost", new FileMetadataStorageManager(metadataPath), new FileDataStorageManager(dataPath), new FileCommitLogManager(logsPath, 64 * 1024 * 1024), tmoDir, null)) {
manager.start();
CreateTableSpaceStatement st1 = new CreateTableSpaceStatement("tblspace1", Collections.singleton(nodeId), nodeId, 1, 0, 0);
manager.executeStatement(st1, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
manager.waitForTablespace("tblspace1", 10000);
Table table = Table.builder().tablespace("tblspace1").name("t1").column("id", ColumnTypes.STRING).column("name", ColumnTypes.STRING).primaryKey("id").build();
manager.executeStatement(new CreateTableStatement(table), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
manager.executeStatement(new InsertStatement("tblspace1", table.name, new Record(key1, key1)), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
manager.executeStatement(new InsertStatement("tblspace1", table.name, new Record(key2, key2)), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
manager.executeStatement(new InsertStatement("tblspace1", table.name, new Record(key3, key3)), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
manager.checkpoint();
manager.executeStatement(new UpdateStatement("tblspace1", table.name, new ConstValueRecordFunction(key2.data), new ConstValueRecordFunction(key3.data), null), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
long tx2 = ((TransactionResult) manager.executeStatement(new BeginTransactionStatement("tblspace1"), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION)).getTransactionId();
manager.executeStatement(new UpdateStatement("tblspace1", table.name, new ConstValueRecordFunction(key2.data), new ConstValueRecordFunction(key3.data), null), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), new TransactionContext(tx2));
manager.executeStatement(new CommitTransactionStatement("tblspace1", tx2), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
// transactions which contains the update will be replayed at reboot
}
try (DBManager manager = new DBManager("localhost", new FileMetadataStorageManager(metadataPath), new FileDataStorageManager(dataPath), new FileCommitLogManager(logsPath, 64 * 1024 * 1024), tmoDir, null)) {
manager.start();
manager.waitForTablespace("tblspace1", 10000);
GetResult result = manager.get(new GetStatement("tblspace1", "t1", key1, null, false), StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT(), TransactionContext.NO_TRANSACTION);
assertTrue(result.found());
}
}
Aggregations