private Optional<Symbol> getSymbol(RelationPlan plan, Expression expression) { if (!analysis.isColumnReference(expression)) { // Expression can be a reference to lambda argument (or DereferenceExpression based on lambda argument reference). // In such case, the expression might still be resolvable with plan.getScope() but we should not resolve it. return Optional.empty(); } return plan.getScope() .tryResolveField(expression) .filter(ResolvedField::isLocal) .map(field -> requireNonNull(plan.getFieldMappings().get(field.getHierarchyFieldIndex()))); } }
public void put(Expression expression, Symbol symbol) { if (expression instanceof FieldReference) { int fieldIndex = ((FieldReference) expression).getFieldIndex(); fieldSymbols[fieldIndex] = symbol; expressionToSymbols.put(rewriteBase.getSymbol(fieldIndex).toSymbolReference(), symbol); return; } Expression translated = translateNamesToSymbols(expression); expressionToSymbols.put(translated, symbol); // also update the field mappings if this expression is a field reference rewriteBase.getScope().tryResolveField(expression) .filter(ResolvedField::isLocal) .ifPresent(field -> fieldSymbols[field.getHierarchyFieldIndex()] = symbol); }
@Override public Expression rewriteDereferenceExpression(DereferenceExpression node, Void context, ExpressionTreeRewriter<Void> treeRewriter) { if (analysis.isColumnReference(node)) { Optional<ResolvedField> resolvedField = rewriteBase.getScope().tryResolveField(node); if (resolvedField.isPresent()) { if (resolvedField.get().isLocal()) { return getSymbol(rewriteBase, node) .map(symbol -> coerceIfNecessary(node, symbol.toSymbolReference())) .orElseThrow(() -> new IllegalStateException("No symbol mapping for node " + node)); } } // do not rewrite outer references, it will be handled in outer scope planner return node; } return rewriteExpression(node, context, treeRewriter); }