Search in sources :

Example 11 with NodeSchema

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

the class TestPlansScalarSubQueries method testSelectScalar.

public void testSelectScalar() {
    AbstractPlanNode pn = compile("select r2.c, (select d from r1) scalar from r2");
    pn = pn.getChild(0);
    assertTrue(pn instanceof AbstractScanPlanNode);
    AbstractPlanNode proj = pn.getInlinePlanNode(PlanNodeType.PROJECTION);
    NodeSchema schema = proj.getOutputSchema();
    assertEquals(2, schema.size());
    SchemaColumn col = schema.getColumns().get(1);
    assertTrue(col != null);
    assertEquals("SCALAR", col.getColumnName());
}
Also used : AbstractPlanNode(org.voltdb.plannodes.AbstractPlanNode) AbstractScanPlanNode(org.voltdb.plannodes.AbstractScanPlanNode) SchemaColumn(org.voltdb.plannodes.SchemaColumn) NodeSchema(org.voltdb.plannodes.NodeSchema)

Example 12 with NodeSchema

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

the class TestWindowedFunctions method validateWindowedFunctionPlan.

/**
     * Validate that each similar windowed query in testRank produces a similar
     * plan, with the expected minor variation to its ORDER BY node.
     * @param windowedQuery a variant of a test query of a known basic format
     * @param nSorts the expected number of sort criteria that should have been
     *        extracted from the variant query's PARTITION BY and ORDER BY.
     * @param descSortIndex the position among the sort criteria of the original
     *        ORDER BY column, always distinguishable by its "DESC" direction.
     **/
private void validateWindowedFunctionPlan(String windowedQuery, int nSorts, int descSortIndex, int numPartitionExprs, ExpressionType winOpType) {
    // Sometimes we get multi-fragment nodes when we
    // expect single fragment nodes.  Keeping all the fragments
    // helps to diagnose the problem.
    List<AbstractPlanNode> nodes = compileToFragments(windowedQuery);
    assertEquals(1, nodes.size());
    AbstractPlanNode node = nodes.get(0);
    // The plan should look like:
    // SendNode -> ProjectionPlanNode -> PartitionByPlanNode -> OrderByPlanNode -> SeqScanNode
    // We also do some sanity checking on the PartitionPlan node.
    // First dissect the plan.
    assertTrue(node instanceof SendPlanNode);
    AbstractPlanNode projPlanNode = node.getChild(0);
    assertTrue(projPlanNode instanceof ProjectionPlanNode);
    AbstractPlanNode windowFuncPlanNode = projPlanNode.getChild(0);
    assertTrue(windowFuncPlanNode instanceof WindowFunctionPlanNode);
    AbstractPlanNode abstractOrderByNode = windowFuncPlanNode.getChild(0);
    assertTrue(abstractOrderByNode instanceof OrderByPlanNode);
    OrderByPlanNode orderByNode = (OrderByPlanNode) abstractOrderByNode;
    NodeSchema input_schema = orderByNode.getOutputSchema();
    assertNotNull(input_schema);
    AbstractPlanNode seqScanNode = orderByNode.getChild(0);
    assertTrue(seqScanNode instanceof SeqScanPlanNode || seqScanNode instanceof NestLoopPlanNode);
    WindowFunctionPlanNode wfPlanNode = (WindowFunctionPlanNode) windowFuncPlanNode;
    NodeSchema schema = wfPlanNode.getOutputSchema();
    //
    // Check that the window function plan node's output schema is correct.
    // Look at the first expression, to verify that it's the windowed expression.
    // Then check that the TVEs all make sense.
    //
    SchemaColumn column = schema.getColumns().get(0);
    assertEquals("ARANK", column.getColumnAlias());
    assertEquals(numPartitionExprs, wfPlanNode.getPartitionByExpressions().size());
    validateTVEs(input_schema, wfPlanNode, false);
    //
    // Check that the operation is what we expect.
    //
    assertTrue(wfPlanNode.getAggregateTypes().size() > 0);
    assertEquals(winOpType, wfPlanNode.getAggregateTypes().get(0));
    //
    for (List<AbstractExpression> exprs : wfPlanNode.getAggregateExpressions()) {
        if (exprs != null) {
            for (AbstractExpression expr : exprs) {
                assertNotNull(expr.getValueType());
            }
        }
    }
    //
    // Check that the order by node has the right number of expressions.
    // and that they have the correct order.
    //
    assertEquals(nSorts, orderByNode.getSortExpressions().size());
    int sortIndex = 0;
    for (SortDirectionType direction : orderByNode.getSortDirections()) {
        SortDirectionType expected = (sortIndex == descSortIndex) ? SortDirectionType.DESC : SortDirectionType.ASC;
        assertEquals(expected, direction);
        ++sortIndex;
    }
}
Also used : AbstractPlanNode(org.voltdb.plannodes.AbstractPlanNode) OrderByPlanNode(org.voltdb.plannodes.OrderByPlanNode) SendPlanNode(org.voltdb.plannodes.SendPlanNode) SchemaColumn(org.voltdb.plannodes.SchemaColumn) SortDirectionType(org.voltdb.types.SortDirectionType) NestLoopPlanNode(org.voltdb.plannodes.NestLoopPlanNode) SeqScanPlanNode(org.voltdb.plannodes.SeqScanPlanNode) AbstractExpression(org.voltdb.expressions.AbstractExpression) WindowFunctionPlanNode(org.voltdb.plannodes.WindowFunctionPlanNode) NodeSchema(org.voltdb.plannodes.NodeSchema) ProjectionPlanNode(org.voltdb.plannodes.ProjectionPlanNode)

