private PlanBuilder planBuilderFor(PlanBuilder builder, Scope scope, Iterable<? extends Expression> expressionsToRemap) { Map<Expression, Symbol> expressionsToSymbols = symbolsForExpressions(builder, expressionsToRemap); PlanBuilder newBuilder = planBuilderFor(builder, scope); expressionsToSymbols.entrySet() .forEach(entry -> newBuilder.getTranslations().put(entry.getKey(), entry.getValue())); return newBuilder; }
private Map<Symbol, Expression> coerce(Iterable<? extends Expression> expressions, PlanBuilder subPlan, TranslationMap translations) { ImmutableMap.Builder<Symbol, Expression> projections = ImmutableMap.builder(); for (Expression expression : expressions) { Type type = analysis.getType(expression); Type coercion = analysis.getCoercion(expression); Symbol symbol = symbolAllocator.newSymbol(expression, firstNonNull(coercion, type)); Expression rewritten = subPlan.rewrite(expression); if (coercion != null) { rewritten = new Cast( rewritten, coercion.getTypeSignature().toString(), false, metadata.getTypeManager().isTypeOnlyCoercion(type, coercion)); } projections.put(symbol, rewritten); translations.put(expression, symbol); } return projections.build(); }
private PlanBuilder createPlanBuilder(Node node) { RelationPlan relationPlan = new RelationPlanner(analysis, symbolAllocator, idAllocator, lambdaDeclarationToSymbolMap, metadata, session) .process(node, null); TranslationMap translations = new TranslationMap(relationPlan, analysis, lambdaDeclarationToSymbolMap); // Make field->symbol mapping from underlying relation plan available for translations // This makes it possible to rewrite FieldOrExpressions that reference fields from the FROM clause directly translations.setFieldMappings(relationPlan.getFieldMappings()); if (node instanceof Expression && relationPlan.getFieldMappings().size() == 1) { translations.put((Expression) node, getOnlyElement(relationPlan.getFieldMappings())); } return new PlanBuilder(translations, relationPlan.getRoot(), analysis.getParameters()); }
for (Expression argument : arguments.build()) { Symbol symbol = subPlan.translate(argument); argumentTranslations.put(argument, symbol); aggregationArgumentsBuilder.add(symbol); Symbol input = subPlan.translate(expression); Symbol output = symbolAllocator.newSymbol(expression, analysis.getTypeWithCoercions(expression), "gid"); groupingTranslations.put(expression, output); groupingSetMappings.put(output, input); needPostProjectionCoercion = true; aggregationTranslations.put(aggregate, newSymbol);
public PlanBuilder appendProjections(Iterable<Expression> expressions, SymbolAllocator symbolAllocator, PlanNodeIdAllocator idAllocator) { TranslationMap translations = copyTranslations(); Assignments.Builder projections = Assignments.builder(); // add an identity projection for underlying plan for (Symbol symbol : getRoot().getOutputSymbols()) { projections.put(symbol, symbol.toSymbolReference()); } ImmutableMap.Builder<Symbol, Expression> newTranslations = ImmutableMap.builder(); for (Expression expression : expressions) { Symbol symbol = symbolAllocator.newSymbol(expression, getAnalysis().getTypeWithCoercions(expression)); 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(), getRoot(), projections.build()), parameters); } }
outputTranslations.put(windowFunction, newSymbol);
private PlanBuilder appendScalarSubqueryApplyNode(PlanBuilder subPlan, SubqueryExpression scalarSubquery, boolean correlationAllowed) { if (subPlan.canTranslate(scalarSubquery)) { // given subquery is already appended return subPlan; } List<Expression> coercions = coercionsFor(scalarSubquery); SubqueryExpression uncoercedScalarSubquery = uncoercedSubquery(scalarSubquery); PlanBuilder subqueryPlan = createPlanBuilder(uncoercedScalarSubquery); subqueryPlan = subqueryPlan.withNewRoot(new EnforceSingleRowNode(idAllocator.getNextId(), subqueryPlan.getRoot())); subqueryPlan = subqueryPlan.appendProjections(coercions, symbolAllocator, idAllocator); Symbol uncoercedScalarSubquerySymbol = subqueryPlan.translate(uncoercedScalarSubquery); subPlan.getTranslations().put(uncoercedScalarSubquery, uncoercedScalarSubquerySymbol); for (Expression coercion : coercions) { Symbol coercionSymbol = subqueryPlan.translate(coercion); subPlan.getTranslations().put(coercion, coercionSymbol); } return appendLateralJoin(subPlan, subqueryPlan, scalarSubquery.getQuery(), correlationAllowed, LateralJoinNode.Type.LEFT); }
private PlanBuilder handleGroupingOperations(PlanBuilder subPlan, QuerySpecification node, Optional<Symbol> groupIdSymbol, List<Set<FieldId>> groupingSets) { if (analysis.getGroupingOperations(node).isEmpty()) { return subPlan; } TranslationMap newTranslations = subPlan.copyTranslations(); Assignments.Builder projections = Assignments.builder(); projections.putIdentities(subPlan.getRoot().getOutputSymbols()); List<Set<Integer>> descriptor = groupingSets.stream() .map(set -> set.stream() .map(FieldId::getFieldIndex) .collect(toImmutableSet())) .collect(toImmutableList()); for (GroupingOperation groupingOperation : analysis.getGroupingOperations(node)) { Expression rewritten = GroupingOperationRewriter.rewriteGroupingOperation(groupingOperation, descriptor, analysis.getColumnReferenceFields(), groupIdSymbol); Type coercion = analysis.getCoercion(groupingOperation); Symbol symbol = symbolAllocator.newSymbol(rewritten, analysis.getTypeWithCoercions(groupingOperation)); if (coercion != null) { rewritten = new Cast( rewritten, coercion.getTypeSignature().toString(), false, metadata.getTypeManager().isTypeOnlyCoercion(analysis.getType(groupingOperation), coercion)); } projections.put(symbol, rewritten); newTranslations.put(groupingOperation, symbol); } return new PlanBuilder(newTranslations, new ProjectNode(idAllocator.getNextId(), subPlan.getRoot(), projections.build()), analysis.getParameters()); }
private PlanBuilder project(PlanBuilder subPlan, Iterable<Expression> expressions) { TranslationMap outputTranslations = new TranslationMap(subPlan.getRelationPlan(), analysis, lambdaDeclarationToSymbolMap); Assignments.Builder projections = Assignments.builder(); for (Expression expression : expressions) { if (expression instanceof SymbolReference) { Symbol symbol = Symbol.from(expression); projections.put(symbol, expression); outputTranslations.put(expression, symbol); continue; } Symbol symbol = symbolAllocator.newSymbol(expression, analysis.getTypeWithCoercions(expression)); projections.put(symbol, subPlan.rewrite(expression)); outputTranslations.put(expression, symbol); } return new PlanBuilder(outputTranslations, new ProjectNode( idAllocator.getNextId(), subPlan.getRoot(), projections.build()), analysis.getParameters()); }
private PlanBuilder appendInPredicateApplyNode(PlanBuilder subPlan, InPredicate inPredicate, boolean correlationAllowed, Node node) { if (subPlan.canTranslate(inPredicate)) { // given subquery is already appended return subPlan; } subPlan = handleSubqueries(subPlan, inPredicate.getValue(), node); subPlan = subPlan.appendProjections(ImmutableList.of(inPredicate.getValue()), symbolAllocator, idAllocator); checkState(inPredicate.getValueList() instanceof SubqueryExpression); SubqueryExpression valueListSubquery = (SubqueryExpression) inPredicate.getValueList(); SubqueryExpression uncoercedValueListSubquery = uncoercedSubquery(valueListSubquery); PlanBuilder subqueryPlan = createPlanBuilder(uncoercedValueListSubquery); subqueryPlan = subqueryPlan.appendProjections(ImmutableList.of(valueListSubquery), symbolAllocator, idAllocator); SymbolReference valueList = subqueryPlan.translate(valueListSubquery).toSymbolReference(); Symbol rewrittenValue = subPlan.translate(inPredicate.getValue()); InPredicate inPredicateSubqueryExpression = new InPredicate(rewrittenValue.toSymbolReference(), valueList); Symbol inPredicateSubquerySymbol = symbolAllocator.newSymbol(inPredicateSubqueryExpression, BOOLEAN); subPlan.getTranslations().put(inPredicate, inPredicateSubquerySymbol); return appendApplyNode(subPlan, inPredicate, subqueryPlan.getRoot(), Assignments.of(inPredicateSubquerySymbol, inPredicateSubqueryExpression), correlationAllowed); }
private PlanBuilder planQuantifiedApplyNode(PlanBuilder subPlan, QuantifiedComparisonExpression quantifiedComparison, boolean correlationAllowed) { subPlan = subPlan.appendProjections(ImmutableList.of(quantifiedComparison.getValue()), symbolAllocator, idAllocator); checkState(quantifiedComparison.getSubquery() instanceof SubqueryExpression); SubqueryExpression quantifiedSubquery = (SubqueryExpression) quantifiedComparison.getSubquery(); SubqueryExpression uncoercedQuantifiedSubquery = uncoercedSubquery(quantifiedSubquery); PlanBuilder subqueryPlan = createPlanBuilder(uncoercedQuantifiedSubquery); subqueryPlan = subqueryPlan.appendProjections(ImmutableList.of(quantifiedSubquery), symbolAllocator, idAllocator); QuantifiedComparisonExpression coercedQuantifiedComparison = new QuantifiedComparisonExpression( quantifiedComparison.getOperator(), quantifiedComparison.getQuantifier(), subPlan.translate(quantifiedComparison.getValue()).toSymbolReference(), subqueryPlan.translate(quantifiedSubquery).toSymbolReference()); Symbol coercedQuantifiedComparisonSymbol = symbolAllocator.newSymbol(coercedQuantifiedComparison, BOOLEAN); subPlan.getTranslations().put(quantifiedComparison, coercedQuantifiedComparisonSymbol); return appendApplyNode( subPlan, quantifiedComparison.getSubquery(), subqueryPlan.getRoot(), Assignments.of(coercedQuantifiedComparisonSymbol, coercedQuantifiedComparison), correlationAllowed); }
subPlan.getTranslations().put(quantifiedComparison, subPlan.translate(inPredicate)); return subPlan; Expression notAny = new NotExpression(rewrittenAny); subPlan.getTranslations().put(quantifiedComparison, subPlan.getTranslations().rewrite(notAny)); Expression notAll = new NotExpression(rewrittenAll); subPlan.getTranslations().put(quantifiedComparison, subPlan.getTranslations().rewrite(notAll));
private PlanBuilder explicitCoercionFields(PlanBuilder subPlan, Iterable<Expression> alreadyCoerced, Iterable<? extends Expression> uncoerced) { TranslationMap translations = new TranslationMap(subPlan.getRelationPlan(), analysis, lambdaDeclarationToSymbolMap); Assignments.Builder projections = Assignments.builder(); projections.putAll(coerce(uncoerced, subPlan, translations)); for (Expression expression : alreadyCoerced) { if (expression instanceof SymbolReference) { // If this is an identity projection, no need to rewrite it // This is needed because certain synthetic identity expressions such as "group id" introduced when planning GROUPING // don't have a corresponding analysis, so the code below doesn't work for them projections.put(Symbol.from(expression), expression); continue; } Symbol symbol = symbolAllocator.newSymbol(expression, analysis.getType(expression)); Expression rewritten = subPlan.rewrite(expression); projections.put(symbol, rewritten); translations.put(expression, symbol); } return new PlanBuilder(translations, new ProjectNode( idAllocator.getNextId(), subPlan.getRoot(), projections.build()), analysis.getParameters()); }
public void put(FieldOrExpression fieldOrExpression, Symbol symbol) { if (fieldOrExpression.isFieldReference()) { int fieldIndex = fieldOrExpression.getFieldIndex(); fieldSymbols[fieldIndex] = symbol; expressionMappings.put(new QualifiedNameReference(rewriteBase.getSymbol(fieldIndex).toQualifiedName()), symbol); } else { put(fieldOrExpression.getExpression(), symbol); } }
private PlanBuilder appendProjections(PlanBuilder subPlan, Iterable<Expression> expressions) { TranslationMap translations = copyTranslations(subPlan); 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)); 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 Map<Symbol, Expression> coerce(Iterable<? extends Expression> expressions, PlanBuilder subPlan, TranslationMap translations) { ImmutableMap.Builder<Symbol, Expression> projections = ImmutableMap.builder(); for (Expression expression : expressions) { Type type = analysis.getType(expression); Type coercion = analysis.getCoercion(expression); Symbol symbol = symbolAllocator.newSymbol(expression, firstNonNull(coercion, type)); Expression rewritten = subPlan.rewrite(expression); if (coercion != null) { rewritten = new Cast( rewritten, coercion.getTypeSignature().toString(), false, isTypeOnlyCoercion(type.getTypeSignature(), coercion.getTypeSignature())); } projections.put(symbol, rewritten); translations.put(expression, symbol); } return projections.build(); }
private PlanBuilder project(PlanBuilder subPlan, Iterable<FieldOrExpression> expressions) { TranslationMap outputTranslations = new TranslationMap(subPlan.getRelationPlan(), analysis); ImmutableMap.Builder<Symbol, Expression> projections = ImmutableMap.builder(); for (FieldOrExpression fieldOrExpression : expressions) { Symbol symbol; if (fieldOrExpression.isFieldReference()) { Field field = subPlan.getRelationPlan().getDescriptor().getFieldByIndex(fieldOrExpression.getFieldIndex()); symbol = symbolAllocator.newSymbol(field); } else { Expression expression = fieldOrExpression.getExpression(); symbol = symbolAllocator.newSymbol(expression, analysis.getType(expression)); } projections.put(symbol, subPlan.rewrite(fieldOrExpression)); outputTranslations.put(fieldOrExpression, symbol); } if (subPlan.getSampleWeight().isPresent()) { Symbol symbol = subPlan.getSampleWeight().get(); projections.put(symbol, new QualifiedNameReference(symbol.toQualifiedName())); } return new PlanBuilder(outputTranslations, 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 PlanBuilder explicitCoercionFields(PlanBuilder subPlan, Iterable<FieldOrExpression> alreadyCoerced, Iterable<? extends Expression> uncoerced) { TranslationMap translations = new TranslationMap(subPlan.getRelationPlan(), analysis); ImmutableMap.Builder<Symbol, Expression> projections = ImmutableMap.builder(); projections.putAll(coerce(uncoerced, subPlan, translations)); for (FieldOrExpression fieldOrExpression : alreadyCoerced) { Symbol symbol; if (fieldOrExpression.isFieldReference()) { Field field = subPlan.getRelationPlan().getDescriptor().getFieldByIndex(fieldOrExpression.getFieldIndex()); symbol = symbolAllocator.newSymbol(field); } else { symbol = symbolAllocator.newSymbol(fieldOrExpression.getExpression(), analysis.getType(fieldOrExpression.getExpression())); } Expression rewritten = subPlan.rewrite(fieldOrExpression); projections.put(symbol, rewritten); translations.put(fieldOrExpression, symbol); } return new PlanBuilder(translations, new ProjectNode(idAllocator.getNextId(), subPlan.getRoot(), projections.build()), subPlan.getSampleWeight()); }