use of org.voltdb.plannodes.LimitPlanNode in project voltdb by VoltDB.
the class TestPlansGroupBy method checkHasComplexAgg.
private void checkHasComplexAgg(List<AbstractPlanNode> pns, boolean projectPushdown) {
assertTrue(pns.size() > 0);
boolean isDistributed = pns.size() > 1 ? true : false;
if (projectPushdown) {
assertTrue(isDistributed);
}
AbstractPlanNode p = pns.get(0).getChild(0);
if (p instanceof LimitPlanNode) {
p = p.getChild(0);
}
if (p instanceof OrderByPlanNode) {
p = p.getChild(0);
}
if (!projectPushdown) {
assertTrue(p instanceof ProjectionPlanNode);
}
while (p.getChildCount() > 0) {
p = p.getChild(0);
assertFalse(p instanceof ProjectionPlanNode);
}
if (isDistributed) {
p = pns.get(1).getChild(0);
int projectCount = 0;
while (p.getChildCount() > 0) {
p = p.getChild(0);
if (p instanceof ProjectionPlanNode) {
projectCount++;
assertTrue(projectPushdown);
}
}
if (projectPushdown) {
assertEquals(1, projectCount);
}
}
}
use of org.voltdb.plannodes.LimitPlanNode in project voltdb by VoltDB.
the class TestUnion method checkLimitNode.
private void checkLimitNode(AbstractPlanNode pn, int limit, int offset) {
assertTrue(pn instanceof LimitPlanNode);
LimitPlanNode lpn = (LimitPlanNode) pn;
assertEquals(limit, lpn.getLimit());
assertEquals(offset, lpn.getOffset());
}
use of org.voltdb.plannodes.LimitPlanNode in project voltdb by VoltDB.
the class TestUnion method testUnionOrderByLimitParams.
public void testUnionOrderByLimitParams() {
AbstractPlanNode pn = compile("select C from T3 where C = ? UNION select B from T2 order by C limit ? offset ?");
String[] columnNames = { "C" };
pn = pn.getChild(0);
int[] idxs = { 0 };
checkOrderByNode(pn, columnNames, idxs);
assertTrue(pn.getChild(0) instanceof UnionPlanNode);
pn = pn.getInlinePlanNode(PlanNodeType.LIMIT);
assert (pn instanceof LimitPlanNode);
assertTrue(pn.toExplainPlanString().contains("LIMIT with parameter"));
}
use of org.voltdb.plannodes.LimitPlanNode in project voltdb by VoltDB.
the class PlanAssembler method handleSelectLimitOperator.
/**
* Add a limit, pushed-down if possible, and return the new root.
* @param root top of the original plan
* @return new plan's root node
*/
private AbstractPlanNode handleSelectLimitOperator(AbstractPlanNode root) {
// The coordinator's top limit graph fragment for a MP plan.
// If planning "order by ... limit", getNextSelectPlan()
// will have already added an order by to the coordinator frag.
// This is the only limit node in a SP plan
LimitPlanNode topLimit = m_parsedSelect.getLimitNodeTop();
assert (topLimit != null);
/*
* TODO: allow push down limit with distinct (select distinct C from T limit 5)
* , DISTINCT in aggregates and DISTINCT PUSH DOWN with partition column included.
*/
AbstractPlanNode sendNode = null;
// Whether or not we can push the limit node down
boolean canPushDown = !m_parsedSelect.hasDistinctWithGroupBy();
if (canPushDown) {
sendNode = checkLimitPushDownViability(root);
if (sendNode == null) {
canPushDown = false;
} else {
canPushDown = m_parsedSelect.getCanPushdownLimit();
}
}
if (m_parsedSelect.m_mvFixInfo.needed()) {
// Do not push down limit for mv based distributed query.
canPushDown = false;
}
/*
* Push down the limit plan node when possible even if offset is set. If
* the plan is for a partitioned table, do the push down. Otherwise,
* there is no need to do the push down work, the limit plan node will
* be run in the partition.
*/
if (canPushDown) {
/*
* For partitioned table, the pushed-down limit plan node has a limit based
* on the combined limit and offset, which may require an expression if either of these
* was not a hard-coded constant and didn't get parameterized.
* The top level limit plan node remains the same, with the original limit and offset values.
*/
LimitPlanNode distLimit = m_parsedSelect.getLimitNodeDist();
// Disconnect the distributed parts of the plan below the SEND node
AbstractPlanNode distributedPlan = sendNode.getChild(0);
distributedPlan.clearParents();
sendNode.clearChildren();
// ensure the order of the data on each partition.
if (m_parsedSelect.hasOrderByColumns()) {
distributedPlan = handleOrderBy(m_parsedSelect, distributedPlan);
}
if (isInlineLimitPlanNodePossible(distributedPlan)) {
// Inline the distributed limit.
distributedPlan.addInlinePlanNode(distLimit);
sendNode.addAndLinkChild(distributedPlan);
} else {
distLimit.addAndLinkChild(distributedPlan);
// Add the distributed work back to the plan
sendNode.addAndLinkChild(distLimit);
}
}
// Then we do not need to distinguish the order by node.
return inlineLimitOperator(root, topLimit);
}
use of org.voltdb.plannodes.LimitPlanNode in project voltdb by VoltDB.
the class TestPlansLimit method checkPushedDownLimit.
/**
* Check if the limit node is pushed-down in the given plan.
*
* @param np
* The generated plan
* @param isMultiPart
* Whether or not the plan is distributed
* @param downIntoScan
* limit node is pushed down into the scan node
* @param downIntoJoin
* limit node is pushed down into the join node
* @param isLeftJoin
* Whether or not the join node type is left outer join, TRUE when it's left outer join and downIntoJoin is TRUE
*/
private void checkPushedDownLimit(List<AbstractPlanNode> pn, boolean isMultiPart, boolean downIntoScan, boolean downIntoJoin, boolean isLeftJoin) {
assertTrue(pn.size() > 0);
for (AbstractPlanNode nd : pn) {
System.out.println("PlanNode Explain string:\n" + nd.toExplainPlanString());
}
AbstractPlanNode p;
if (isMultiPart) {
assertTrue(pn.size() == 2);
p = pn.get(0).getChild(0).getChild(0);
if (p.getPlanNodeType() == PlanNodeType.PROJECTION) {
p = p.getChild(0);
}
assertTrue(p instanceof LimitPlanNode);
assertTrue(p.toJSONString().contains("\"LIMIT\""));
checkPushedDownLimit(pn.get(1).getChild(0), downIntoScan, downIntoJoin, isLeftJoin);
} else {
p = pn.get(0).getChild(0);
if (p.getPlanNodeType() == PlanNodeType.PROJECTION) {
p = p.getChild(0);
}
checkPushedDownLimit(p, downIntoScan, downIntoJoin, isLeftJoin);
}
}
Aggregations