[fix](nereids) push filter through window, using slot equal-set (#35361)

example:

filter (y=1)
+-- window( ... partition by x)
    +-- project( A as x, A as y)

filter(y=1) is equivalent to filter(x=1),
because x and y are in the same equal-set in window#logicalProperties.
And hence we could push filter(y=1) through window operator
This commit is contained in:
minghong
2024-05-28 10:48:48 +08:00
committed by yiguolei
parent 2310915c26
commit d2df392994
4 changed files with 74 additions and 0 deletions

View File

@ -106,6 +106,10 @@ public class FunctionalDependencies {
return equalSet.calEqualSetList();
}
public Set<Slot> calEqualSet(Slot s) {
return equalSet.calEqualSet(s);
}
public ImmutableSet<FdItem> getFdItems() {
return fdItems;
}

View File

@ -25,6 +25,7 @@ import org.apache.doris.nereids.glue.translator.PlanTranslatorContext;
import org.apache.doris.nereids.trees.expressions.Alias;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.NamedExpression;
import org.apache.doris.nereids.trees.expressions.Slot;
import org.apache.doris.nereids.trees.expressions.SlotReference;
import org.apache.doris.nereids.trees.expressions.WindowExpression;
import org.apache.doris.nereids.trees.expressions.WindowFrame;
@ -32,6 +33,7 @@ import org.apache.doris.nereids.trees.expressions.WindowFrame.FrameBoundType;
import org.apache.doris.nereids.trees.expressions.WindowFrame.FrameBoundary;
import org.apache.doris.nereids.trees.expressions.WindowFrame.FrameUnitsType;
import org.apache.doris.nereids.trees.expressions.literal.Literal;
import org.apache.doris.nereids.trees.plans.logical.LogicalWindow;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
@ -115,6 +117,16 @@ public interface Window {
int winExprCount = getWindowExpressions().size();
for (Map.Entry<Expression, Integer> entry : partitionKeyCount.entrySet()) {
if (entry.getValue() == winExprCount && entry.getKey() instanceof SlotReference) {
SlotReference slot = (SlotReference) entry.getKey();
if (this instanceof LogicalWindow) {
LogicalWindow lw = (LogicalWindow) this;
Set<Slot> equalSlots = lw.getLogicalProperties().getTrait().calEqualSet(slot);
for (Slot other : equalSlots) {
if (other instanceof SlotReference) {
commonPartitionKeySet.add((SlotReference) other);
}
}
}
commonPartitionKeySet.add((SlotReference) entry.getKey());
}
}