use of org.voltdb.expressions.AbstractExpression in project voltdb by VoltDB.
the class TestPlansSubQueries method countTerms.
private static int countTerms(AbstractExpression expr) {
int result = 0;
AbstractExpression left = expr.getLeft();
result += (left instanceof ConjunctionExpression) ? countTerms(left) : 1;
AbstractExpression right = expr.getRight();
result += (right instanceof ConjunctionExpression) ? countTerms(right) : 1;
return result;
}
use of org.voltdb.expressions.AbstractExpression in project voltdb by VoltDB.
the class TestSelfJoins method testSelfJoin.
public void testSelfJoin() {
AbstractPlanNode pn = compile("select * FROM R1 A JOIN R1 B ON A.C = B.C WHERE B.A > 0 AND A.C < 3");
pn = pn.getChild(0).getChild(0);
assertTrue(pn instanceof NestLoopPlanNode);
assertEquals(4, pn.getOutputSchema().getColumns().size());
assertEquals(2, pn.getChildCount());
AbstractPlanNode c = pn.getChild(0);
assertTrue(c instanceof SeqScanPlanNode);
SeqScanPlanNode ss = (SeqScanPlanNode) c;
assertEquals("R1", ss.getTargetTableName());
assertEquals("A", ss.getTargetTableAlias());
assertEquals(ExpressionType.COMPARE_LESSTHAN, ss.getPredicate().getExpressionType());
c = pn.getChild(1);
assertTrue(c instanceof SeqScanPlanNode);
ss = (SeqScanPlanNode) c;
assertEquals("R1", ss.getTargetTableName());
assertEquals("B", ss.getTargetTableAlias());
assertEquals(ExpressionType.COMPARE_GREATERTHAN, ss.getPredicate().getExpressionType());
pn = compile("select * FROM R1 JOIN R1 B ON R1.C = B.C");
pn = pn.getChild(0).getChild(0);
assertTrue(pn instanceof NestLoopPlanNode);
assertEquals(4, pn.getOutputSchema().getColumns().size());
assertEquals(2, pn.getChildCount());
c = pn.getChild(0);
assertTrue(c instanceof SeqScanPlanNode);
ss = (SeqScanPlanNode) c;
assertEquals("R1", ss.getTargetTableName());
assertEquals("R1", ss.getTargetTableAlias());
c = pn.getChild(1);
assertTrue(c instanceof SeqScanPlanNode);
ss = (SeqScanPlanNode) c;
assertEquals("R1", ss.getTargetTableName());
assertEquals("B", ss.getTargetTableAlias());
pn = compile("select A.A, A.C, B.A, B.C FROM R1 A JOIN R1 B ON A.C = B.C");
pn = pn.getChild(0).getChild(0);
assertTrue(pn instanceof NestLoopPlanNode);
assertEquals(4, pn.getOutputSchema().getColumns().size());
pn = compile("select A,B.C FROM R1 A JOIN R2 B USING(A)");
pn = pn.getChild(0);
assertTrue(pn instanceof ProjectionPlanNode);
NodeSchema ns = pn.getOutputSchema();
for (SchemaColumn sc : ns.getColumns()) {
AbstractExpression e = sc.getExpression();
assertTrue(e instanceof TupleValueExpression);
TupleValueExpression tve = (TupleValueExpression) e;
assertNotSame(-1, tve.getColumnIndex());
}
}
use of org.voltdb.expressions.AbstractExpression in project voltdb by VoltDB.
the class TestSelfJoins method testIndexedSelfJoin.
public void testIndexedSelfJoin() {
AbstractPlanNode.enableVerboseExplainForDebugging();
IndexScanPlanNode c;
AbstractPlanNode apn;
AbstractPlanNode pn;
NestLoopIndexPlanNode nlij;
List<AbstractExpression> searchKeys;
// SELF JOIN using two different indexes on the same table
// sometimes with a surviving sort ordering that supports GROUP BY and/or ORDER BY.
apn = compile("select * FROM R2 A, R2 B WHERE A.A = B.A AND B.C > 1 ORDER BY B.C");
//* for debug */ System.out.println(apn.toExplainPlanString());
// Some day, the wasteful projection node will not be here to skip.
pn = apn.getChild(0).getChild(0);
assertTrue(pn instanceof NestLoopIndexPlanNode);
nlij = (NestLoopIndexPlanNode) pn;
assertNull(nlij.getPreJoinPredicate());
assertNull(nlij.getJoinPredicate());
assertNull(nlij.getWherePredicate());
assertEquals(1, nlij.getChildCount());
c = (IndexScanPlanNode) nlij.getChild(0);
assertNull(c.getPredicate());
assertEquals(IndexLookupType.GT, c.getLookupType());
searchKeys = c.getSearchKeyExpressions();
assertEquals(1, searchKeys.size());
assertTrue(searchKeys.get(0) instanceof ConstantValueExpression);
c = (IndexScanPlanNode) nlij.getInlinePlanNode(PlanNodeType.INDEXSCAN);
assertEquals(IndexLookupType.GTE, c.getLookupType());
assertNull(c.getPredicate());
searchKeys = c.getSearchKeyExpressions();
assertEquals(1, searchKeys.size());
assertTrue(searchKeys.get(0) instanceof TupleValueExpression);
apn = compile("select * FROM R2 A, R2 B WHERE A.A = B.A AND B.C > 1 ORDER BY B.A, B.C");
//* for debug */ System.out.println(apn.toExplainPlanString());
// Some day, the wasteful projection node will not be here to skip.
pn = apn.getChild(0).getChild(0);
assertTrue(pn instanceof OrderByPlanNode);
pn = pn.getChild(0);
assertTrue(pn instanceof NestLoopIndexPlanNode);
nlij = (NestLoopIndexPlanNode) pn;
assertNull(nlij.getPreJoinPredicate());
assertNull(nlij.getJoinPredicate());
assertNull(nlij.getWherePredicate());
assertEquals(1, nlij.getChildCount());
c = (IndexScanPlanNode) nlij.getChild(0);
assertNull(c.getPredicate());
assertEquals(IndexLookupType.GT, c.getLookupType());
searchKeys = c.getSearchKeyExpressions();
assertEquals(1, searchKeys.size());
assertTrue(searchKeys.get(0) instanceof ConstantValueExpression);
c = (IndexScanPlanNode) nlij.getInlinePlanNode(PlanNodeType.INDEXSCAN);
assertEquals(IndexLookupType.GTE, c.getLookupType());
assertNull(c.getPredicate());
searchKeys = c.getSearchKeyExpressions();
assertEquals(1, searchKeys.size());
assertTrue(searchKeys.get(0) instanceof TupleValueExpression);
apn = compile("select * FROM R2 A, R2 B WHERE A.A = B.A AND B.A > 1 ORDER BY B.A, B.C");
//* for debug */ System.out.println(apn.toExplainPlanString());
// Some day, the wasteful projection node will not be here to skip.
pn = apn.getChild(0).getChild(0);
assertTrue(pn instanceof NestLoopIndexPlanNode);
nlij = (NestLoopIndexPlanNode) pn;
assertNull(nlij.getPreJoinPredicate());
assertNull(nlij.getJoinPredicate());
assertNull(nlij.getWherePredicate());
assertEquals(1, nlij.getChildCount());
assertTrue(nlij.getChild(0) instanceof IndexScanPlanNode);
c = (IndexScanPlanNode) nlij.getChild(0);
assertEquals(IndexLookupType.GT, c.getLookupType());
searchKeys = c.getSearchKeyExpressions();
assertEquals(1, searchKeys.size());
assertTrue(searchKeys.get(0) instanceof ConstantValueExpression);
c = (IndexScanPlanNode) nlij.getInlinePlanNode(PlanNodeType.INDEXSCAN);
assertEquals(IndexLookupType.GTE, c.getLookupType());
assertNull(c.getPredicate());
searchKeys = c.getSearchKeyExpressions();
assertEquals(1, searchKeys.size());
assertTrue(searchKeys.get(0) instanceof TupleValueExpression);
apn = compile("select B.C, MAX(A.C) FROM R2 A, R2 B WHERE A.A = B.A AND B.C > 1 GROUP BY B.C ORDER BY B.C");
//* for debug */ System.out.println(apn.toExplainPlanString());
// Some day, the wasteful projection node will not be here to skip.
pn = apn.getChild(0);
assertNotNull(AggregatePlanNode.getInlineAggregationNode(pn));
assertTrue(pn instanceof NestLoopIndexPlanNode);
nlij = (NestLoopIndexPlanNode) pn;
assertNull(nlij.getPreJoinPredicate());
assertNull(nlij.getJoinPredicate());
assertNull(nlij.getWherePredicate());
assertEquals(1, nlij.getChildCount());
c = (IndexScanPlanNode) nlij.getChild(0);
assertNull(c.getPredicate());
assertEquals(IndexLookupType.GT, c.getLookupType());
searchKeys = c.getSearchKeyExpressions();
assertEquals(1, searchKeys.size());
assertTrue(searchKeys.get(0) instanceof ConstantValueExpression);
c = (IndexScanPlanNode) nlij.getInlinePlanNode(PlanNodeType.INDEXSCAN);
assertEquals(IndexLookupType.GTE, c.getLookupType());
assertNull(c.getPredicate());
searchKeys = c.getSearchKeyExpressions();
assertEquals(1, searchKeys.size());
assertTrue(searchKeys.get(0) instanceof TupleValueExpression);
apn = compile("select B.C, B.A FROM R2 A, R2 B WHERE A.A = B.A AND B.C > 1 GROUP BY B.A, B.C ORDER BY B.A, B.C");
//* for debug */ System.out.println(apn.toExplainPlanString());
// Some day, the wasteful projection node will not be here to skip.
pn = apn.getChild(0).getChild(0);
assertTrue(pn instanceof OrderByPlanNode);
pn = pn.getChild(0);
assertNotNull(AggregatePlanNode.getInlineAggregationNode(pn));
assertTrue(pn instanceof NestLoopIndexPlanNode);
nlij = (NestLoopIndexPlanNode) pn;
assertNull(nlij.getPreJoinPredicate());
assertNull(nlij.getJoinPredicate());
assertNull(nlij.getWherePredicate());
assertEquals(1, nlij.getChildCount());
c = (IndexScanPlanNode) nlij.getChild(0);
assertNull(c.getPredicate());
assertEquals(IndexLookupType.GT, c.getLookupType());
searchKeys = c.getSearchKeyExpressions();
assertEquals(1, searchKeys.size());
assertTrue(searchKeys.get(0) instanceof ConstantValueExpression);
c = (IndexScanPlanNode) nlij.getInlinePlanNode(PlanNodeType.INDEXSCAN);
assertEquals(IndexLookupType.GTE, c.getLookupType());
assertNull(c.getPredicate());
searchKeys = c.getSearchKeyExpressions();
assertEquals(1, searchKeys.size());
assertTrue(searchKeys.get(0) instanceof TupleValueExpression);
apn = compile("select B.C, B.A FROM R2 A, R2 B WHERE A.A = B.A AND B.A > 1 GROUP BY B.A, B.C ORDER BY B.A, B.C");
//* for debug */ System.out.println(apn.toExplainPlanString());
pn = apn.getChild(0);
assertNotNull(AggregatePlanNode.getInlineAggregationNode(pn));
assertTrue(pn instanceof NestLoopIndexPlanNode);
nlij = (NestLoopIndexPlanNode) pn;
assertNull(nlij.getPreJoinPredicate());
assertNull(nlij.getJoinPredicate());
assertNull(nlij.getWherePredicate());
assertEquals(1, nlij.getChildCount());
assertTrue(nlij.getChild(0) instanceof IndexScanPlanNode);
c = (IndexScanPlanNode) nlij.getChild(0);
assertEquals(IndexLookupType.GT, c.getLookupType());
searchKeys = c.getSearchKeyExpressions();
assertEquals(1, searchKeys.size());
assertTrue(searchKeys.get(0) instanceof ConstantValueExpression);
c = (IndexScanPlanNode) nlij.getInlinePlanNode(PlanNodeType.INDEXSCAN);
assertEquals(IndexLookupType.GTE, c.getLookupType());
assertNull(c.getPredicate());
searchKeys = c.getSearchKeyExpressions();
assertEquals(1, searchKeys.size());
assertTrue(searchKeys.get(0) instanceof TupleValueExpression);
// Here's a case that can't be optimized because it purposely uses the "wrong" column
// in the GROUP BY and ORDER BY.
apn = compile("select B.C FROM R2 A, R2 B WHERE B.A = A.A AND B.C > 1 GROUP BY A.A, B.C ORDER BY A.A, B.C");
//* for debug */ System.out.println(apn.toExplainPlanString());
// Complex ORDER BY case: GROUP BY column that is not in the display column list
pn = apn.getChild(0);
assertTrue(pn instanceof ProjectionPlanNode);
pn = pn.getChild(0);
assertTrue(pn instanceof OrderByPlanNode);
pn = pn.getChild(0);
assertNotNull(AggregatePlanNode.getInlineAggregationNode(pn));
assertTrue(pn instanceof NestLoopIndexPlanNode);
nlij = (NestLoopIndexPlanNode) pn;
assertNull(nlij.getPreJoinPredicate());
assertNull(nlij.getJoinPredicate());
assertNull(nlij.getWherePredicate());
assertEquals(1, nlij.getChildCount());
c = (IndexScanPlanNode) nlij.getChild(0);
assertNull(c.getPredicate());
assertEquals(IndexLookupType.GT, c.getLookupType());
searchKeys = c.getSearchKeyExpressions();
assertEquals(1, searchKeys.size());
assertTrue(searchKeys.get(0) instanceof ConstantValueExpression);
c = (IndexScanPlanNode) nlij.getInlinePlanNode(PlanNodeType.INDEXSCAN);
assertEquals(IndexLookupType.GTE, c.getLookupType());
assertNull(c.getPredicate());
searchKeys = c.getSearchKeyExpressions();
assertEquals(1, searchKeys.size());
assertTrue(searchKeys.get(0) instanceof TupleValueExpression);
// Here's a case that can't be optimized because it purposely uses the "wrong" column
// in the GROUP BY and ORDER BY.
apn = compile("select B.C FROM R2 A, R2 B WHERE B.A = A.A AND B.C > 1 GROUP BY A.A, B.C ORDER BY B.C");
//* for debug */ System.out.println(apn.toExplainPlanString());
// Project-first case: GROUP BY column that is not in the order by or the display column list
pn = apn.getChild(0);
assertTrue(pn instanceof OrderByPlanNode);
pn = pn.getChild(0);
//TODO: This represents a missed optimization.
// The projection could have been inlined.
assertTrue(pn instanceof ProjectionPlanNode);
pn = pn.getChild(0);
assertNotNull(AggregatePlanNode.getInlineAggregationNode(pn));
assertTrue(pn instanceof NestLoopIndexPlanNode);
nlij = (NestLoopIndexPlanNode) pn;
assertNull(nlij.getPreJoinPredicate());
assertNull(nlij.getJoinPredicate());
assertNull(nlij.getWherePredicate());
assertEquals(1, nlij.getChildCount());
c = (IndexScanPlanNode) nlij.getChild(0);
assertNull(c.getPredicate());
assertEquals(IndexLookupType.GT, c.getLookupType());
searchKeys = c.getSearchKeyExpressions();
assertEquals(1, searchKeys.size());
assertTrue(searchKeys.get(0) instanceof ConstantValueExpression);
c = (IndexScanPlanNode) nlij.getInlinePlanNode(PlanNodeType.INDEXSCAN);
assertEquals(IndexLookupType.GTE, c.getLookupType());
assertNull(c.getPredicate());
searchKeys = c.getSearchKeyExpressions();
assertEquals(1, searchKeys.size());
assertTrue(searchKeys.get(0) instanceof TupleValueExpression);
// This variant shows that the GROUP BY can be a permutation of the sort order
// without messing up the optimization
apn = compile("select B.C, B.A FROM R2 A, R2 B WHERE A.A = B.A AND B.A > 1 GROUP BY B.C, B.A ORDER BY B.A, B.C");
//* for debug */ System.out.println(apn.toExplainPlanString());
// Some day, the wasteful projection node will not be here to skip.
pn = apn.getChild(0);
assertNotNull(AggregatePlanNode.getInlineAggregationNode(pn));
assertTrue(pn instanceof NestLoopIndexPlanNode);
nlij = (NestLoopIndexPlanNode) pn;
assertNull(nlij.getPreJoinPredicate());
assertNull(nlij.getJoinPredicate());
assertNull(nlij.getWherePredicate());
assertEquals(1, nlij.getChildCount());
assertTrue(nlij.getChild(0) instanceof IndexScanPlanNode);
c = (IndexScanPlanNode) nlij.getChild(0);
assertEquals(IndexLookupType.GT, c.getLookupType());
searchKeys = c.getSearchKeyExpressions();
assertEquals(1, searchKeys.size());
assertTrue(searchKeys.get(0) instanceof ConstantValueExpression);
c = (IndexScanPlanNode) nlij.getInlinePlanNode(PlanNodeType.INDEXSCAN);
assertEquals(IndexLookupType.GTE, c.getLookupType());
assertNull(c.getPredicate());
searchKeys = c.getSearchKeyExpressions();
assertEquals(1, searchKeys.size());
assertTrue(searchKeys.get(0) instanceof TupleValueExpression);
}
use of org.voltdb.expressions.AbstractExpression in project voltdb by VoltDB.
the class TestWindowedFunctions method validateTVEs.
public void validateTVEs(NodeSchema input_schema, WindowFunctionPlanNode pbPlanNode, boolean waiveAliasMatch) {
List<AbstractExpression> tves = new ArrayList<>();
for (AbstractExpression ae : pbPlanNode.getPartitionByExpressions()) {
tves.addAll(ae.findAllTupleValueSubexpressions());
}
List<SchemaColumn> columns = input_schema.getColumns();
for (AbstractExpression ae : tves) {
TupleValueExpression tve = (TupleValueExpression) ae;
assertTrue(0 <= tve.getColumnIndex() && tve.getColumnIndex() < columns.size());
SchemaColumn col = columns.get(tve.getColumnIndex());
String msg = String.format("TVE %d, COL %s: ", tve.getColumnIndex(), col.getColumnName() + ":" + col.getColumnAlias());
assertEquals(msg, col.getTableName(), tve.getTableName());
assertEquals(msg, col.getTableAlias(), tve.getTableAlias());
assertEquals(msg, col.getColumnName(), tve.getColumnName());
if (!waiveAliasMatch) {
assertEquals(msg, col.getColumnAlias(), tve.getColumnAlias());
}
}
}
use of org.voltdb.expressions.AbstractExpression in project voltdb by VoltDB.
the class TestPlansSubQueries method testExpressionSubqueryWithIndexScan.
/**
* Expression subquery currently is not optimized to use any index. But this does not prevent the
* parent query to use index for other purposes.
*/
public void testExpressionSubqueryWithIndexScan() {
AbstractPlanNode pn;
String sql;
// INDEX on A, for sort order only
sql = "SELECT A FROM R4 where A in (select A from R4 where A > 3) order by A;";
pn = compile(sql);
pn = pn.getChild(0);
assertTrue(pn instanceof IndexScanPlanNode);
assertEquals(0, ((IndexScanPlanNode) pn).getSearchKeyExpressions().size());
assertNotNull(((IndexScanPlanNode) pn).getPredicate());
// INDEX on A, uniquely match A = 4,
sql = "SELECT A FROM R4 where A = 4 and C in (select A from R4 where A > 3);";
pn = compile(sql);
pn = pn.getChild(0);
assertTrue(pn instanceof IndexScanPlanNode);
assertEquals(1, ((IndexScanPlanNode) pn).getSearchKeyExpressions().size());
AbstractExpression comp = ((IndexScanPlanNode) pn).getSearchKeyExpressions().get(0);
assertEquals(ExpressionType.VALUE_CONSTANT, comp.getExpressionType());
assertEquals("4", ((ConstantValueExpression) comp).getValue());
assertNotNull(((IndexScanPlanNode) pn).getPredicate());
}
Aggregations