Search in sources :

Example 6 with HashAggregatePlanNode

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

the class TestPlansGroupBy method checkMVReaggregateFeature.

// topNode, reAggNode
private void checkMVReaggregateFeature(List<AbstractPlanNode> pns, boolean needFix, int numGroupByOfTopAggNode, int numAggsOfTopAggNode, int numGroupByOfReaggNode, int numAggsOfReaggNode, boolean aggPushdown, boolean aggInline) {
    assertEquals(2, pns.size());
    AbstractPlanNode p = pns.get(0);
    assertTrue(p instanceof SendPlanNode);
    p = p.getChild(0);
    if (p instanceof ProjectionPlanNode) {
        p = p.getChild(0);
    }
    if (p instanceof LimitPlanNode) {
        // No limit pushed down.
        p = p.getChild(0);
    }
    if (p instanceof OrderByPlanNode) {
        p = p.getChild(0);
    }
    HashAggregatePlanNode reAggNode = null;
    List<AbstractPlanNode> nodes = p.findAllNodesOfClass(AbstractReceivePlanNode.class);
    assertEquals(1, nodes.size());
    AbstractPlanNode receiveNode = nodes.get(0);
    // Indicates that there is no top aggregation node.
    if (numGroupByOfTopAggNode == -1) {
        if (needFix) {
            p = receiveNode.getParent(0);
            assertTrue(p instanceof HashAggregatePlanNode);
            reAggNode = (HashAggregatePlanNode) p;
            assertEquals(numGroupByOfReaggNode, reAggNode.getGroupByExpressionsSize());
            assertEquals(numAggsOfReaggNode, reAggNode.getAggregateTypesSize());
            p = p.getChild(0);
        }
        assertTrue(p instanceof ReceivePlanNode);
        p = pns.get(1);
        assertTrue(p instanceof SendPlanNode);
        p = p.getChild(0);
        assertTrue(p instanceof AbstractScanPlanNode);
        return;
    }
    if (p instanceof ProjectionPlanNode) {
        p = p.getChild(0);
    }
    //
    // Hash top aggregate node
    //
    AggregatePlanNode topAggNode = null;
    if (p instanceof AbstractJoinPlanNode) {
        // Inline aggregation with join
        topAggNode = AggregatePlanNode.getInlineAggregationNode(p);
    } else {
        assertTrue(p instanceof AggregatePlanNode);
        topAggNode = (AggregatePlanNode) p;
        p = p.getChild(0);
    }
    assertEquals(numGroupByOfTopAggNode, topAggNode.getGroupByExpressionsSize());
    assertEquals(numAggsOfTopAggNode, topAggNode.getAggregateTypesSize());
    if (needFix) {
        p = receiveNode.getParent(0);
        assertTrue(p instanceof HashAggregatePlanNode);
        reAggNode = (HashAggregatePlanNode) p;
        assertEquals(numGroupByOfReaggNode, reAggNode.getGroupByExpressionsSize());
        assertEquals(numAggsOfReaggNode, reAggNode.getAggregateTypesSize());
        p = p.getChild(0);
    }
    assertTrue(p instanceof ReceivePlanNode);
    // Test the second part
    p = pns.get(1);
    assertTrue(p instanceof SendPlanNode);
    p = p.getChild(0);
    if (aggPushdown) {
        assertTrue(!needFix);
        if (aggInline) {
            assertNotNull(AggregatePlanNode.getInlineAggregationNode(p));
        } else {
            assertTrue(p instanceof AggregatePlanNode);
            p = p.getChild(0);
        }
    }
    if (needFix) {
        assertTrue(p instanceof AbstractScanPlanNode);
    } else {
        assertTrue(p instanceof AbstractScanPlanNode || p instanceof AbstractJoinPlanNode);
    }
}
Also used : AbstractPlanNode(org.voltdb.plannodes.AbstractPlanNode) AbstractScanPlanNode(org.voltdb.plannodes.AbstractScanPlanNode) OrderByPlanNode(org.voltdb.plannodes.OrderByPlanNode) HashAggregatePlanNode(org.voltdb.plannodes.HashAggregatePlanNode) AggregatePlanNode(org.voltdb.plannodes.AggregatePlanNode) SendPlanNode(org.voltdb.plannodes.SendPlanNode) ReceivePlanNode(org.voltdb.plannodes.ReceivePlanNode) AbstractReceivePlanNode(org.voltdb.plannodes.AbstractReceivePlanNode) AbstractJoinPlanNode(org.voltdb.plannodes.AbstractJoinPlanNode) HashAggregatePlanNode(org.voltdb.plannodes.HashAggregatePlanNode) LimitPlanNode(org.voltdb.plannodes.LimitPlanNode) ProjectionPlanNode(org.voltdb.plannodes.ProjectionPlanNode)

