Search in sources :

Example 6 with AbstractJoinPlanNode

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

the class PlanAssembler method isOrderByNodeRequired.

/**
     * Determine if an OrderByPlanNode is needed.  This may return false if the
     * statement has no ORDER BY clause, or if the subtree is already producing
     * rows in the correct order.  Note that a hash aggregate node will cause this
     * to return true, and a serial or partial aggregate node may cause this
     * to return true.
     *
     * @param parsedStmt    The statement whose plan may need an OrderByPlanNode
     * @param root          The subtree which may need its output tuples ordered
     * @return true if the plan needs an OrderByPlanNode, false otherwise
     */
private static boolean isOrderByNodeRequired(AbstractParsedStmt parsedStmt, AbstractPlanNode root) {
    // Only sort when the statement has an ORDER BY.
    if (!parsedStmt.hasOrderByColumns()) {
        return false;
    }
    // Skip the explicit ORDER BY plan step if an IndexScan is already providing the equivalent ordering.
    // Note that even tree index scans that produce values in their own "key order" only report
    // their sort direction != SortDirectionType.INVALID
    // when they enforce an ordering equivalent to the one requested in the ORDER BY
    // or window function clause.  Even an intervening non-hash aggregate will not interfere
    // in this optimization.
    // Is there a window function between the root and the
    // scan or join nodes?  Also, does this window function
    // use the index.
    int numberWindowFunctions = 0;
    int numberReceiveNodes = 0;
    int numberHashAggregates = 0;
    // EE keeps the insertion ORDER so that ORDER BY could apply before DISTINCT.
    // However, this probably is not optimal if there are low cardinality results.
    // Again, we have to replace the TVEs for ORDER BY clause for these cases in planning.
    //
    // Find the scan or join node.
    AbstractPlanNode probe;
    for (probe = root; !((probe instanceof AbstractJoinPlanNode) || (probe instanceof AbstractScanPlanNode)) && (probe != null); probe = (probe.getChildCount() > 0) ? probe.getChild(0) : null) {
        // we will have recorded it in the scan or join node.
        if (probe.getPlanNodeType() == PlanNodeType.WINDOWFUNCTION) {
            numberWindowFunctions += 1;
        }
        // needs them.
        if (probe.getPlanNodeType() == PlanNodeType.RECEIVE) {
            numberReceiveNodes += 1;
        }
        // the ordering, but a serial aggregation does not.
        if ((probe.getPlanNodeType() == PlanNodeType.HASHAGGREGATE) || (probe.getPlanNodeType() == PlanNodeType.PARTIALAGGREGATE)) {
            numberHashAggregates += 1;
        }
    }
    if (probe == null) {
        // to be right.  Maybe this should be an assert?
        return true;
    }
    //
    if (!(probe instanceof IndexSortablePlanNode)) {
        return true;
    }
    IndexUseForOrderBy indexUse = ((IndexSortablePlanNode) probe).indexUse();
    if (indexUse.getSortOrderFromIndexScan() == SortDirectionType.INVALID) {
        return true;
    }
    // an ORDERBY node.
    if (numberHashAggregates > 0) {
        return true;
    }
    if (numberWindowFunctions == 0) {
        if (indexUse.getWindowFunctionUsesIndex() == SubPlanAssembler.NO_INDEX_USE) {
            return true;
        }
        assert (indexUse.getWindowFunctionUsesIndex() == SubPlanAssembler.STATEMENT_LEVEL_ORDER_BY_INDEX);
        // false for SP (numberReceiveNodes == 0);
        return numberReceiveNodes > 0;
    }
    if (numberWindowFunctions == 1) {
        // will return 0.
        if ((indexUse.getWindowFunctionUsesIndex() != 0) || (!indexUse.isWindowFunctionCompatibleWithOrderBy())) {
            return true;
        }
        // does not need one.  So this is a false.
        return false;
    }
    // because we only support one window function.
    return true;
}
Also used : AbstractPlanNode(org.voltdb.plannodes.AbstractPlanNode) IndexSortablePlanNode(org.voltdb.plannodes.IndexSortablePlanNode) AbstractScanPlanNode(org.voltdb.plannodes.AbstractScanPlanNode) AbstractJoinPlanNode(org.voltdb.plannodes.AbstractJoinPlanNode) Constraint(org.voltdb.catalog.Constraint) IndexUseForOrderBy(org.voltdb.plannodes.IndexUseForOrderBy)

Example 7 with AbstractJoinPlanNode

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

the class PlanAssembler method handleMVBasedMultiPartQuery.

