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);
}
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);
}
}
Aggregations