use of herddb.model.Column 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);
}
use of herddb.model.Column in project herddb by diennea.
the class SQLProjection method addExpressionsForFunctionArguments.
private static void addExpressionsForFunctionArguments(ColumnReferencesDiscovery discovery, List<OutputColumn> output, Table table) throws StatementExecutionException {
List<net.sf.jsqlparser.schema.Column> columns = discovery.getColumnsByTable().get(table.name);
if (columns != null) {
for (Expression e : columns) {
net.sf.jsqlparser.schema.Column c = (net.sf.jsqlparser.schema.Column) e;
String columnName = c.getColumnName();
boolean found = false;
for (OutputColumn outputColumn : output) {
if (columnName.equalsIgnoreCase(outputColumn.column.name)) {
found = true;
break;
} else if (outputColumn.directColumnReference != null && outputColumn.directColumnReference.getColumnName().equalsIgnoreCase(columnName)) {
found = true;
break;
}
}
if (!found) {
Column column = table.getColumn(c.getColumnName());
if (column == null) {
throw new StatementExecutionException("invalid column name " + c.getColumnName());
}
output.add(new OutputColumn(null, Column.column(columnName, column.type), c, null));
}
}
}
}
use of herddb.model.Column in project herddb by diennea.
the class SyscolumnsTableManager method buildVirtualRecordList.
@Override
protected Iterable<Record> buildVirtualRecordList(Transaction transaction) {
List<Table> tables = tableSpaceManager.getAllVisibleTables(transaction);
List<Record> result = new ArrayList<>();
for (Table t : tables) {
int pos = 1;
for (Column c : t.columns) {
boolean pk = t.isPrimaryKeyColumn(c.name);
boolean nonNullCType = pk || ColumnTypes.isNotNullDataType(c.type);
String defaultValue = Column.defaultValueToString(c);
result.add(RecordSerializer.makeRecord(table, "table_name", t.name, "column_name", c.name, "ordinal_position", pos++, "is_nullable", nonNullCType ? DatabaseMetaData.columnNoNulls : DatabaseMetaData.columnNullable, "data_type", ColumnTypes.sqlDataType(c.type), "type_name", ColumnTypes.typeToString(c.type), "auto_increment", (pk && t.auto_increment) ? 1 : 0, "default_value", defaultValue));
}
}
return result;
}
use of herddb.model.Column in project herddb by diennea.
the class CalcitePlanner method planEnumerableJoin.
private PlannerOp planEnumerableJoin(EnumerableHashJoin op, RelDataType rowType) {
// please note that EnumerableJoin has a condition field which actually is not useful
PlannerOp left = convertRelNode(op.getLeft(), null, false, false);
PlannerOp right = convertRelNode(op.getRight(), null, false, false);
final JoinInfo analyzeCondition = op.analyzeCondition();
int[] leftKeys = analyzeCondition.leftKeys.toIntArray();
int[] rightKeys = analyzeCondition.rightKeys.toIntArray();
boolean generateNullsOnLeft = op.getJoinType().generatesNullsOnLeft();
boolean generateNullsOnRight = op.getJoinType().generatesNullsOnRight();
List<CompiledSQLExpression> nonEquiConditions = convertJoinNonEquiConditions(analyzeCondition);
final RelDataType _rowType = rowType == null ? op.getRowType() : rowType;
List<RelDataTypeField> fieldList = _rowType.getFieldList();
Column[] columns = new Column[fieldList.size()];
String[] fieldNames = new String[columns.length];
int i = 0;
for (RelDataTypeField field : fieldList) {
Column col = Column.column(field.getName().toLowerCase(), convertToHerdType(field.getType()));
fieldNames[i] = col.name;
columns[i++] = col;
}
return new JoinOp(fieldNames, columns, leftKeys, left, rightKeys, right, generateNullsOnLeft, generateNullsOnRight, false, nonEquiConditions);
}
use of herddb.model.Column in project herddb by diennea.
the class InsertOp method executeAsync.
@Override
public CompletableFuture<StatementExecutionResult> executeAsync(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;
List<DMLStatement> statements = new ArrayList<>();
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, column.type);
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, upsert).setReturnValues(returnValues);
statements.add(insertStatement);
}
if (statements.isEmpty()) {
return CompletableFuture.completedFuture(new DMLStatementExecutionResult(transactionId, 0, null, null));
}
if (statements.size() == 1) {
return tableSpaceManager.executeStatementAsync(statements.get(0), context, transactionContext);
}
if (returnValues) {
return Futures.exception(new StatementExecutionException("cannot 'return values' on multi-values insert"));
}
CompletableFuture<StatementExecutionResult> finalResult = new CompletableFuture<>();
AtomicInteger updateCounts = new AtomicInteger();
AtomicReference<Bytes> lastKey = new AtomicReference<>();
AtomicReference<Bytes> lastNewValue = new AtomicReference<>();
class ComputeNext implements BiConsumer<StatementExecutionResult, Throwable> {
int current;
public ComputeNext(int current) {
this.current = current;
}
@Override
public void accept(StatementExecutionResult res, Throwable error) {
if (error != null) {
finalResult.completeExceptionally(error);
return;
}
DMLStatementExecutionResult dml = (DMLStatementExecutionResult) res;
updateCounts.addAndGet(dml.getUpdateCount());
if (returnValues) {
lastKey.set(dml.getKey());
lastNewValue.set(dml.getNewvalue());
}
long newTransactionId = res.transactionId;
if (current == statements.size()) {
DMLStatementExecutionResult finalDMLResult = new DMLStatementExecutionResult(newTransactionId, updateCounts.get(), lastKey.get(), lastNewValue.get());
finalResult.complete(finalDMLResult);
return;
}
DMLStatement nextStatement = statements.get(current);
TransactionContext transactionContext = new TransactionContext(newTransactionId);
CompletableFuture<StatementExecutionResult> nextPromise = tableSpaceManager.executeStatementAsync(nextStatement, context, transactionContext);
nextPromise.whenComplete(new ComputeNext(current + 1));
}
}
DMLStatement firstStatement = statements.get(0);
tableSpaceManager.executeStatementAsync(firstStatement, context, transactionContext).whenComplete(new ComputeNext(1));
return finalResult;
} catch (DataScannerException err) {
throw new StatementExecutionException(err);
}
}
Aggregations