private AbstractPlanNode handleMVBasedMultiPartQuery(HashAggregatePlanNode reAggNode, AbstractPlanNode root, boolean edgeCaseOuterJoin) {
    MaterializedViewFixInfo mvFixInfo = m_parsedSelect.m_mvFixInfo;
    AbstractPlanNode receiveNode = root;
    AbstractPlanNode reAggParent = null;
    // re-aggregation plan node.
    if (root instanceof AbstractReceivePlanNode) {
        root = reAggNode;
    } else {
        List<AbstractPlanNode> recList = root.findAllNodesOfClass(AbstractReceivePlanNode.class);
        assert (recList.size() == 1);
        receiveNode = recList.get(0);
        reAggParent = receiveNode.getParent(0);
        boolean result = reAggParent.replaceChild(receiveNode, reAggNode);
        assert (result);
    }
    reAggNode.addAndLinkChild(receiveNode);
    reAggNode.m_isCoordinatingAggregator = true;
    assert (receiveNode instanceof ReceivePlanNode);
    AbstractPlanNode sendNode = receiveNode.getChild(0);
    assert (sendNode instanceof SendPlanNode);
    AbstractPlanNode sendNodeChild = sendNode.getChild(0);
    HashAggregatePlanNode reAggNodeForReplace = null;
    if (m_parsedSelect.m_tableList.size() > 1 && !edgeCaseOuterJoin) {
        reAggNodeForReplace = reAggNode;
    }
    boolean find = mvFixInfo.processScanNodeWithReAggNode(sendNode, reAggNodeForReplace);
    assert (find);
    // receive node with materialized view scan node.
    if (m_parsedSelect.m_tableList.size() > 1 && !edgeCaseOuterJoin) {
        AbstractPlanNode joinNode = sendNodeChild;
        // No agg, limit pushed down at this point.
        assert (joinNode instanceof AbstractJoinPlanNode);
        // Fix the node after Re-aggregation node.
        joinNode.clearParents();
        assert (mvFixInfo.m_scanNode != null);
        mvFixInfo.m_scanNode.clearParents();
        // replace joinNode with MV scan node on each partition.
        sendNode.clearChildren();
        sendNode.addAndLinkChild(mvFixInfo.m_scanNode);
        // its parent will be the parent of the new join node. Update the root node.
        if (reAggParent != null) {
            reAggParent.replaceChild(reAggNode, joinNode);
            root = reAggParent;
        } else {
            root = joinNode;
        }
    }
    return root;
}
Also used : AbstractPlanNode(org.voltdb.plannodes.AbstractPlanNode) AbstractReceivePlanNode(org.voltdb.plannodes.AbstractReceivePlanNode) SendPlanNode(org.voltdb.plannodes.SendPlanNode) AbstractReceivePlanNode(org.voltdb.plannodes.AbstractReceivePlanNode) MergeReceivePlanNode(org.voltdb.plannodes.MergeReceivePlanNode) ReceivePlanNode(org.voltdb.plannodes.ReceivePlanNode) AbstractJoinPlanNode(org.voltdb.plannodes.AbstractJoinPlanNode) HashAggregatePlanNode(org.voltdb.plannodes.HashAggregatePlanNode)

Aggregations

AbstractJoinPlanNode (org.voltdb.plannodes.AbstractJoinPlanNode)7 AbstractPlanNode (org.voltdb.plannodes.AbstractPlanNode)5 AbstractReceivePlanNode (org.voltdb.plannodes.AbstractReceivePlanNode)3 AbstractScanPlanNode (org.voltdb.plannodes.AbstractScanPlanNode)3 ArrayList (java.util.ArrayList)2 AbstractExpression (org.voltdb.expressions.AbstractExpression)2 HashAggregatePlanNode (org.voltdb.plannodes.HashAggregatePlanNode)2 IndexScanPlanNode (org.voltdb.plannodes.IndexScanPlanNode)2 LimitPlanNode (org.voltdb.plannodes.LimitPlanNode)2 NestLoopPlanNode (org.voltdb.plannodes.NestLoopPlanNode)2 ProjectionPlanNode (org.voltdb.plannodes.ProjectionPlanNode)2 ReceivePlanNode (org.voltdb.plannodes.ReceivePlanNode)2 SendPlanNode (org.voltdb.plannodes.SendPlanNode)2 Constraint (org.voltdb.catalog.Constraint)1 BranchNode (org.voltdb.planner.parseinfo.BranchNode)1 JoinNode (org.voltdb.planner.parseinfo.JoinNode)1 AggregatePlanNode (org.voltdb.plannodes.AggregatePlanNode)1 IndexSortablePlanNode (org.voltdb.plannodes.IndexSortablePlanNode)1 IndexUseForOrderBy (org.voltdb.plannodes.IndexUseForOrderBy)1 MaterializedScanPlanNode (org.voltdb.plannodes.MaterializedScanPlanNode)1