use of herddb.model.DMLStatement 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.DMLStatement 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.DMLStatement 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.DMLStatement in project herddb by diennea.
the class CalcitePlanner method planInsert.
private PlannerOp planInsert(EnumerableTableModify dml, boolean returnValues) {
final String tableSpace = dml.getTable().getQualifiedName().get(0);
final String tableName = dml.getTable().getQualifiedName().get(1);
DMLStatement statement = null;
if (dml.getInput() instanceof EnumerableProject) {
// fastest path for insert into TABLE(s,b,c) values(?,?,?)
EnumerableProject project = (EnumerableProject) dml.getInput();
if (project.getInput() instanceof EnumerableValues) {
EnumerableValues values = (EnumerableValues) project.getInput();
if (values.getTuples().size() == 1) {
final TableImpl tableImpl = (TableImpl) dml.getTable().unwrap(org.apache.calcite.schema.Table.class);
Table table = tableImpl.tableManager.getTable();
int index = 0;
List<RexNode> projects = project.getProjects();
List<CompiledSQLExpression> keyValueExpression = new ArrayList<>();
List<String> keyExpressionToColumn = new ArrayList<>();
List<CompiledSQLExpression> valuesExpressions = new ArrayList<>();
List<String> valuesColumns = new ArrayList<>();
boolean invalid = false;
for (Column column : table.getColumns()) {
CompiledSQLExpression exp = SQLExpressionCompiler.compileExpression(projects.get(index));
if (exp instanceof ConstantExpression || exp instanceof JdbcParameterExpression || exp instanceof TypedJdbcParameterExpression) {
boolean isAlwaysNull = (exp instanceof ConstantExpression) && ((ConstantExpression) exp).isNull();
if (!isAlwaysNull) {
if (table.isPrimaryKeyColumn(column.name)) {
keyExpressionToColumn.add(column.name);
keyValueExpression.add(exp);
}
valuesColumns.add(column.name);
valuesExpressions.add(exp);
}
index++;
} else {
invalid = true;
break;
}
}
if (!invalid) {
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);
statement = new InsertStatement(tableSpace, tableName, keyfunction, valuesfunction).setReturnValues(returnValues);
}
}
}
}
if (statement != null) {
return new SimpleInsertOp(statement);
}
PlannerOp input = convertRelNode(dml.getInput(), null, false);
try {
return new InsertOp(tableSpace, tableName, input, returnValues);
} catch (IllegalArgumentException err) {
throw new StatementExecutionException(err);
}
}
use of herddb.model.DMLStatement in project herddb by diennea.
the class SQLPlanner method buildUpdateStatement.
private ExecutionPlan buildUpdateStatement(String defaultTableSpace, Update s, boolean returnValues) throws StatementExecutionException {
if (s.getTables().size() != 1) {
throw new StatementExecutionException("unsupported multi-table update " + s);
}
net.sf.jsqlparser.schema.Table fromTable = s.getTables().get(0);
String tableSpace = fromTable.getSchemaName();
String tableName = fromTable.getName();
if (tableSpace == null) {
tableSpace = defaultTableSpace;
}
TableSpaceManager tableSpaceManager = manager.getTableSpaceManager(tableSpace);
if (tableSpaceManager == null) {
throw new StatementExecutionException("no such tablespace " + tableSpace + " here at " + manager.getNodeId());
}
AbstractTableManager tableManager = tableSpaceManager.getTableManager(tableName);
if (tableManager == null) {
throw new StatementExecutionException("no such table " + tableName + " in tablespace " + tableSpace);
}
Table table = tableManager.getTable();
for (net.sf.jsqlparser.schema.Column c : s.getColumns()) {
Column column = table.getColumn(c.getColumnName());
if (column == null) {
throw new StatementExecutionException("no such column " + c.getColumnName() + " in table " + tableName + " in tablespace " + tableSpace);
}
if (table.isPrimaryKeyColumn(c.getColumnName())) {
throw new StatementExecutionException("updates of fields on the PK (" + Arrays.toString(table.primaryKey) + ") are not supported. Please perform a DELETE and than an INSERT");
}
}
List<CompiledSQLExpression> compiledSQLExpressions = new ArrayList<>();
for (Expression e : s.getExpressions()) {
compiledSQLExpressions.add(SQLExpressionCompiler.compileExpression(null, e));
}
RecordFunction function = new SQLRecordFunction(table, s.getColumns(), compiledSQLExpressions);
// Perform a scan and then update each row
SQLRecordPredicate where = s.getWhere() != null ? new SQLRecordPredicate(table, table.name, s.getWhere()) : null;
if (where != null) {
Expression expressionWhere = s.getWhere();
discoverIndexOperations(expressionWhere, table, table.name, where, tableSpaceManager);
}
DMLStatement st = new UpdateStatement(tableSpace, tableName, null, function, where).setReturnValues(returnValues);
return ExecutionPlan.simple(st);
}
Aggregations