Example 7 with HashAggregatePlanNode

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

the class TestPlansSubQueries method testPartitionedGroupByWithoutAggregate.

public void testPartitionedGroupByWithoutAggregate() {
    AbstractPlanNode pn;
    List<AbstractPlanNode> planNodes;
    // group by non-partition column, no pushed down
    planNodes = compileToFragments("SELECT * FROM (SELECT C FROM P1 GROUP BY C) T1");
    assertEquals(2, planNodes.size());
    pn = planNodes.get(0).getChild(0);
    checkSeqScan(pn, "T1");
    pn = pn.getChild(0);
    assertTrue(pn instanceof HashAggregatePlanNode);
    pn = planNodes.get(1).getChild(0);
    checkPrimaryKeyIndexScan(pn, "P1");
    // count(*), no pushed down
    planNodes = compileToFragments("SELECT count(*) FROM (SELECT c FROM P1 GROUP BY c) T1");
    assertEquals(2, planNodes.size());
    pn = planNodes.get(0).getChild(0);
    assertTrue(pn instanceof TableCountPlanNode);
    pn = pn.getChild(0);
    assertTrue(pn instanceof HashAggregatePlanNode);
    pn = planNodes.get(1).getChild(0);
    checkPrimaryKeyIndexScan(pn, "P1");
    // group by partition column, pushed down
    planNodes = compileToFragments("SELECT * FROM (SELECT A FROM P1 GROUP BY A) T1");
    assertEquals(2, planNodes.size());
    pn = planNodes.get(0).getChild(0);
    assertTrue(pn instanceof ProjectionPlanNode);
    assertTrue(pn.getChild(0) instanceof ReceivePlanNode);
    pn = planNodes.get(1).getChild(0);
    checkSeqScan(pn, "T1");
    pn = pn.getChild(0);
    checkPrimaryKeyIndexScan(pn, "P1");
    planNodes = compileToFragments("SELECT count(*) FROM (SELECT A FROM P1 GROUP BY A) T1");
    assertEquals(2, planNodes.size());
    pn = planNodes.get(0).getChild(0);
    assertTrue(pn.getChild(0) instanceof ReceivePlanNode);
    pn = planNodes.get(1).getChild(0);
    assertTrue(pn instanceof TableCountPlanNode);
    pn = pn.getChild(0);
    checkPrimaryKeyIndexScan(pn, "P1");
}
Also used : AbstractPlanNode(org.voltdb.plannodes.AbstractPlanNode) MergeReceivePlanNode(org.voltdb.plannodes.MergeReceivePlanNode) ReceivePlanNode(org.voltdb.plannodes.ReceivePlanNode) HashAggregatePlanNode(org.voltdb.plannodes.HashAggregatePlanNode) TableCountPlanNode(org.voltdb.plannodes.TableCountPlanNode) ProjectionPlanNode(org.voltdb.plannodes.ProjectionPlanNode)

Example 8 with HashAggregatePlanNode

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

the class TestPlansSubQueries method testPartitionedSameLevel.

