private CompiledPlan getNextUnionPlan() {
        String isContentDeterministic = null;
        // Since only the one "best" plan is considered,
        // this method should be called only once.
        if (m_bestAndOnlyPlanWasGenerated) {
            return null;
        }

        m_bestAndOnlyPlanWasGenerated = true;
        // Simply return an union plan node with a corresponding union type set
        AbstractPlanNode subUnionRoot = new UnionPlanNode(m_parsedUnion.m_unionType);
        m_recentErrorMsg = null;

        ArrayList<CompiledPlan> childrenPlans = new ArrayList<>();
        StatementPartitioning commonPartitioning = null;

        // Build best plans for the children first
        int planId = 0;
        for (AbstractParsedStmt parsedChildStmt : m_parsedUnion.m_children) {
            StatementPartitioning partitioning = (StatementPartitioning)m_partitioning.clone();
            PlanSelector planSelector = (PlanSelector) m_planSelector.clone();
            planSelector.m_planId = planId;
            PlanAssembler assembler = new PlanAssembler(m_catalogDb, partitioning, planSelector, m_isLargeQuery);
            CompiledPlan bestChildPlan = assembler.getBestCostPlan(parsedChildStmt);
            partitioning = assembler.m_partitioning;

            // make sure we got a winner
            if (bestChildPlan == null) {
                m_recentErrorMsg = assembler.getErrorMessage();
                if (m_recentErrorMsg == null) {
                    m_recentErrorMsg = "Unable to plan for statement. Error unknown.";
                }
                return null;
            }

            childrenPlans.add(bestChildPlan);
            // Remember the content non-determinism message for the
            // first non-deterministic children we find.
            if (isContentDeterministic != null) {
                isContentDeterministic = bestChildPlan.nondeterminismDetail();
            }

            // Make sure that next child's plans won't override current ones.
            planId = planSelector.m_planId;

            // Decide whether child statements' partitioning is compatible.
            if (commonPartitioning == null) {
                commonPartitioning = partitioning;
                continue;
            }

            AbstractExpression statementPartitionExpression = partitioning.singlePartitioningExpression();
            if (commonPartitioning.requiresTwoFragments()) {
                if (partitioning.requiresTwoFragments() || statementPartitionExpression != null) {
                    // If two child statements need to use a second fragment,
                    // it can't currently be a two-fragment plan.
                    // The coordinator expects a single-table result from each partition.
                    // Also, currently the coordinator of a two-fragment plan is not allowed to
                    // target a particular partition, so neither can the union of the coordinator
                    // and a statement that wants to run single-partition.
                    throw new PlanningErrorException(
                            "Statements are too complex in set operation using multiple partitioned tables.");
                }
                // the new statement is apparently a replicated read and has no effect on partitioning
                continue;
            }

            AbstractExpression commonPartitionExpression = commonPartitioning.singlePartitioningExpression();
            if (commonPartitionExpression == null) {
                // the prior statement(s) were apparently replicated reads
                // and have no effect on partitioning
                commonPartitioning = partitioning;
                continue;
            }

            if (partitioning.requiresTwoFragments()) {
                // Again, currently the coordinator of a two-fragment plan is not allowed to
                // target a particular partition, so neither can the union of the coordinator
                // and a statement that wants to run single-partition.
                throw new PlanningErrorException(
                        "Statements are too complex in set operation using multiple partitioned tables.");
            }

            if (statementPartitionExpression == null) {
                // the new statement is apparently a replicated read and has no effect on partitioning
                continue;
            }

            if ( ! commonPartitionExpression.equals(statementPartitionExpression)) {
                throw new PlanningErrorException(
                        "Statements use conflicting partitioned table filters in set operation or sub-query.");
            }
        }

        if (commonPartitioning != null) {
            m_partitioning = commonPartitioning;
        }

        // need to reset plan id for the entire UNION
        m_planSelector.m_planId = planId;

        // Add and link children plans
        for (CompiledPlan selectPlan : childrenPlans) {
            subUnionRoot.addAndLinkChild(selectPlan.rootPlanGraph);
        }

        // order by
        if (m_parsedUnion.hasOrderByColumns()) {
            subUnionRoot = handleOrderBy(m_parsedUnion, subUnionRoot);
        }

        // limit/offset
        if (m_parsedUnion.hasLimitOrOffset()) {
            subUnionRoot = handleUnionLimitOperator(subUnionRoot);
        }

        CompiledPlan retval = new CompiledPlan(m_isLargeQuery);
        retval.rootPlanGraph = subUnionRoot;
        retval.setReadOnly(true);
        retval.sql = m_planSelector.m_sql;
        boolean orderIsDeterministic = m_parsedUnion.isOrderDeterministic();
        boolean hasLimitOrOffset = m_parsedUnion.hasLimitOrOffset();
        retval.statementGuaranteesDeterminism(hasLimitOrOffset, orderIsDeterministic, isContentDeterministic);

        // compute the cost - total of all children
        retval.cost = 0.0;
        for (CompiledPlan bestChildPlan : childrenPlans) {
            retval.cost += bestChildPlan.cost;
        }
        return retval;
    }