Example 13 with NodeSchema

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

the class TestWindowedFunctions method validateQueryWithSubquery.

/**
     * Validate that each similar windowed query in testRankWithSubqueries
     * produces a similar plan
     * @param windowedQuery a variant of a test query of a known basic format
     **/
private void validateQueryWithSubquery(String windowedQuery, boolean waiveAliasMatch) {
    AbstractPlanNode node = compile(windowedQuery);
    // Dissect the plan.
    assertTrue(node instanceof SendPlanNode);
    AbstractPlanNode projectionPlanNode = node.getChild(0);
    assertTrue(projectionPlanNode instanceof ProjectionPlanNode);
    AbstractPlanNode partitionByPlanNode = projectionPlanNode.getChild(0);
    assertTrue(partitionByPlanNode instanceof WindowFunctionPlanNode);
    AbstractPlanNode orderByPlanNode = partitionByPlanNode.getChild(0);
    assertTrue(orderByPlanNode instanceof OrderByPlanNode);
    NodeSchema input_schema = orderByPlanNode.getOutputSchema();
    AbstractPlanNode scanNode = orderByPlanNode.getChild(0);
    assertTrue(scanNode instanceof NestLoopPlanNode);
    NodeSchema schema = partitionByPlanNode.getOutputSchema();
    SchemaColumn column = schema.getColumns().get(0);
    assertEquals("ARANK", column.getColumnAlias());
    validateTVEs(input_schema, (WindowFunctionPlanNode) partitionByPlanNode, waiveAliasMatch);
}
Also used : AbstractPlanNode(org.voltdb.plannodes.AbstractPlanNode) OrderByPlanNode(org.voltdb.plannodes.OrderByPlanNode) SendPlanNode(org.voltdb.plannodes.SendPlanNode) WindowFunctionPlanNode(org.voltdb.plannodes.WindowFunctionPlanNode) SchemaColumn(org.voltdb.plannodes.SchemaColumn) NestLoopPlanNode(org.voltdb.plannodes.NestLoopPlanNode) NodeSchema(org.voltdb.plannodes.NodeSchema) ProjectionPlanNode(org.voltdb.plannodes.ProjectionPlanNode)

Example 14 with NodeSchema

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

the class PlanAssembler method getNextDeletePlan.