public void testPartitionedSameLevel() {
    // force it to be single partitioned.
    AbstractPlanNode pn;
    List<AbstractPlanNode> planNodes;
    String sql, sqlNoSimplification, equivalentSql;
    //
    // Single partition detection : single table
    //
    sql = "select A FROM (SELECT A FROM P1 WHERE A = 3) T1 ";
    sqlNoSimplification = "select A FROM (SELECT A FROM P1 WHERE A = 3 LIMIT 1) T1 ";
    equivalentSql = "SELECT A FROM P1 T1 WHERE A = 3";
    planNodes = compileToFragments(sqlNoSimplification);
    assertEquals(1, planNodes.size());
    pn = planNodes.get(0);
    assertTrue(pn instanceof SendPlanNode);
    pn = pn.getChild(0);
    checkSeqScan(pn, "T1", "A");
    pn = pn.getChild(0);
    checkPrimaryKeyIndexScan(pn, "P1", "A");
    assertNotNull(((IndexScanPlanNode) pn).getInlinePlanNode(PlanNodeType.PROJECTION));
    checkSubquerySimplification(sql, equivalentSql);
    sql = "select A, C FROM (SELECT A, C FROM P1 WHERE A = 3) T1 ";
    sqlNoSimplification = "select A, C FROM (SELECT A, C FROM P1 WHERE A = 3 LIMIT 1) T1 ";
    equivalentSql = "SELECT A, C FROM P1 T1 WHERE A = 3";
    planNodes = compileToFragments(sqlNoSimplification);
    assertEquals(1, planNodes.size());
    pn = planNodes.get(0);
    assertTrue(pn instanceof SendPlanNode);
    pn = pn.getChild(0);
    checkSeqScan(pn, "T1", "A", "C");
    pn = pn.getChild(0);
    checkPrimaryKeyIndexScan(pn, "P1", "A", "C");
    assertNotNull(((IndexScanPlanNode) pn).getInlinePlanNode(PlanNodeType.PROJECTION));
    checkSubquerySimplification(sql, equivalentSql);
    // Single partition query without selecting partition column from sub-query
    planNodes = compileToFragments("select C FROM (SELECT A, C FROM P1 WHERE A = 3 LIMIT 1) T1 ");
    assertEquals(1, planNodes.size());
    planNodes = compileToFragments("select C FROM (SELECT C FROM P1 WHERE A = 3 LIMIT 1) T1 ");
    assertEquals(1, planNodes.size());
    //
    // AdHoc multiple partitioned sub-select queries.
    //
    sql = "select A1, C FROM (SELECT A A1, C FROM P1) T1  ";
    sqlNoSimplification = "select A1, C FROM (SELECT DISTINCT A A1, C FROM P1) T1 ";
    equivalentSql = "SELECT A A1, C FROM P1 T1";
    planNodes = compileToFragments(sqlNoSimplification);
    assertEquals(2, planNodes.size());
    pn = planNodes.get(0).getChild(0);
    assertTrue(pn instanceof ProjectionPlanNode);
    pn = pn.getChild(0);
    assertTrue(pn instanceof ReceivePlanNode);
    pn = planNodes.get(1).getChild(0);
    checkSeqScan(pn, "T1", "A1", "C");
    checkSubquerySimplification(sql, equivalentSql);
    sql = "select A1 FROM (SELECT A A1, C FROM P1 WHERE A > 3) T1 ";
    sqlNoSimplification = "select A1 FROM (SELECT A A1, C FROM P1 WHERE A > 3 LIMIT 10) T1 ";
    equivalentSql = "SELECT A A1 FROM P1 T1 WHERE A > 3";
    planNodes = compileToFragments(sqlNoSimplification);
    assertEquals(2, planNodes.size());
    pn = planNodes.get(0).getChild(0);
    checkSeqScan(pn, "T1", "A1");
    checkSubquerySimplification(sql, equivalentSql);
    //
    // Group by
    //
    planNodes = compileToFragments("select C, SD FROM " + "(SELECT C, SUM(D) as SD FROM P1 GROUP BY C) T1 ");
    assertEquals(2, planNodes.size());
    pn = planNodes.get(0).getChild(0);
    checkSeqScan(pn, "T1", "C", "SD");
    assertNotNull(pn.getInlinePlanNode(PlanNodeType.PROJECTION));
    pn = pn.getChild(0);
    assertTrue(pn instanceof HashAggregatePlanNode);
    pn = pn.getChild(0);
    assertTrue(pn instanceof ReceivePlanNode);
    pn = planNodes.get(1);
    assertTrue(pn instanceof SendPlanNode);
    pn = pn.getChild(0);
    checkPrimaryKeyIndexScan(pn, "P1", "C", "SD");
    assertNotNull(pn.getInlinePlanNode(PlanNodeType.PROJECTION));
    assertNotNull(pn.getInlinePlanNode(PlanNodeType.HASHAGGREGATE));
    // rename group by column
    planNodes = compileToFragments("select X, SD FROM " + "(SELECT C AS X, SUM(D) as SD FROM P1 GROUP BY C) T1 ");
    assertEquals(2, planNodes.size());
    pn = planNodes.get(0).getChild(0);
    checkSeqScan(pn, "T1", "X", "SD");
    assertNotNull(pn.getInlinePlanNode(PlanNodeType.PROJECTION));
    pn = pn.getChild(0);
    assertTrue(pn instanceof HashAggregatePlanNode);
    pn = pn.getChild(0);
    assertTrue(pn instanceof ReceivePlanNode);
    pn = planNodes.get(1);
    assertTrue(pn instanceof SendPlanNode);
    pn = pn.getChild(0);
    checkPrimaryKeyIndexScan(pn, "P1", "C", "SD");
    assertNotNull(pn.getInlinePlanNode(PlanNodeType.PROJECTION));
    assertNotNull(pn.getInlinePlanNode(PlanNodeType.HASHAGGREGATE));
    AbstractPlanNode nlpn;
    //
    // Partitioned Joined tests
    //
    failToCompile("select * FROM " + "(SELECT C, SUM(D) as SD FROM P1 GROUP BY C) T1, P2 where T1.C = P2.A ", joinErrorMsg);
    planNodes = compileToFragments("select T1.C, T1.SD FROM " + "(SELECT C, SUM(D) as SD FROM P1 GROUP BY C) T1, R1 Where T1.C = R1.C ");
    assertEquals(2, planNodes.size());
    pn = planNodes.get(0).getChild(0);
    assertTrue(pn instanceof ProjectionPlanNode);
    nlpn = pn.getChild(0);
    assertTrue(nlpn instanceof NestLoopPlanNode);
    pn = nlpn.getChild(1);
    checkSeqScan(pn, "R1");
    pn = nlpn.getChild(0);
    checkSeqScan(pn, "T1", "C", "SD");
    assertNotNull(pn.getInlinePlanNode(PlanNodeType.PROJECTION));
    pn = pn.getChild(0);
    assertTrue(pn instanceof HashAggregatePlanNode);
    pn = pn.getChild(0);
    assertTrue(pn instanceof ReceivePlanNode);
    pn = planNodes.get(1);
    assertTrue(pn instanceof SendPlanNode);
    pn = pn.getChild(0);
    checkPrimaryKeyIndexScan(pn, "P1", "C", "SD");
    assertNotNull(pn.getInlinePlanNode(PlanNodeType.PROJECTION));
    assertNotNull(pn.getInlinePlanNode(PlanNodeType.HASHAGGREGATE));
    // Group by Partitioned column
    planNodes = compileToFragments("select C, SD FROM " + "(SELECT A, C, SUM(D) as SD FROM P1 WHERE A > 3 GROUP BY A, C) T1 ");
    assertEquals(2, planNodes.size());
    planNodes = compileToFragments("select C, SD FROM " + "(SELECT A, C, SUM(D) as SD FROM P1 WHERE A = 3 GROUP BY A, C) T1 ");
    assertEquals(1, planNodes.size());
    planNodes = compileToFragments("select T1.C, T1.SD FROM " + "(SELECT A, C, SUM(D) as SD FROM P1 WHERE A = 3 GROUP BY A, C) T1, R1 WHERE T1.C = R1.C ");
    assertEquals(1, planNodes.size());
    //
    // Limit
    //
    planNodes = compileToFragments("select C FROM (SELECT C FROM P1 WHERE A > 3 ORDER BY C LIMIT 5) T1 ");
    assertEquals(2, planNodes.size());
    planNodes = compileToFragments("select T1.C FROM (SELECT C FROM P1 WHERE A > 3 ORDER BY C LIMIT 5) T1, " + "R1 WHERE T1.C > R1.C ");
    assertEquals(2, planNodes.size());
    planNodes = compileToFragments("select C FROM (SELECT A, C FROM P1 WHERE A = 3 ORDER BY C LIMIT 5) T1 ");
    assertEquals(1, planNodes.size());
    // Without selecting partition column from sub-query
    planNodes = compileToFragments(("select C FROM (SELECT C FROM P1 WHERE A = 3 ORDER BY C LIMIT 5) T1 "));
    assertEquals(1, planNodes.size());
    planNodes = compileToFragments("select T1.C FROM (SELECT A, C FROM P1 WHERE A = 3 ORDER BY C LIMIT 5) T1, " + "R1 WHERE T1.C > R1.C ");
    assertEquals(1, planNodes.size());
    // Without selecting partition column from sub-query
    planNodes = compileToFragments("select T1.C FROM (SELECT C FROM P1 WHERE A = 3 ORDER BY C LIMIT 5) T1, " + "R1 WHERE T1.C > R1.C ");
    assertEquals(1, planNodes.size());
    //
    // Group by & LIMIT 5
    //
    planNodes = compileToFragments("select C, SD FROM " + "(SELECT C, SUM(D) as SD FROM P1 GROUP BY C ORDER BY C LIMIT 5) T1 ");
    assertEquals(2, planNodes.size());
    // Without selecting partition column from sub-query
    planNodes = compileToFragments("select C, SD FROM " + "(SELECT C, SUM(D) as SD FROM P1 WHERE A = 3 GROUP BY C ORDER BY C LIMIT 5) T1 ");
    assertEquals(1, planNodes.size());
}
Also used : AbstractPlanNode(org.voltdb.plannodes.AbstractPlanNode) SendPlanNode(org.voltdb.plannodes.SendPlanNode) MergeReceivePlanNode(org.voltdb.plannodes.MergeReceivePlanNode) ReceivePlanNode(org.voltdb.plannodes.ReceivePlanNode) HashAggregatePlanNode(org.voltdb.plannodes.HashAggregatePlanNode) NestLoopPlanNode(org.voltdb.plannodes.NestLoopPlanNode) ProjectionPlanNode(org.voltdb.plannodes.ProjectionPlanNode)

