[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());
}
}

View File

@ -0,0 +1,12 @@
-- This file is automatically generated. You should know what you did if you want to edit this
-- !eqset --
PhysicalResultSink
--PhysicalDistribute[DistributionSpecGather]
----PhysicalProject
------PhysicalWindow
--------PhysicalQuickSort[LOCAL_SORT]
----------PhysicalDistribute[DistributionSpecHash]
------------PhysicalProject
--------------filter((region.r_regionkey = 1))
----------------PhysicalOlapScan[region]

View File

@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
suite("push_filter_window_eqset") {
String db = context.config.getDbNameByFile(new File(context.file.parent))
sql "use ${db}"
sql 'set enable_nereids_planner=true'
sql 'set enable_fallback_to_original_planner=false';
/**
check the filter is pushed through window
PhysicalResultSink
--PhysicalDistribute[DistributionSpecGather]
----PhysicalProject
------PhysicalWindow
--------PhysicalQuickSort[LOCAL_SORT]
----------PhysicalDistribute[DistributionSpecHash]
------------PhysicalProject
>>>>>--------filter((region.r_regionkey = 1))
----------------PhysicalOlapScan[region]
**/
qt_eqset """
explain shape plan
select y
from (
select r_regionkey as x, r_regionkey as y, row_number() over(partition by r_regionkey) as rn from region
) T
where y = 1;
"""
}