DRILL-4474: Ensure that ConvertCountToDirectScan does not push through project when nullable input of count is not RexInputRef This closes #416
Project: http://git-wip-us.apache.org/repos/asf/drill/repo Commit: http://git-wip-us.apache.org/repos/asf/drill/commit/49ae6d36 Tree: http://git-wip-us.apache.org/repos/asf/drill/tree/49ae6d36 Diff: http://git-wip-us.apache.org/repos/asf/drill/diff/49ae6d36 Branch: refs/heads/master Commit: 49ae6d363efe78df4e89f7913d1d560e9627b325 Parents: 39f6fa3 Author: Jinfeng Ni <[email protected]> Authored: Tue Mar 8 14:15:27 2016 -0800 Committer: Parth Chandra <[email protected]> Committed: Tue Mar 8 17:14:33 2016 -0800 ---------------------------------------------------------------------- .../physical/ConvertCountToDirectScan.java | 23 +++++++-- .../logical/TestConvertCountToDirectScan.java | 52 ++++++++++++++++++++ 2 files changed, 70 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/drill/blob/49ae6d36/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/ConvertCountToDirectScan.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/ConvertCountToDirectScan.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/ConvertCountToDirectScan.java index 710eb60..c93978c 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/ConvertCountToDirectScan.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/ConvertCountToDirectScan.java @@ -25,7 +25,6 @@ import org.apache.calcite.plan.RelOptRule; import org.apache.calcite.plan.RelOptRuleCall; import org.apache.calcite.plan.RelOptRuleOperand; import org.apache.calcite.rel.core.AggregateCall; -import org.apache.calcite.rel.rules.ProjectRemoveRule; import org.apache.calcite.rel.type.RelDataType; import org.apache.calcite.rel.type.RelDataTypeFactory; import org.apache.calcite.rel.type.RelDataTypeField; @@ -104,10 +103,6 @@ public class ConvertCountToDirectScan extends Prule { return; } - if (proj != null && !ProjectRemoveRule.isTrivial(proj)) { - return; - } - AggregateCall aggCall = agg.getAggCallList().get(0); if (aggCall.getAggregation().getName().equals("COUNT") ) { @@ -122,6 +117,24 @@ public class ConvertCountToDirectScan extends Prule { } else if (aggCall.getArgList().size() == 1) { // count(columnName) ==> Agg ( Scan )) ==> columnValueCount int index = aggCall.getArgList().get(0); + + if (proj != null) { + // project in the middle of Agg and Scan : Only when input of AggCall is a RexInputRef in Project, we find the index of Scan's field. + // For instance, + // Agg - count($0) + // \ + // Proj - Exp={$1} + // \ + // Scan (col1, col2). + // return count of "col2" in Scan's metadata, if found. + + if (proj.getProjects().get(index) instanceof RexInputRef) { + index = ((RexInputRef) proj.getProjects().get(index)).getIndex(); + } else { + return; // do not apply for all other cases. + } + } + String columnName = scan.getRowType().getFieldNames().get(index).toLowerCase(); cnt = oldGrpScan.getColumnValueCount(SchemaPath.getSimplePath(columnName)); http://git-wip-us.apache.org/repos/asf/drill/blob/49ae6d36/exec/java-exec/src/test/java/org/apache/drill/exec/planner/logical/TestConvertCountToDirectScan.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/planner/logical/TestConvertCountToDirectScan.java b/exec/java-exec/src/test/java/org/apache/drill/exec/planner/logical/TestConvertCountToDirectScan.java index ec8bcf0..21b4c79 100644 --- a/exec/java-exec/src/test/java/org/apache/drill/exec/planner/logical/TestConvertCountToDirectScan.java +++ b/exec/java-exec/src/test/java/org/apache/drill/exec/planner/logical/TestConvertCountToDirectScan.java @@ -30,4 +30,56 @@ public class TestConvertCountToDirectScan extends PlanTestBase { new String[] { "CASE" }, new String[]{}); } + + @Test + public void ensureConvertSimpleCountToDirectScan() throws Exception { + final String sql = "select count(*) as cnt from cp.`tpch/nation.parquet`"; + testPlanMatchingPatterns( + sql, + new String[] { "PojoRecordReader" }, + new String[]{}); + + testBuilder() + .sqlQuery(sql) + .unOrdered() + .baselineColumns("cnt") + .baselineValues(25L) + .go(); + + } + + @Test + public void ensureConvertSimpleCountConstToDirectScan() throws Exception { + final String sql = "select count(100) as cnt from cp.`tpch/nation.parquet`"; + testPlanMatchingPatterns( + sql, + new String[] { "PojoRecordReader" }, + new String[]{}); + + testBuilder() + .sqlQuery(sql) + .unOrdered() + .baselineColumns("cnt") + .baselineValues(25L) + .go(); + + } + + @Test + public void ensureConvertSimpleCountConstExprToDirectScan() throws Exception { + final String sql = "select count(1 + 2) as cnt from cp.`tpch/nation.parquet`"; + testPlanMatchingPatterns( + sql, + new String[] { "PojoRecordReader" }, + new String[]{}); + + testBuilder() + .sqlQuery(sql) + .unOrdered() + .baselineColumns("cnt") + .baselineValues(25L) + .go(); + + } + }
