use of org.voltdb.plannodes.IndexScanPlanNode in project voltdb by VoltDB.
the class TestPlansJoin method perJoinOpTestSeqScanOuterJoinCondition.
private void perJoinOpTestSeqScanOuterJoinCondition(JoinOp joinOp) {
String query;
AbstractPlanNode pn;
AbstractPlanNode node;
NestLoopPlanNode nlj;
AbstractExpression predicate;
SeqScanPlanNode seqScan;
IndexScanPlanNode indexScan;
// R1.C" + joinOp + "R2.C Inner-Outer join Expr stays at the NLJ as Join predicate
query = "SELECT * FROM R1 LEFT JOIN R2 ON R1.C" + joinOp + "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();
assertExprTopDownTree(predicate, 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());
// R1.C" + joinOp + "R2.C Inner-Outer join Expr stays at the NLJ as Join predicate
// R1.A > 0 Outer Join Expr stays at the the NLJ as pre-join predicate
// R2.A < 0 Inner Join Expr is pushed down to the inner SeqScan node
query = "SELECT * FROM R1 LEFT JOIN R2 ON R1.C" + joinOp + "R2.C AND R1.A > 0 AND R2.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;
predicate = nlj.getPreJoinPredicate();
assertExprTopDownTree(predicate, ExpressionType.COMPARE_GREATERTHAN, ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_CONSTANT);
predicate = nlj.getJoinPredicate();
assertExprTopDownTree(predicate, joinOp.toOperator(), ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_TUPLE);
assertNull(nlj.getWherePredicate());
seqScan = (SeqScanPlanNode) nlj.getChild(0);
assertNull(seqScan.getPredicate());
seqScan = (SeqScanPlanNode) nlj.getChild(1);
predicate = seqScan.getPredicate();
assertExprTopDownTree(predicate, ExpressionType.COMPARE_LESSTHAN, ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_CONSTANT);
// R1.C" + joinOp + "R2.C Inner-Outer join Expr stays at the NLJ as Join predicate
// (R1.A > 0 OR R2.A < 0) Inner-Outer join Expr stays at the NLJ as Join predicate
query = "SELECT * FROM R1 LEFT JOIN R2 ON R1.C" + joinOp + "R2.C AND (R1.A > 0 OR R2.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();
boolean theOrIsOnTheLeft = (predicate != null) && (predicate.getLeft() != null) && (ExpressionType.CONJUNCTION_OR == predicate.getLeft().getExpressionType());
if (theOrIsOnTheLeft) {
assertExprTopDownTree(predicate, ExpressionType.CONJUNCTION_AND, ExpressionType.CONJUNCTION_OR, ExpressionType.COMPARE_GREATERTHAN, ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_CONSTANT, ExpressionType.COMPARE_LESSTHAN, ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_CONSTANT, joinOp.toOperator(), ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_TUPLE);
} else {
assertExprTopDownTree(predicate, ExpressionType.CONJUNCTION_AND, joinOp.toOperator(), ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_TUPLE, ExpressionType.CONJUNCTION_OR, ExpressionType.COMPARE_GREATERTHAN, ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_CONSTANT, ExpressionType.COMPARE_LESSTHAN, ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_CONSTANT);
}
assertNull(nlj.getWherePredicate());
seqScan = (SeqScanPlanNode) nlj.getChild(0);
assertNull(seqScan.getPredicate());
seqScan = (SeqScanPlanNode) nlj.getChild(1);
assertNull(seqScan.getPredicate());
// R1.C" + joinOp + "R2.C Inner-Outer join Expr stays at the NLJ as Join predicate
// R1.A > 0 Outer Where Expr is pushed down to the outer SeqScan node
// R2.A IS NULL Inner Where Expr stays at the the NLJ as post join (where) predicate
// (R1.C > R2.C OR R2.C IS NULL) Inner-Outer Where stays at the the NLJ as post join (where) predicate
query = "SELECT * FROM R1 LEFT JOIN R2 ON R1.C" + joinOp + "R2.C WHERE R1.A > 0 AND R2.A IS NULL AND (R1.C > R2.C OR R2.C IS NULL)";
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;
assertEquals(JoinType.LEFT, nlj.getJoinType());
assertNull(nlj.getPreJoinPredicate());
predicate = nlj.getJoinPredicate();
assertExprTopDownTree(predicate, joinOp.toOperator(), ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_TUPLE);
predicate = nlj.getWherePredicate();
assertExprTopDownTree(predicate, ExpressionType.CONJUNCTION_AND, ExpressionType.CONJUNCTION_OR, ExpressionType.COMPARE_GREATERTHAN, ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_TUPLE, ExpressionType.OPERATOR_IS_NULL, ExpressionType.VALUE_TUPLE, ExpressionType.OPERATOR_IS_NULL, ExpressionType.VALUE_TUPLE);
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());
// R3.A" + joinOp + "R2.A Inner-Outer index join Expr. NLJ predicate.
// R3.A > 3 Index Outer where expr pushed down to IndexScanPlanNode
// R3.C < 0 non-index Outer where expr pushed down to IndexScanPlanNode as a predicate
query = "SELECT * FROM R3 LEFT JOIN R2 ON R3.A" + joinOp + "R2.A WHERE R3.A > 3 AND R3.C < 0";
pn = compileToTopDownTree(query, 4, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOP, PlanNodeType.INDEXSCAN, PlanNodeType.SEQSCAN);
node = followAssertedLeftChain(pn, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOP);
nlj = (NestLoopPlanNode) node;
assertEquals(JoinType.LEFT, nlj.getJoinType());
assertNull(nlj.getPreJoinPredicate());
predicate = nlj.getJoinPredicate();
assertExprTopDownTree(predicate, joinOp.toOperator(), ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_TUPLE);
assertNull(nlj.getWherePredicate());
indexScan = (IndexScanPlanNode) nlj.getChild(0);
assertEquals(IndexLookupType.GT, indexScan.getLookupType());
assertNull(indexScan.getEndExpression());
predicate = indexScan.getPredicate();
assertExprTopDownTree(predicate, ExpressionType.COMPARE_LESSTHAN, ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_CONSTANT);
// R3.C" + joinOp + "R2.C Inner-Outer non-index join Expr. NLJ predicate.
// R3.A > 3 Index null rejecting inner where expr pushed down to IndexScanPlanNode
// NLJ is simplified to be INNER
query = "SELECT * FROM R2 LEFT JOIN R3 ON R3.C" + joinOp + "R2.C WHERE R3.A > 3";
pn = compileToTopDownTree(query, 4, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOP, PlanNodeType.SEQSCAN, PlanNodeType.INDEXSCAN);
node = followAssertedLeftChain(pn, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOP);
nlj = (NestLoopPlanNode) node;
assertEquals(JoinType.INNER, nlj.getJoinType());
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("R2", seqScan.getTargetTableName());
assertNull(seqScan.getPredicate());
indexScan = (IndexScanPlanNode) nlj.getChild(1);
assertEquals(IndexLookupType.GT, indexScan.getLookupType());
assertNull(indexScan.getEndExpression());
assertNull(indexScan.getPredicate());
if (joinOp != JoinOp.EQUAL) {
// weaken test for now
return;
}
query = "SELECT * FROM R2 LEFT JOIN R3 ON R3.A" + joinOp + "R2.C WHERE R3.A > 3";
pn = compileToTopDownTree(query, 4, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOPINDEX, PlanNodeType.SEQSCAN);
node = followAssertedLeftChain(pn, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOPINDEX);
NestLoopIndexPlanNode nlij = (NestLoopIndexPlanNode) node;
assertEquals(JoinType.INNER, nlij.getJoinType());
}
use of org.voltdb.plannodes.IndexScanPlanNode in project voltdb by VoltDB.
the class TestPlansSubQueries method assertPlanNodeHasNoIndexScans.
private void assertPlanNodeHasNoIndexScans(AbstractPlanNode node) {
if (node instanceof IndexScanPlanNode) {
IndexScanPlanNode indexScan = (IndexScanPlanNode) node;
assertTrue("Expected plan to use no indexes, but it contains an index scan plan node " + "used for something other than forcing a deterministic order", indexScan.isForDeterminismOnly());
} else {
String className = node.getClass().getSimpleName();
assertFalse("Expected plan to use no indexes, but it contains an instance of " + className, className.toLowerCase().contains("index"));
}
}
use of org.voltdb.plannodes.IndexScanPlanNode in project voltdb by VoltDB.
the class TestPlansSubQueries method checkIndexScan.
private void checkIndexScan(AbstractPlanNode indexNode, String tableName, String indexName, String... columns) {
assertTrue(indexNode instanceof IndexScanPlanNode);
IndexScanPlanNode idxNode = (IndexScanPlanNode) indexNode;
if (tableName != null) {
assertEquals(tableName, idxNode.getTargetTableName());
}
if (indexName != null) {
String actualIndexName = idxNode.getTargetIndexName();
assertTrue(actualIndexName.contains(indexName));
}
checkOutputSchema(idxNode, columns);
}
use of org.voltdb.plannodes.IndexScanPlanNode in project voltdb by VoltDB.
the class TestPlansJoin method perJoinTestOpIndexInnerJoin.
private void perJoinTestOpIndexInnerJoin(JoinOp joinOp) {
String query;
AbstractPlanNode pn;
AbstractPlanNode node;
IndexScanPlanNode indexScan;
query = "SELECT * FROM R3 JOIN R1 ON R1.C" + joinOp + "R3.A";
pn = compileToTopDownTree(query, 5, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOPINDEX, PlanNodeType.SEQSCAN);
// Test ORDER BY optimization on indexed self-join, ordering by LHS
query = "SELECT X.A FROM R5 X, R5 Y WHERE X.A" + joinOp + "Y.A ORDER BY X.A";
pn = compileToTopDownTree(query, 1, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOPINDEX, PlanNodeType.INDEXSCAN);
node = followAssertedLeftChain(pn, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOPINDEX, PlanNodeType.INDEXSCAN);
indexScan = (IndexScanPlanNode) node;
assertEquals("X", indexScan.getTargetTableAlias());
// Test ORDER BY optimization on indexed self-join, ordering by RHS
query = "SELECT X.A FROM R5 X, R5 Y WHERE X.A" + joinOp + "Y.A ORDER BY Y.A";
pn = compileToTopDownTree(query, 1, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOPINDEX, PlanNodeType.INDEXSCAN);
node = followAssertedLeftChain(pn, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOPINDEX, PlanNodeType.INDEXSCAN);
indexScan = (IndexScanPlanNode) node;
assertEquals("Y", indexScan.getTargetTableAlias());
// Test safety guarding misapplication of ORDER BY optimization on indexed self-join,
// when ordering by combination of LHS and RHS columns.
// These MAY become valid optimization cases when ENG-4728 is done,
// using transitive equality to determine that the ORDER BY clause can be re-expressed
// as being based on only one of the two table scans.
query = "SELECT X.A, X.C FROM R4 X, R4 Y WHERE X.A" + joinOp + "Y.A ORDER BY X.A, Y.C";
pn = compileToTopDownTree(query, 2, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.ORDERBY, PlanNodeType.NESTLOOPINDEX, PlanNodeType.SEQSCAN);
query = "SELECT X.A FROM R4 X, R4 Y WHERE X.A" + joinOp + "Y.A ORDER BY Y.A, X.C";
pn = compileToTopDownTree(query, 1, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.ORDERBY, PlanNodeType.NESTLOOPINDEX, PlanNodeType.SEQSCAN);
}
use of org.voltdb.plannodes.IndexScanPlanNode in project voltdb by VoltDB.
the class TestPlansJoin method perJoinOpTestTransitiveValueEquivalenceConditions.
private void perJoinOpTestTransitiveValueEquivalenceConditions(JoinOp joinOp) {
String query;
AbstractPlanNode pn;
AbstractPlanNode node;
NestLoopPlanNode nlj;
SeqScanPlanNode seqScan;
IndexScanPlanNode indexScan;
AbstractExpression predicate;
boolean theConstantIsOnTheLeft;
// R1.A" + joinOp + "R2.A AND R2.A = 1 => R1.A = 1 AND R2.A = 1
query = "SELECT * FROM R1 LEFT JOIN R2 ON R1.A" + joinOp + "R2.A AND R2.A = 1 ";
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;
predicate = nlj.getPreJoinPredicate();
theConstantIsOnTheLeft = (predicate != null) && (predicate.getLeft() != null) && (predicate.getLeft().getExpressionType() == ExpressionType.VALUE_CONSTANT);
if (theConstantIsOnTheLeft) {
assertExprTopDownTree(predicate, joinOp.toOperator(), ExpressionType.VALUE_CONSTANT, ExpressionType.VALUE_TUPLE);
} else {
assertExprTopDownTree(predicate, joinOp.toOperator(), ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_CONSTANT);
}
assertNull(nlj.getJoinPredicate());
assertNull(nlj.getWherePredicate());
seqScan = (SeqScanPlanNode) nlj.getChild(0);
assertNull(seqScan.getPredicate());
seqScan = (SeqScanPlanNode) nlj.getChild(1);
predicate = seqScan.getPredicate();
assertExprTopDownTree(predicate, ExpressionType.COMPARE_EQUAL, ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_CONSTANT);
// Same test but now R2 is outer table R1.A " +
// joinOp + "R2.A AND R2.A = 1 => R1.A = 1 AND R2.A = 1
query = "SELECT * FROM R2 LEFT JOIN R1 ON R1.A" + joinOp + "R2.A AND R2.A = 1 ";
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;
predicate = nlj.getPreJoinPredicate();
assertExprTopDownTree(predicate, ExpressionType.COMPARE_EQUAL, ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_CONSTANT);
assertNull(nlj.getJoinPredicate());
assertNull(nlj.getWherePredicate());
seqScan = (SeqScanPlanNode) nlj.getChild(0);
assertNull(seqScan.getPredicate());
seqScan = (SeqScanPlanNode) nlj.getChild(1);
predicate = seqScan.getPredicate();
assertExprTopDownTree(predicate, joinOp.toOperator(), ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_CONSTANT);
// R1.A" + joinOp + "R2.A AND R2.C = 1 => R1.A " +
// joinOp + "R2.A AND R2.C = 1
query = "SELECT * FROM R1 LEFT JOIN R2 ON R1.A" + joinOp + "R2.A AND R2.C = 1 ";
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;
predicate = nlj.getJoinPredicate();
assertExprTopDownTree(predicate, joinOp.toOperator(), ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_TUPLE);
// R1.A" + joinOp + "R2.A AND ABS(R2.C) = 1 => R1.A " +
// joinOp + "R2.A AND ABS(R2.C) = 1
query = "SELECT * FROM R1 LEFT JOIN R2 ON R1.A" + joinOp + "R2.A AND ABS(R2.C) = 1 ";
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;
predicate = nlj.getJoinPredicate();
assertExprTopDownTree(predicate, joinOp.toOperator(), ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_TUPLE);
// R1.A" + joinOp + "R3.A - NLIJ
query = "SELECT * FROM R1 LEFT JOIN R3 ON R1.A" + joinOp + "R3.A";
pn = compileToTopDownTree(query, 5, PlanNodeType.SEND, PlanNodeType.PROJECTION, // PlanNodeType.NESTLOOPINDEX,
null);
// PlanNodeType.SEQSCAN); weakened for now
if (joinOp == JoinOp.EQUAL) {
// weaken test for now
node = followAssertedLeftChain(pn, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOPINDEX);
}
// R1.A" + joinOp + "R3.A AND R1.A = 4 => R3.A = 4 AND R1.A = 4 -- NLJ/IndexScan
query = "SELECT * FROM R1 LEFT JOIN R3 ON R1.A" + joinOp + "R3.A AND R1.A = 4";
pn = compileToTopDownTree(query, 5, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOP, PlanNodeType.SEQSCAN, // weakened for now
null);
node = followAssertedLeftChain(pn, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOP);
nlj = (NestLoopPlanNode) node;
predicate = nlj.getPreJoinPredicate();
assertExprTopDownTree(predicate, ExpressionType.COMPARE_EQUAL, ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_CONSTANT);
assertNull(nlj.getJoinPredicate());
assertNull(nlj.getWherePredicate());
seqScan = (SeqScanPlanNode) nlj.getChild(0);
assertEquals("R1", seqScan.getTargetTableName());
assertNull(seqScan.getPredicate());
if (joinOp == JoinOp.EQUAL) {
// weakened for now
indexScan = (IndexScanPlanNode) nlj.getChild(1);
assertEquals(IndexLookupType.EQ, indexScan.getLookupType());
predicate = indexScan.getEndExpression();
assertExprTopDownTree(predicate, ExpressionType.COMPARE_EQUAL, ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_CONSTANT);
assertNull(indexScan.getPredicate());
assertEquals("R3", indexScan.getTargetTableName());
}
// R1.A" + joinOp + "R3.A AND R3.A = 4 => R3.A = 4 AND R1.A = 4 -- NLJ/IndexScan
query = "SELECT * FROM R1 LEFT JOIN R3 ON R1.A" + joinOp + "R3.A AND R3.A = 4";
pn = compileToTopDownTree(query, 5, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOP, PlanNodeType.SEQSCAN, PlanNodeType.INDEXSCAN);
node = followAssertedLeftChain(pn, PlanNodeType.SEND, PlanNodeType.PROJECTION, PlanNodeType.NESTLOOP);
nlj = (NestLoopPlanNode) node;
predicate = nlj.getPreJoinPredicate();
theConstantIsOnTheLeft = (predicate != null) && (predicate.getLeft() != null) && (predicate.getLeft().getExpressionType() == ExpressionType.VALUE_CONSTANT);
if (theConstantIsOnTheLeft) {
assertExprTopDownTree(predicate, joinOp.toOperator(), ExpressionType.VALUE_CONSTANT, ExpressionType.VALUE_TUPLE);
} else {
assertExprTopDownTree(predicate, joinOp.toOperator(), ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_CONSTANT);
}
assertNull(nlj.getJoinPredicate());
assertNull(nlj.getWherePredicate());
seqScan = (SeqScanPlanNode) nlj.getChild(0);
assertEquals("R1", seqScan.getTargetTableName());
assertNull(seqScan.getPredicate());
// predicate = seqScan.getPredicate();
// assertExprTopDownTree(predicate, ExpressionType.COMPARE_EQUAL,
// ExpressionType.VALUE_TUPLE,
// ExpressionType.VALUE_CONSTANT);
indexScan = (IndexScanPlanNode) nlj.getChild(1);
assertEquals("R3", indexScan.getTargetTableName());
assertEquals(IndexLookupType.EQ, indexScan.getLookupType());
predicate = indexScan.getEndExpression();
assertExprTopDownTree(predicate, ExpressionType.COMPARE_EQUAL, ExpressionType.VALUE_TUPLE, ExpressionType.VALUE_CONSTANT);
assertNull(indexScan.getPredicate());
}
Aggregations