diff --git a/presto-main/src/main/java/io/prestosql/sql/planner/PlanOptimizers.java b/presto-main/src/main/java/io/prestosql/sql/planner/PlanOptimizers.java index bef5efdd9ec9..0a4fbc2ef7d8 100644 --- a/presto-main/src/main/java/io/prestosql/sql/planner/PlanOptimizers.java +++ b/presto-main/src/main/java/io/prestosql/sql/planner/PlanOptimizers.java @@ -46,11 +46,7 @@ import io.prestosql.sql.planner.iterative.rule.GatherAndMergeWindows; import io.prestosql.sql.planner.iterative.rule.ImplementBernoulliSampleAsFilter; import io.prestosql.sql.planner.iterative.rule.ImplementFilteredAggregations; -import io.prestosql.sql.planner.iterative.rule.ImplementOffsetOverOther; -import io.prestosql.sql.planner.iterative.rule.ImplementOffsetOverProjectSort; -import io.prestosql.sql.planner.iterative.rule.ImplementOffsetOverProjectTopN; -import io.prestosql.sql.planner.iterative.rule.ImplementOffsetOverSort; -import io.prestosql.sql.planner.iterative.rule.ImplementOffsetOverTopN; +import io.prestosql.sql.planner.iterative.rule.ImplementOffset; import io.prestosql.sql.planner.iterative.rule.InlineProjections; import io.prestosql.sql.planner.iterative.rule.MergeFilters; import io.prestosql.sql.planner.iterative.rule.MergeLimitOverProjectWithSort; @@ -343,23 +339,9 @@ public PlanOptimizers( estimatedExchangesCostCalculator, // Temporary hack: separate optimizer step to avoid the sample node being replaced by filter before pushing // it to table scan node - ImmutableSet.of(new ImplementBernoulliSampleAsFilter())), - new IterativeOptimizer( - ruleStats, - statsCalculator, - estimatedExchangesCostCalculator, ImmutableSet.of( - new ImplementOffsetOverTopN(), - new ImplementOffsetOverProjectTopN(), - new ImplementOffsetOverSort(), - new ImplementOffsetOverProjectSort())), - new IterativeOptimizer( - ruleStats, - statsCalculator, - estimatedExchangesCostCalculator, - // Temporary hack: separate optimizer step to avoid a plan that's missing a SortNode over a RowNumber node - // if the rules fires too early - ImmutableSet.of(new ImplementOffsetOverOther())), + new ImplementBernoulliSampleAsFilter(), + new ImplementOffset())), simplifyOptimizer, new UnaliasSymbolReferences(), new IterativeOptimizer( diff --git a/presto-main/src/main/java/io/prestosql/sql/planner/iterative/rule/ImplementOffsetOverOther.java b/presto-main/src/main/java/io/prestosql/sql/planner/iterative/rule/ImplementOffset.java similarity index 87% rename from presto-main/src/main/java/io/prestosql/sql/planner/iterative/rule/ImplementOffsetOverOther.java rename to presto-main/src/main/java/io/prestosql/sql/planner/iterative/rule/ImplementOffset.java index 87c2608104e8..9e0a78b1389a 100644 --- a/presto-main/src/main/java/io/prestosql/sql/planner/iterative/rule/ImplementOffsetOverOther.java +++ b/presto-main/src/main/java/io/prestosql/sql/planner/iterative/rule/ImplementOffset.java @@ -23,8 +23,6 @@ import io.prestosql.sql.planner.plan.OffsetNode; import io.prestosql.sql.planner.plan.ProjectNode; import io.prestosql.sql.planner.plan.RowNumberNode; -import io.prestosql.sql.planner.plan.SortNode; -import io.prestosql.sql.planner.plan.TopNNode; import io.prestosql.sql.tree.ComparisonExpression; import io.prestosql.sql.tree.GenericLiteral; @@ -32,13 +30,12 @@ import static io.prestosql.spi.type.BigintType.BIGINT; import static io.prestosql.sql.planner.plan.Patterns.offset; -import static io.prestosql.sql.planner.plan.Patterns.source; /** * Transforms: *
  * - Offset (row count = x)
- *    - Source (other than Sort, TopN)
+ *    - Source
  * 
* Into: *
@@ -47,12 +44,14 @@
  *       - RowNumber
  *          - Source
  * 
+ * Relies on RowNumberNode's property of keeping order of its input. + * If the query contains an ORDER BY clause, the sorted order + * will be respected when leading rows are removed. */ -public class ImplementOffsetOverOther +public class ImplementOffset implements Rule { - private static final Pattern PATTERN = offset() - .with(source().matching(node -> !(node instanceof TopNNode || node instanceof SortNode))); + private static final Pattern PATTERN = offset(); @Override public Pattern getPattern() diff --git a/presto-main/src/main/java/io/prestosql/sql/planner/iterative/rule/ImplementOffsetOverProjectSort.java b/presto-main/src/main/java/io/prestosql/sql/planner/iterative/rule/ImplementOffsetOverProjectSort.java deleted file mode 100644 index 2fcc7162774c..000000000000 --- a/presto-main/src/main/java/io/prestosql/sql/planner/iterative/rule/ImplementOffsetOverProjectSort.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.prestosql.sql.planner.iterative.rule; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import io.prestosql.matching.Capture; -import io.prestosql.matching.Captures; -import io.prestosql.matching.Pattern; -import io.prestosql.spi.block.SortOrder; -import io.prestosql.sql.planner.OrderingScheme; -import io.prestosql.sql.planner.Symbol; -import io.prestosql.sql.planner.iterative.Rule; -import io.prestosql.sql.planner.plan.FilterNode; -import io.prestosql.sql.planner.plan.OffsetNode; -import io.prestosql.sql.planner.plan.ProjectNode; -import io.prestosql.sql.planner.plan.RowNumberNode; -import io.prestosql.sql.planner.plan.SortNode; -import io.prestosql.sql.tree.ComparisonExpression; -import io.prestosql.sql.tree.GenericLiteral; - -import java.util.Optional; - -import static io.prestosql.matching.Capture.newCapture; -import static io.prestosql.spi.type.BigintType.BIGINT; -import static io.prestosql.sql.planner.plan.Patterns.offset; -import static io.prestosql.sql.planner.plan.Patterns.project; -import static io.prestosql.sql.planner.plan.Patterns.sort; -import static io.prestosql.sql.planner.plan.Patterns.source; - -/** - * Transforms: - *
- * - Offset (row count = x)
- *    - Project (prunes sort symbols no longer useful)
- *       - Sort (order by a, b, c)
- * 
- * Into: - *
- * - Project (prunes rowNumber symbol and sort symbols no longer useful)
- *    - Sort (order by rowNumber)
- *       - Filter (rowNumber > x)
- *          - RowNumber
- *             - Sort (order by a, b, c)
- * 
- */ -public class ImplementOffsetOverProjectSort - implements Rule -{ - private static final Capture PROJECT = newCapture(); - private static final Capture SORT = newCapture(); - - private static final Pattern PATTERN = offset() - .with(source().matching( - project().capturedAs(PROJECT).matching(ProjectNode::isIdentity) - .with(source().matching( - sort().capturedAs(SORT))))); - - @Override - public Pattern getPattern() - { - return PATTERN; - } - - @Override - public Result apply(OffsetNode parent, Captures captures, Context context) - { - ProjectNode project = captures.get(PROJECT); - SortNode sort = captures.get(SORT); - - Symbol rowNumberSymbol = context.getSymbolAllocator().newSymbol("row_number", BIGINT); - - RowNumberNode rowNumberNode = new RowNumberNode( - context.getIdAllocator().getNextId(), - sort, - ImmutableList.of(), - rowNumberSymbol, - Optional.empty(), - Optional.empty()); - - FilterNode filterNode = new FilterNode( - context.getIdAllocator().getNextId(), - rowNumberNode, - new ComparisonExpression( - ComparisonExpression.Operator.GREATER_THAN, - rowNumberSymbol.toSymbolReference(), - new GenericLiteral("BIGINT", Long.toString(parent.getCount())))); - - SortNode sortNode = new SortNode( - context.getIdAllocator().getNextId(), - filterNode, - new OrderingScheme(ImmutableList.of(rowNumberSymbol), ImmutableMap.of(rowNumberSymbol, SortOrder.ASC_NULLS_FIRST))); - - ProjectNode projectNode = (ProjectNode) project.replaceChildren(ImmutableList.of(sortNode)); - - return Result.ofPlanNode(projectNode); - } -} diff --git a/presto-main/src/main/java/io/prestosql/sql/planner/iterative/rule/ImplementOffsetOverProjectTopN.java b/presto-main/src/main/java/io/prestosql/sql/planner/iterative/rule/ImplementOffsetOverProjectTopN.java deleted file mode 100644 index 7de6abe9515a..000000000000 --- a/presto-main/src/main/java/io/prestosql/sql/planner/iterative/rule/ImplementOffsetOverProjectTopN.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.prestosql.sql.planner.iterative.rule; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import io.prestosql.matching.Capture; -import io.prestosql.matching.Captures; -import io.prestosql.matching.Pattern; -import io.prestosql.spi.block.SortOrder; -import io.prestosql.sql.planner.OrderingScheme; -import io.prestosql.sql.planner.Symbol; -import io.prestosql.sql.planner.iterative.Rule; -import io.prestosql.sql.planner.plan.FilterNode; -import io.prestosql.sql.planner.plan.OffsetNode; -import io.prestosql.sql.planner.plan.ProjectNode; -import io.prestosql.sql.planner.plan.RowNumberNode; -import io.prestosql.sql.planner.plan.SortNode; -import io.prestosql.sql.planner.plan.TopNNode; -import io.prestosql.sql.tree.ComparisonExpression; -import io.prestosql.sql.tree.GenericLiteral; - -import java.util.Optional; - -import static io.prestosql.matching.Capture.newCapture; -import static io.prestosql.spi.type.BigintType.BIGINT; -import static io.prestosql.sql.planner.plan.Patterns.offset; -import static io.prestosql.sql.planner.plan.Patterns.project; -import static io.prestosql.sql.planner.plan.Patterns.source; -import static io.prestosql.sql.planner.plan.Patterns.topN; - -/** - * Transforms: - *
- * - Offset (row count = x)
- *    - Project (prunes sort symbols no longer useful)
- *       - TopN (order by a, b, c)
- * 
- * Into: - *
- * - Project (prunes rowNumber symbol and sort symbols no longer useful)
- *    - Sort (order by rowNumber)
- *       - Filter (rowNumber > x)
- *          - RowNumber
- *             - TopN (order by a, b, c)
- * 
- */ -public class ImplementOffsetOverProjectTopN - implements Rule -{ - private static final Capture PROJECT = newCapture(); - private static final Capture TOPN = newCapture(); - - private static final Pattern PATTERN = offset() - .with(source().matching( - project().capturedAs(PROJECT).matching(ProjectNode::isIdentity) - .with(source().matching( - topN().capturedAs(TOPN))))); - - @Override - public Pattern getPattern() - { - return PATTERN; - } - - @Override - public Result apply(OffsetNode parent, Captures captures, Context context) - { - ProjectNode project = captures.get(PROJECT); - TopNNode topN = captures.get(TOPN); - - Symbol rowNumberSymbol = context.getSymbolAllocator().newSymbol("row_number", BIGINT); - - RowNumberNode rowNumberNode = new RowNumberNode( - context.getIdAllocator().getNextId(), - topN, - ImmutableList.of(), - rowNumberSymbol, - Optional.empty(), - Optional.empty()); - - FilterNode filterNode = new FilterNode( - context.getIdAllocator().getNextId(), - rowNumberNode, - new ComparisonExpression( - ComparisonExpression.Operator.GREATER_THAN, - rowNumberSymbol.toSymbolReference(), - new GenericLiteral("BIGINT", Long.toString(parent.getCount())))); - - SortNode sortNode = new SortNode( - context.getIdAllocator().getNextId(), - filterNode, - new OrderingScheme(ImmutableList.of(rowNumberSymbol), ImmutableMap.of(rowNumberSymbol, SortOrder.ASC_NULLS_FIRST))); - - ProjectNode projectNode = (ProjectNode) project.replaceChildren(ImmutableList.of(sortNode)); - - return Result.ofPlanNode(projectNode); - } -} diff --git a/presto-main/src/main/java/io/prestosql/sql/planner/iterative/rule/ImplementOffsetOverSort.java b/presto-main/src/main/java/io/prestosql/sql/planner/iterative/rule/ImplementOffsetOverSort.java deleted file mode 100644 index cf5b695f9b21..000000000000 --- a/presto-main/src/main/java/io/prestosql/sql/planner/iterative/rule/ImplementOffsetOverSort.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.prestosql.sql.planner.iterative.rule; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import io.prestosql.matching.Capture; -import io.prestosql.matching.Captures; -import io.prestosql.matching.Pattern; -import io.prestosql.spi.block.SortOrder; -import io.prestosql.sql.planner.OrderingScheme; -import io.prestosql.sql.planner.Symbol; -import io.prestosql.sql.planner.iterative.Rule; -import io.prestosql.sql.planner.plan.Assignments; -import io.prestosql.sql.planner.plan.FilterNode; -import io.prestosql.sql.planner.plan.OffsetNode; -import io.prestosql.sql.planner.plan.ProjectNode; -import io.prestosql.sql.planner.plan.RowNumberNode; -import io.prestosql.sql.planner.plan.SortNode; -import io.prestosql.sql.tree.ComparisonExpression; -import io.prestosql.sql.tree.GenericLiteral; - -import java.util.Optional; - -import static io.prestosql.matching.Capture.newCapture; -import static io.prestosql.spi.type.BigintType.BIGINT; -import static io.prestosql.sql.planner.plan.Patterns.offset; -import static io.prestosql.sql.planner.plan.Patterns.sort; -import static io.prestosql.sql.planner.plan.Patterns.source; - -/** - * Transforms: - *
- * - Offset (row count = x)
- *    - Sort (order by a, b, c)
- * 
- * Into: - *
- * - Project (prune rowNumber symbol)
- *    - Sort (order by rowNumber)
- *       - Filter (rowNumber > x)
- *          - RowNumber
- *             - Sort (order by a, b, c)
- * 
- */ -public class ImplementOffsetOverSort - implements Rule -{ - private static final Capture SORT = newCapture(); - - private static final Pattern PATTERN = offset() - .with(source().matching( - sort().capturedAs(SORT))); - - @Override - public Pattern getPattern() - { - return PATTERN; - } - - @Override - public Result apply(OffsetNode parent, Captures captures, Context context) - { - SortNode sort = captures.get(SORT); - - Symbol rowNumberSymbol = context.getSymbolAllocator().newSymbol("row_number", BIGINT); - - RowNumberNode rowNumberNode = new RowNumberNode( - context.getIdAllocator().getNextId(), - sort, - ImmutableList.of(), - rowNumberSymbol, - Optional.empty(), - Optional.empty()); - - FilterNode filterNode = new FilterNode( - context.getIdAllocator().getNextId(), - rowNumberNode, - new ComparisonExpression( - ComparisonExpression.Operator.GREATER_THAN, - rowNumberSymbol.toSymbolReference(), - new GenericLiteral("BIGINT", Long.toString(parent.getCount())))); - - SortNode sortNode = new SortNode( - context.getIdAllocator().getNextId(), - filterNode, - new OrderingScheme(ImmutableList.of(rowNumberSymbol), ImmutableMap.of(rowNumberSymbol, SortOrder.ASC_NULLS_FIRST))); - - ProjectNode projectNode = new ProjectNode( - context.getIdAllocator().getNextId(), - sortNode, - Assignments.identity(sort.getOutputSymbols())); - - return Result.ofPlanNode(projectNode); - } -} diff --git a/presto-main/src/main/java/io/prestosql/sql/planner/iterative/rule/ImplementOffsetOverTopN.java b/presto-main/src/main/java/io/prestosql/sql/planner/iterative/rule/ImplementOffsetOverTopN.java deleted file mode 100644 index 03f0f8b3c6f7..000000000000 --- a/presto-main/src/main/java/io/prestosql/sql/planner/iterative/rule/ImplementOffsetOverTopN.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.prestosql.sql.planner.iterative.rule; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import io.prestosql.matching.Capture; -import io.prestosql.matching.Captures; -import io.prestosql.matching.Pattern; -import io.prestosql.spi.block.SortOrder; -import io.prestosql.sql.planner.OrderingScheme; -import io.prestosql.sql.planner.Symbol; -import io.prestosql.sql.planner.iterative.Rule; -import io.prestosql.sql.planner.plan.Assignments; -import io.prestosql.sql.planner.plan.FilterNode; -import io.prestosql.sql.planner.plan.OffsetNode; -import io.prestosql.sql.planner.plan.ProjectNode; -import io.prestosql.sql.planner.plan.RowNumberNode; -import io.prestosql.sql.planner.plan.SortNode; -import io.prestosql.sql.planner.plan.TopNNode; -import io.prestosql.sql.tree.ComparisonExpression; -import io.prestosql.sql.tree.GenericLiteral; - -import java.util.Optional; - -import static io.prestosql.matching.Capture.newCapture; -import static io.prestosql.spi.type.BigintType.BIGINT; -import static io.prestosql.sql.planner.plan.Patterns.offset; -import static io.prestosql.sql.planner.plan.Patterns.source; -import static io.prestosql.sql.planner.plan.Patterns.topN; - -/** - * Transforms: - *
- * - Offset (row count = x)
- *    - TopN (order by a, b, c)
- * 
- * Into: - *
- * - Project (prune rowNumber symbol)
- *    - Sort (order by rowNumber)
- *       - Filter (rowNumber > x)
- *          - RowNumber
- *             - TopN (order by a, b, c)
- * 
- */ -public class ImplementOffsetOverTopN - implements Rule -{ - private static final Capture TOPN = newCapture(); - - private static final Pattern PATTERN = offset() - .with(source().matching( - topN().capturedAs(TOPN))); - - @Override - public Pattern getPattern() - { - return PATTERN; - } - - @Override - public Result apply(OffsetNode parent, Captures captures, Context context) - { - TopNNode topN = captures.get(TOPN); - - Symbol rowNumberSymbol = context.getSymbolAllocator().newSymbol("row_number", BIGINT); - - RowNumberNode rowNumberNode = new RowNumberNode( - context.getIdAllocator().getNextId(), - topN, - ImmutableList.of(), - rowNumberSymbol, - Optional.empty(), - Optional.empty()); - - FilterNode filterNode = new FilterNode( - context.getIdAllocator().getNextId(), - rowNumberNode, - new ComparisonExpression( - ComparisonExpression.Operator.GREATER_THAN, - rowNumberSymbol.toSymbolReference(), - new GenericLiteral("BIGINT", Long.toString(parent.getCount())))); - - SortNode sortNode = new SortNode( - context.getIdAllocator().getNextId(), - filterNode, - new OrderingScheme(ImmutableList.of(rowNumberSymbol), ImmutableMap.of(rowNumberSymbol, SortOrder.ASC_NULLS_FIRST))); - - ProjectNode projectNode = new ProjectNode( - context.getIdAllocator().getNextId(), - sortNode, - Assignments.identity(topN.getOutputSymbols())); - - return Result.ofPlanNode(projectNode); - } -} diff --git a/presto-main/src/test/java/io/prestosql/sql/planner/TestLogicalPlanner.java b/presto-main/src/test/java/io/prestosql/sql/planner/TestLogicalPlanner.java index 9e6caaff836e..fdd207fcb074 100644 --- a/presto-main/src/test/java/io/prestosql/sql/planner/TestLogicalPlanner.java +++ b/presto-main/src/test/java/io/prestosql/sql/planner/TestLogicalPlanner.java @@ -102,7 +102,6 @@ import static io.prestosql.sql.planner.plan.JoinNode.DistributionType.REPLICATED; import static io.prestosql.sql.planner.plan.JoinNode.Type.INNER; import static io.prestosql.sql.planner.plan.JoinNode.Type.LEFT; -import static io.prestosql.sql.tree.SortItem.NullOrdering.FIRST; import static io.prestosql.sql.tree.SortItem.NullOrdering.LAST; import static io.prestosql.sql.tree.SortItem.Ordering.ASCENDING; import static io.prestosql.sql.tree.SortItem.Ordering.DESCENDING; @@ -879,7 +878,7 @@ public void testOffset() strictProject( ImmutableMap.of("name", new ExpressionMatcher("name")), filter( - "(row_num > BIGINT '2')", + "row_num > BIGINT '2'", rowNumber( pattern -> pattern .partitionBy(ImmutableList.of()), @@ -892,43 +891,36 @@ public void testOffset() any( strictProject( ImmutableMap.of("name", new ExpressionMatcher("name")), - any( - sort( - ImmutableList.of(sort("row_num", ASCENDING, FIRST)), - any( - filter( - "(row_num > BIGINT '2')", - rowNumber( - pattern -> pattern - .partitionBy(ImmutableList.of()), - any( - sort( - ImmutableList.of(sort("regionkey", ASCENDING, LAST)), - any( - tableScan("nation", ImmutableMap.of("NAME", "name", "REGIONKEY", "regionkey")))))) - .withAlias("row_num", new RowNumberSymbolMatcher())))))))); + filter( + "row_num > BIGINT '2'", + rowNumber( + pattern -> pattern + .partitionBy(ImmutableList.of()), + anyTree( + sort( + ImmutableList.of(sort("regionkey", ASCENDING, LAST)), + any( + tableScan("nation", ImmutableMap.of("NAME", "name", "REGIONKEY", "regionkey")))))) + .withAlias("row_num", new RowNumberSymbolMatcher()))))); assertPlan( "SELECT name FROM nation ORDER BY regionkey OFFSET 2 ROWS FETCH NEXT 5 ROWS ONLY", any( strictProject( ImmutableMap.of("name", new ExpressionMatcher("name")), - any( - sort( - ImmutableList.of(sort("row_num", ASCENDING, FIRST)), + filter( + "row_num > BIGINT '2'", + rowNumber( + pattern -> pattern + .partitionBy(ImmutableList.of()), any( - filter( - "(row_num > BIGINT '2')", - rowNumber( - pattern -> pattern - .partitionBy(ImmutableList.of()), - topN( - 7, - ImmutableList.of(sort("regionkey", ASCENDING, LAST)), - TopNNode.Step.FINAL, - anyTree( - tableScan("nation", ImmutableMap.of("NAME", "name", "REGIONKEY", "regionkey"))))) - .withAlias("row_num", new RowNumberSymbolMatcher())))))))); + topN( + 7, + ImmutableList.of(sort("regionkey", ASCENDING, LAST)), + TopNNode.Step.FINAL, + anyTree( + tableScan("nation", ImmutableMap.of("NAME", "name", "REGIONKEY", "regionkey")))))) + .withAlias("row_num", new RowNumberSymbolMatcher()))))); assertPlan( "SELECT name FROM nation OFFSET 2 ROWS FETCH NEXT 5 ROWS ONLY", @@ -936,7 +928,7 @@ public void testOffset() strictProject( ImmutableMap.of("name", new ExpressionMatcher("name")), filter( - "(row_num > BIGINT '2')", + "row_num > BIGINT '2'", rowNumber( pattern -> pattern .partitionBy(ImmutableList.of()), diff --git a/presto-main/src/test/java/io/prestosql/sql/planner/iterative/rule/TestImplementOffsetOverOther.java b/presto-main/src/test/java/io/prestosql/sql/planner/iterative/rule/TestImplementOffset.java similarity index 56% rename from presto-main/src/test/java/io/prestosql/sql/planner/iterative/rule/TestImplementOffsetOverOther.java rename to presto-main/src/test/java/io/prestosql/sql/planner/iterative/rule/TestImplementOffset.java index 27c1049a5da3..741eada368d5 100644 --- a/presto-main/src/test/java/io/prestosql/sql/planner/iterative/rule/TestImplementOffsetOverOther.java +++ b/presto-main/src/test/java/io/prestosql/sql/planner/iterative/rule/TestImplementOffset.java @@ -23,16 +23,19 @@ import static io.prestosql.sql.planner.assertions.PlanMatchPattern.filter; import static io.prestosql.sql.planner.assertions.PlanMatchPattern.rowNumber; +import static io.prestosql.sql.planner.assertions.PlanMatchPattern.sort; import static io.prestosql.sql.planner.assertions.PlanMatchPattern.strictProject; import static io.prestosql.sql.planner.assertions.PlanMatchPattern.values; +import static io.prestosql.sql.tree.SortItem.NullOrdering.FIRST; +import static io.prestosql.sql.tree.SortItem.Ordering.ASCENDING; -public class TestImplementOffsetOverOther +public class TestImplementOffset extends BaseRuleTest { @Test - public void testReplaceOffsetOverOther() + public void testReplaceOffsetOverValues() { - tester().assertThat(new ImplementOffsetOverOther()) + tester().assertThat(new ImplementOffset()) .on(p -> { Symbol a = p.symbol("a"); Symbol b = p.symbol("b"); @@ -44,11 +47,38 @@ public void testReplaceOffsetOverOther() strictProject( ImmutableMap.of("a", new ExpressionMatcher("a"), "b", new ExpressionMatcher("b")), filter( - "(row_num > BIGINT '2')", + "row_num > BIGINT '2'", rowNumber( pattern -> pattern .partitionBy(ImmutableList.of()), values("a", "b")) .withAlias("row_num", new RowNumberSymbolMatcher())))); } + + @Test + public void testReplaceOffsetOverSort() + { + tester().assertThat(new ImplementOffset()) + .on(p -> { + Symbol a = p.symbol("a"); + Symbol b = p.symbol("b"); + return p.offset( + 2, + p.sort( + ImmutableList.of(a), + p.values(a, b))); + }) + .matches( + strictProject( + ImmutableMap.of("a", new ExpressionMatcher("a"), "b", new ExpressionMatcher("b")), + filter( + "row_num > BIGINT '2'", + rowNumber( + pattern -> pattern + .partitionBy(ImmutableList.of()), + sort( + ImmutableList.of(sort("a", ASCENDING, FIRST)), + values("a", "b"))) + .withAlias("row_num", new RowNumberSymbolMatcher())))); + } } diff --git a/presto-main/src/test/java/io/prestosql/sql/planner/iterative/rule/TestImplementOffsetOverProjectSort.java b/presto-main/src/test/java/io/prestosql/sql/planner/iterative/rule/TestImplementOffsetOverProjectSort.java deleted file mode 100644 index 9fbd324e81c7..000000000000 --- a/presto-main/src/test/java/io/prestosql/sql/planner/iterative/rule/TestImplementOffsetOverProjectSort.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.prestosql.sql.planner.iterative.rule; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import io.prestosql.sql.planner.Symbol; -import io.prestosql.sql.planner.assertions.ExpressionMatcher; -import io.prestosql.sql.planner.assertions.RowNumberSymbolMatcher; -import io.prestosql.sql.planner.iterative.rule.test.BaseRuleTest; -import io.prestosql.sql.planner.plan.Assignments; -import org.testng.annotations.Test; - -import static io.prestosql.sql.planner.assertions.PlanMatchPattern.filter; -import static io.prestosql.sql.planner.assertions.PlanMatchPattern.rowNumber; -import static io.prestosql.sql.planner.assertions.PlanMatchPattern.sort; -import static io.prestosql.sql.planner.assertions.PlanMatchPattern.strictProject; -import static io.prestosql.sql.planner.assertions.PlanMatchPattern.values; -import static io.prestosql.sql.tree.SortItem.NullOrdering.FIRST; -import static io.prestosql.sql.tree.SortItem.Ordering.ASCENDING; - -public class TestImplementOffsetOverProjectSort - extends BaseRuleTest -{ - @Test - public void testReplaceOffsetOverProjectSort() - { - tester().assertThat(new ImplementOffsetOverProjectSort()) - .on(p -> { - Symbol a = p.symbol("a"); - Symbol b = p.symbol("b"); - return p.offset( - 2, - p.project( - Assignments.identity(b), - p.sort( - ImmutableList.of(a), - p.values(a, b)))); - }) - .matches( - strictProject( - ImmutableMap.of("b", new ExpressionMatcher("b")), - sort( - ImmutableList.of(sort("row_num", ASCENDING, FIRST)), - filter( - "(row_num > BIGINT '2')", - rowNumber( - pattern -> pattern - .partitionBy(ImmutableList.of()), - sort( - ImmutableList.of(sort("a", ASCENDING, FIRST)), - values("a", "b"))) - .withAlias("row_num", new RowNumberSymbolMatcher()))))); - } -} diff --git a/presto-main/src/test/java/io/prestosql/sql/planner/iterative/rule/TestImplementOffsetOverProjectTopN.java b/presto-main/src/test/java/io/prestosql/sql/planner/iterative/rule/TestImplementOffsetOverProjectTopN.java deleted file mode 100644 index 0e3e5ce6558f..000000000000 --- a/presto-main/src/test/java/io/prestosql/sql/planner/iterative/rule/TestImplementOffsetOverProjectTopN.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.prestosql.sql.planner.iterative.rule; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import io.prestosql.sql.planner.Symbol; -import io.prestosql.sql.planner.assertions.ExpressionMatcher; -import io.prestosql.sql.planner.assertions.RowNumberSymbolMatcher; -import io.prestosql.sql.planner.iterative.rule.test.BaseRuleTest; -import io.prestosql.sql.planner.plan.Assignments; -import org.testng.annotations.Test; - -import static io.prestosql.sql.planner.assertions.PlanMatchPattern.filter; -import static io.prestosql.sql.planner.assertions.PlanMatchPattern.rowNumber; -import static io.prestosql.sql.planner.assertions.PlanMatchPattern.sort; -import static io.prestosql.sql.planner.assertions.PlanMatchPattern.strictProject; -import static io.prestosql.sql.planner.assertions.PlanMatchPattern.topN; -import static io.prestosql.sql.planner.assertions.PlanMatchPattern.values; -import static io.prestosql.sql.tree.SortItem.NullOrdering.FIRST; -import static io.prestosql.sql.tree.SortItem.Ordering.ASCENDING; - -public class TestImplementOffsetOverProjectTopN - extends BaseRuleTest -{ - @Test - public void testReplaceOffsetOverProjectTopN() - { - tester().assertThat(new ImplementOffsetOverProjectTopN()) - .on(p -> { - Symbol a = p.symbol("a"); - Symbol b = p.symbol("b"); - return p.offset( - 2, - p.project( - Assignments.identity(b), - p.topN( - 5, - ImmutableList.of(a), - p.values(a, b)))); - }) - .matches( - strictProject( - ImmutableMap.of("b", new ExpressionMatcher("b")), - sort( - ImmutableList.of(sort("row_num", ASCENDING, FIRST)), - filter( - "(row_num > BIGINT '2')", - rowNumber( - pattern -> pattern - .partitionBy(ImmutableList.of()), - topN( - 5, - ImmutableList.of(sort("a", ASCENDING, FIRST)), - values("a", "b"))) - .withAlias("row_num", new RowNumberSymbolMatcher()))))); - } -} diff --git a/presto-main/src/test/java/io/prestosql/sql/planner/iterative/rule/TestImplementOffsetOverSort.java b/presto-main/src/test/java/io/prestosql/sql/planner/iterative/rule/TestImplementOffsetOverSort.java deleted file mode 100644 index e2a1c261ec8b..000000000000 --- a/presto-main/src/test/java/io/prestosql/sql/planner/iterative/rule/TestImplementOffsetOverSort.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.prestosql.sql.planner.iterative.rule; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import io.prestosql.sql.planner.Symbol; -import io.prestosql.sql.planner.assertions.ExpressionMatcher; -import io.prestosql.sql.planner.assertions.RowNumberSymbolMatcher; -import io.prestosql.sql.planner.iterative.rule.test.BaseRuleTest; -import org.testng.annotations.Test; - -import static io.prestosql.sql.planner.assertions.PlanMatchPattern.filter; -import static io.prestosql.sql.planner.assertions.PlanMatchPattern.rowNumber; -import static io.prestosql.sql.planner.assertions.PlanMatchPattern.sort; -import static io.prestosql.sql.planner.assertions.PlanMatchPattern.strictProject; -import static io.prestosql.sql.planner.assertions.PlanMatchPattern.values; -import static io.prestosql.sql.tree.SortItem.NullOrdering.FIRST; -import static io.prestosql.sql.tree.SortItem.Ordering.ASCENDING; - -public class TestImplementOffsetOverSort - extends BaseRuleTest -{ - @Test - public void testReplaceOffsetOverSort() - { - tester().assertThat(new ImplementOffsetOverSort()) - .on(p -> { - Symbol a = p.symbol("a"); - Symbol b = p.symbol("b"); - return p.offset( - 2, - p.sort( - ImmutableList.of(a), - p.values(a, b))); - }) - .matches( - strictProject( - ImmutableMap.of("a", new ExpressionMatcher("a"), "b", new ExpressionMatcher("b")), - sort( - ImmutableList.of(sort("row_num", ASCENDING, FIRST)), - filter( - "(row_num > BIGINT '2')", - rowNumber( - pattern -> pattern - .partitionBy(ImmutableList.of()), - sort( - ImmutableList.of(sort("a", ASCENDING, FIRST)), - values("a", "b"))) - .withAlias("row_num", new RowNumberSymbolMatcher()))))); - } -} diff --git a/presto-main/src/test/java/io/prestosql/sql/planner/iterative/rule/TestImplementOffsetOverTopN.java b/presto-main/src/test/java/io/prestosql/sql/planner/iterative/rule/TestImplementOffsetOverTopN.java deleted file mode 100644 index 399eec970860..000000000000 --- a/presto-main/src/test/java/io/prestosql/sql/planner/iterative/rule/TestImplementOffsetOverTopN.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.prestosql.sql.planner.iterative.rule; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import io.prestosql.sql.planner.Symbol; -import io.prestosql.sql.planner.assertions.ExpressionMatcher; -import io.prestosql.sql.planner.assertions.RowNumberSymbolMatcher; -import io.prestosql.sql.planner.iterative.rule.test.BaseRuleTest; -import org.testng.annotations.Test; - -import static io.prestosql.sql.planner.assertions.PlanMatchPattern.filter; -import static io.prestosql.sql.planner.assertions.PlanMatchPattern.rowNumber; -import static io.prestosql.sql.planner.assertions.PlanMatchPattern.sort; -import static io.prestosql.sql.planner.assertions.PlanMatchPattern.strictProject; -import static io.prestosql.sql.planner.assertions.PlanMatchPattern.topN; -import static io.prestosql.sql.planner.assertions.PlanMatchPattern.values; -import static io.prestosql.sql.tree.SortItem.NullOrdering.FIRST; -import static io.prestosql.sql.tree.SortItem.Ordering.ASCENDING; - -public class TestImplementOffsetOverTopN - extends BaseRuleTest -{ - @Test - public void testReplaceOffsetOverTopN() - { - tester().assertThat(new ImplementOffsetOverTopN()) - .on(p -> { - Symbol a = p.symbol("a"); - Symbol b = p.symbol("b"); - return p.offset( - 2, - p.topN( - 5, - ImmutableList.of(a), - p.values(a, b))); - }) - .matches( - strictProject( - ImmutableMap.of("a", new ExpressionMatcher("a"), "b", new ExpressionMatcher("b")), - sort( - ImmutableList.of(sort("row_num", ASCENDING, FIRST)), - filter( - "(row_num > BIGINT '2')", - rowNumber( - pattern -> pattern - .partitionBy(ImmutableList.of()), - topN( - 5, - ImmutableList.of(sort("a", ASCENDING, FIRST)), - values("a", "b"))) - .withAlias("row_num", new RowNumberSymbolMatcher()))))); - } -}