public Builder put(String alias, SymbolReference symbolReference) { requireNonNull(alias, "alias is null"); requireNonNull(symbolReference, "symbolReference is null"); alias = toKey(alias); // Special case to allow identity binding (i.e. "ALIAS" -> expression("ALIAS")) if (bindings.containsKey(alias) && bindings.get(alias).equals(symbolReference)) { return this; } checkState(!bindings.containsKey(alias), "Alias '%s' already bound to expression '%s'. Tried to rebind to '%s'", alias, bindings.get(alias), symbolReference); bindings.put(alias, symbolReference); return this; }
@Override protected Boolean visitSymbolReference(SymbolReference actual, Node expected) { if (!(expected instanceof SymbolReference)) { return false; } return symbolAliases.get(((SymbolReference) expected).getName()).equals(actual); }
ImmutableList.Builder<Expression> arguments = ImmutableList.builder(); for (Expression argument : functionCall.getArguments()) { if (distinctSymbol.toSymbolReference().equals(argument)) { arguments.add(duplicatedDistinctSymbol.toSymbolReference());
private Map<String, SymbolReference> getUpdatedAssignments(Assignments assignments) { ImmutableMap.Builder<String, SymbolReference> mapUpdate = ImmutableMap.builder(); for (Map.Entry<Symbol, Expression> assignment : assignments.getMap().entrySet()) { for (Map.Entry<String, SymbolReference> existingAlias : map.entrySet()) { if (assignment.getValue().equals(existingAlias.getValue())) { // Simple symbol rename mapUpdate.put(existingAlias.getKey(), assignment.getKey().toSymbolReference()); } else if (assignment.getKey().toSymbolReference().equals(existingAlias.getValue())) { /* * Special case for nodes that can alias symbols in the node's assignment map. * In this case, we've already added the alias in the map, but we won't include it * as a simple rename as covered above. Add the existing alias to the result if * the LHS of the assignment matches the symbol reference of the existing alias. * * This comes up when we alias expressions in project nodes for use further up the tree. * At the beginning for the function, map contains { NEW_ALIAS: SymbolReference("expr_2" } * and the assignments map contains { expr_2 := <some expression> }. */ mapUpdate.put(existingAlias.getKey(), existingAlias.getValue()); } } } return mapUpdate.build(); }
@Override public MatchResult detailMatches(PlanNode node, StatsProvider stats, Session session, Metadata metadata, SymbolAliases symbolAliases) { checkState( shapeMatches(node), "Plan testing framework error: shapeMatches returned false in detailMatches in %s", this.getClass().getName()); List<Symbol> actualCorrelation = getCorrelation(node); if (this.correlation.size() != actualCorrelation.size()) { return NO_MATCH; } int i = 0; for (String alias : this.correlation) { if (!symbolAliases.get(alias).equals(actualCorrelation.get(i++).toSymbolReference())) { return NO_MATCH; } } return match(); }
@Override public MatchResult detailMatches(PlanNode node, StatsProvider stats, Session session, Metadata metadata, SymbolAliases symbolAliases) { checkState(shapeMatches(node), "Plan testing framework error: shapeMatches returned false in detailMatches in %s", this.getClass().getName()); SemiJoinNode semiJoinNode = (SemiJoinNode) node; if (!(symbolAliases.get(sourceSymbolAlias).equals(semiJoinNode.getSourceJoinSymbol().toSymbolReference()) && symbolAliases.get(filteringSymbolAlias).equals(semiJoinNode.getFilteringSourceJoinSymbol().toSymbolReference()))) { return NO_MATCH; } if (distributionType.isPresent() && !distributionType.equals(semiJoinNode.getDistributionType())) { return NO_MATCH; } return match(outputAlias, semiJoinNode.getSemiJoinOutput().toSymbolReference()); }