Search in sources :

Example 1 with TupleAddressExpression

use of org.voltdb.expressions.TupleAddressExpression in project voltdb by VoltDB.

the class TestScanPlanNode method testOutputSchemaOverriddenProjection.

// test that if someone provides their own inline projection
// that the output schema of the scan node consists of the output
// schema of the projection.  Updates will do this so that the
// inlined projection fills the values of the output tuples correctly
// before it attempts to update them
public void testOutputSchemaOverriddenProjection() {
    AbstractScanPlanNode dut = new SeqScanPlanNode(TABLE1, TABLE1);
    // Create an output schema like we might see for an inlined projection
    // generated for update.  We'll have 4 output columns, the first will
    // be the tuple address, the second one a parameter expression, next
    // will be a constant, and the other will be a more complex expression
    // that uses some TVEs.
    NodeSchema proj_schema = new NodeSchema();
    String[] cols = new String[4];
    TupleAddressExpression col1_exp = new TupleAddressExpression();
    proj_schema.addColumn("", "", "tuple_address", "tuple_address", col1_exp);
    cols[0] = "tuple_address";
    // update column 1 with a parameter value
    ParameterValueExpression col2_exp = new ParameterValueExpression();
    col2_exp.setParameterIndex(0);
    col2_exp.setValueType(COLTYPES[1]);
    col2_exp.setValueSize(COLTYPES[1].getLengthInBytesForFixedTypes());
    // XXX I'm not sure what to do with the name for the updated column yet.
    // I think it should be an alias and not the original table name/col name
    proj_schema.addColumn(TABLE1, TABLE1, COLS[1], COLS[1], col2_exp);
    cols[1] = COLS[1];
    // Update column 3 with a constant value
    ConstantValueExpression col3_exp = new ConstantValueExpression();
    col3_exp.setValueType(COLTYPES[3]);
    col3_exp.setValueSize(COLTYPES[3].getLengthInBytesForFixedTypes());
    col3_exp.setValue("3.14159");
    proj_schema.addColumn(TABLE1, TABLE1, COLS[3], COLS[3], col3_exp);
    cols[2] = COLS[3];
    // update column 4 with a sum of columns 0 and 2
    OperatorExpression col4_exp = new OperatorExpression();
    col4_exp.setValueType(COLTYPES[4]);
    col4_exp.setValueSize(COLTYPES[4].getLengthInBytesForFixedTypes());
    col4_exp.setExpressionType(ExpressionType.OPERATOR_PLUS);
    TupleValueExpression left = new TupleValueExpression(TABLE1, TABLE1, COLS[0], COLS[0], 0);
    left.setValueType(COLTYPES[0]);
    left.setValueSize(COLTYPES[0].getLengthInBytesForFixedTypes());
    TupleValueExpression right = new TupleValueExpression(TABLE1, TABLE1, COLS[2], COLS[2], 0);
    right.setValueType(COLTYPES[2]);
    right.setValueSize(COLTYPES[2].getLengthInBytesForFixedTypes());
    col4_exp.setLeft(left);
    col4_exp.setRight(right);
    proj_schema.addColumn(TABLE1, TABLE1, COLS[4], "C1", col4_exp);
    cols[3] = COLS[4];
    ProjectionPlanNode proj_node = new ProjectionPlanNode(proj_schema);
    dut.addInlinePlanNode(proj_node);
    System.out.println("ProjSchema: " + proj_schema.toString());
    dut.generateOutputSchema(m_voltdb.getDatabase());
    NodeSchema dut_schema = dut.getOutputSchema();
    System.out.println(dut_schema.toString());
    for (int i = 0; i < cols.length; i++) {
        SchemaColumn col = null;
        if (i == 0) {
            col = dut_schema.find("", "", cols[i], cols[i]);
        } else {
            col = dut_schema.find(TABLE1, TABLE1, cols[i], cols[i]);
        }
        assertNotNull(col);
        assertEquals(col.getExpression().getExpressionType(), ExpressionType.VALUE_TUPLE);
    }
}
Also used : TupleAddressExpression(org.voltdb.expressions.TupleAddressExpression) TupleValueExpression(org.voltdb.expressions.TupleValueExpression) ConstantValueExpression(org.voltdb.expressions.ConstantValueExpression) OperatorExpression(org.voltdb.expressions.OperatorExpression) ParameterValueExpression(org.voltdb.expressions.ParameterValueExpression)

Example 2 with TupleAddressExpression

use of org.voltdb.expressions.TupleAddressExpression 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 3 with TupleAddressExpression

use of org.voltdb.expressions.TupleAddressExpression in project voltdb by VoltDB.

the class PlanAssembler method getNextUpdatePlan.