private CompiledPlan getNextDeletePlan() {
    assert (m_subAssembler != null);
    // figure out which table we're deleting from
    assert (m_parsedDelete.m_tableList.size() == 1);
    Table targetTable = m_parsedDelete.m_tableList.get(0);
    AbstractPlanNode subSelectRoot = m_subAssembler.nextPlan();
    if (subSelectRoot == null) {
        return null;
    }
    // ENG-4909 Bug: currently disable NESTLOOPINDEX plan for IN
    if (disableNestedLoopIndexJoinForInComparison(subSelectRoot, m_parsedDelete)) {
        // simply jumps ahead to the next plan (if any).
        return getNextDeletePlan();
    }
    boolean isSinglePartitionPlan = m_partitioning.wasSpecifiedAsSingle() || m_partitioning.isInferredSingle();
    // generate the delete node with the right target table
    DeletePlanNode deleteNode = new DeletePlanNode();
    deleteNode.setTargetTableName(targetTable.getTypeName());
    assert (subSelectRoot instanceof AbstractScanPlanNode);
    // nodes and use a truncate delete node.
    if (deleteIsTruncate(m_parsedDelete, subSelectRoot)) {
        deleteNode.setTruncate(true);
    } else {
        // User may have specified an ORDER BY ... LIMIT clause
        if (m_parsedDelete.orderByColumns().size() > 0 && !isSinglePartitionPlan && !targetTable.getIsreplicated()) {
            throw new PlanningErrorException("DELETE statements affecting partitioned tables must " + "be able to execute on one partition " + "when ORDER BY and LIMIT or OFFSET clauses " + "are present.");
        }
        boolean needsOrderByNode = isOrderByNodeRequired(m_parsedDelete, subSelectRoot);
        AbstractExpression addressExpr = new TupleAddressExpression();
        NodeSchema proj_schema = new NodeSchema();
        // This planner-created column is magic.
        proj_schema.addColumn(AbstractParsedStmt.TEMP_TABLE_NAME, AbstractParsedStmt.TEMP_TABLE_NAME, "tuple_address", "tuple_address", addressExpr);
        if (needsOrderByNode) {
            // Projection will need to pass the sort keys to the order by node
            for (ParsedColInfo col : m_parsedDelete.orderByColumns()) {
                proj_schema.addColumn(col.asSchemaColumn());
            }
        }
        ProjectionPlanNode projectionNode = new ProjectionPlanNode(proj_schema);
        subSelectRoot.addInlinePlanNode(projectionNode);
        AbstractPlanNode root = subSelectRoot;
        if (needsOrderByNode) {
            OrderByPlanNode ob = buildOrderByPlanNode(m_parsedDelete.orderByColumns());
            ob.addAndLinkChild(root);
            root = ob;
        }
        if (m_parsedDelete.hasLimitOrOffset()) {
            assert (m_parsedDelete.orderByColumns().size() > 0);
            root.addInlinePlanNode(m_parsedDelete.limitPlanNode());
        }
        deleteNode.addAndLinkChild(root);
    }
    CompiledPlan plan = new CompiledPlan();
    plan.setReadOnly(false);
    // check non-determinism status
    // treat this as deterministic for reporting purposes:
    // delete statements produce just one row that is the
    // number of rows affected
    boolean orderIsDeterministic = true;
    boolean hasLimitOrOffset = m_parsedDelete.hasLimitOrOffset();
    // The delete statement cannot be inherently content non-deterministic.
    // So, the last parameter is always null.
    plan.statementGuaranteesDeterminism(hasLimitOrOffset, orderIsDeterministic, null);
    if (isSinglePartitionPlan) {
        plan.rootPlanGraph = deleteNode;
        return plan;
    }
    // Add a compensating sum of modified tuple counts or a limit 1
    // AND a send on top of the union-like receive node.
    boolean isReplicated = targetTable.getIsreplicated();
    plan.rootPlanGraph = addCoordinatorToDMLNode(deleteNode, isReplicated);
    return plan;
}
Also used : AbstractPlanNode(org.voltdb.plannodes.AbstractPlanNode) TupleAddressExpression(org.voltdb.expressions.TupleAddressExpression) AbstractScanPlanNode(org.voltdb.plannodes.AbstractScanPlanNode) Table(org.voltdb.catalog.Table) OrderByPlanNode(org.voltdb.plannodes.OrderByPlanNode) DeletePlanNode(org.voltdb.plannodes.DeletePlanNode) AbstractExpression(org.voltdb.expressions.AbstractExpression) NodeSchema(org.voltdb.plannodes.NodeSchema) ProjectionPlanNode(org.voltdb.plannodes.ProjectionPlanNode)

