use of herddb.sql.expressions.CompiledSQLExpression in project herddb by diennea.
the class CalcitePlanner method buildProjection.
private Projection buildProjection(final List<RexNode> projects, final RelDataType rowType, final boolean allowIdentity, final Column[] tableSchema) {
boolean allowZeroCopyProjection = true;
List<CompiledSQLExpression> fields = new ArrayList<>(projects.size());
Column[] columns = new Column[projects.size()];
String[] fieldNames = new String[columns.length];
int i = 0;
int[] zeroCopyProjections = new int[fieldNames.length];
boolean identity = allowIdentity && tableSchema != null && tableSchema.length == fieldNames.length;
for (RexNode node : projects) {
CompiledSQLExpression exp = SQLExpressionCompiler.compileExpression(node);
if (exp instanceof AccessCurrentRowExpression) {
AccessCurrentRowExpression accessCurrentRowExpression = (AccessCurrentRowExpression) exp;
int mappedIndex = accessCurrentRowExpression.getIndex();
zeroCopyProjections[i] = mappedIndex;
if (i != mappedIndex) {
identity = false;
}
} else {
allowZeroCopyProjection = false;
}
fields.add(exp);
Column col = Column.column(rowType.getFieldNames().get(i).toLowerCase(), convertToHerdType(node.getType()));
identity = identity && col.name.equals(tableSchema[i].name);
fieldNames[i] = col.name;
columns[i++] = col;
}
if (allowZeroCopyProjection) {
if (identity) {
return Projection.IDENTITY(fieldNames, columns);
}
return new ProjectOp.ZeroCopyProjection(fieldNames, columns, zeroCopyProjections);
} else {
return new ProjectOp.BasicProjection(fieldNames, columns, fields);
}
}
use of herddb.sql.expressions.CompiledSQLExpression in project herddb by diennea.
the class CalcitePlanner method planUpdate.
private PlannerOp planUpdate(EnumerableTableModify dml, boolean returnValues) {
PlannerOp input = convertRelNode(dml.getInput(), null, false, false);
List<String> updateColumnList = dml.getUpdateColumnList();
List<RexNode> sourceExpressionList = dml.getSourceExpressionList();
final String tableSpace = dml.getTable().getQualifiedName().get(0);
final String tableName = dml.getTable().getQualifiedName().get(1);
final TableImpl tableImpl = (TableImpl) dml.getTable().unwrap(org.apache.calcite.schema.Table.class);
Table table = tableImpl.tableManager.getTable();
List<CompiledSQLExpression> expressionsForValue = new ArrayList<>(sourceExpressionList.size());
List<CompiledSQLExpression> expressionsForKey = new ArrayList<>(sourceExpressionList.size());
List<String> updateColumnListInValue = new ArrayList<>(updateColumnList.size());
List<String> updateColumnListInPk = new ArrayList<>();
for (int i = 0; i < updateColumnList.size(); i++) {
String columnName = updateColumnList.get(i);
boolean isPk = table.isPrimaryKeyColumn(columnName);
RexNode node = sourceExpressionList.get(i);
CompiledSQLExpression exp = SQLExpressionCompiler.compileExpression(node);
if (isPk) {
updateColumnListInPk.add(columnName);
expressionsForKey.add(exp);
} else {
updateColumnListInValue.add(columnName);
expressionsForValue.add(exp);
}
}
if (expressionsForKey.isEmpty()) {
// standard UPDATE, we are not updating any column in the PK
RecordFunction function = new SQLRecordFunction(updateColumnListInValue, table, expressionsForValue);
UpdateStatement update = null;
if (input instanceof TableScanOp) {
update = new UpdateStatement(tableSpace, tableName, null, function, null);
} else if (input instanceof FilterOp) {
FilterOp filter = (FilterOp) input;
if (filter.getInput() instanceof TableScanOp) {
SQLRecordPredicate pred = new SQLRecordPredicate(table, null, filter.getCondition());
update = new UpdateStatement(tableSpace, tableName, null, function, pred);
}
} else if (input instanceof ProjectOp) {
ProjectOp proj = (ProjectOp) input;
if (proj.getInput() instanceof TableScanOp) {
update = new UpdateStatement(tableSpace, tableName, null, function, null);
} else if (proj.getInput() instanceof FilterOp) {
FilterOp filter = (FilterOp) proj.getInput();
if (filter.getInput() instanceof TableScanOp) {
SQLRecordPredicate pred = new SQLRecordPredicate(table, null, filter.getCondition());
update = new UpdateStatement(tableSpace, tableName, null, function, pred);
}
} else if (proj.getInput() instanceof FilteredTableScanOp) {
FilteredTableScanOp filter = (FilteredTableScanOp) proj.getInput();
Predicate pred = filter.getPredicate();
update = new UpdateStatement(tableSpace, tableName, null, function, pred);
} else if (proj.getInput() instanceof BindableTableScanOp) {
BindableTableScanOp filter = (BindableTableScanOp) proj.getInput();
ScanStatement scan = filter.getStatement();
if (scan.getComparator() == null && scan.getLimits() == null && scan.getTableDef() != null) {
Predicate pred = scan.getPredicate();
update = new UpdateStatement(tableSpace, tableName, null, function, pred);
}
}
}
if (update != null) {
return new SimpleUpdateOp(update.setReturnValues(returnValues));
} else {
return new UpdateOp(tableSpace, tableName, input, returnValues, function);
}
} else {
// bad stuff ! we are updating the PK, we need to transform this to a sequence of delete and inserts
// ReplaceOp won't execute the two statements atomically
RecordFunction functionForValue = new SQLRecordFunction(updateColumnListInValue, table, expressionsForValue);
SQLRecordKeyFunction functionForKey = new SQLRecordKeyFunction(updateColumnListInPk, expressionsForKey, table);
return new ReplaceOp(tableSpace, tableName, input, returnValues, functionForKey, functionForValue);
}
}
use of herddb.sql.expressions.CompiledSQLExpression in project herddb by diennea.
the class CalcitePlanner method planLimit.
private PlannerOp planLimit(EnumerableLimit op, RelDataType rowType) {
PlannerOp input = convertRelNode(op.getInput(), rowType, false, false);
CompiledSQLExpression maxRows = SQLExpressionCompiler.compileExpression(op.fetch);
CompiledSQLExpression offset = SQLExpressionCompiler.compileExpression(op.offset);
return new LimitOp(input, maxRows, offset);
}
use of herddb.sql.expressions.CompiledSQLExpression in project herddb by diennea.
the class CalcitePlanner method planValues.
private PlannerOp planValues(EnumerableValues op) {
List<List<CompiledSQLExpression>> tuples = new ArrayList<>(op.getTuples().size());
RelDataType rowType = op.getRowType();
List<RelDataTypeField> fieldList = rowType.getFieldList();
Column[] columns = new Column[fieldList.size()];
for (ImmutableList<RexLiteral> tuple : op.getTuples()) {
List<CompiledSQLExpression> row = new ArrayList<>(tuple.size());
for (RexLiteral node : tuple) {
CompiledSQLExpression exp = SQLExpressionCompiler.compileExpression(node);
row.add(exp);
}
tuples.add(row);
}
int i = 0;
String[] fieldNames = new String[fieldList.size()];
for (RelDataTypeField field : fieldList) {
Column col = Column.column(field.getName(), convertToHerdType(field.getType()));
fieldNames[i] = field.getName();
columns[i++] = col;
}
return new ValuesOp(manager.getNodeId(), fieldNames, columns, tuples);
}
use of herddb.sql.expressions.CompiledSQLExpression in project herddb by diennea.
the class CalcitePlanner method planEnumerableNestedLoopJoin.
private PlannerOp planEnumerableNestedLoopJoin(EnumerableNestedLoopJoin op, RelDataType rowType) {
PlannerOp left = convertRelNode(op.getLeft(), null, false, false);
PlannerOp right = convertRelNode(op.getRight(), null, false, false);
CompiledSQLExpression condition = SQLExpressionCompiler.compileExpression(op.getCondition());
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 NestedLoopJoinOp(fieldNames, columns, left, right, condition, op.getJoinType(), false);
}
Aggregations