private PlanBuilder appendProjections(PlanBuilder subPlan, Iterable<Expression> expressions) { TranslationMap translations = new TranslationMap(subPlan.getRelationPlan(), analysis); // Carry over the translations from the source because we are appending projections translations.copyMappingsFrom(subPlan.getTranslations()); ImmutableMap.Builder<Symbol, Expression> projections = ImmutableMap.builder(); // add an identity projection for underlying plan for (Symbol symbol : subPlan.getRoot().getOutputSymbols()) { Expression expression = new QualifiedNameReference(symbol.toQualifiedName()); projections.put(symbol, expression); } ImmutableMap.Builder<Symbol, Expression> newTranslations = ImmutableMap.builder(); for (Expression expression : expressions) { Symbol symbol = symbolAllocator.newSymbol(expression, analysis.getType(expression)); // TODO: CHECK IF THE REWRITE OF A SEMI JOINED EXPRESSION WILL WORK!!!!!!! projections.put(symbol, translations.rewrite(expression)); newTranslations.put(symbol, expression); } // Now append the new translations into the TranslationMap for (Map.Entry<Symbol, Expression> entry : newTranslations.build().entrySet()) { translations.put(entry.getValue(), entry.getKey()); } return new PlanBuilder( translations, new ProjectNode(idAllocator.getNextId(), subPlan.getRoot(), projections.build()), subPlan.getSampleWeight()); }
private PlanBuilder appendSemiJoin(PlanBuilder subPlan, InPredicate inPredicate) { TranslationMap translations = new TranslationMap(subPlan.getRelationPlan(), analysis); translations.copyMappingsFrom(subPlan.getTranslations()); subPlan = appendProjections(subPlan, ImmutableList.of(inPredicate.getValue())); Symbol sourceJoinSymbol = subPlan.translate(inPredicate.getValue()); checkState(inPredicate.getValueList() instanceof SubqueryExpression); SubqueryExpression subqueryExpression = (SubqueryExpression) inPredicate.getValueList(); RelationPlanner relationPlanner = new RelationPlanner(analysis, symbolAllocator, idAllocator, metadata, session); RelationPlan valueListRelation = relationPlanner.process(subqueryExpression.getQuery(), null); Symbol filteringSourceJoinSymbol = Iterables.getOnlyElement(valueListRelation.getRoot().getOutputSymbols()); Symbol semiJoinOutputSymbol = symbolAllocator.newSymbol("semijoinresult", BOOLEAN); translations.put(inPredicate, semiJoinOutputSymbol); return new PlanBuilder( translations, new SemiJoinNode( idAllocator.getNextId(), subPlan.getRoot(), valueListRelation.getRoot(), sourceJoinSymbol, filteringSourceJoinSymbol, semiJoinOutputSymbol, Optional.empty(), Optional.empty()), subPlan.getSampleWeight()); }
private RelationPlan planCrossJoinUnnest(RelationPlan leftPlan, Join joinNode, Unnest node) { TupleDescriptor outputDescriptor = analysis.getOutputDescriptor(joinNode); TupleDescriptor unnestOutputDescriptor = analysis.getOutputDescriptor(node); // Create symbols for the result of unnesting ImmutableList.Builder<Symbol> unnestedSymbolsBuilder = ImmutableList.builder(); for (Field field : unnestOutputDescriptor.getVisibleFields()) { Symbol symbol = symbolAllocator.newSymbol(field); unnestedSymbolsBuilder.add(symbol); } ImmutableList<Symbol> unnestedSymbols = unnestedSymbolsBuilder.build(); // Add a projection for all the unnest arguments PlanBuilder planBuilder = initializePlanBuilder(leftPlan); planBuilder = appendProjections(planBuilder, node.getExpressions()); TranslationMap translations = planBuilder.getTranslations(); ProjectNode projectNode = checkType(planBuilder.getRoot(), ProjectNode.class, "planBuilder.getRoot()"); ImmutableMap.Builder<Symbol, List<Symbol>> unnestSymbols = ImmutableMap.builder(); UnmodifiableIterator<Symbol> unnestedSymbolsIterator = unnestedSymbols.iterator(); for (Expression expression : node.getExpressions()) { Type type = analysis.getType(expression); Symbol inputSymbol = translations.get(expression); if (type instanceof ArrayType) { unnestSymbols.put(inputSymbol, ImmutableList.of(unnestedSymbolsIterator.next())); } else if (type instanceof MapType) { unnestSymbols.put( inputSymbol, ImmutableList.of(unnestedSymbolsIterator.next(), unnestedSymbolsIterator.next())); } else { throw new IllegalArgumentException("Unsupported type for UNNEST: " + type); } } Optional<Symbol> ordinalitySymbol = node.isWithOrdinality() ? Optional.of(unnestedSymbolsIterator.next()) : Optional.empty(); checkState( !unnestedSymbolsIterator.hasNext(), "Not all output symbols were matched with input symbols"); UnnestNode unnestNode = new UnnestNode( idAllocator.getNextId(), projectNode, leftPlan.getOutputSymbols(), unnestSymbols.build(), ordinalitySymbol); return new RelationPlan( unnestNode, outputDescriptor, unnestNode.getOutputSymbols(), Optional.empty()); }