Example 15 with NodeSchema

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

the class ParsedSelectStmt method placeTVEsinColumns.

/**
     * Generate new output Schema and Place TVEs for display columns if needed.
     * Place TVEs for order by columns always.
     */
private void placeTVEsinColumns() {
    // Build the association between the table column with its index
    Map<AbstractExpression, Integer> aggTableIndexMap = new HashMap<>();
    Map<Integer, ParsedColInfo> indexToColumnMap = new HashMap<>();
    int index = 0;
    for (ParsedColInfo col : m_aggResultColumns) {
        aggTableIndexMap.put(col.expression, index);
        if (col.alias == null) {
            // hack any unique string
            col.alias = "$$_" + col.expression.getExpressionType().symbol() + "_$$_" + index;
        }
        indexToColumnMap.put(index, col);
        index++;
    }
    // Replace TVE for group by columns
    m_groupByExpressions = new HashMap<>();
    for (ParsedColInfo groupbyCol : m_groupByColumns) {
        AbstractExpression expr = groupbyCol.expression;
        assert (aggTableIndexMap.get(expr) != null);
        expr = expr.replaceWithTVE(aggTableIndexMap, indexToColumnMap);
        m_groupByExpressions.put(groupbyCol.alias, expr);
    }
    if (m_having != null) {
        m_having = m_having.replaceWithTVE(aggTableIndexMap, indexToColumnMap);
        ExpressionUtil.finalizeValueTypes(m_having);
    }
    // Replace TVE for display columns
    m_projectSchema = new NodeSchema();
    for (ParsedColInfo col : m_displayColumns) {
        AbstractExpression expr = col.expression;
        if (hasComplexAgg()) {
            expr = expr.replaceWithTVE(aggTableIndexMap, indexToColumnMap);
        }
        m_projectSchema.addColumn(col.tableName, col.tableAlias, col.columnName, col.alias, expr, col.differentiator);
    }
    // DISTINCT group by expressions are already TVEs when set
    placeTVEsForOrderby(aggTableIndexMap, indexToColumnMap);
}
Also used : AbstractExpression(org.voltdb.expressions.AbstractExpression) HashMap(java.util.HashMap) NodeSchema(org.voltdb.plannodes.NodeSchema)

Aggregations

NodeSchema (org.voltdb.plannodes.NodeSchema)21 SchemaColumn (org.voltdb.plannodes.SchemaColumn)15 AbstractPlanNode (org.voltdb.plannodes.AbstractPlanNode)14 AbstractExpression (org.voltdb.expressions.AbstractExpression)13 ProjectionPlanNode (org.voltdb.plannodes.ProjectionPlanNode)9 TupleValueExpression (org.voltdb.expressions.TupleValueExpression)8 AbstractScanPlanNode (org.voltdb.plannodes.AbstractScanPlanNode)8 Table (org.voltdb.catalog.Table)4 HashAggregatePlanNode (org.voltdb.plannodes.HashAggregatePlanNode)4 HashMap (java.util.HashMap)3 Column (org.voltdb.catalog.Column)3 NestLoopPlanNode (org.voltdb.plannodes.NestLoopPlanNode)3 OrderByPlanNode (org.voltdb.plannodes.OrderByPlanNode)3 SendPlanNode (org.voltdb.plannodes.SendPlanNode)3 SeqScanPlanNode (org.voltdb.plannodes.SeqScanPlanNode)3 Constraint (org.voltdb.catalog.Constraint)2 AbstractSubqueryExpression (org.voltdb.expressions.AbstractSubqueryExpression)2 ScalarValueExpression (org.voltdb.expressions.ScalarValueExpression)2 TupleAddressExpression (org.voltdb.expressions.TupleAddressExpression)2 AggregatePlanNode (org.voltdb.plannodes.AggregatePlanNode)2