use of org.voltdb.expressions.AbstractExpression in project voltdb by VoltDB.
the class PlanNodeTree method extractSubqueries.
/**
* Traverse down the plan extracting all the subquery plans. The potential places where
* the subqueries could be found are:
* - NestLoopInPlan
* - AbstractScanPlanNode predicate
* - AbstractJoinPlanNode predicates
* - IndexScan search keys and predicates
* - IndexJoin inline inner scan
* - Aggregate post-predicate(HAVING clause)
* - Projection, output schema (scalar subquery)
* @param node
* @throws Exception
*/
private void extractSubqueries(AbstractPlanNode node) throws Exception {
assert (node != null);
Collection<AbstractExpression> subexprs = node.findAllSubquerySubexpressions();
for (AbstractExpression nextexpr : subexprs) {
assert (nextexpr instanceof AbstractSubqueryExpression);
AbstractSubqueryExpression subqueryExpr = (AbstractSubqueryExpression) nextexpr;
int stmtId = subqueryExpr.getSubqueryId();
List<AbstractPlanNode> planNodes = new ArrayList<AbstractPlanNode>();
assert (!m_planNodesListMap.containsKey(stmtId));
m_planNodesListMap.put(stmtId, planNodes);
constructTree(planNodes, subqueryExpr.getSubqueryNode());
}
}
use of org.voltdb.expressions.AbstractExpression in project voltdb by VoltDB.
the class SchemaColumn method fromJSONObject.
public static SchemaColumn fromJSONObject(JSONObject jobj) throws JSONException {
String tableName = null;
String tableAlias = null;
String columnName = null;
String columnAlias = null;
AbstractExpression expression = null;
if (!jobj.isNull(Members.COLUMN_NAME)) {
columnName = jobj.getString(Members.COLUMN_NAME);
}
expression = AbstractExpression.fromJSONChild(jobj, Members.EXPRESSION);
return new SchemaColumn(tableName, tableAlias, columnName, columnAlias, expression);
}
use of org.voltdb.expressions.AbstractExpression in project voltdb by VoltDB.
the class PlannerTestCase method assertExprTopDownTree.
/**
* Assert that an expression tree contains the expected types of expressions
* in the order listed, assuming a top-down left-to-right depth-first
* traversal through left, right, and args children.
* A null expression type in the list will match any expression
* node or tree at the corresponding position.
**/
protected static void assertExprTopDownTree(AbstractExpression start, ExpressionType... exprTypes) {
assertNotNull(start);
Stack<AbstractExpression> stack = new Stack<>();
stack.push(start);
for (ExpressionType type : exprTypes) {
// Process each node before its children or later siblings.
AbstractExpression parent;
try {
parent = stack.pop();
} catch (EmptyStackException ese) {
fail("No expression was found in the tree to match type " + type);
// This dead code hushes warnings.
return;
}
List<AbstractExpression> args = parent.getArgs();
AbstractExpression rightExpr = parent.getRight();
AbstractExpression leftExpr = parent.getLeft();
int argCount = (args == null) ? 0 : args.size();
int childCount = argCount + (rightExpr == null ? 0 : 1) + (leftExpr == null ? 0 : 1);
if (type == null) {
// A null type wildcard matches any child TREE or NODE.
System.out.println("DEBUG: Suggestion -- expect " + parent.getExpressionType() + " with " + childCount + " direct children.");
continue;
}
assertEquals(type, parent.getExpressionType());
// Iterate from the last child to the first.
while (argCount > 0) {
// Push each child to be processed before its parent's
// or its own later siblings (already pushed).
stack.push(parent.getArgs().get(--argCount));
}
if (rightExpr != null) {
stack.push(rightExpr);
}
if (leftExpr != null) {
stack.push(leftExpr);
}
}
assertTrue("Extra expression node(s) (" + stack.size() + ") were found in the tree with no expression type to match", stack.isEmpty());
}
use of org.voltdb.expressions.AbstractExpression in project voltdb by VoltDB.
the class TestPlansJoin method testIndexJoinConditions.
public void testIndexJoinConditions() {
String query;
AbstractPlanNode pn;
IndexScanPlanNode indexScan;
AbstractExpression predicate;
//TODO: These are not even join queries. They should
// probably be moved to some other test class.
query = "SELECT * FROM R3 WHERE R3.A = 0";
pn = compileToTopDownTree(query, 2, PlanNodeType.SEND, PlanNodeType.INDEXSCAN);
indexScan = (IndexScanPlanNode) pn.getChild(0);
assertEquals(IndexLookupType.EQ, indexScan.getLookupType());
predicate = indexScan.getEndExpression();
assertExprTopDownTree(predicate, ExpressionType.COMPARE_EQUAL, ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_CONSTANT);
assertNull(indexScan.getPredicate());
query = "SELECT * FROM R3 WHERE R3.A > 0 AND R3.A < 5 AND R3.C = 4";
pn = compileToTopDownTree(query, 2, PlanNodeType.SEND, PlanNodeType.INDEXSCAN);
indexScan = (IndexScanPlanNode) pn.getChild(0);
assertEquals(IndexLookupType.GT, indexScan.getLookupType());
predicate = indexScan.getEndExpression();
assertExprTopDownTree(predicate, ExpressionType.COMPARE_LESSTHAN, ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_CONSTANT);
predicate = indexScan.getPredicate();
assertExprTopDownTree(predicate, ExpressionType.COMPARE_EQUAL, ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_CONSTANT);
for (JoinOp joinOp : JoinOp.JOIN_OPS) {
if (joinOp != JoinOp.EQUAL) {
// weaken test for now
continue;
}
perJoinOpTestIndexJoinConditions(joinOp);
}
}
use of org.voltdb.expressions.AbstractExpression in project voltdb by VoltDB.
the class TestPlansJoin method perJoinOpTestScanJoinConditions.
private void perJoinOpTestScanJoinConditions(JoinOp joinOp) {
String query;
AbstractPlanNode pn;
AbstractPlanNode node;
NestLoopPlanNode nlj;
SeqScanPlanNode seqScan;
AbstractExpression predicate;
boolean theOpIsOnTheLeft;
query = "SELECT * FROM R1, R2 WHERE R1.A" + joinOp + "R2.A AND R1.C > 0";
pn = compileToTopDownTree(query, 5, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOP, PlanNodeType.SEQSCAN, PlanNodeType.SEQSCAN);
node = followAssertedLeftChain(pn, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOP);
nlj = (NestLoopPlanNode) node;
assertNull(nlj.getPreJoinPredicate());
predicate = nlj.getJoinPredicate();
assertExprTopDownTree(predicate, joinOp.toOperator(), ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_TUPLE);
assertNull(nlj.getWherePredicate());
seqScan = (SeqScanPlanNode) node.getChild(0);
assertEquals("R1", seqScan.getTargetTableName());
predicate = seqScan.getPredicate();
assertExprTopDownTree(predicate, ExpressionType.COMPARE_GREATERTHAN, ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_CONSTANT);
query = "SELECT * FROM R1, R2 WHERE R1.A" + joinOp + "R2.A AND R1.C > R2.C";
pn = compileToTopDownTree(query, 5, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOP, PlanNodeType.SEQSCAN, PlanNodeType.SEQSCAN);
node = followAssertedLeftChain(pn, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOP);
nlj = (NestLoopPlanNode) node;
assertNull(nlj.getPreJoinPredicate());
predicate = nlj.getJoinPredicate();
theOpIsOnTheLeft = (predicate != null) && (predicate.getLeft() != null) && predicate.getLeft().getExpressionType() == joinOp.toOperator();
assertExprTopDownTree(predicate, ExpressionType.CONJUNCTION_AND, (theOpIsOnTheLeft ? joinOp.toOperator() : ExpressionType.COMPARE_LESSTHAN), ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_TUPLE, (theOpIsOnTheLeft ? ExpressionType.COMPARE_LESSTHAN : joinOp.toOperator()), ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_TUPLE);
assertNull(nlj.getWherePredicate());
seqScan = (SeqScanPlanNode) nlj.getChild(0);
assertNull(seqScan.getPredicate());
seqScan = (SeqScanPlanNode) nlj.getChild(1);
assertNull(seqScan.getPredicate());
query = "SELECT * FROM R1 JOIN R2 ON R1.A" + joinOp + "R2.A WHERE R1.C > 0";
pn = compileToTopDownTree(query, 5, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOP, PlanNodeType.SEQSCAN, PlanNodeType.SEQSCAN);
node = followAssertedLeftChain(pn, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOP);
nlj = (NestLoopPlanNode) node;
assertNull(nlj.getPreJoinPredicate());
predicate = nlj.getJoinPredicate();
assertExprTopDownTree(predicate, joinOp.toOperator(), ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_TUPLE);
assertNull(nlj.getWherePredicate());
seqScan = (SeqScanPlanNode) nlj.getChild(0);
assertEquals("R1", seqScan.getTargetTableName());
predicate = seqScan.getPredicate();
assertExprTopDownTree(predicate, ExpressionType.COMPARE_GREATERTHAN, ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_CONSTANT);
seqScan = (SeqScanPlanNode) nlj.getChild(1);
assertEquals("R2", seqScan.getTargetTableName());
assertNull(seqScan.getPredicate());
query = "SELECT * FROM R1 JOIN R2 ON R1.A" + joinOp + "R2.A WHERE R1.C > R2.C";
pn = compileToTopDownTree(query, 5, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOP, PlanNodeType.SEQSCAN, PlanNodeType.SEQSCAN);
node = followAssertedLeftChain(pn, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOP);
nlj = (NestLoopPlanNode) node;
assertNull(nlj.getPreJoinPredicate());
predicate = nlj.getJoinPredicate();
theOpIsOnTheLeft = (predicate != null) && (predicate.getLeft() != null) && predicate.getLeft().getExpressionType() == joinOp.toOperator();
assertExprTopDownTree(predicate, ExpressionType.CONJUNCTION_AND, (theOpIsOnTheLeft ? joinOp.toOperator() : ExpressionType.COMPARE_LESSTHAN), ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_TUPLE, (theOpIsOnTheLeft ? ExpressionType.COMPARE_LESSTHAN : joinOp.toOperator()), ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_TUPLE);
assertNull(nlj.getWherePredicate());
seqScan = (SeqScanPlanNode) nlj.getChild(0);
assertNull(seqScan.getPredicate());
seqScan = (SeqScanPlanNode) nlj.getChild(1);
assertNull(seqScan.getPredicate());
query = "SELECT * FROM R1, R2, R3 WHERE R1.A" + joinOp + "R2.A AND R1.C" + joinOp + "R3.C AND R1.A > 0";
pn = compileToTopDownTree(query, 7, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOP, PlanNodeType.NESTLOOP, PlanNodeType.SEQSCAN, PlanNodeType.SEQSCAN, PlanNodeType.SEQSCAN);
node = followAssertedLeftChain(pn, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOP);
nlj = (NestLoopPlanNode) node;
assertNull(nlj.getPreJoinPredicate());
predicate = nlj.getJoinPredicate();
assertExprTopDownTree(predicate, joinOp.toOperator(), ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_TUPLE);
assertNull(nlj.getWherePredicate());
// Validate trivial child 1 before child 0 to free up local variable nlj.
seqScan = (SeqScanPlanNode) nlj.getChild(1);
assertEquals("R3", seqScan.getTargetTableName());
assertNull(seqScan.getPredicate());
nlj = (NestLoopPlanNode) nlj.getChild(0);
assertNull(nlj.getPreJoinPredicate());
predicate = nlj.getJoinPredicate();
assertExprTopDownTree(predicate, joinOp.toOperator(), ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_TUPLE);
assertNull(nlj.getWherePredicate());
seqScan = (SeqScanPlanNode) nlj.getChild(0);
assertEquals("R1", seqScan.getTargetTableName());
predicate = seqScan.getPredicate();
assertExprTopDownTree(predicate, ExpressionType.COMPARE_GREATERTHAN, ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_CONSTANT);
seqScan = (SeqScanPlanNode) nlj.getChild(1);
assertEquals("R2", seqScan.getTargetTableName());
assertNull(seqScan.getPredicate());
query = "SELECT * FROM R1 JOIN R2 ON R1.A" + joinOp + "R2.A AND R1.C" + joinOp + "R2.C WHERE R1.A > 0";
pn = compileToTopDownTree(query, 5, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOP, PlanNodeType.SEQSCAN, PlanNodeType.SEQSCAN);
node = followAssertedLeftChain(pn, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOP);
nlj = (NestLoopPlanNode) node;
assertNull(nlj.getPreJoinPredicate());
predicate = nlj.getJoinPredicate();
assertExprTopDownTree(predicate, ExpressionType.CONJUNCTION_AND, joinOp.toOperator(), ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_TUPLE, joinOp.toOperator(), ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_TUPLE);
assertNull(nlj.getWherePredicate());
seqScan = (SeqScanPlanNode) nlj.getChild(0);
assertEquals("R1", seqScan.getTargetTableName());
predicate = seqScan.getPredicate();
assertExprTopDownTree(predicate, ExpressionType.COMPARE_GREATERTHAN, ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_CONSTANT);
seqScan = (SeqScanPlanNode) nlj.getChild(1);
assertEquals("R2", seqScan.getTargetTableName());
assertNull(seqScan.getPredicate());
query = "SELECT A, C FROM R1 JOIN R2 USING (A, C)";
pn = compileToTopDownTree(query, 2, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOP, PlanNodeType.SEQSCAN, PlanNodeType.SEQSCAN);
node = followAssertedLeftChain(pn, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOP);
nlj = (NestLoopPlanNode) node;
assertNull(nlj.getPreJoinPredicate());
predicate = nlj.getJoinPredicate();
assertExprTopDownTree(predicate, ExpressionType.CONJUNCTION_AND, ExpressionType.COMPARE_EQUAL, ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_TUPLE, ExpressionType.COMPARE_EQUAL, ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_TUPLE);
assertNull(nlj.getWherePredicate());
query = "SELECT A, C FROM R1 JOIN R2 USING (A, C) WHERE A > 0";
pn = compileToTopDownTree(query, 2, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOP, PlanNodeType.SEQSCAN, PlanNodeType.SEQSCAN);
node = followAssertedLeftChain(pn, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOP);
nlj = (NestLoopPlanNode) node;
assertNull(nlj.getPreJoinPredicate());
predicate = nlj.getJoinPredicate();
assertExprTopDownTree(predicate, ExpressionType.CONJUNCTION_AND, ExpressionType.COMPARE_EQUAL, ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_TUPLE, ExpressionType.COMPARE_EQUAL, ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_TUPLE);
assertNull(nlj.getWherePredicate());
seqScan = (SeqScanPlanNode) nlj.getChild(0);
predicate = seqScan.getPredicate();
assertExprTopDownTree(predicate, ExpressionType.COMPARE_GREATERTHAN, ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_CONSTANT);
seqScan = (SeqScanPlanNode) nlj.getChild(1);
assertNull(seqScan.getPredicate());
query = "SELECT * FROM R1 JOIN R2 ON R1.A" + joinOp + "R2.A JOIN R3 ON R1.C" + joinOp + "R3.C WHERE R1.A > 0";
pn = compileToTopDownTree(query, 7, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOP, PlanNodeType.NESTLOOP, PlanNodeType.SEQSCAN, PlanNodeType.SEQSCAN, PlanNodeType.SEQSCAN);
node = followAssertedLeftChain(pn, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOP);
nlj = (NestLoopPlanNode) node;
assertNull(nlj.getPreJoinPredicate());
predicate = nlj.getJoinPredicate();
assertExprTopDownTree(predicate, joinOp.toOperator(), ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_TUPLE);
assertNull(nlj.getWherePredicate());
// Validate trivial child 1 before child 0 to free up local variable nlj.
seqScan = (SeqScanPlanNode) nlj.getChild(1);
assertEquals("R3", seqScan.getTargetTableName());
assertNull(seqScan.getPredicate());
nlj = (NestLoopPlanNode) nlj.getChild(0);
assertNull(nlj.getPreJoinPredicate());
predicate = nlj.getJoinPredicate();
assertExprTopDownTree(predicate, joinOp.toOperator(), ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_TUPLE);
assertNull(nlj.getWherePredicate());
seqScan = (SeqScanPlanNode) nlj.getChild(0);
assertEquals("R1", seqScan.getTargetTableName());
predicate = seqScan.getPredicate();
assertExprTopDownTree(predicate, ExpressionType.COMPARE_GREATERTHAN, ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_CONSTANT);
seqScan = (SeqScanPlanNode) nlj.getChild(1);
assertEquals("R2", seqScan.getTargetTableName());
assertNull(seqScan.getPredicate());
}
Aggregations