Example 9 with HashAggregatePlanNode

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

the class MaterializedViewFixInfo method processMVBasedQueryFix.

/**
     * Check whether the results from a materialized view need to be
     * re-aggregated on the coordinator by the view's GROUP BY columns
     * prior to any of the processing specified by the query.
     * This is normally the case when a mat view's source table is partitioned
     * and the view's GROUP BY does not include the partition key.
     * There is a special edge case where the query already contains the exact
     * reaggregations that the added-cost fix would introduce, so the fix can
     * be skipped as an optimization.
     * Set the m_needed flag to true, only if the reaggregation fix is needed.
     * @return The value of m_needed
     */
public boolean processMVBasedQueryFix(StmtTableScan mvTableScan, Set<SchemaColumn> scanColumns, JoinNode joinTree, List<ParsedColInfo> displayColumns, List<ParsedColInfo> groupByColumns) {
    //@TODO
    if (!(mvTableScan instanceof StmtTargetTableScan)) {
        return false;
    }
    Table table = ((StmtTargetTableScan) mvTableScan).getTargetTable();
    assert (table != null);
    String mvTableName = table.getTypeName();
    Table srcTable = table.getMaterializer();
    if (srcTable == null) {
        return false;
    }
    if (table.getIsreplicated()) {
        return false;
    }
    // Justify whether partition column is in group by column list or not
    if (table.getPartitioncolumn() != null) {
        return false;
    }
    m_mvTableScan = mvTableScan;
    Set<String> mvDDLGroupbyColumnNames = new HashSet<>();
    List<Column> mvColumnArray = CatalogUtil.getSortedCatalogItems(table.getColumns(), "index");
    String mvTableAlias = getMVTableAlias();
    // Get the number of group-by columns.
    int numOfGroupByColumns;
    MaterializedViewInfo mvInfo = srcTable.getViews().get(mvTableName);
    if (mvInfo != null) {
        // single table view
        String complexGroupbyJson = mvInfo.getGroupbyexpressionsjson();
        if (complexGroupbyJson.length() > 0) {
            List<AbstractExpression> mvComplexGroupbyCols = null;
            try {
                mvComplexGroupbyCols = AbstractExpression.fromJSONArrayString(complexGroupbyJson, null);
            } catch (JSONException e) {
                e.printStackTrace();
            }
            numOfGroupByColumns = mvComplexGroupbyCols.size();
        } else {
            numOfGroupByColumns = mvInfo.getGroupbycols().size();
        }
    } else {
        // joined table view
        MaterializedViewHandlerInfo mvHandlerInfo = table.getMvhandlerinfo().get("mvHandlerInfo");
        numOfGroupByColumns = mvHandlerInfo.getGroupbycolumncount();
    }
    if (scanColumns.isEmpty() && numOfGroupByColumns == 0) {
        // This is an edge case that can happen if the view
        // has no group by keys, and we are just
        // doing a count(*) on the output of the view.
        //
        // Having no GB keys or scan columns would cause us to
        // produce plan nodes that have a 0-column output schema.
        // We can't handle this in several places, so add the
        // count(*) column from the view to the scan columns.
        // this is the "count(*)" column.
        Column mvCol = mvColumnArray.get(0);
        TupleValueExpression tve = new TupleValueExpression(mvTableName, mvTableAlias, mvCol, 0);
        tve.setOrigStmtId(mvTableScan.getStatementId());
        String colName = mvCol.getName();
        SchemaColumn scol = new SchemaColumn(mvTableName, mvTableAlias, colName, colName, tve);
        scanColumns.add(scol);
    }
    // Start to do real materialized view processing to fix the duplicates problem.
    // (1) construct new projection columns for scan plan node.
    Set<SchemaColumn> mvDDLGroupbyColumns = new HashSet<>();
    NodeSchema inlineProjSchema = new NodeSchema();
    for (SchemaColumn scol : scanColumns) {
        inlineProjSchema.addColumn(scol);
    }
    for (int i = 0; i < numOfGroupByColumns; i++) {
        Column mvCol = mvColumnArray.get(i);
        String colName = mvCol.getName();
        TupleValueExpression tve = new TupleValueExpression(mvTableName, mvTableAlias, mvCol, i);
        tve.setOrigStmtId(mvTableScan.getStatementId());
        mvDDLGroupbyColumnNames.add(colName);
        SchemaColumn scol = new SchemaColumn(mvTableName, mvTableAlias, colName, colName, tve);
        mvDDLGroupbyColumns.add(scol);
        if (!scanColumns.contains(scol)) {
            scanColumns.add(scol);
            // construct new projection columns for scan plan node.
            inlineProjSchema.addColumn(scol);
        }
    }
    // Record the re-aggregation type for each scan columns.
    Map<String, ExpressionType> mvColumnReAggType = new HashMap<>();
    for (int i = numOfGroupByColumns; i < mvColumnArray.size(); i++) {
        Column mvCol = mvColumnArray.get(i);
        ExpressionType reAggType = ExpressionType.get(mvCol.getAggregatetype());
        if (reAggType == ExpressionType.AGGREGATE_COUNT_STAR || reAggType == ExpressionType.AGGREGATE_COUNT) {
            reAggType = ExpressionType.AGGREGATE_SUM;
        }
        mvColumnReAggType.put(mvCol.getName(), reAggType);
    }
    assert (inlineProjSchema.size() > 0);
    m_scanInlinedProjectionNode = new ProjectionPlanNode(inlineProjSchema);
    // (2) Construct the reAggregation Node.
    // Construct the reAggregation plan node's aggSchema
    m_reAggNode = new HashAggregatePlanNode();
    int outputColumnIndex = 0;
    // inlineProjSchema contains the group by columns, while aggSchema may do not.
    NodeSchema aggSchema = new NodeSchema();
    // Construct reAggregation node's aggregation and group by list.
    for (SchemaColumn scol : inlineProjSchema.getColumns()) {
        if (mvDDLGroupbyColumns.contains(scol)) {
            // Add group by expression.
            m_reAggNode.addGroupByExpression(scol.getExpression());
        } else {
            ExpressionType reAggType = mvColumnReAggType.get(scol.getColumnName());
            assert (reAggType != null);
            AbstractExpression agg_input_expr = scol.getExpression();
            assert (agg_input_expr instanceof TupleValueExpression);
            // Add aggregation information.
            m_reAggNode.addAggregate(reAggType, false, outputColumnIndex, agg_input_expr);
        }
        aggSchema.addColumn(scol);
        outputColumnIndex++;
    }
    assert (aggSchema.size() > 0);
    m_reAggNode.setOutputSchema(aggSchema);
    // Collect all TVEs that need to be do re-aggregation in coordinator.
    List<TupleValueExpression> needReAggTVEs = new ArrayList<>();
    List<AbstractExpression> aggPostExprs = new ArrayList<>();
    for (int i = numOfGroupByColumns; i < mvColumnArray.size(); i++) {
        Column mvCol = mvColumnArray.get(i);
        TupleValueExpression tve = new TupleValueExpression(mvTableName, mvTableAlias, mvCol, -1);
        tve.setOrigStmtId(mvTableScan.getStatementId());
        needReAggTVEs.add(tve);
    }
    collectReAggNodePostExpressions(joinTree, needReAggTVEs, aggPostExprs);
    AbstractExpression aggPostExpr = ExpressionUtil.combinePredicates(aggPostExprs);
    // Add post filters for the reAggregation node.
    m_reAggNode.setPostPredicate(aggPostExpr);
    // ENG-5386
    if (m_edgeCaseQueryNoFixNeeded && edgeCaseQueryNoFixNeeded(mvDDLGroupbyColumnNames, mvColumnReAggType, displayColumns, groupByColumns)) {
        return false;
    }
    m_needed = true;
    return true;
}
Also used : MaterializedViewInfo(org.voltdb.catalog.MaterializedViewInfo) TupleValueExpression(org.voltdb.expressions.TupleValueExpression) Table(org.voltdb.catalog.Table) HashMap(java.util.HashMap) SchemaColumn(org.voltdb.plannodes.SchemaColumn) HashAggregatePlanNode(org.voltdb.plannodes.HashAggregatePlanNode) ArrayList(java.util.ArrayList) JSONException(org.json_voltpatches.JSONException) AbstractExpression(org.voltdb.expressions.AbstractExpression) Column(org.voltdb.catalog.Column) SchemaColumn(org.voltdb.plannodes.SchemaColumn) StmtTargetTableScan(org.voltdb.planner.parseinfo.StmtTargetTableScan) MaterializedViewHandlerInfo(org.voltdb.catalog.MaterializedViewHandlerInfo) ExpressionType(org.voltdb.types.ExpressionType) NodeSchema(org.voltdb.plannodes.NodeSchema) HashSet(java.util.HashSet) ProjectionPlanNode(org.voltdb.plannodes.ProjectionPlanNode)

