diff --git a/fe/fe-core/src/main/java/com/starrocks/sql/optimizer/rule/transformation/PushDownProjectLimitRule.java b/fe/fe-core/src/main/java/com/starrocks/sql/optimizer/rule/transformation/PushDownProjectLimitRule.java index 9d50db92d061b..31df09cbb576c 100644 --- a/fe/fe-core/src/main/java/com/starrocks/sql/optimizer/rule/transformation/PushDownProjectLimitRule.java +++ b/fe/fe-core/src/main/java/com/starrocks/sql/optimizer/rule/transformation/PushDownProjectLimitRule.java @@ -18,6 +18,7 @@ import com.google.common.collect.Lists; import com.starrocks.sql.optimizer.OptExpression; import com.starrocks.sql.optimizer.OptimizerContext; +import com.starrocks.sql.optimizer.operator.Operator; import com.starrocks.sql.optimizer.operator.OperatorType; import com.starrocks.sql.optimizer.operator.logical.LogicalLimitOperator; import com.starrocks.sql.optimizer.operator.pattern.Pattern; @@ -54,6 +55,10 @@ public boolean check(OptExpression input, OptimizerContext context) { @Override public List transform(OptExpression project, OptimizerContext context) { LogicalLimitOperator limit = (LogicalLimitOperator) project.getInputs().get(0).getOp(); + // clear the project limit when limit has offset + if (project.getOp().hasLimit() && limit.hasOffset()) { + project.getOp().setLimit(Operator.DEFAULT_LIMIT); + } return Lists.newArrayList(OptExpression.create(limit, OptExpression.create(project.getOp(), project.getInputs().get(0).getInputs()))); } diff --git a/fe/fe-core/src/test/java/com/starrocks/sql/plan/LimitTest.java b/fe/fe-core/src/test/java/com/starrocks/sql/plan/LimitTest.java index 0846a1fb078ff..2e135ccd1f371 100644 --- a/fe/fe-core/src/test/java/com/starrocks/sql/plan/LimitTest.java +++ b/fe/fe-core/src/test/java/com/starrocks/sql/plan/LimitTest.java @@ -655,6 +655,22 @@ public void testOffsetWithSubTopN() throws Exception { " limit: 400"); } + @Test + public void testPushDownLimitToTopN() throws Exception { + connectContext.getSessionVariable().setOptimizerExecuteTimeout(3000000); + String sql; + String plan; + sql = "select c0 from (select * from ( select v1 c0, v2 c1 from t0 order by c0 asc limit 1000, 600 ) l " + + "union all select 0 as c0, '0' as c1 ) b limit 100;"; + plan = getFragmentPlan(sql); + assertContains(plan, " 2:TOP-N\n" + + " | order by: 1: v1 ASC\n" + + " | offset: 0\n" + + " | limit: 1100\n" + + " | \n" + + " 1:OlapScanNode"); + } + @Test public void testUnionLimit() throws Exception { String queryStr = "select 1 from (select 4, 3 from t0 union all select 2, 3 ) as a limit 3";