private PlanBuilder limit(PlanBuilder subPlan, List<SortItem> orderBy, Optional<String> limit) { if (orderBy.isEmpty() && limit.isPresent()) { if (limit.get().equalsIgnoreCase("all")) { return subPlan; } else { long limitValue = Long.parseLong(limit.get()); return new PlanBuilder(subPlan.getTranslations(), new LimitNode(idAllocator.getNextId(), subPlan.getRoot(), limitValue), subPlan.getSampleWeight()); } } return subPlan; }
@Override protected RelationPlan visitQuery(Query node, Void context) { Optional<Double> approximationConfidence = node.getApproximate().map(Approximate::getConfidence).map(confidence -> Double.valueOf(confidence) / 100.0); PlanBuilder subPlan = new QueryPlanner(analysis, symbolAllocator, idAllocator, metadata, session, approximationConfidence).process(node, null); ImmutableList.Builder<Symbol> outputSymbols = ImmutableList.builder(); for (FieldOrExpression fieldOrExpression : analysis.getOutputExpressions(node)) { outputSymbols.add(subPlan.translate(fieldOrExpression)); } return new RelationPlan(subPlan.getRoot(), analysis.getOutputDescriptor(node), outputSymbols.build(), subPlan.getSampleWeight()); }
@Override protected RelationPlan visitQuerySpecification(QuerySpecification node, Void context) { PlanBuilder subPlan = new QueryPlanner(analysis, symbolAllocator, idAllocator, metadata, session, Optional.empty()).process(node, null); ImmutableList.Builder<Symbol> outputSymbols = ImmutableList.builder(); for (FieldOrExpression fieldOrExpression : analysis.getOutputExpressions(node)) { outputSymbols.add(subPlan.translate(fieldOrExpression)); } return new RelationPlan(subPlan.getRoot(), analysis.getOutputDescriptor(node), outputSymbols.build(), subPlan.getSampleWeight()); }
private PlanBuilder sort(PlanBuilder subPlan, List<SortItem> orderBy, Optional<String> limit, List<FieldOrExpression> orderByExpressions) { if (orderBy.isEmpty()) { return subPlan; } Iterator<SortItem> sortItems = orderBy.iterator(); ImmutableList.Builder<Symbol> orderBySymbols = ImmutableList.builder(); Map<Symbol, SortOrder> orderings = new HashMap<>(); for (FieldOrExpression fieldOrExpression : orderByExpressions) { Symbol symbol = subPlan.translate(fieldOrExpression); SortItem sortItem = sortItems.next(); if (!orderings.containsKey(symbol)) { orderBySymbols.add(symbol); orderings.put(symbol, toSortOrder(sortItem)); } } PlanNode planNode; if (limit.isPresent() && !limit.get().equalsIgnoreCase("all")) { planNode = new TopNNode(idAllocator.getNextId(), subPlan.getRoot(), Long.parseLong(limit.get()), orderBySymbols.build(), orderings, false); } else { planNode = new SortNode(idAllocator.getNextId(), subPlan.getRoot(), orderBySymbols.build(), orderings); } return new PlanBuilder(subPlan.getTranslations(), planNode, subPlan.getSampleWeight()); }
private PlanBuilder distinct(PlanBuilder subPlan, QuerySpecification node, List<FieldOrExpression> outputs, List<FieldOrExpression> orderBy) { if (node.getSelect().isDistinct()) { checkState(outputs.containsAll(orderBy), "Expected ORDER BY terms to be in SELECT. Broken analysis"); AggregationNode aggregation = new AggregationNode(idAllocator.getNextId(), subPlan.getRoot(), subPlan.getRoot().getOutputSymbols(), ImmutableMap.<Symbol, FunctionCall>of(), ImmutableMap.<Symbol, Signature>of(), ImmutableMap.<Symbol, Symbol>of(), AggregationNode.Step.SINGLE, Optional.empty(), 1.0, Optional.empty()); return new PlanBuilder(subPlan.getTranslations(), aggregation, subPlan.getSampleWeight()); } return subPlan; }
private PlanBuilder explicitCoercionSymbols(PlanBuilder subPlan, Iterable<Symbol> alreadyCoerced, Iterable<? extends Expression> uncoerced) { TranslationMap translations = copyTranslations(subPlan); ImmutableMap.Builder<Symbol, Expression> projections = ImmutableMap.builder(); projections.putAll(coerce(uncoerced, subPlan, translations)); for (Symbol symbol : alreadyCoerced) { projections.put(symbol, new QualifiedNameReference(symbol.toQualifiedName())); } return new PlanBuilder(translations, new ProjectNode(idAllocator.getNextId(), subPlan.getRoot(), projections.build()), subPlan.getSampleWeight()); }
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 PlanBuilder appendScalarSubqueryJoin(PlanBuilder builder, SubqueryExpression scalarSubquery) { EnforceSingleRowNode enforceSingleRowNode = new EnforceSingleRowNode(idAllocator.getNextId(), createRelationPlan(scalarSubquery).getRoot()); TranslationMap translations = copyTranslations(builder); translations.put(scalarSubquery, getOnlyElement(enforceSingleRowNode.getOutputSymbols())); // Cross join current (root) relation with subquery PlanNode root = builder.getRoot(); if (root.getOutputSymbols().isEmpty()) { // there is nothing to join with - e.g. SELECT (SELECT 1) return new PlanBuilder(translations, enforceSingleRowNode, builder.getSampleWeight()); } else { return new PlanBuilder(translations, new JoinNode(idAllocator.getNextId(), JoinNode.Type.FULL, root, enforceSingleRowNode, ImmutableList.of(), Optional.empty(), Optional.empty()), builder.getSampleWeight()); } }
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 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()); }
Symbol groupIdSymbol = symbolAllocator.newSymbol("groupId", BIGINT); GroupIdNode groupId = new GroupIdNode(idAllocator.getNextId(), subPlan.getRoot(), subPlan.getRoot().getOutputSymbols(), groupingSetsSymbolsBuilder.build(), groupIdSymbol); subPlan = new PlanBuilder(subPlan.getTranslations(), groupId, subPlan.getSampleWeight()); distinctGroupingSymbolsBuilder.add(groupIdSymbol); builder.build(), Optional.empty()); subPlan = new PlanBuilder(subPlan.getTranslations(), markDistinct, subPlan.getSampleWeight()); masks, AggregationNode.Step.SINGLE, subPlan.getSampleWeight(), confidence, Optional.empty());
ImmutableSet.of(), 0), 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()); }
Optional.empty(), Optional.empty()), 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()); }
if (leftPlanBuilder.getSampleWeight().isPresent() || rightPlanBuilder.getSampleWeight().isPresent()) { Expression expression = new ArithmeticBinaryExpression(ArithmeticBinaryExpression.Type.MULTIPLY, oneIfNull(leftPlanBuilder.getSampleWeight()), oneIfNull(rightPlanBuilder.getSampleWeight())); sampleWeight = Optional.of(symbolAllocator.newSymbol(expression, BIGINT)); ImmutableMap.Builder<Symbol, Expression> projections = ImmutableMap.builder();
private PlanBuilder filter(PlanBuilder subPlan, Expression predicate, Node node) { if (predicate == null) { return subPlan; } // rewrite expressions which contain already handled subqueries Expression rewrittenBeforeSubqueries = subPlan.rewrite(predicate); subPlan = handleSubqueries(subPlan, rewrittenBeforeSubqueries, node); Expression rewrittenAfterSubqueries = subPlan.rewrite(predicate); return new PlanBuilder( subPlan.getTranslations(), new FilterNode(idAllocator.getNextId(), subPlan.getRoot(), rewrittenAfterSubqueries), subPlan.getSampleWeight()); }