Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 package com.facebook.presto.sql.planner;
 
 
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
 import static com.facebook.presto.spi.type.BigintType.BIGINT;
 import static com.facebook.presto.spi.type.BooleanType.BOOLEAN;
 import static com.facebook.presto.sql.analyzer.SemanticErrorCode.EXPRESSION_NOT_CONSTANT;
 import static com.facebook.presto.sql.analyzer.SemanticErrorCode.NOT_SUPPORTED;
 import static com.facebook.presto.sql.tree.ComparisonExpression.Type.EQUAL;
 import static com.facebook.presto.sql.tree.ComparisonExpression.Type.GREATER_THAN;
 import static com.facebook.presto.sql.tree.ComparisonExpression.Type.GREATER_THAN_OR_EQUAL;
 import static com.facebook.presto.sql.tree.ComparisonExpression.Type.IS_DISTINCT_FROM;
 import static com.facebook.presto.sql.tree.ComparisonExpression.Type.LESS_THAN;
 import static com.facebook.presto.sql.tree.ComparisonExpression.Type.LESS_THAN_OR_EQUAL;
 import static com.facebook.presto.sql.tree.ComparisonExpression.Type.NOT_EQUAL;
 import static com.facebook.presto.sql.tree.Join.Type.INNER;
 import static com.facebook.presto.util.ImmutableCollectors.toImmutableList;