private CompiledPlan getNextUnionPlan ( ) { String isContentDeterministic = null ; if ( m_bestAndOnlyPlanWasGenerated ) { return null ; } m_bestAndOnlyPlanWasGenerated = true ; AbstractPlanNode subUnionRoot = new UnionPlanNode ( m_parsedUnion . m_unionType ) ; m_recentErrorMsg = null ; ArrayList < CompiledPlan > childrenPlans = new ArrayList < > ( ) ; StatementPartitioning commonPartitioning = null ; int planId = 0 ; for ( AbstractParsedStmt parsedChildStmt : m_parsedUnion . m_children ) { StatementPartitioning partitioning = ( StatementPartitioning ) m_partitioning . clone ( ) ; PlanSelector planSelector = ( PlanSelector ) m_planSelector . clone ( ) ; planSelector . m_planId = planId ; PlanAssembler assembler = new PlanAssembler ( m_catalogDb , partitioning , planSelector , m_isLargeQuery ) ; CompiledPlan bestChildPlan = assembler . getBestCostPlan ( parsedChildStmt ) ; partitioning = assembler . m_partitioning ; if ( bestChildPlan == null ) { m_recentErrorMsg = assembler . getErrorMessage ( ) ; if ( m_recentErrorMsg == null ) { m_recentErrorMsg = "Unable to plan for statement. Error unknown." ; } return null ; } childrenPlans . add ( bestChildPlan ) ; if ( isContentDeterministic != null ) { isContentDeterministic = bestChildPlan . nondeterminismDetail ( ) ; } planId = planSelector . m_planId ; if ( commonPartitioning == null ) { commonPartitioning = partitioning ; continue ; } AbstractExpression statementPartitionExpression = partitioning . singlePartitioningExpression ( ) ; if ( commonPartitioning . requiresTwoFragments ( ) ) { if ( partitioning . requiresTwoFragments ( ) || statementPartitionExpression != null ) { throw new PlanningErrorException ( "Statements are too complex in set operation using multiple partitioned tables." ) ; } continue ; } AbstractExpression commonPartitionExpression = commonPartitioning . singlePartitioningExpression ( ) ; if ( commonPartitionExpression == null ) { commonPartitioning = partitioning ; continue ; } if ( partitioning . requiresTwoFragments ( ) ) { throw new PlanningErrorException ( "Statements are too complex in set operation using multiple partitioned tables." ) ; } if ( statementPartitionExpression == null ) { continue ; } if ( ! commonPartitionExpression . equals ( statementPartitionExpression ) ) { throw new PlanningErrorException ( "Statements use conflicting partitioned table filters in set operation or sub-query." ) ; } } if ( commonPartitioning != null ) { m_partitioning = commonPartitioning ; } m_planSelector . m_planId = planId ; for ( CompiledPlan selectPlan : childrenPlans ) { subUnionRoot . addAndLinkChild ( selectPlan . rootPlanGraph ) ; } if ( m_parsedUnion . hasOrderByColumns ( ) ) { subUnionRoot = handleOrderBy ( m_parsedUnion , subUnionRoot ) ; } if ( m_parsedUnion . hasLimitOrOffset ( ) ) { subUnionRoot = handleUnionLimitOperator ( subUnionRoot ) ; } CompiledPlan retval = new CompiledPlan ( m_isLargeQuery ) ; retval . rootPlanGraph = subUnionRoot ; retval . setReadOnly ( true ) ; retval . sql = m_planSelector . m_sql ; boolean orderIsDeterministic = m_parsedUnion . isOrderDeterministic ( ) ; boolean hasLimitOrOffset = m_parsedUnion . hasLimitOrOffset ( ) ; retval . statementGuaranteesDeterminism ( hasLimitOrOffset , orderIsDeterministic , isContentDeterministic ) ; retval . cost = 0.0 ; for ( CompiledPlan bestChildPlan : childrenPlans ) { retval . cost += bestChildPlan . cost ; } return retval ; }
This is a UNION specific method. Generate a unique and correct plan
for the current SQL UNION statement by building the best plans for each individual statements
within the UNION.

@return A union plan or null.