use of org.voltdb.plannodes.AggregatePlanNode in project voltdb by VoltDB.
the class TestPlansGroupBy method testComplexAggwithLimit.
public void testComplexAggwithLimit() {
List<AbstractPlanNode> pns;
pns = compileToFragments("SELECT A1, sum(A1), sum(A1)+11 FROM P1 GROUP BY A1 ORDER BY A1 LIMIT 2");
checkHasComplexAgg(pns);
// Test limit is not pushed down
AbstractPlanNode p = pns.get(0).getChild(0);
assertTrue(p instanceof OrderByPlanNode);
assertNotNull(p.getInlinePlanNode(PlanNodeType.LIMIT));
assertTrue(p.getChild(0) instanceof ProjectionPlanNode);
assertTrue(p.getChild(0).getChild(0) instanceof AggregatePlanNode);
p = pns.get(1).getChild(0);
// inline limit with order by
assertTrue(p instanceof OrderByPlanNode);
assertNotNull(p.getInlinePlanNode(PlanNodeType.LIMIT));
p = p.getChild(0);
// inline aggregate
assertTrue(p instanceof AbstractScanPlanNode);
assertNotNull(p.getInlinePlanNode(PlanNodeType.HASHAGGREGATE));
}
use of org.voltdb.plannodes.AggregatePlanNode in project voltdb by VoltDB.
the class TestPlansInExistsSubQueries method testInHaving.
public void testInHaving() {
String sql;
AbstractPlanNode pn;
AggregatePlanNode aggNode;
sql = "select a from r1 group by a having max(c) in (select c from r2 )";
failToCompile(sql, HavingErrorMsg);
// ENG-8306: Uncomment next block when HAVING with subquery is supported
// AbstractPlanNode pn = compile(sql);
// pn = pn.getChild(0);
// assertTrue(pn instanceof ProjectionPlanNode);
// pn = pn.getChild(0);
// assertTrue(pn instanceof SeqScanPlanNode);
// AggregatePlanNode aggNode = AggregatePlanNode.getInlineAggregationNode(pn);
// assertNotNull(aggNode);
// NodeSchema ns = aggNode.getOutputSchema();
// assertEquals(2, ns.size());
// SchemaColumn aggColumn = ns.getColumns().get(1);
// assertEquals("$$_MAX_$$_1", aggColumn.getColumnAlias());
// AbstractExpression having = aggNode.getPostPredicate();
// assertEquals(ExpressionType.OPERATOR_EXISTS, having.getExpressionType());
// AbstractExpression se = having.getLeft();
// assertEquals(1, se.getArgs().size());
// assertTrue(se.getArgs().get(0) instanceof TupleValueExpression);
// TupleValueExpression argTve = (TupleValueExpression) se.getArgs().get(0);
// assertEquals(1, argTve.getColumnIndex());
// assertEquals("$$_MAX_$$_1", argTve.getColumnAlias());
// HAVING expression evaluates to TRUE and dropped
sql = "select a from r1 " + " group by a " + " having exists (select max(a) from r2) or max(c) > 0";
pn = compile(sql);
pn = pn.getChild(0);
assertTrue(pn instanceof SeqScanPlanNode);
aggNode = AggregatePlanNode.getInlineAggregationNode(pn);
assertNotNull(aggNode);
assertTrue(aggNode.getPostPredicate() == null);
// HAVING expression evaluates to FALSE and retained
sql = "select a from r1 " + " group by a " + " having exists (select max(a) from r2 limit 0) and max(c) > 0";
pn = compile(sql);
pn = pn.getChild(0);
assertTrue(pn instanceof ProjectionPlanNode);
pn = pn.getChild(0);
assertTrue(pn instanceof SeqScanPlanNode);
aggNode = AggregatePlanNode.getInlineAggregationNode(pn);
assertNotNull(aggNode);
AbstractExpression having = aggNode.getPostPredicate();
assertTrue(ConstantValueExpression.isBooleanFalse(having));
}
use of org.voltdb.plannodes.AggregatePlanNode in project voltdb by VoltDB.
the class TestPlansInExistsSubQueries method testInAggregated.
public void testInAggregated() {
AbstractPlanNode pn = compile("select a, sum(c) as sc1 from r1 where (a, c) in " + "( SELECT a, count(c) as sc2 " + "from r1 GROUP BY a ORDER BY a DESC) GROUP BY A;");
pn = pn.getChild(0);
assertTrue(pn instanceof AbstractScanPlanNode);
AbstractExpression e = ((AbstractScanPlanNode) pn).getPredicate();
assertEquals(ExpressionType.OPERATOR_EXISTS, e.getExpressionType());
AbstractSubqueryExpression subExpr = (AbstractSubqueryExpression) e.getLeft();
AbstractPlanNode sn = subExpr.getSubqueryNode();
// Added LIMIT 1
assertTrue(sn instanceof LimitPlanNode);
assertEquals(1, ((LimitPlanNode) sn).getLimit());
sn = sn.getChild(0);
assertTrue(sn instanceof SeqScanPlanNode);
AggregatePlanNode aggNode = AggregatePlanNode.getInlineAggregationNode(sn);
assertNotNull(aggNode.getPostPredicate());
}
use of org.voltdb.plannodes.AggregatePlanNode in project voltdb by VoltDB.
the class TestPushDownAggregates method checkPushedDown.
private void checkPushedDown(List<AbstractPlanNode> pn, boolean isAggInlined, ExpressionType[] aggTypes, ExpressionType[] pushDownTypes, boolean hasProjectionNode) {
// Aggregate push down check has to run on two fragments
assertTrue(pn.size() == 2);
AbstractPlanNode p = pn.get(0).getChild(0);
;
if (hasProjectionNode) {
// Complex aggregation or optimized AVG
assertTrue(p instanceof ProjectionPlanNode);
p = p.getChild(0);
}
assertTrue(p instanceof AggregatePlanNode);
String fragmentString = p.toJSONString();
ExpressionType[] topTypes = (pushDownTypes != null) ? pushDownTypes : aggTypes;
for (ExpressionType type : topTypes) {
assertTrue(fragmentString.contains("\"AGGREGATE_TYPE\":\"" + type.toString() + "\""));
}
// Check the pushed down aggregation
p = pn.get(1).getChild(0);
if (pushDownTypes == null) {
assertTrue(p instanceof AbstractScanPlanNode);
return;
}
if (isAggInlined) {
// See ENG-6131
if (p instanceof TableCountPlanNode) {
return;
}
assertTrue(p instanceof AbstractScanPlanNode);
assertTrue(p.getInlinePlanNode(PlanNodeType.AGGREGATE) != null || p.getInlinePlanNode(PlanNodeType.HASHAGGREGATE) != null);
if (p.getInlinePlanNode(PlanNodeType.AGGREGATE) != null) {
p = p.getInlinePlanNode(PlanNodeType.AGGREGATE);
} else {
p = p.getInlinePlanNode(PlanNodeType.HASHAGGREGATE);
}
} else {
assertTrue(p instanceof AggregatePlanNode);
}
fragmentString = p.toJSONString();
for (ExpressionType type : aggTypes) {
assertTrue(fragmentString.contains("\"AGGREGATE_TYPE\":\"" + type.toString() + "\""));
}
}
use of org.voltdb.plannodes.AggregatePlanNode in project voltdb by VoltDB.
the class PlanAssembler method pushDownAggregate.
/**
* Push the given aggregate if the plan is distributed, then add the
* coordinator node on top of the send/receive pair. If the plan
* is not distributed, or coordNode is not provided, the distNode
* is added at the top of the plan.
*
* Note: this works in part because the push-down node is also an acceptable
* top level node if the plan is not distributed. This wouldn't be true
* if we started pushing down something like (sum, count) to calculate
* a distributed average. (We already do something like this for
* APPROX_COUNT_DISTINCT, which must be split into two different functions
* for the pushed-down case.)
*
* @param root
* The root node
* @param distNode
* The node to push down
* @param coordNode [may be null]
* The top node to put on top of the send/receive pair after
* push-down. If this is null, no push-down will be performed.
* @return The new root node.
*/
private static AbstractPlanNode pushDownAggregate(AbstractPlanNode root, AggregatePlanNode distNode, AggregatePlanNode coordNode, ParsedSelectStmt selectStmt) {
AggregatePlanNode rootAggNode;
// to be pushed down past the receive as well.
if (coordNode != null) {
coordNode.m_isCoordinatingAggregator = true;
}
/*
* Push this node down to partition if it's distributed. First remove
* the send/receive pair, add the node, then put the send/receive pair
* back on top of the node, followed by another top node at the
* coordinator.
*/
if (coordNode != null && root instanceof ReceivePlanNode) {
AbstractPlanNode accessPlanTemp = root;
root = accessPlanTemp.getChild(0).getChild(0);
root.clearParents();
accessPlanTemp.getChild(0).clearChildren();
distNode.addAndLinkChild(root);
if (selectStmt.hasPartitionColumnInGroupby()) {
// Set post predicate for final distributed Aggregation node
distNode.setPostPredicate(selectStmt.getHavingPredicate());
// a very edge ORDER BY case.
if (selectStmt.isComplexOrderBy()) {
// Put the send/receive pair back into place
accessPlanTemp.getChild(0).addAndLinkChild(distNode);
root = processComplexAggProjectionNode(selectStmt, accessPlanTemp);
return root;
}
root = processComplexAggProjectionNode(selectStmt, distNode);
// Put the send/receive pair back into place
accessPlanTemp.getChild(0).addAndLinkChild(root);
return accessPlanTemp;
}
// Without including partition column in GROUP BY clause,
// there has to be a top GROUP BY plan node on coordinator.
//
// Now that we're certain the aggregate will be pushed down
// (no turning back now!), fix any APPROX_COUNT_DISTINCT aggregates.
fixDistributedApproxCountDistinct(distNode, coordNode);
// Put the send/receive pair back into place
accessPlanTemp.getChild(0).addAndLinkChild(distNode);
// Add the top node
coordNode.addAndLinkChild(accessPlanTemp);
rootAggNode = coordNode;
} else {
distNode.addAndLinkChild(root);
rootAggNode = distNode;
}
// Set post predicate for final Aggregation node.
rootAggNode.setPostPredicate(selectStmt.getHavingPredicate());
root = processComplexAggProjectionNode(selectStmt, rootAggNode);
return root;
}
Aggregations