import static com.facebook.presto.util.Types.checkType;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
        extends DefaultTraversalVisitor<RelationPlanVoid>
    private final Analysis analysis;
    private final SymbolAllocator symbolAllocator;
    private final PlanNodeIdAllocator idAllocator;
    private final Metadata metadata;
    private final Session session;
    RelationPlanner(Analysis analysisSymbolAllocator symbolAllocatorPlanNodeIdAllocator idAllocatorMetadata metadataSession session)
    {
        Preconditions.checkNotNull(analysis"analysis is null");
        Preconditions.checkNotNull(symbolAllocator"symbolAllocator is null");
        Preconditions.checkNotNull(idAllocator"idAllocator is null");
        Preconditions.checkNotNull(metadata"metadata is null");
        Preconditions.checkNotNull(session"session is null");
        this. = analysis;
        this. = symbolAllocator;
        this. = idAllocator;
        this. = metadata;
        this. = session;
    }
    @Override
    protected RelationPlan visitTable(Table nodeVoid context)
    {
        Query namedQuery = .getNamedQuery(node);
        if (namedQuery != null) {
            RelationPlan subPlan = process(namedQuerynull);
            return new RelationPlan(subPlan.getRoot(), .getOutputDescriptor(node), subPlan.getOutputSymbols(), subPlan.getSampleWeight());
        }
        TupleDescriptor descriptor = .getOutputDescriptor(node);
        TableHandle handle = .getTableHandle(node);
        ImmutableList.Builder<SymboloutputSymbolsBuilder = ImmutableList.builder();
        ImmutableMap.Builder<SymbolColumnHandlecolumns = ImmutableMap.builder();
        for (Field field : descriptor.getAllFields()) {
            Symbol symbol = .newSymbol(field.getName().get(), field.getType());
            outputSymbolsBuilder.add(symbol);
            columns.put(symbol.getColumn(field));
        }
        List<SymbolplanOutputSymbols = outputSymbolsBuilder.build();
        Optional<ColumnHandlesampleWeightColumn = .getSampleWeightColumnHandle(handle);
        Symbol sampleWeightSymbol = null;
        if (sampleWeightColumn.isPresent()) {
            sampleWeightSymbol = .newSymbol("$sampleWeight");
            outputSymbolsBuilder.add(sampleWeightSymbol);
            columns.put(sampleWeightSymbolsampleWeightColumn.get());
        }
        List<SymbolnodeOutputSymbols = outputSymbolsBuilder.build();
        PlanNode root = new TableScanNode(.getNextId(), handlenodeOutputSymbolscolumns.build(), Optional.empty(), TupleDomain.all(), null);
        return new RelationPlan(rootdescriptorplanOutputSymbols, Optional.ofNullable(sampleWeightSymbol));
    }
    @Override
    protected RelationPlan visitAliasedRelation(AliasedRelation nodeVoid context)
    {
        RelationPlan subPlan = process(node.getRelation(), context);
        TupleDescriptor outputDescriptor = .getOutputDescriptor(node);
        return new RelationPlan(subPlan.getRoot(), outputDescriptorsubPlan.getOutputSymbols(), subPlan.getSampleWeight());
    }
    @Override
    protected RelationPlan visitSampledRelation(SampledRelation nodeVoid context)
    {
        if (node.getColumnsToStratifyOn().isPresent()) {
            throw new UnsupportedOperationException("STRATIFY ON is not yet implemented");
        }
        RelationPlan subPlan = process(node.getRelation(), context);
        TupleDescriptor outputDescriptor = .getOutputDescriptor(node);
        double ratio = .getSampleRatio(node);
        Symbol sampleWeightSymbol = null;
        if (node.getType() == ..) {
            sampleWeightSymbol = .newSymbol("$sampleWeight");
        }
        PlanNode planNode = new SampleNode(.getNextId(),
                subPlan.getRoot(),
                ratio,
                SampleNode.Type.fromType(node.getType()),
                node.isRescaled(),
                Optional.ofNullable(sampleWeightSymbol));
        return new RelationPlan(planNodeoutputDescriptorsubPlan.getOutputSymbols(), Optional.ofNullable(sampleWeightSymbol));
    }
    @Override
    protected RelationPlan visitJoin(Join nodeVoid context)
    {
        // TODO: translate the RIGHT join into a mirrored LEFT join when we refactor (@martint)
        RelationPlan leftPlan = process(node.getLeft(), context);
        // Convert CROSS JOIN UNNEST to an UnnestNode
        if (node.getRight() instanceof Unnest || (node.getRight() instanceof AliasedRelation && ((AliasedRelationnode.getRight()).getRelation() instanceof Unnest)) {
            Unnest unnest;
            if (node.getRight() instanceof AliasedRelation) {
                unnest = (Unnest) ((AliasedRelationnode.getRight()).getRelation();
            }
            else {
                unnest = (Unnestnode.getRight();
            }
            if (node.getType() != .. && node.getType() != ..) {
                throw new SemanticException(unnest"UNNEST only supported on the right side of CROSS JOIN");
            }
            return planCrossJoinUnnest(leftPlannodeunnest);
        }
        RelationPlan rightPlan = process(node.getRight(), context);
        PlanBuilder leftPlanBuilder = initializePlanBuilder(leftPlan);
        PlanBuilder rightPlanBuilder = initializePlanBuilder(rightPlan);
        TupleDescriptor outputDescriptor = .getOutputDescriptor(node);
        // NOTE: symbols must be in the same order as the outputDescriptor
        List<SymboloutputSymbols = ImmutableList.<Symbol>builder()
                .addAll(leftPlan.getOutputSymbols())
                .addAll(rightPlan.getOutputSymbols())
                .build();
        ImmutableList.Builder<JoinNode.EquiJoinClauseequiClauses = ImmutableList.builder();
        Expression postInnerJoinCriteria = new BooleanLiteral("TRUE");
        if (node.getType() != .. && node.getType() != ..) {
            Expression criteria = .getJoinCriteria(node);
            TupleDescriptor left = .getOutputDescriptor(node.getLeft());
            TupleDescriptor right = .getOutputDescriptor(node.getRight());
            List<ExpressionleftExpressions = new ArrayList<>();
            List<ExpressionrightExpressions = new ArrayList<>();
            List<ComparisonExpression.TypecomparisonTypes = new ArrayList<>();
            for (Expression conjunct : ExpressionUtils.extractConjuncts(criteria)) {
                if (!(conjunct instanceof ComparisonExpression)) {
                    throw new SemanticException(node"Unsupported non-equi join form: %s"conjunct);
                }
                ComparisonExpression comparison = (ComparisonExpressionconjunct;
                ComparisonExpression.Type comparisonType = comparison.getType();
                if (comparison.getType() !=  && node.getType() != ) {
                    throw new SemanticException(node"Non-equi joins only supported for inner join: %s"conjunct);
                }
                Set<QualifiedNamefirstDependencies = TupleAnalyzer.DependencyExtractor.extract(comparison.getLeft());
                Set<QualifiedNamesecondDependencies = TupleAnalyzer.DependencyExtractor.extract(comparison.getRight());
                Expression leftExpression;
                Expression rightExpression;
                if (Iterables.all(firstDependenciesleft.canResolvePredicate()) && Iterables.all(secondDependenciesright.canResolvePredicate())) {
                    leftExpression = comparison.getLeft();
                    rightExpression = comparison.getRight();
                }
                else if (Iterables.all(firstDependenciesright.canResolvePredicate()) && Iterables.all(secondDependenciesleft.canResolvePredicate())) {
                    leftExpression = comparison.getRight();
                    rightExpression = comparison.getLeft();
                    comparisonType = flipComparison(comparisonType);
                }
                else {
                    // must have a complex expression that involves both tuples on one side of the comparison expression (e.g., coalesce(left.x, right.x) = 1)
                    throw new SemanticException(node"Unsupported non-equi join form: %s"conjunct);
                }
                leftExpressions.add(leftExpression);
                rightExpressions.add(rightExpression);
                comparisonTypes.add(comparisonType);
            }
            Analysis.JoinInPredicates joinInPredicates = .getJoinInPredicates(node);
            // Add semi joins if necessary
            if (joinInPredicates != null) {
                leftPlanBuilder = appendSemiJoins(leftPlanBuilderjoinInPredicates.getLeftInPredicates());
                rightPlanBuilder = appendSemiJoins(rightPlanBuilderjoinInPredicates.getRightInPredicates());
            }
            // Add projections for join criteria
            leftPlanBuilder = appendProjections(leftPlanBuilderleftExpressions);
            rightPlanBuilder = appendProjections(rightPlanBuilderrightExpressions);
            List<ExpressionpostInnerJoinComparisons = new ArrayList<>();
            for (int i = 0; i < comparisonTypes.size(); i++) {
                Symbol leftSymbol = leftPlanBuilder.translate(leftExpressions.get(i));
                Symbol rightSymbol = rightPlanBuilder.translate(rightExpressions.get(i));
                equiClauses.add(new JoinNode.EquiJoinClause(leftSymbolrightSymbol));
                Expression leftExpression = leftPlanBuilder.rewrite(leftExpressions.get(i));
                Expression rightExpression = rightPlanBuilder.rewrite(rightExpressions.get(i));
                postInnerJoinComparisons.add(new ComparisonExpression(comparisonTypes.get(i), leftExpressionrightExpression));
            }
            postInnerJoinCriteria = ExpressionUtils.and(postInnerJoinComparisons);
        }
        PlanNode root;
        if (node.getType() == ) {
            root = new JoinNode(.getNextId(),
                    ..,
                    leftPlanBuilder.getRoot(),
                    rightPlanBuilder.getRoot(),
                    ImmutableList.<JoinNode.EquiJoinClause>of(),
                    Optional.empty(),
                    Optional.empty());
            root = new FilterNode(.getNextId(), rootpostInnerJoinCriteria);
        }
        else {
            root = new JoinNode(.getNextId(),
                    JoinNode.Type.typeConvert(node.getType()),
                    leftPlanBuilder.getRoot(),
                    rightPlanBuilder.getRoot(),
                    equiClauses.build(),
                    Optional.empty(),
                    Optional.empty());
        }
        Optional<SymbolsampleWeight = Optional.empty();
        if (leftPlanBuilder.getSampleWeight().isPresent() || rightPlanBuilder.getSampleWeight().isPresent()) {
                    oneIfNull(leftPlanBuilder.getSampleWeight()),
                    oneIfNull(rightPlanBuilder.getSampleWeight()));
            sampleWeight = Optional.of(.newSymbol(expression));
            ImmutableMap.Builder<SymbolExpressionprojections = ImmutableMap.builder();
            projections.put(sampleWeight.get(), expression);
            for (Symbol symbol : root.getOutputSymbols()) {
                projections.put(symbolnew QualifiedNameReference(symbol.toQualifiedName()));
            }
            root = new ProjectNode(.getNextId(), rootprojections.build());
        }
        return new RelationPlan(rootoutputDescriptoroutputSymbolssampleWeight);
    }
    {
        switch (type) {
            case :
                return ;
            case :
                return ;
            case :
                return ;
            case :
                return ;
            case :
                return ;
            case :
                return ;
            case :
                return ;
            default:
                throw new IllegalArgumentException("Unsupported comparison: " + type);
        }
    }
    private RelationPlan planCrossJoinUnnest(RelationPlan leftPlanJoin joinNodeUnnest node)
    {
        TupleDescriptor outputDescriptor = .getOutputDescriptor(joinNode);
        TupleDescriptor unnestOutputDescriptor = .getOutputDescriptor(node);
        // Create symbols for the result of unnesting
        ImmutableList.Builder<SymbolunnestedSymbolsBuilder = ImmutableList.builder();
        for (Field field : unnestOutputDescriptor.getVisibleFields()) {
            Symbol symbol = .newSymbol(field);
            unnestedSymbolsBuilder.add(symbol);
        }
        ImmutableList<SymbolunnestedSymbols = unnestedSymbolsBuilder.build();
        // Add a projection for all the unnest arguments
        PlanBuilder planBuilder = initializePlanBuilder(leftPlan);
        planBuilder = appendProjections(planBuildernode.getExpressions());
        TranslationMap translations = planBuilder.getTranslations();
        ProjectNode projectNode = checkType(planBuilder.getRoot(), ProjectNode.class"planBuilder.getRoot()");
        ImmutableMap.Builder<SymbolList<Symbol>> unnestSymbols = ImmutableMap.builder();
        UnmodifiableIterator<SymbolunnestedSymbolsIterator = unnestedSymbols.iterator();
        for (Expression expression : node.getExpressions()) {
            Type type = .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<SymbolordinalitySymbol = node.isWithOrdinality() ? Optional.of(unnestedSymbolsIterator.next()) : Optional.empty();
        checkState(!unnestedSymbolsIterator.hasNext(), "Not all output symbols were matched with input symbols");
        UnnestNode unnestNode = new UnnestNode(.getNextId(), projectNodeleftPlan.getOutputSymbols(), unnestSymbols.build(), ordinalitySymbol);
        return new RelationPlan(unnestNodeoutputDescriptorunnestNode.getOutputSymbols(), Optional.empty());
    }
    private static Expression oneIfNull(Optional<Symbolsymbol)
    {
        if (symbol.isPresent()) {
            return new CoalesceExpression(new QualifiedNameReference(symbol.get().toQualifiedName()), new LongLiteral("1"));
        }
        else {
            return new LongLiteral("1");
        }
    }
    @Override
    protected RelationPlan visitTableSubquery(TableSubquery nodeVoid context)
    {
        return process(node.getQuery(), context);
    }
    @Override
    protected RelationPlan visitQuery(Query nodeVoid context)
    {
        PlanBuilder subPlan = new QueryPlanner().process(nodenull);
        ImmutableList.Builder<SymboloutputSymbols = ImmutableList.builder();
        for (FieldOrExpression fieldOrExpression : .getOutputExpressions(node)) {
            outputSymbols.add(subPlan.translate(fieldOrExpression));
        }
        return new RelationPlan(subPlan.getRoot(), .getOutputDescriptor(node), outputSymbols.build(), subPlan.getSampleWeight());
    }
    @Override
    protected RelationPlan visitQuerySpecification(QuerySpecification nodeVoid context)
    {
        PlanBuilder subPlan = new QueryPlanner().process(nodenull);
        ImmutableList.Builder<SymboloutputSymbols = ImmutableList.builder();
        for (FieldOrExpression fieldOrExpression : .getOutputExpressions(node)) {
            outputSymbols.add(subPlan.translate(fieldOrExpression));
        }
        return new RelationPlan(subPlan.getRoot(), .getOutputDescriptor(node), outputSymbols.build(), subPlan.getSampleWeight());
    }
    @Override
    protected RelationPlan visitValues(Values nodeVoid context)
    {
        TupleDescriptor descriptor = .getOutputDescriptor(node);
        ImmutableList.Builder<SymboloutputSymbolsBuilder = ImmutableList.builder();
        for (Field field : descriptor.getVisibleFields()) {
            Symbol symbol = .newSymbol(field);
            outputSymbolsBuilder.add(symbol);
        }
        ImmutableList.Builder<List<Expression>> rows = ImmutableList.builder();
        for (Expression row : node.getRows()) {
            ImmutableList.Builder<Expressionvalues = ImmutableList.builder();
            if (row instanceof Row) {
                List<Expressionitems = ((Rowrow).getItems();
                for (int i = 0; i < items.size(); i++) {
                    Expression expression = items.get(i);
                    Object constantValue = evaluateConstantExpression(expression);
                    values.add(LiteralInterpreter.toExpression(constantValuedescriptor.getFieldByIndex(i).getType()));
                }
            }
            else {
                Object constantValue = evaluateConstantExpression(row);
                values.add(LiteralInterpreter.toExpression(constantValuedescriptor.getFieldByIndex(0).getType()));
            }
            rows.add(values.build());
        }
        ValuesNode valuesNode = new ValuesNode(.getNextId(), outputSymbolsBuilder.build(), rows.build());
        return new RelationPlan(valuesNodedescriptoroutputSymbolsBuilder.build(), Optional.empty());
    }
    @Override
    protected RelationPlan visitUnnest(Unnest nodeVoid context)
    {
        TupleDescriptor descriptor = .getOutputDescriptor(node);
        ImmutableList.Builder<SymboloutputSymbolsBuilder = ImmutableList.builder();
        for (Field field : descriptor.getVisibleFields()) {
            Symbol symbol = .newSymbol(field);
            outputSymbolsBuilder.add(symbol);
        }
        List<SymbolunnestedSymbols = outputSymbolsBuilder.build();
        // If we got here, then we must be unnesting a constant, and not be in a join (where there could be column references)
        ImmutableList.Builder<SymbolargumentSymbols = ImmutableList.builder();
        ImmutableList.Builder<Expressionvalues = ImmutableList.builder();
        ImmutableMap.Builder<SymbolList<Symbol>> unnestSymbols = ImmutableMap.builder();
        Iterator<SymbolunnestedSymbolsIterator = unnestedSymbols.iterator();
        for (Expression expression : node.getExpressions()) {
            Object constantValue = evaluateConstantExpression(expression);
            Type type = .getType(expression);
            values.add(LiteralInterpreter.toExpression(constantValuetype));
            Symbol inputSymbol = .newSymbol(expressiontype);
            argumentSymbols.add(inputSymbol);
            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<SymbolordinalitySymbol = node.isWithOrdinality() ? Optional.of(unnestedSymbolsIterator.next()) : Optional.empty();
        checkState(!unnestedSymbolsIterator.hasNext(), "Not all output symbols were matched with input symbols");
        ValuesNode valuesNode = new ValuesNode(.getNextId(), argumentSymbols.build(), ImmutableList.<List<Expression>>of(values.build()));
        UnnestNode unnestNode = new UnnestNode(.getNextId(), valuesNode, ImmutableList.<Symbol>of(), unnestSymbols.build(), ordinalitySymbol);
        return new RelationPlan(unnestNodedescriptorunnestedSymbols, Optional.empty());
    }
    private Object evaluateConstantExpression(Expression expression)
    {
        // verify expression is constant
        expression.accept(new DefaultTraversalVisitor<VoidVoid>()
        {
            @Override
            protected Void visitQualifiedNameReference(QualifiedNameReference nodeVoid context)
            {
                throw new SemanticException(expression"Constant expression cannot contain column references");
            }
            @Override
            protected Void visitInputReference(InputReference nodeVoid context)
            {
                throw new SemanticException(expression"Constant expression cannot contain input references");
            }
        }, null);
        // add coercions
        Expression rewrite = ExpressionTreeRewriter.rewriteWith(new ExpressionRewriter<Void>()
        {
            @Override
            public Expression rewriteExpression(Expression nodeVoid contextExpressionTreeRewriter<VoidtreeRewriter)
            {
                Expression rewrittenExpression = treeRewriter.defaultRewrite(nodecontext);
                // cast expression if coercion is registered
                Type coercion = .getCoercion(node);
                if (coercion != null) {
                    rewrittenExpression = new Cast(rewrittenExpressioncoercion.getTypeSignature().toString());
                }
                return rewrittenExpression;
            }
        }, expression);
        try {
            // expressionInterpreter/optimizer only understands a subset of expression types
            // TODO: remove this when the new expression tree is implemented
            Expression canonicalized = CanonicalizeExpressions.canonicalizeExpression(rewrite);
            // The optimization above may have rewritten the expression tree which breaks all the identity maps, so redo the analysis
            // to re-analyze coercions that might be necessary
            ExpressionAnalyzer analyzer = ExpressionAnalyzer.createWithoutSubqueries(
                    .getFunctionRegistry(),
                    .getTypeManager(),
                    ,
                    "Constant expression cannot contain as sub-query");
            analyzer.analyze(canonicalizednew TupleDescriptor(), new AnalysisContext());
            // evaluate the expression
            Object result = ExpressionInterpreter.expressionInterpreter(canonicalizedanalyzer.getExpressionTypes()).evaluate(0);
            checkState(!(result instanceof Expression), "Expression interpreter returned an unresolved expression");
            return result;
        }
        catch (Exception e) {
            throw new SemanticException(expression"Error evaluating constant expression: %s"e.getMessage());
        }
    }
    @Override
    protected RelationPlan visitUnion(Union nodeVoid context)
    {
        checkArgument(!node.getRelations().isEmpty(), "No relations specified for UNION");
        List<SymbolunionOutputSymbols = null;
        ImmutableList.Builder<PlanNodesources = ImmutableList.builder();
        ImmutableListMultimap.Builder<SymbolSymbolsymbolMapping = ImmutableListMultimap.builder();
        List<RelationPlansubPlans = node.getRelations().stream()
                .map(relation -> process(relationcontext))
                .collect(toImmutableList());
        boolean hasSampleWeight = false;
        for (RelationPlan subPlan : subPlans) {
            if (subPlan.getSampleWeight().isPresent()) {
                hasSampleWeight = true;
                break;
            }
        }
        Optional<SymboloutputSampleWeight = Optional.empty();
        for (RelationPlan relationPlan : subPlans) {
            if (hasSampleWeight && !relationPlan.getSampleWeight().isPresent()) {
                relationPlan = addConstantSampleWeight(relationPlan);
            }
            List<SymbolchildOutputSymbols = relationPlan.getOutputSymbols();
            if (unionOutputSymbols == null) {
                // Use the first Relation to derive output symbol names
                TupleDescriptor descriptor = relationPlan.getDescriptor();
                ImmutableList.Builder<SymboloutputSymbolBuilder = ImmutableList.builder();
                for (Field field : descriptor.getVisibleFields()) {
                    int fieldIndex = descriptor.indexOf(field);
                    Symbol symbol = childOutputSymbols.get(fieldIndex);
                    outputSymbolBuilder.add(.newSymbol(symbol.getName(), .getTypes().get(symbol)));
                }
                unionOutputSymbols = outputSymbolBuilder.build();
                outputSampleWeight = relationPlan.getSampleWeight();
            }
            TupleDescriptor descriptor = relationPlan.getDescriptor();
            checkArgument(descriptor.getVisibleFieldCount() == unionOutputSymbols.size(),
                    "Expected relation to have %s symbols but has %s symbols",
                    descriptor.getVisibleFieldCount(),
                    unionOutputSymbols.size());
            int unionFieldId = 0;
            for (Field field : descriptor.getVisibleFields()) {
                int fieldIndex = descriptor.indexOf(field);
                symbolMapping.put(unionOutputSymbols.get(unionFieldId), childOutputSymbols.get(fieldIndex));
                unionFieldId++;
            }
            sources.add(relationPlan.getRoot());
        }
        PlanNode planNode = new UnionNode(.getNextId(), sources.build(), symbolMapping.build());
        if (node.isDistinct()) {
            planNode = distinct(planNode);
        }
        return new RelationPlan(planNode.getOutputDescriptor(node), planNode.getOutputSymbols(), outputSampleWeight);
    }
    {
        ImmutableMap.Builder<SymbolExpressionprojections = ImmutableMap.builder();
        for (Symbol symbol : subPlan.getOutputSymbols()) {
            Expression expression = new QualifiedNameReference(symbol.toQualifiedName());
            projections.put(symbolexpression);
        }
        Expression one = new LongLiteral("1");
        Symbol sampleWeightSymbol = .newSymbol("$sampleWeight");
        projections.put(sampleWeightSymbolone);
        ProjectNode projectNode = new ProjectNode(.getNextId(), subPlan.getRoot(), projections.build());
        return new RelationPlan(projectNodesubPlan.getDescriptor(), projectNode.getOutputSymbols(), Optional.of(sampleWeightSymbol));
    }
    private PlanBuilder initializePlanBuilder(RelationPlan relationPlan)
    {
        TranslationMap translations = new TranslationMap(relationPlan);
        // Make field->symbol mapping from underlying relation plan available for translations
        // This makes it possible to rewrite FieldOrExpressions that reference fields from the underlying tuple directly
        translations.setFieldMappings(relationPlan.getOutputSymbols());
        return new PlanBuilder(translationsrelationPlan.getRoot(), relationPlan.getSampleWeight());
    }
    private PlanBuilder appendProjections(PlanBuilder subPlanIterable<Expressionexpressions)
    {
        TranslationMap translations = new TranslationMap(subPlan.getRelationPlan(), );
        // Carry over the translations from the source because we are appending projections
        translations.copyMappingsFrom(subPlan.getTranslations());
        ImmutableMap.Builder<SymbolExpressionprojections = ImmutableMap.builder();
        // add an identity projection for underlying plan
        for (Symbol symbol : subPlan.getRoot().getOutputSymbols()) {
            Expression expression = new QualifiedNameReference(symbol.toQualifiedName());
            projections.put(symbolexpression);
        }
        ImmutableMap.Builder<SymbolExpressionnewTranslations = ImmutableMap.builder();
        for (Expression expression : expressions) {
            Symbol symbol = .newSymbol(expression.getType(expression));
            // TODO: CHECK IF THE REWRITE OF A SEMI JOINED EXPRESSION WILL WORK!!!!!!!
            projections.put(symboltranslations.rewrite(expression));
            newTranslations.put(symbolexpression);
        }
        // Now append the new translations into the TranslationMap
        for (Map.Entry<SymbolExpressionentry : newTranslations.build().entrySet()) {
            translations.put(entry.getValue(), entry.getKey());
        }
        return new PlanBuilder(translationsnew ProjectNode(.getNextId(), subPlan.getRoot(), projections.build()), subPlan.getSampleWeight());
    }
    private PlanBuilder appendSemiJoins(PlanBuilder subPlanSet<InPredicateinPredicates)
    {
        for (InPredicate inPredicate : inPredicates) {
            subPlan = appendSemiJoin(subPlaninPredicate);
        }
        return subPlan;
    }
    private PlanBuilder appendSemiJoin(PlanBuilder subPlanInPredicate inPredicate)
    {
        TranslationMap translations = new TranslationMap(subPlan.getRelationPlan(), );
        translations.copyMappingsFrom(subPlan.getTranslations());
        subPlan = appendProjections(subPlan, ImmutableList.of(inPredicate.getValue()));
        Symbol sourceJoinSymbol = subPlan.translate(inPredicate.getValue());
        checkState(inPredicate.getValueList() instanceof SubqueryExpression);
        SubqueryExpression subqueryExpression = (SubqueryExpressioninPredicate.getValueList();
        RelationPlanner relationPlanner = new RelationPlanner();
        RelationPlan valueListRelation = relationPlanner.process(subqueryExpression.getQuery(), null);
        Symbol filteringSourceJoinSymbol = Iterables.getOnlyElement(valueListRelation.getRoot().getOutputSymbols());
        Symbol semiJoinOutputSymbol = .newSymbol("semijoinresult");
        translations.put(inPredicatesemiJoinOutputSymbol);
        return new PlanBuilder(translations,
                new SemiJoinNode(.getNextId(),
                        subPlan.getRoot(),
                        valueListRelation.getRoot(),
                        sourceJoinSymbol,
                        filteringSourceJoinSymbol,
                        semiJoinOutputSymbol,
                        Optional.empty(),
                        Optional.empty()),
                subPlan.getSampleWeight());
    }
    private PlanNode distinct(PlanNode node)
    {
        return new AggregationNode(.getNextId(),
                node,
                node.getOutputSymbols(),
                ImmutableMap.<SymbolFunctionCall>of(),
                ImmutableMap.<SymbolSignature>of(),
                ImmutableMap.<SymbolSymbol>of(),
                ..,
                Optional.empty(),
                1.0,
                Optional.empty());
    }
New to GrepCode? Check out our FAQ X