Search in sources :

Example 16 with SchemaColumn

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

the class TestUnion method checkOrderByNode.

private void checkOrderByNode(AbstractPlanNode pn, String[] columns, int[] idxs) {
    assertTrue(pn != null);
    assertTrue(pn instanceof OrderByPlanNode);
    OrderByPlanNode opn = (OrderByPlanNode) pn;
    assertEquals(columns.length, opn.getOutputSchema().size());
    for (int i = 0; i < columns.length; ++i) {
        SchemaColumn col = opn.getOutputSchema().getColumns().get(i);
        assertEquals(columns[i], col.getColumnAlias());
        AbstractExpression colExpr = col.getExpression();
        assertEquals(ExpressionType.VALUE_TUPLE, colExpr.getExpressionType());
        assertEquals(idxs[i], ((TupleValueExpression) colExpr).getColumnIndex());
    }
}
Also used : AbstractExpression(org.voltdb.expressions.AbstractExpression) OrderByPlanNode(org.voltdb.plannodes.OrderByPlanNode) SchemaColumn(org.voltdb.plannodes.SchemaColumn)

Example 17 with SchemaColumn

use of org.voltdb.plannodes.SchemaColumn 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 18 with SchemaColumn

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

the class ParsedSelectStmt method prepareMVBasedQueryFix.

/**
     * Prepare for the mv based distributed query fix only if it might be required.
     */
private void prepareMVBasedQueryFix() {
    // aggregation push down does not need reAggregation work.
    if (m_hasComplexGroupby) {
        m_mvFixInfo.setEdgeCaseQueryNoFixNeeded(false);
    }
    // that need to be fixed should not exceed one.
    for (StmtTableScan mvTableScan : allScans()) {
        Set<SchemaColumn> mvNewScanColumns = new HashSet<>();
        Collection<SchemaColumn> columns = mvTableScan.getScanColumns();
        // TB has no scan columns
        if (columns != null) {
            mvNewScanColumns.addAll(columns);
        }
        // also need to be checked.
        if (m_mvFixInfo.processMVBasedQueryFix(mvTableScan, mvNewScanColumns, m_joinTree, m_aggResultColumns, groupByColumns())) {
            break;
        }
    }
}
Also used : SchemaColumn(org.voltdb.plannodes.SchemaColumn) StmtTableScan(org.voltdb.planner.parseinfo.StmtTableScan) HashSet(java.util.HashSet)

Example 19 with SchemaColumn

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

the class ParsedSelectStmt method isPartitionColumnInWindowedAggregatePartitionByList.

/**
     * Return true iff all the windowed partition expressions
     * have a table partition column in their partition by list,
     * and if there is one such windowed partition expression.
     * If there are no windowed expressions, we return false.
     * Note that there can only be one windowed
     * expression currently, so this is more general than it needs to be.
     *
     * @return
     */
public boolean isPartitionColumnInWindowedAggregatePartitionByList() {
    if (getWindowFunctionExpressions().size() == 0) {
        return false;
    }
    // If we ever do, this should fail gracelessly.
    assert (getWindowFunctionExpressions().size() == 1);
    WindowFunctionExpression we = getWindowFunctionExpressions().get(0);
    List<AbstractExpression> partitionByExprs = we.getPartitionByExpressions();
    boolean foundPartExpr = false;
    for (AbstractExpression ae : partitionByExprs) {
        if (!(ae instanceof TupleValueExpression)) {
            continue;
        }
        TupleValueExpression tve = (TupleValueExpression) ae;
        String tableAlias = tve.getTableAlias();
        String columnName = tve.getColumnName();
        StmtTableScan scanTable = getStmtTableScanByAlias(tableAlias);
        if (scanTable == null || scanTable.getPartitioningColumns() == null) {
            continue;
        }
        boolean foundPartCol = false;
        for (SchemaColumn pcol : scanTable.getPartitioningColumns()) {
            if (pcol != null && pcol.getColumnName().equals(columnName)) {
                foundPartCol = true;
                break;
            }
        }
        // in this windowed expression.
        if (foundPartCol) {
            foundPartExpr = true;
            break;
        }
    }
    return foundPartExpr;
}
Also used : TupleValueExpression(org.voltdb.expressions.TupleValueExpression) AbstractExpression(org.voltdb.expressions.AbstractExpression) WindowFunctionExpression(org.voltdb.expressions.WindowFunctionExpression) SchemaColumn(org.voltdb.plannodes.SchemaColumn) StmtTableScan(org.voltdb.planner.parseinfo.StmtTableScan)

Example 20 with SchemaColumn

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

the class StmtSubqueryScan method addPartitioningColumns.

private void addPartitioningColumns(List<SchemaColumn> scols) {
    // in order to be referenced on parent level.
    for (SchemaColumn partitionCol : scols) {
        SchemaColumn matchedCol = null;
        // Find whether the partition column is in output column list
        for (SchemaColumn outputCol : m_outputColumnList) {
            AbstractExpression outputExpr = outputCol.getExpression();
            if (!(outputExpr instanceof TupleValueExpression)) {
                continue;
            }
            TupleValueExpression tve = (TupleValueExpression) outputExpr;
            if (tve.getTableName().equals(partitionCol.getTableName()) && tve.getColumnName().equals(partitionCol.getColumnName())) {
                matchedCol = outputCol;
                break;
            }
        }
        String colNameForParentQuery;
        if (matchedCol != null) {
            colNameForParentQuery = matchedCol.getColumnAlias();
        } else // including partition column in its display column list
        if (!m_subqueriesPartitioning.requiresTwoFragments()) {
            colNameForParentQuery = partitionCol.getColumnName();
        } else {
            continue;
        }
        partitionCol.reset(m_tableAlias, m_tableAlias, colNameForParentQuery, colNameForParentQuery);
        m_partitioningColumns.add(partitionCol);
    }
}
Also used : TupleValueExpression(org.voltdb.expressions.TupleValueExpression) AbstractExpression(org.voltdb.expressions.AbstractExpression) SchemaColumn(org.voltdb.plannodes.SchemaColumn)

Aggregations

SchemaColumn (org.voltdb.plannodes.SchemaColumn)37 AbstractExpression (org.voltdb.expressions.AbstractExpression)19 TupleValueExpression (org.voltdb.expressions.TupleValueExpression)16 AbstractPlanNode (org.voltdb.plannodes.AbstractPlanNode)13 NodeSchema (org.voltdb.plannodes.NodeSchema)13 ProjectionPlanNode (org.voltdb.plannodes.ProjectionPlanNode)6 HashSet (java.util.HashSet)5 StmtTableScan (org.voltdb.planner.parseinfo.StmtTableScan)5 AbstractScanPlanNode (org.voltdb.plannodes.AbstractScanPlanNode)5 NestLoopPlanNode (org.voltdb.plannodes.NestLoopPlanNode)5 Table (org.voltdb.catalog.Table)4 OrderByPlanNode (org.voltdb.plannodes.OrderByPlanNode)4 SeqScanPlanNode (org.voltdb.plannodes.SeqScanPlanNode)4 ArrayList (java.util.ArrayList)3 HashMap (java.util.HashMap)3 Column (org.voltdb.catalog.Column)3 Constraint (org.voltdb.catalog.Constraint)3 AbstractReceivePlanNode (org.voltdb.plannodes.AbstractReceivePlanNode)3 SendPlanNode (org.voltdb.plannodes.SendPlanNode)3 Set (java.util.Set)2