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()))); } }
private ResolvedField asResolvedField(Field field, int fieldIndexOffset, boolean local) { int relationFieldIndex = relation.indexOf(field); int hierarchyFieldIndex = relation.indexOf(field) + fieldIndexOffset; return new ResolvedField(this, field, hierarchyFieldIndex, relationFieldIndex, local); }
assertEquals(outer.tryResolveField(c1).get().getField(), outerColumn1); assertEquals(outer.tryResolveField(c1).get().isLocal(), true); assertEquals(outer.tryResolveField(c1).get().getHierarchyFieldIndex(), 0); assertTrue(outer.tryResolveField(c2).isPresent()); assertEquals(outer.tryResolveField(c2).get().getField(), outerColumn2); assertEquals(outer.tryResolveField(c2).get().isLocal(), true); assertEquals(outer.tryResolveField(c2).get().getHierarchyFieldIndex(), 1); assertFalse(outer.tryResolveField(c3).isPresent()); assertFalse(outer.tryResolveField(c4).isPresent()); assertEquals(inner.tryResolveField(c1).get().getField(), outerColumn1); assertEquals(inner.tryResolveField(c1).get().isLocal(), false); assertEquals(inner.tryResolveField(c1).get().getHierarchyFieldIndex(), 2); assertEquals(inner.tryResolveField(c1).get().getRelationFieldIndex(), 0); assertTrue(inner.tryResolveField(c2).isPresent()); assertEquals(inner.tryResolveField(c2).get().getField(), innerColumn2); assertEquals(inner.tryResolveField(c2).get().isLocal(), true); assertEquals(inner.tryResolveField(c2).get().getHierarchyFieldIndex(), 0); assertTrue(inner.tryResolveField(c2).isPresent()); assertEquals(inner.tryResolveField(c3).get().getField(), innerColumn3); assertEquals(inner.tryResolveField(c3).get().isLocal(), true); assertEquals(inner.tryResolveField(c3).get().getHierarchyFieldIndex(), 1); assertFalse(inner.tryResolveField(c4).isPresent());
leftField.get().getType(), rightField.get().getType())); Optional<Type> type = metadata.getTypeManager().getCommonSuperType(leftField.get().getType(), rightField.get().getType()); analysis.addTypes(ImmutableMap.of(NodeRef.of(column), type.get())); leftJoinFields.add(leftField.get().getRelationFieldIndex()); rightJoinFields.add(rightField.get().getRelationFieldIndex());
private Type handleResolvedField(Expression node, ResolvedField resolvedField, StackableAstVisitorContext<Context> context) { return handleResolvedField(node, FieldId.from(resolvedField), resolvedField.getField(), context); }
@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); }
@Override protected Type visitSymbolReference(SymbolReference node, StackableAstVisitorContext<Context> context) { if (context.getContext().isInLambda()) { Optional<ResolvedField> resolvedField = context.getContext().getScope().tryResolveField(node, QualifiedName.of(node.getName())); if (resolvedField.isPresent() && context.getContext().getFieldToLambdaArgumentDeclaration().containsKey(FieldId.from(resolvedField.get()))) { return setExpressionType(node, resolvedField.get().getType()); } } Type type = symbolTypes.get(Symbol.from(node)); return setExpressionType(node, type); }
.filter(resolvedField -> seen.add(resolvedField.getField())) .map(ResolvedField::getField); return sourceField
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); }