[fix](Nereids): merge Offset in Limit Translator (#29100)

This commit is contained in:
jakevin
2023-12-28 15:32:45 +08:00
committed by GitHub
parent 14c902b504
commit 5171a77f9e
7 changed files with 98 additions and 151 deletions

View File

@ -65,6 +65,7 @@ import org.apache.doris.nereids.properties.DistributionSpecStorageGather;
import org.apache.doris.nereids.properties.OrderKey;
import org.apache.doris.nereids.properties.PhysicalProperties;
import org.apache.doris.nereids.rules.implementation.LogicalWindowToPhysicalWindow.WindowFrameGroup;
import org.apache.doris.nereids.rules.rewrite.MergeLimits;
import org.apache.doris.nereids.stats.StatsErrorEstimator;
import org.apache.doris.nereids.trees.UnaryNode;
import org.apache.doris.nereids.trees.expressions.AggregateExpression;
@ -1536,8 +1537,8 @@ public class PhysicalPlanTranslator extends DefaultPlanVisitor<PlanFragment, Pla
public PlanFragment visitPhysicalLimit(PhysicalLimit<? extends Plan> physicalLimit, PlanTranslatorContext context) {
PlanFragment inputFragment = physicalLimit.child(0).accept(this, context);
PlanNode child = inputFragment.getPlanRoot();
child.setOffset(physicalLimit.getOffset());
child.setLimit(physicalLimit.getLimit());
child.setLimit(MergeLimits.mergeLimit(physicalLimit.getLimit(), physicalLimit.getOffset(), child.getLimit()));
child.setOffset(MergeLimits.mergeOffset(physicalLimit.getOffset(), child.getOffset()));
updateLegacyPlanIdToPhysicalPlan(child, physicalLimit);
return inputFragment;
}

View File

@ -47,11 +47,21 @@ public class MergeLimits extends OneRewriteRuleFactory {
.then(upperLimit -> {
LogicalLimit<? extends Plan> bottomLimit = upperLimit.child();
return new LogicalLimit<>(
Math.min(upperLimit.getLimit(),
Math.max(bottomLimit.getLimit() - upperLimit.getOffset(), 0)),
bottomLimit.getOffset() + upperLimit.getOffset(),
mergeLimit(upperLimit.getLimit(), upperLimit.getOffset(), bottomLimit.getLimit()),
mergeOffset(upperLimit.getOffset(), bottomLimit.getOffset()),
upperLimit.child().getPhase(), bottomLimit.child()
);
}).toRule(RuleType.MERGE_LIMITS);
}
public static long mergeOffset(long upperOffset, long bottomOffset) {
return upperOffset + bottomOffset;
}
public static long mergeLimit(long upperLimit, long upperOffset, long bottomLimit) {
if (bottomLimit < 0) {
return upperLimit;
}
return Math.min(upperLimit, Math.max(bottomLimit - upperOffset, 0));
}
}