Search in sources :

Example 11 with UnionPlanNode

use of org.voltdb.plannodes.UnionPlanNode in project voltdb by VoltDB.

the class TestUnion method testSubqueryUnionWithParamENG7783.

public void testSubqueryUnionWithParamENG7783() {
    AbstractPlanNode pn = compile("SELECT B, ABS( B - ? ) AS distance FROM ( " + "( SELECT B FROM T2 WHERE B >=? ORDER BY B LIMIT ? " + ") UNION ALL ( " + "SELECT B FROM T2 WHERE B < ? ORDER BY B DESC LIMIT ? ) " + ") AS n ORDER BY distance LIMIT ?;");
    assertTrue(pn.getChild(0) instanceof ProjectionPlanNode);
    assertTrue(pn.getChild(0).getChild(0) instanceof OrderByPlanNode);
    assertTrue(pn.getChild(0).getChild(0).getChild(0) instanceof SeqScanPlanNode);
    assertTrue(pn.getChild(0).getChild(0).getChild(0).getChild(0) instanceof UnionPlanNode);
}
Also used : AbstractPlanNode(org.voltdb.plannodes.AbstractPlanNode) SeqScanPlanNode(org.voltdb.plannodes.SeqScanPlanNode) UnionPlanNode(org.voltdb.plannodes.UnionPlanNode) OrderByPlanNode(org.voltdb.plannodes.OrderByPlanNode) ProjectionPlanNode(org.voltdb.plannodes.ProjectionPlanNode)

Example 12 with UnionPlanNode

use of org.voltdb.plannodes.UnionPlanNode in project voltdb by VoltDB.

the class TestUnion method testExceptAll.

public void testExceptAll() {
    AbstractPlanNode pn = compile("select A from T1 EXCEPT ALL select B from T2");
    assertTrue(pn.getChild(0) instanceof UnionPlanNode);
    UnionPlanNode unionPN = (UnionPlanNode) pn.getChild(0);
    assertTrue(unionPN.getUnionType() == ParsedUnionStmt.UnionType.EXCEPT_ALL);
    assertTrue(unionPN.getChildCount() == 2);
    pn = compile("select A from T1 EXCEPT ALL (select B from T2 EXCEPT ALL select C from T3) EXCEPT ALL select F from T6");
    unionPN = (UnionPlanNode) pn.getChild(0);
    assertTrue(unionPN.getUnionType() == ParsedUnionStmt.UnionType.EXCEPT_ALL);
    assertTrue(unionPN.getChildCount() == 3);
    UnionPlanNode childPN = (UnionPlanNode) unionPN.getChild(1);
    assertTrue(childPN.getUnionType() == ParsedUnionStmt.UnionType.EXCEPT_ALL);
    assertTrue(childPN.getChildCount() == 2);
}
Also used : AbstractPlanNode(org.voltdb.plannodes.AbstractPlanNode) UnionPlanNode(org.voltdb.plannodes.UnionPlanNode)

Example 13 with UnionPlanNode

use of org.voltdb.plannodes.UnionPlanNode in project voltdb by VoltDB.

the class TestUnion method testMultipleSetOperations.

public void testMultipleSetOperations() {
    AbstractPlanNode pn = compile("select A from T1 UNION select B from T2 EXCEPT select C from T3");
    assertTrue(pn.getChild(0) instanceof UnionPlanNode);
    UnionPlanNode unionPN1 = (UnionPlanNode) pn.getChild(0);
    assertTrue(unionPN1.getUnionType() == ParsedUnionStmt.UnionType.EXCEPT);
    assertTrue(unionPN1.getChildCount() == 2);
    assertTrue(unionPN1.getChild(0) instanceof UnionPlanNode);
    UnionPlanNode unionPN2 = (UnionPlanNode) unionPN1.getChild(0);
    assertTrue(unionPN2.getUnionType() == ParsedUnionStmt.UnionType.UNION);
    assertTrue(unionPN2.getChildCount() == 2);
    assertTrue(unionPN1.getChild(1) instanceof SeqScanPlanNode);
}
Also used : AbstractPlanNode(org.voltdb.plannodes.AbstractPlanNode) SeqScanPlanNode(org.voltdb.plannodes.SeqScanPlanNode) UnionPlanNode(org.voltdb.plannodes.UnionPlanNode)

Example 14 with UnionPlanNode

use of org.voltdb.plannodes.UnionPlanNode in project voltdb by VoltDB.

the class PlanAssembler method getNextUnionPlan.

/**
     * 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.
     */
private CompiledPlan getNextUnionPlan() {
    String isContentDeterministic = null;
    // 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);
        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);
        // 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) {
                // 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()) {
            // 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();
    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;
}
Also used : AbstractPlanNode(org.voltdb.plannodes.AbstractPlanNode) UnionPlanNode(org.voltdb.plannodes.UnionPlanNode) ArrayList(java.util.ArrayList) Constraint(org.voltdb.catalog.Constraint) AbstractExpression(org.voltdb.expressions.AbstractExpression)

Aggregations

AbstractPlanNode (org.voltdb.plannodes.AbstractPlanNode)14 UnionPlanNode (org.voltdb.plannodes.UnionPlanNode)14 ProjectionPlanNode (org.voltdb.plannodes.ProjectionPlanNode)3 SeqScanPlanNode (org.voltdb.plannodes.SeqScanPlanNode)3 OrderByPlanNode (org.voltdb.plannodes.OrderByPlanNode)2 ArrayList (java.util.ArrayList)1 Constraint (org.voltdb.catalog.Constraint)1 AbstractExpression (org.voltdb.expressions.AbstractExpression)1 LimitPlanNode (org.voltdb.plannodes.LimitPlanNode)1 NestLoopPlanNode (org.voltdb.plannodes.NestLoopPlanNode)1