use of io.crate.expression.symbol.ScopedSymbol in project crate by crate.
the class Rename method pruneOutputsExcept.
@Override
public LogicalPlan pruneOutputsExcept(TableStats tableStats, Collection<Symbol> outputsToKeep) {
/* In `SELECT * FROM (SELECT t1.*, t2.* FROM tbl AS t1, tbl AS t2) AS tjoin`
* The `ScopedSymbol`s are ambiguous; To map them correctly this uses a IdentityHashMap
*/
IdentityHashMap<Symbol, Symbol> parentToChildMap = new IdentityHashMap<>(outputs.size());
IdentityHashMap<Symbol, Symbol> childToParentMap = new IdentityHashMap<>(outputs.size());
for (int i = 0; i < outputs.size(); i++) {
parentToChildMap.put(outputs.get(i), source.outputs().get(i));
childToParentMap.put(source.outputs().get(i), outputs.get(i));
}
ArrayList<Symbol> mappedToKeep = new ArrayList<>();
for (Symbol outputToKeep : outputsToKeep) {
SymbolVisitors.intersection(outputToKeep, outputs, s -> {
Symbol childSymbol = parentToChildMap.get(s);
assert childSymbol != null : "There must be a mapping available for symbol " + s;
mappedToKeep.add(childSymbol);
});
}
LogicalPlan newSource = source.pruneOutputsExcept(tableStats, mappedToKeep);
if (newSource == source) {
return this;
}
ArrayList<Symbol> newOutputs = new ArrayList<>(newSource.outputs().size());
for (Symbol sourceOutput : newSource.outputs()) {
newOutputs.add(childToParentMap.get(sourceOutput));
}
return new Rename(newOutputs, name, fieldResolver, newSource);
}
use of io.crate.expression.symbol.ScopedSymbol in project crate by crate.
the class AliasedAnalyzedRelation method getField.
@Override
public Symbol getField(ColumnIdent column, Operation operation, boolean errorOnUnknownObjectKey) throws AmbiguousColumnException, ColumnUnknownException, UnsupportedOperationException {
if (operation != Operation.READ) {
throw new UnsupportedOperationException(operation + " is not supported on " + alias);
}
ColumnIdent childColumnName = aliasToColumnMapping.get(column);
if (childColumnName == null) {
if (column.isTopLevel()) {
return null;
}
childColumnName = aliasToColumnMapping.get(column.getRoot());
if (childColumnName == null) {
// The column ident maybe a quoted subscript which points to an alias of a sub relation.
// Aliases are always strings but due to the support for quoted subscript expressions,
// the select column ident may already be expanded to a subscript.
var maybeQuotedSubscriptColumnAlias = new ColumnIdent(column.sqlFqn());
childColumnName = aliasToColumnMapping.get(maybeQuotedSubscriptColumnAlias);
if (childColumnName == null) {
return null;
}
column = maybeQuotedSubscriptColumnAlias;
} else {
childColumnName = new ColumnIdent(childColumnName.name(), column.path());
}
}
Symbol field = relation.getField(childColumnName, operation, errorOnUnknownObjectKey);
if (field == null || field instanceof VoidReference) {
return field;
}
ScopedSymbol scopedSymbol = new ScopedSymbol(alias, column, field.valueType());
// If the scopedSymbol exists already, return that instance.
// Otherwise (e.g. lazy-loaded subscript expression) it must be stored to comply with
// IdentityHashMap constraints.
int i = scopedSymbols.indexOf(scopedSymbol);
if (i >= 0) {
return scopedSymbols.get(i);
}
scopedSymbols.add(scopedSymbol);
return scopedSymbol;
}
use of io.crate.expression.symbol.ScopedSymbol in project crate by crate.
the class MoveOrderBeneathNestedLoop method apply.
@Override
public LogicalPlan apply(Order order, Captures captures, TableStats tableStats, TransactionContext txnCtx, NodeContext nodeCtx) {
NestedLoopJoin nestedLoop = captures.get(nlCapture);
Set<RelationName> relationsInOrderBy = Collections.newSetFromMap(new IdentityHashMap<>());
Consumer<ScopedSymbol> gatherRelationsFromField = f -> relationsInOrderBy.add(f.relation());
Consumer<Reference> gatherRelationsFromRef = r -> relationsInOrderBy.add(r.ident().tableIdent());
OrderBy orderBy = order.orderBy();
for (Symbol orderExpr : orderBy.orderBySymbols()) {
FieldsVisitor.visitFields(orderExpr, gatherRelationsFromField);
RefVisitor.visitRefs(orderExpr, gatherRelationsFromRef);
}
if (relationsInOrderBy.size() == 1) {
RelationName relationInOrderBy = relationsInOrderBy.iterator().next();
if (relationInOrderBy == nestedLoop.topMostLeftRelation().relationName()) {
LogicalPlan lhs = nestedLoop.sources().get(0);
LogicalPlan newLhs = order.replaceSources(List.of(lhs));
return new NestedLoopJoin(newLhs, nestedLoop.sources().get(1), nestedLoop.joinType(), nestedLoop.joinCondition(), nestedLoop.isFiltered(), nestedLoop.topMostLeftRelation(), true, nestedLoop.isRewriteFilterOnOuterJoinToInnerJoinDone());
}
}
return null;
}
Aggregations