use of org.voltdb.plannodes.HashAggregatePlanNode in project voltdb by VoltDB.
the class TestPlansScalarSubQueries method testSelectCorrelatedScalarInGroupbyClause.
public void testSelectCorrelatedScalarInGroupbyClause() {
String sql = "select franchise_id, count(*) as stores_in_category_AdHoc " + " from stores group by franchise_id, (select category from store_types where type_id = stores.type_id);";
AbstractPlanNode pn = compile(sql);
pn = pn.getChild(0);
assertTrue(pn instanceof ProjectionPlanNode);
NodeSchema schema = pn.getOutputSchema();
assertEquals(2, schema.size());
pn = pn.getChild(0);
assertTrue(pn instanceof AbstractScanPlanNode);
assertNotNull(pn.getInlinePlanNode(PlanNodeType.HASHAGGREGATE));
HashAggregatePlanNode aggNode = (HashAggregatePlanNode) pn.getInlinePlanNode(PlanNodeType.HASHAGGREGATE);
assertEquals(2, aggNode.getGroupByExpressionsSize());
AbstractExpression tveExpr = aggNode.getGroupByExpressions().get(0);
assertTrue(tveExpr instanceof TupleValueExpression);
AbstractExpression gbExpr = aggNode.getGroupByExpressions().get(1);
assertTrue(gbExpr instanceof ScalarValueExpression);
assertTrue(gbExpr.getLeft() instanceof SelectSubqueryExpression);
}
use of org.voltdb.plannodes.HashAggregatePlanNode in project voltdb by VoltDB.
the class InlineOrderByIntoMergeReceive method convertToSerialAggregation.
/**
* The Hash aggregate can be converted to a Serial or Partial aggregate if
* - all GROUP BY and ORDER BY expressions bind to each other - Serial Aggregate
* - a subset of the GROUP BY expressions covers all of the ORDER BY - Partial
* - anything else - remains a Hash Aggregate
* @param aggregateNode
* @param orderbyNode
* @return new aggregate node if the conversion is possible or the original hash aggregate otherwise
*/
AbstractPlanNode convertToSerialAggregation(AbstractPlanNode aggregateNode, OrderByPlanNode orderbyNode) {
assert (aggregateNode instanceof HashAggregatePlanNode);
HashAggregatePlanNode hashAggr = (HashAggregatePlanNode) aggregateNode;
List<AbstractExpression> groupbys = new ArrayList<>(hashAggr.getGroupByExpressions());
List<AbstractExpression> orderbys = new ArrayList<>(orderbyNode.getSortExpressions());
Set<Integer> coveredGroupByColumns = new HashSet<>();
Iterator<AbstractExpression> orderbyIt = orderbys.iterator();
while (orderbyIt.hasNext()) {
AbstractExpression orderby = orderbyIt.next();
int idx = 0;
for (AbstractExpression groupby : groupbys) {
if (!coveredGroupByColumns.contains(idx)) {
if (orderby.equals(groupby)) {
orderbyIt.remove();
coveredGroupByColumns.add(idx);
break;
}
}
++idx;
}
}
if (orderbys.isEmpty() && groupbys.size() == coveredGroupByColumns.size()) {
// All GROUP BY expressions are also ORDER BY - Serial aggregation
return AggregatePlanNode.convertToSerialAggregatePlanNode(hashAggr);
}
if (orderbys.isEmpty() && !coveredGroupByColumns.isEmpty()) {
// Partial aggregation
List<Integer> coveredGroupByColumnList = new ArrayList<>();
coveredGroupByColumnList.addAll(coveredGroupByColumns);
return AggregatePlanNode.convertToPartialAggregatePlanNode(hashAggr, coveredGroupByColumnList);
}
return aggregateNode;
}
use of org.voltdb.plannodes.HashAggregatePlanNode in project voltdb by VoltDB.
the class TestPlansGroupBy method checkMVFixWithWhere.
private void checkMVFixWithWhere(List<AbstractPlanNode> pns, Object aggFilters, Object scanFilters) {
AbstractPlanNode p = pns.get(0);
List<AbstractPlanNode> nodes = p.findAllNodesOfClass(AbstractReceivePlanNode.class);
assertEquals(1, nodes.size());
p = nodes.get(0);
// Find re-aggregation node.
assertTrue(p instanceof ReceivePlanNode);
assertTrue(p.getParent(0) instanceof HashAggregatePlanNode);
HashAggregatePlanNode reAggNode = (HashAggregatePlanNode) p.getParent(0);
String reAggNodeStr = reAggNode.toExplainPlanString().toLowerCase();
// Find scan node.
p = pns.get(1);
assertEquals(1, p.getScanNodeList().size());
p = p.getScanNodeList().get(0);
String scanNodeStr = p.toExplainPlanString().toLowerCase();
if (aggFilters != null) {
String[] aggFilterStrings = null;
if (aggFilters instanceof String) {
aggFilterStrings = new String[] { (String) aggFilters };
} else {
aggFilterStrings = (String[]) aggFilters;
}
for (String aggFilter : aggFilterStrings) {
//* enable to debug */ System.out.println(reAggNodeStr.contains(aggFilter.toLowerCase()));
assertTrue(reAggNodeStr.contains(aggFilter.toLowerCase()));
//* enable to debug */ System.out.println(scanNodeStr.contains(aggFilter.toLowerCase()));
assertFalse(scanNodeStr.contains(aggFilter.toLowerCase()));
}
} else {
assertNull(reAggNode.getPostPredicate());
}
if (scanFilters != null) {
String[] scanFilterStrings = null;
if (scanFilters instanceof String) {
scanFilterStrings = new String[] { (String) scanFilters };
} else {
scanFilterStrings = (String[]) scanFilters;
}
for (String scanFilter : scanFilterStrings) {
//* enable to debug */ System.out.println(reAggNodeStr.contains(scanFilter.toLowerCase()));
assertFalse(reAggNodeStr.contains(scanFilter.toLowerCase()));
//* enable to debug */ System.out.println(scanNodeStr.contains(scanFilter.toLowerCase()));
assertTrue(scanNodeStr.contains(scanFilter.toLowerCase()));
}
}
}
use of org.voltdb.plannodes.HashAggregatePlanNode in project voltdb by VoltDB.
the class TestPlansGroupBy method testCountDistinct.
public void testCountDistinct() {
AbstractPlanNode p;
List<AbstractPlanNode> pns;
// push down distinct because of group by partition column
pns = compileToFragments("SELECT A4, count(distinct B4) FROM T4 GROUP BY A4");
p = pns.get(0).getChild(0);
assertTrue(p instanceof ReceivePlanNode);
p = pns.get(1).getChild(0);
assertTrue(p instanceof AbstractScanPlanNode);
assertNotNull(p.getInlinePlanNode(PlanNodeType.HASHAGGREGATE));
// group by multiple columns
pns = compileToFragments("SELECT C4, A4, count(distinct B4) FROM T4 GROUP BY C4, A4");
p = pns.get(0).getChild(0);
assertTrue(p instanceof ReceivePlanNode);
p = pns.get(1).getChild(0);
assertTrue(p instanceof AbstractScanPlanNode);
assertNotNull(p.getInlinePlanNode(PlanNodeType.HASHAGGREGATE));
// not push down distinct
pns = compileToFragments("SELECT ABS(A4), count(distinct B4) FROM T4 GROUP BY ABS(A4)");
p = pns.get(0).getChild(0);
assertTrue(p instanceof HashAggregatePlanNode);
assertTrue(p.getChild(0) instanceof ReceivePlanNode);
p = pns.get(1).getChild(0);
assertTrue(p instanceof AbstractScanPlanNode);
assertNull(p.getInlinePlanNode(PlanNodeType.HASHAGGREGATE));
// test not group by partition column with index available
pns = compileToFragments("SELECT A.NUM, COUNT(DISTINCT A.ID ) AS Q58 FROM P2 A GROUP BY A.NUM; ");
p = pns.get(0).getChild(0);
assertTrue(p instanceof HashAggregatePlanNode);
assertTrue(p.getChild(0) instanceof ReceivePlanNode);
p = pns.get(1).getChild(0);
assertTrue(p instanceof IndexScanPlanNode);
assertTrue(p.toExplainPlanString().contains("for deterministic order only"));
}
Aggregations