for (Map.Entry<Symbol, Expression> entry : node.getOutputMap().entrySet()) {
Expression expression = canonicalize(entry.getValue());
if (entry.getValue() instanceof QualifiedNameReference) {
// Always map a trivial symbol projection
Symbol symbol = Symbol.fromQualifiedName(((QualifiedNameReference) entry.getValue()).getName());
if (!symbol.equals(entry.getKey())) {
map(entry.getKey(), symbol);
}
}
else if (DeterminismEvaluator.isDeterministic(expression) && !(expression instanceof NullLiteral)) {
// Try to map same deterministic expressions within a projection into the same symbol
// Omit NullLiterals since those have ambiguous types
Symbol computedSymbol = computedExpressions.get(expression);
if (computedSymbol == null) {
// If we haven't seen the expression before in this projection, record it
computedExpressions.put(expression, entry.getKey());
}
else {
// If we have seen the expression before and if it is deterministic
// then we can rewrite references to the current symbol in terms of the parallel computedSymbol in the projection
map(entry.getKey(), computedSymbol);
}
}
Symbol canonical = canonicalize(entry.getKey());
if (!assignments.containsKey(canonical)) {
assignments.put(canonical, expression);
}
}