private RelationPlan createRelationPlan(Analysis analysis, Query query) { return new RelationPlanner(analysis, symbolAllocator, idAllocator, buildLambdaDeclarationToSymbolMap(analysis, symbolAllocator), metadata, session) .process(query, null); }
private RelationPlan processAndCoerceIfNecessary(Relation node, Void context) { Type[] coerceToTypes = analysis.getRelationCoercion(node); RelationPlan plan = this.process(node, context); if (coerceToTypes == null) { return plan; } return addCoercions(plan, coerceToTypes); }
private Optional<Lateral> getLateral(Relation relation) { if (relation instanceof AliasedRelation) { return getLateral(((AliasedRelation) relation).getRelation()); } if (relation instanceof Lateral) { return Optional.of((Lateral) relation); } return Optional.empty(); }
RelationPlan leftPlan = process(node.getLeft(), context); Optional<Unnest> unnest = getUnnest(node.getRight()); if (unnest.isPresent()) { if (node.getType() != Join.Type.CROSS && node.getType() != Join.Type.IMPLICIT) { throw notSupportedException(unnest.get(), "UNNEST on other than the right side of CROSS JOIN"); return planCrossJoinUnnest(leftPlan, node, unnest.get()); Optional<Lateral> lateral = getLateral(node.getRight()); if (lateral.isPresent()) { if (node.getType() != Join.Type.CROSS && node.getType() != Join.Type.IMPLICIT) { throw notSupportedException(lateral.get(), "LATERAL on other than the right side of CROSS JOIN"); return planLateralJoin(node, leftPlan, lateral.get()); RelationPlan rightPlan = process(node.getRight(), context); return planJoinUsing(node, leftPlan, rightPlan); PlanBuilder leftPlanBuilder = initializePlanBuilder(leftPlan); PlanBuilder rightPlanBuilder = initializePlanBuilder(rightPlan); conjunct = ExpressionUtils.normalize(conjunct); if (!isEqualComparisonExpression(conjunct) && node.getType() != INNER) { complexJoinExpressions.add(conjunct); continue;
private RelationPlan planLateralJoin(Join join, RelationPlan leftPlan, Lateral lateral) { RelationPlan rightPlan = process(lateral.getQuery(), null); PlanBuilder leftPlanBuilder = initializePlanBuilder(leftPlan); PlanBuilder rightPlanBuilder = initializePlanBuilder(rightPlan); PlanBuilder planBuilder = subqueryPlanner.appendLateralJoin(leftPlanBuilder, rightPlanBuilder, lateral.getQuery(), true, LateralJoinNode.Type.INNER); List<Symbol> outputSymbols = ImmutableList.<Symbol>builder() .addAll(leftPlan.getRoot().getOutputSymbols()) .addAll(rightPlan.getRoot().getOutputSymbols()) .build(); return new RelationPlan(planBuilder.getRoot(), analysis.getScope(join), outputSymbols); }
@Override protected RelationPlan visitUnion(Union node, Void context) { checkArgument(!node.getRelations().isEmpty(), "No relations specified for UNION"); SetOperationPlan setOperationPlan = process(node); PlanNode planNode = new UnionNode(idAllocator.getNextId(), setOperationPlan.getSources(), setOperationPlan.getSymbolMapping(), ImmutableList.copyOf(setOperationPlan.getSymbolMapping().keySet())); if (node.isDistinct()) { planNode = distinct(planNode); } return new RelationPlan(planNode, analysis.getScope(node), planNode.getOutputSymbols()); }
private Optional<Unnest> getUnnest(Relation relation) { if (relation instanceof AliasedRelation) { return getUnnest(((AliasedRelation) relation).getRelation()); } if (relation instanceof Unnest) { return Optional.of((Unnest) relation); } return Optional.empty(); }
PlanBuilder planBuilder = initializePlanBuilder(leftPlan); planBuilder = planBuilder.appendProjections(node.getExpressions(), symbolAllocator, idAllocator); TranslationMap translations = planBuilder.getTranslations();
RelationPlan leftPlan = process(node.getLeft(), context); Optional<Unnest> unnest = getUnnest(node.getRight()); if (unnest.isPresent()) { if (node.getType() != Join.Type.CROSS && node.getType() != Join.Type.IMPLICIT) { throw notSupportedException(unnest.get(), "UNNEST on other than the right side of CROSS JOIN"); return planCrossJoinUnnest(leftPlan, node, unnest.get()); Optional<Lateral> lateral = getLateral(node.getRight()); if (lateral.isPresent()) { if (node.getType() != Join.Type.CROSS && node.getType() != Join.Type.IMPLICIT) { throw notSupportedException(lateral.get(), "LATERAL on other than the right side of CROSS JOIN"); return planLateralJoin(node, leftPlan, lateral.get()); RelationPlan rightPlan = process(node.getRight(), context); return planJoinUsing(node, leftPlan, rightPlan); PlanBuilder leftPlanBuilder = initializePlanBuilder(leftPlan); PlanBuilder rightPlanBuilder = initializePlanBuilder(rightPlan); conjunct = ExpressionUtils.normalize(conjunct); if (!isEqualComparisonExpression(conjunct) && node.getType() != INNER) { complexJoinExpressions.add(conjunct); continue;
private RelationPlan planLateralJoin(Join join, RelationPlan leftPlan, Lateral lateral) { RelationPlan rightPlan = process(lateral.getQuery(), null); PlanBuilder leftPlanBuilder = initializePlanBuilder(leftPlan); PlanBuilder rightPlanBuilder = initializePlanBuilder(rightPlan); PlanBuilder planBuilder = subqueryPlanner.appendLateralJoin(leftPlanBuilder, rightPlanBuilder, lateral.getQuery(), true, LateralJoinNode.Type.INNER); List<Symbol> outputSymbols = ImmutableList.<Symbol>builder() .addAll(leftPlan.getRoot().getOutputSymbols()) .addAll(rightPlan.getRoot().getOutputSymbols()) .build(); return new RelationPlan(planBuilder.getRoot(), analysis.getScope(join), outputSymbols); }
@Override protected RelationPlan visitUnion(Union node, Void context) { checkArgument(!node.getRelations().isEmpty(), "No relations specified for UNION"); SetOperationPlan setOperationPlan = process(node); PlanNode planNode = new UnionNode(idAllocator.getNextId(), setOperationPlan.getSources(), setOperationPlan.getSymbolMapping(), ImmutableList.copyOf(setOperationPlan.getSymbolMapping().keySet())); if (node.isDistinct()) { planNode = distinct(planNode); } return new RelationPlan(planNode, analysis.getScope(node), planNode.getOutputSymbols()); }
private Optional<Unnest> getUnnest(Relation relation) { if (relation instanceof AliasedRelation) { return getUnnest(((AliasedRelation) relation).getRelation()); } if (relation instanceof Unnest) { return Optional.of((Unnest) relation); } return Optional.empty(); }
PlanBuilder planBuilder = initializePlanBuilder(leftPlan); planBuilder = planBuilder.appendProjections(node.getExpressions(), symbolAllocator, idAllocator); TranslationMap translations = planBuilder.getTranslations();
private RelationPlan createRelationPlan(Analysis analysis, Query query) { return new RelationPlanner(analysis, symbolAllocator, idAllocator, buildLambdaDeclarationToSymbolMap(analysis, symbolAllocator), metadata, session) .process(query, null); }
private RelationPlan processAndCoerceIfNecessary(Relation node, Void context) { Type[] coerceToTypes = analysis.getRelationCoercion(node); RelationPlan plan = this.process(node, context); if (coerceToTypes == null) { return plan; } return addCoercions(plan, coerceToTypes); }
private Optional<Lateral> getLateral(Relation relation) { if (relation instanceof AliasedRelation) { return getLateral(((AliasedRelation) relation).getRelation()); } if (relation instanceof Lateral) { return Optional.of((Lateral) relation); } return Optional.empty(); }
private PlanBuilder planQueryBody(Query query) { RelationPlan relationPlan = new RelationPlanner(analysis, symbolAllocator, idAllocator, lambdaDeclarationToSymbolMap, metadata, session) .process(query.getQueryBody(), null); return planBuilderFor(relationPlan); }
@Override protected RelationPlan visitTable(Table node, Void context) { Query namedQuery = analysis.getNamedQuery(node); Scope scope = analysis.getScope(node); if (namedQuery != null) { RelationPlan subPlan = process(namedQuery, null); // Add implicit coercions if view query produces types that don't match the declared output types // of the view (e.g., if the underlying tables referenced by the view changed) Type[] types = scope.getRelationType().getAllFields().stream().map(Field::getType).toArray(Type[]::new); RelationPlan withCoercions = addCoercions(subPlan, types); return new RelationPlan(withCoercions.getRoot(), scope, withCoercions.getFieldMappings()); } TableHandle handle = analysis.getTableHandle(node); ImmutableList.Builder<Symbol> outputSymbolsBuilder = ImmutableList.builder(); ImmutableMap.Builder<Symbol, ColumnHandle> columns = ImmutableMap.builder(); for (Field field : scope.getRelationType().getAllFields()) { Symbol symbol = symbolAllocator.newSymbol(field.getName().get(), field.getType()); outputSymbolsBuilder.add(symbol); columns.put(symbol, analysis.getColumn(field)); } List<Symbol> outputSymbols = outputSymbolsBuilder.build(); PlanNode root = new TableScanNode(idAllocator.getNextId(), handle, outputSymbols, columns.build()); return new RelationPlan(root, scope, outputSymbols); }
private PlanBuilder planQueryBody(Query query) { RelationPlan relationPlan = new RelationPlanner(analysis, symbolAllocator, idAllocator, lambdaDeclarationToSymbolMap, metadata, session) .process(query.getQueryBody(), null); return planBuilderFor(relationPlan); }
@Override protected RelationPlan visitTable(Table node, Void context) { Query namedQuery = analysis.getNamedQuery(node); Scope scope = analysis.getScope(node); if (namedQuery != null) { RelationPlan subPlan = process(namedQuery, null); // Add implicit coercions if view query produces types that don't match the declared output types // of the view (e.g., if the underlying tables referenced by the view changed) Type[] types = scope.getRelationType().getAllFields().stream().map(Field::getType).toArray(Type[]::new); RelationPlan withCoercions = addCoercions(subPlan, types); return new RelationPlan(withCoercions.getRoot(), scope, withCoercions.getFieldMappings()); } TableHandle handle = analysis.getTableHandle(node); ImmutableList.Builder<Symbol> outputSymbolsBuilder = ImmutableList.builder(); ImmutableMap.Builder<Symbol, ColumnHandle> columns = ImmutableMap.builder(); for (Field field : scope.getRelationType().getAllFields()) { Symbol symbol = symbolAllocator.newSymbol(field.getName().get(), field.getType()); outputSymbolsBuilder.add(symbol); columns.put(symbol, analysis.getColumn(field)); } List<Symbol> outputSymbols = outputSymbolsBuilder.build(); PlanNode root = new TableScanNode(idAllocator.getNextId(), handle, outputSymbols, columns.build()); return new RelationPlan(root, scope, outputSymbols); }