Example 10 with HashAggregatePlanNode

use of org.voltdb.plannodes.HashAggregatePlanNode 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

HashAggregatePlanNode (org.voltdb.plannodes.HashAggregatePlanNode)14 AbstractPlanNode (org.voltdb.plannodes.AbstractPlanNode)11 ReceivePlanNode (org.voltdb.plannodes.ReceivePlanNode)9 AbstractReceivePlanNode (org.voltdb.plannodes.AbstractReceivePlanNode)7 ProjectionPlanNode (org.voltdb.plannodes.ProjectionPlanNode)7 MergeReceivePlanNode (org.voltdb.plannodes.MergeReceivePlanNode)6 AbstractExpression (org.voltdb.expressions.AbstractExpression)5 AbstractScanPlanNode (org.voltdb.plannodes.AbstractScanPlanNode)4 AggregatePlanNode (org.voltdb.plannodes.AggregatePlanNode)4 SendPlanNode (org.voltdb.plannodes.SendPlanNode)4 TupleValueExpression (org.voltdb.expressions.TupleValueExpression)3 NodeSchema (org.voltdb.plannodes.NodeSchema)3 OrderByPlanNode (org.voltdb.plannodes.OrderByPlanNode)3 ArrayList (java.util.ArrayList)2 HashSet (java.util.HashSet)2 AbstractJoinPlanNode (org.voltdb.plannodes.AbstractJoinPlanNode)2 LimitPlanNode (org.voltdb.plannodes.LimitPlanNode)2 NestLoopPlanNode (org.voltdb.plannodes.NestLoopPlanNode)2 PartialAggregatePlanNode (org.voltdb.plannodes.PartialAggregatePlanNode)2 SchemaColumn (org.voltdb.plannodes.SchemaColumn)2