use of herddb.model.StatementEvaluationContext in project herddb by diennea.
the class TableManager method executeStatementAsync.
@Override
public CompletableFuture<StatementExecutionResult> executeStatementAsync(Statement statement, Transaction transaction, StatementEvaluationContext context) {
CompletableFuture<StatementExecutionResult> res;
long lockStamp = checkpointLock.readLock();
if (statement instanceof UpdateStatement) {
UpdateStatement update = (UpdateStatement) statement;
res = executeUpdateAsync(update, transaction, context);
} else if (statement instanceof InsertStatement) {
InsertStatement insert = (InsertStatement) statement;
res = executeInsertAsync(insert, transaction, context);
} else if (statement instanceof GetStatement) {
GetStatement get = (GetStatement) statement;
res = executeGetAsync(get, transaction, context);
} else if (statement instanceof DeleteStatement) {
DeleteStatement delete = (DeleteStatement) statement;
res = executeDeleteAsync(delete, transaction, context);
} else if (statement instanceof TruncateTableStatement) {
try {
TruncateTableStatement truncate = (TruncateTableStatement) statement;
res = CompletableFuture.completedFuture(executeTruncate(truncate, transaction, context));
} catch (StatementExecutionException err) {
LOGGER.log(Level.SEVERE, "Truncate table failed", err);
res = Futures.exception(err);
}
} else if (statement instanceof TableConsistencyCheckStatement) {
DBManager manager = this.tableSpaceManager.getDbmanager();
res = CompletableFuture.completedFuture(manager.createTableCheckSum((TableConsistencyCheckStatement) statement, context));
} else {
res = Futures.exception(new StatementExecutionException("not implemented " + statement.getClass()));
}
res = res.whenComplete((r, error) -> {
checkpointLock.unlockRead(lockStamp);
});
if (statement instanceof TruncateTableStatement) {
res = res.whenComplete((r, error) -> {
if (error == null) {
try {
flush();
} catch (DataStorageManagerException err) {
throw new HerdDBInternalException(new StatementExecutionException("internal data error: " + err, err));
}
}
});
}
return res;
}
use of herddb.model.StatementEvaluationContext in project herddb by diennea.
the class TableManager method checkForeignKeyConstraintsAsChildTable.
private void checkForeignKeyConstraintsAsChildTable(ForeignKeyDef fk, DataAccessor values, StatementEvaluationContext context, Transaction transaction) throws StatementExecutionException {
// We are creating a SQL query and then using DBManager
// using an SQL query will let us leverage the SQL Planner
// and use the best index to perform the execution
// the SQL Planner will cache the plan, and the plan will also be
// invalidated consistently during DML operations.
String query = childForeignKeyQueries.computeIfAbsent(fk.name, (l -> {
Table parentTable = tableSpaceManager.getTableManagerByUUID(fk.parentTableId).getTable();
// with '*' we are not going to perform projections or copies
StringBuilder q = new StringBuilder("SELECT * FROM ");
q.append(delimit(parentTable.tablespace));
q.append(".");
q.append(delimit(parentTable.name));
q.append(" WHERE ");
for (int i = 0; i < fk.parentTableColumns.length; i++) {
if (i > 0) {
q.append(" AND ");
}
q.append(delimit(fk.parentTableColumns[i]));
q.append("=?");
}
return q.toString();
}));
final List<Object> valuesToMatch = new ArrayList<>(fk.columns.length);
boolean allNulls = true;
for (int i = 0; i < fk.columns.length; i++) {
Object value = values.get(fk.columns[i]);
allNulls = allNulls && value == null;
valuesToMatch.add(value);
}
if (allNulls) {
// all of the values are null, so no check on the parent table
return;
}
TransactionContext tx = transaction != null ? new TransactionContext(transaction.transactionId) : TransactionContext.NO_TRANSACTION;
boolean fkOk;
try (DataScanner scan = tableSpaceManager.getDbmanager().executeSimpleQuery(tableSpaceManager.getTableSpaceName(), query, valuesToMatch, // only one record
1, // keep read locks in TransactionContext
true, tx, null)) {
List<DataAccessor> resultSet = scan.consume();
fkOk = !resultSet.isEmpty();
} catch (DataScannerException err) {
throw new StatementExecutionException(err);
}
if (!fkOk) {
throw new ForeignKeyViolationException(fk.name, "foreignKey " + table.name + "." + fk.name + " violated");
}
}
use of herddb.model.StatementEvaluationContext in project herddb by diennea.
the class AbstractSystemTableManager method scan.
@Override
public DataScanner scan(ScanStatement statement, StatementEvaluationContext context, Transaction transaction, boolean lockRequired, boolean forWrite) throws StatementExecutionException {
Predicate predicate = statement.getPredicate();
MaterializedRecordSet recordSet = tableSpaceManager.getDbmanager().getRecordSetFactory().createRecordSet(table.columnNames, table.columns);
Iterable<Record> data = buildVirtualRecordList(transaction);
StreamSupport.stream(data.spliterator(), false).filter(record -> {
return (predicate == null || predicate.evaluate(record, context));
}).sorted(// enforce sort by PK
sortByPk).map(r -> r.getDataAccessor(table)).forEach(recordSet::add);
recordSet.writeFinished();
recordSet.sort(statement.getComparator());
recordSet.applyLimits(statement.getLimits(), context);
recordSet.applyProjection(statement.getProjection(), context);
return new SimpleDataScanner(transaction, recordSet);
}
use of herddb.model.StatementEvaluationContext in project herddb by diennea.
the class SQLRecordFunction method computeNewValue.
@Override
public byte[] computeNewValue(Record previous, StatementEvaluationContext context, TableContext tableContext) throws StatementExecutionException {
try {
if (previous != null) {
Map<String, Object> asMap = previous.toBean(table);
DataAccessor bean = previous.getDataAccessor(table);
Function<String, Object> fieldValueComputer = (columnName) -> {
CompiledSQLExpression e = expressionsByColumnName.get(columnName);
if (e == null) {
return asMap.get(columnName);
} else {
herddb.model.Column column = table.getColumn(columnName);
if (column == null) {
throw new StatementExecutionException("unknown column " + columnName + " in table " + table.name);
}
try {
return RecordSerializer.convert(column.type, e.evaluate(bean, context));
} catch (StatementExecutionException err) {
throw new StatementExecutionException("error on column " + column.name + " (" + ColumnTypes.typeToString(column.type) + "):" + err.getMessage(), err);
}
}
};
return RecordSerializer.buildRecord(previous.value != null ? previous.value.getLength() : 0, table, fieldValueComputer);
} else {
Function<String, Object> fieldValueComputer = (columnName) -> {
CompiledSQLExpression e = expressionsByColumnName.get(columnName);
if (e == null) {
return null;
} else {
herddb.model.Column column = table.getColumn(columnName);
if (column == null) {
throw new StatementExecutionException("unknown column " + columnName + " in table " + table.name);
}
try {
return RecordSerializer.convert(column.type, e.evaluate(DataAccessor.NULL, context));
} catch (StatementExecutionException err) {
throw new StatementExecutionException("error on column " + column.name + " (" + ColumnTypes.typeToString(column.type) + "):" + err.getMessage(), err);
}
}
};
return RecordSerializer.buildRecord(0, table, fieldValueComputer);
}
} catch (IllegalArgumentException err) {
throw new StatementExecutionException(err);
}
}
use of herddb.model.StatementEvaluationContext in project herddb by diennea.
the class RecordSetSuite method testApplyProjectionNoSwap.
@Test
public void testApplyProjectionNoSwap() throws Exception {
RecordSetFactory factory = buildRecordSetFactory(Integer.MAX_VALUE);
Column[] columns = new Column[2];
columns[0] = Column.column("s1", ColumnTypes.STRING);
columns[1] = Column.column("n1", ColumnTypes.LONG);
Set<String> expected_s2 = new HashSet<>();
Set<Integer> expected_n2 = new HashSet<>();
String[] fieldNames = Column.buildFieldNamesList(columns);
try (MaterializedRecordSet rs = factory.createRecordSet(fieldNames, columns)) {
for (int i = 0; i < 100; i++) {
Map<String, Object> record = new HashMap<>();
String s1 = "test_" + i;
record.put("s1", s1);
record.put("n1", i);
expected_s2.add(s1);
expected_n2.add(i);
rs.add(new Tuple(record, fieldNames));
}
rs.writeFinished();
Column[] columns_projected = new Column[2];
columns_projected[0] = Column.column("n2", ColumnTypes.LONG);
columns_projected[1] = Column.column("s2", ColumnTypes.STRING);
String[] fieldNames_projected = new String[] { "n2", "s2" };
rs.applyProjection(new Projection() {
@Override
public Column[] getColumns() {
return columns_projected;
}
@Override
public String[] getFieldNames() {
return fieldNames_projected;
}
@Override
public Tuple map(DataAccessor tuple, StatementEvaluationContext context) throws StatementExecutionException {
Object[] projected_values = new Object[2];
projected_values[0] = tuple.get("n1");
projected_values[1] = tuple.get("s1");
return new Tuple(fieldNames_projected, projected_values);
}
}, StatementEvaluationContext.DEFAULT_EVALUATION_CONTEXT());
for (DataAccessor t : rs) {
expected_s2.remove(t.get("s2"));
expected_n2.remove(t.get("n2"));
}
assertTrue(expected_s2.isEmpty());
assertTrue(expected_n2.isEmpty());
assertEquals("n2", rs.getColumns()[0].name);
assertEquals("s2", rs.getColumns()[1].name);
}
}
Aggregations