Search in sources :

Example 6 with OperatorExpression

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

the class AbstractParsedStmt method optimizeInExpressions.

/**
     * Perform various optimizations for IN/EXISTS subqueries if possible
     *
     * @param expr to optimize
     * @return optimized expression
     */
private AbstractExpression optimizeInExpressions(AbstractExpression expr) {
    ExpressionType exprType = expr.getExpressionType();
    if (ExpressionType.CONJUNCTION_AND == exprType || ExpressionType.CONJUNCTION_OR == exprType) {
        AbstractExpression optimizedLeft = optimizeInExpressions(expr.getLeft());
        expr.setLeft(optimizedLeft);
        AbstractExpression optimizedRight = optimizeInExpressions(expr.getRight());
        expr.setRight(optimizedRight);
        return expr;
    }
    if (ExpressionType.COMPARE_EQUAL != exprType) {
        return expr;
    }
    assert (expr instanceof ComparisonExpression);
    if (((ComparisonExpression) expr).getQuantifier() != QuantifierType.ANY) {
        return expr;
    }
    /*
         * Verify that an IN expression can be safely converted to an EXISTS one
         * IN (SELECT" forms e.g. "(A, B) IN (SELECT X, Y, FROM ...) =>
         * EXISTS (SELECT 42 FROM ... AND|WHERE|HAVING A=X AND|WHERE|HAVING B=Y)
         */
    AbstractExpression inColumns = expr.getLeft();
    if (inColumns instanceof SelectSubqueryExpression) {
        // (expression must return a single row at most)
        return expr;
    }
    // The right hand operand of the equality operation must be a SELECT statement
    AbstractExpression rightExpr = expr.getRight();
    if (!(rightExpr instanceof SelectSubqueryExpression)) {
        return expr;
    }
    SelectSubqueryExpression subqueryExpr = (SelectSubqueryExpression) rightExpr;
    AbstractParsedStmt subquery = subqueryExpr.getSubqueryStmt();
    if (!(subquery instanceof ParsedSelectStmt)) {
        return expr;
    }
    ParsedSelectStmt selectStmt = (ParsedSelectStmt) subquery;
    //      seems to require 1 match that has exactly 10-14 rows (matching or not) with lesser or equal values of Y.
    if (selectStmt.hasLimitOrOffset()) {
        return expr;
    }
    ParsedSelectStmt.rewriteInSubqueryAsExists(selectStmt, inColumns);
    subqueryExpr.resolveCorrelations();
    AbstractExpression existsExpr = new OperatorExpression();
    existsExpr.setExpressionType(ExpressionType.OPERATOR_EXISTS);
    existsExpr.setLeft(subqueryExpr);
    return optimizeExistsExpression(existsExpr);
}
Also used : ComparisonExpression(org.voltdb.expressions.ComparisonExpression) AbstractExpression(org.voltdb.expressions.AbstractExpression) OperatorExpression(org.voltdb.expressions.OperatorExpression) SelectSubqueryExpression(org.voltdb.expressions.SelectSubqueryExpression) ExpressionType(org.voltdb.types.ExpressionType)

Example 7 with OperatorExpression

use of org.voltdb.expressions.OperatorExpression 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)

Aggregations

OperatorExpression (org.voltdb.expressions.OperatorExpression)7 AbstractExpression (org.voltdb.expressions.AbstractExpression)5 ArrayList (java.util.ArrayList)2 JSONException (org.json_voltpatches.JSONException)2 ColumnRef (org.voltdb.catalog.ColumnRef)2 ComparisonExpression (org.voltdb.expressions.ComparisonExpression)2 ConstantValueExpression (org.voltdb.expressions.ConstantValueExpression)2 TupleValueExpression (org.voltdb.expressions.TupleValueExpression)2 ExpressionType (org.voltdb.types.ExpressionType)2 VoltType (org.voltdb.VoltType)1 Column (org.voltdb.catalog.Column)1 AggregateExpression (org.voltdb.expressions.AggregateExpression)1 ParameterValueExpression (org.voltdb.expressions.ParameterValueExpression)1 SelectSubqueryExpression (org.voltdb.expressions.SelectSubqueryExpression)1 TupleAddressExpression (org.voltdb.expressions.TupleAddressExpression)1 StmtTargetTableScan (org.voltdb.planner.parseinfo.StmtTargetTableScan)1 LimitPlanNode (org.voltdb.plannodes.LimitPlanNode)1