private CompiledPlan getNextUpdatePlan() {
    assert (m_subAssembler != null);
    AbstractPlanNode subSelectRoot = m_subAssembler.nextPlan();
    if (subSelectRoot == null) {
        return null;
    }
    if (disableNestedLoopIndexJoinForInComparison(subSelectRoot, m_parsedUpdate)) {
        // simply jumps ahead to the next plan (if any).
        return getNextUpdatePlan();
    }
    UpdatePlanNode updateNode = new UpdatePlanNode();
    // It was not in Mike A's original branch.
    assert (m_parsedUpdate.m_tableList.size() == 1);
    Table targetTable = m_parsedUpdate.m_tableList.get(0);
    updateNode.setTargetTableName(targetTable.getTypeName());
    // set this to false until proven otherwise
    updateNode.setUpdateIndexes(false);
    TupleAddressExpression tae = new TupleAddressExpression();
    NodeSchema proj_schema = new NodeSchema();
    // This planner-generated column is magic.
    proj_schema.addColumn(AbstractParsedStmt.TEMP_TABLE_NAME, AbstractParsedStmt.TEMP_TABLE_NAME, "tuple_address", "tuple_address", tae);
    // get the set of columns affected by indexes
    Set<String> affectedColumns = getIndexedColumnSetForTable(targetTable);
    // to avoid any false schema/column matches with the actual table.
    for (Entry<Column, AbstractExpression> colEntry : m_parsedUpdate.columns.entrySet()) {
        Column col = colEntry.getKey();
        String colName = col.getTypeName();
        AbstractExpression expr = colEntry.getValue();
        expr.setInBytes(colEntry.getKey().getInbytes());
        proj_schema.addColumn(AbstractParsedStmt.TEMP_TABLE_NAME, AbstractParsedStmt.TEMP_TABLE_NAME, colName, colName, expr);
        // check if this column is an indexed column
        if (affectedColumns.contains(colName)) {
            updateNode.setUpdateIndexes(true);
        }
    }
    ProjectionPlanNode projectionNode = new ProjectionPlanNode(proj_schema);
    // in order to simply cull the columns from the persistent table.
    assert (subSelectRoot instanceof AbstractScanPlanNode);
    subSelectRoot.addInlinePlanNode(projectionNode);
    // connect the nodes to build the graph
    updateNode.addAndLinkChild(subSelectRoot);
    CompiledPlan retval = new CompiledPlan();
    retval.setReadOnly(false);
    if (targetTable.getIsreplicated()) {
        retval.replicatedTableDML = true;
    }
    //FIXME: This assumption was only safe when we didn't support updates
    // w/ possibly non-deterministic subqueries.
    // Is there some way to integrate a "subquery determinism" check here?
    // because we didn't support updates with limits, either.
    // Since the update cannot be inherently non-deterministic, there is
    // no message, and the last parameter is null.
    retval.statementGuaranteesDeterminism(false, true, null);
    if (m_partitioning.wasSpecifiedAsSingle() || m_partitioning.isInferredSingle()) {
        retval.rootPlanGraph = updateNode;
        return retval;
    }
    // Send the local result counts to the coordinator.
    // 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();
    retval.rootPlanGraph = addCoordinatorToDMLNode(updateNode, isReplicated);
    return retval;
}
Also used : AbstractPlanNode(org.voltdb.plannodes.AbstractPlanNode) TupleAddressExpression(org.voltdb.expressions.TupleAddressExpression) AbstractScanPlanNode(org.voltdb.plannodes.AbstractScanPlanNode) Table(org.voltdb.catalog.Table) AbstractExpression(org.voltdb.expressions.AbstractExpression) Column(org.voltdb.catalog.Column) SchemaColumn(org.voltdb.plannodes.SchemaColumn) UpdatePlanNode(org.voltdb.plannodes.UpdatePlanNode) NodeSchema(org.voltdb.plannodes.NodeSchema) ProjectionPlanNode(org.voltdb.plannodes.ProjectionPlanNode)

Aggregations

TupleAddressExpression (org.voltdb.expressions.TupleAddressExpression)3 Table (org.voltdb.catalog.Table)2 AbstractExpression (org.voltdb.expressions.AbstractExpression)2 AbstractPlanNode (org.voltdb.plannodes.AbstractPlanNode)2 AbstractScanPlanNode (org.voltdb.plannodes.AbstractScanPlanNode)2 NodeSchema (org.voltdb.plannodes.NodeSchema)2 ProjectionPlanNode (org.voltdb.plannodes.ProjectionPlanNode)2 Column (org.voltdb.catalog.Column)1 ConstantValueExpression (org.voltdb.expressions.ConstantValueExpression)1 OperatorExpression (org.voltdb.expressions.OperatorExpression)1 ParameterValueExpression (org.voltdb.expressions.ParameterValueExpression)1 TupleValueExpression (org.voltdb.expressions.TupleValueExpression)1 DeletePlanNode (org.voltdb.plannodes.DeletePlanNode)1 OrderByPlanNode (org.voltdb.plannodes.OrderByPlanNode)1 SchemaColumn (org.voltdb.plannodes.SchemaColumn)1 UpdatePlanNode (org.voltdb.plannodes.UpdatePlanNode)1