[fix](Nereids) should not remove any limit from uncorrelated subquery (#21976)

We should not remove any limit from uncorrelated subquery. For Example
```sql
-- should return nothing, but return all tuple of t if we remove limit from exists
SELECT * FROM t WHERE EXISTS (SELECT * FROM t limit 0);

-- should return the tuple with smallest c1 in t,
-- but report error if we remove limit from scalar subquery
SELECT * FROM t WHERE c1 = (SELECT * FROM t ORDER BY c1 LIMIT 1);
```
This commit is contained in:
morrySnow
2023-07-20 18:37:04 +08:00
committed by GitHub
parent 7947569993
commit ee65e0a6b1
3 changed files with 45 additions and 23 deletions

View File

@ -20,7 +20,6 @@ package org.apache.doris.nereids.rules.rewrite;
import org.apache.doris.nereids.rules.Rule;
import org.apache.doris.nereids.rules.RuleType;
import org.apache.doris.nereids.trees.plans.Plan;
import org.apache.doris.nereids.trees.plans.logical.LogicalSort;
import com.google.common.collect.ImmutableList;
@ -33,11 +32,8 @@ public class EliminateLimitUnderApply extends OneRewriteRuleFactory {
@Override
public Rule build() {
return logicalApply(any(), logicalLimit()).then(apply -> {
if (!apply.isCorrelated() && apply.isIn() && (apply.right().child() instanceof LogicalSort
|| (apply.right().child().children().size() > 0
&& apply.right().child().child(0) instanceof LogicalSort))) {
// must keep the limit if it's an uncorrelated in-subquery with limit on sort
// select a from t1 where a in ( select b from t2 order by xx limit yy )
if (!apply.isCorrelated()) {
// must keep the limit if it's an uncorrelated because the return number of rows is affected by limit
return null;
}
List<Plan> children = new ImmutableList.Builder<Plan>()