This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch branch-4.2
in repository https://gitbox.apache.org/repos/asf/doris.git
commit d7cb6d11243d8595618904188bd39b2583e67c50
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Thu Sep 10 08:53:54 2026 +0800
branch-4.1: [fix](window) Respect frames when simplifying window functions
#67706 (#67743)
Cherry-picked from #67706
Co-authored-by: morrySnow <[email protected]>
---
.../rules/rewrite/SimplifyWindowExpression.java | 14 +++-
.../simplify_window_frame.out | 22 ++++++
.../simplify_window_frame.groovy | 78 ++++++++++++++++++++++
3 files changed, 111 insertions(+), 3 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/SimplifyWindowExpression.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/SimplifyWindowExpression.java
index 311fe57cf16..9e8e0e5f8cf 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/SimplifyWindowExpression.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/SimplifyWindowExpression.java
@@ -27,6 +27,7 @@ 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.WindowExpression;
+import org.apache.doris.nereids.trees.expressions.WindowFrame;
import org.apache.doris.nereids.trees.expressions.functions.BoundFunction;
import org.apache.doris.nereids.trees.expressions.functions.agg.Count;
import org.apache.doris.nereids.trees.expressions.literal.TinyIntLiteral;
@@ -90,11 +91,12 @@ public class SimplifyWindowExpression extends
OneRewriteRuleFactory {
if (function instanceof BoundFunction) {
BoundFunction boundFunction = (BoundFunction) function;
String name = ((BoundFunction) function).getName();
- if ((name.equals(COUNT) && checkCount((Count) boundFunction))
- || REWRRITE_TO_CONST_WINDOW_FUNCTIONS.contains(name)) {
+ boolean frameContainsCurrentRow =
windowFrameContainsCurrentRow(windowExpression);
+ if (REWRRITE_TO_CONST_WINDOW_FUNCTIONS.contains(name)
+ || (frameContainsCurrentRow && name.equals(COUNT) &&
checkCount((Count) boundFunction))) {
projectionsBuilder.add(new Alias(alias.getExprId(),
new Cast(new TinyIntLiteral((byte) 1),
function.getDataType()), alias.getName()));
- } else if (REWRRITE_TO_SLOT_WINDOW_FUNCTIONS.contains(name)) {
+ } else if (frameContainsCurrentRow &&
REWRRITE_TO_SLOT_WINDOW_FUNCTIONS.contains(name)) {
projectionsBuilder.add(new Alias(alias.getExprId(),
TypeCoercionUtils.castIfNotSameType(boundFunction.child(0),
boundFunction.getDataType()),
alias.getName()));
@@ -127,6 +129,12 @@ public class SimplifyWindowExpression extends
OneRewriteRuleFactory {
}
}
+ private boolean windowFrameContainsCurrentRow(WindowExpression
windowExpression) {
+ WindowFrame windowFrame = windowExpression.getWindowFrame().get();
+ return !windowFrame.getLeftBoundary().asFollowing()
+ && !windowFrame.getRightBoundary().asPreceding();
+ }
+
private boolean checkCount(Count count) {
return count.isCountStar() || count.child(0).notNullable();
}
diff --git
a/regression-test/data/nereids_rules_p0/simplify_window_expression/simplify_window_frame.out
b/regression-test/data/nereids_rules_p0/simplify_window_expression/simplify_window_frame.out
new file mode 100644
index 00000000000..78e824fb4e4
--- /dev/null
+++
b/regression-test/data/nereids_rules_p0/simplify_window_expression/simplify_window_frame.out
@@ -0,0 +1,22 @@
+-- This file is automatically generated. You should know what you did if you
want to edit this
+-- !frames_exclude_current_row --
+1 \N 0 \N 0
+
+-- !frames_exclude_current_row_shape --
+PhysicalResultSink
+--PhysicalProject
+----PhysicalWindow
+------PhysicalWindow
+--------PhysicalQuickSort[LOCAL_SORT]
+----------PhysicalProject
+------------filter((test_simplify_window_frame.__DORIS_DELETE_SIGN__ = 0))
+--------------PhysicalOlapScan[test_simplify_window_frame]
+
+-- !frames_contain_current_row --
+1 7 1
+
+-- !frames_contain_current_row_shape --
+PhysicalResultSink
+--PhysicalProject
+----filter((test_simplify_window_frame.__DORIS_DELETE_SIGN__ = 0))
+------PhysicalOlapScan[test_simplify_window_frame]
diff --git
a/regression-test/suites/nereids_rules_p0/simplify_window_expression/simplify_window_frame.groovy
b/regression-test/suites/nereids_rules_p0/simplify_window_expression/simplify_window_frame.groovy
new file mode 100644
index 00000000000..68e90026920
--- /dev/null
+++
b/regression-test/suites/nereids_rules_p0/simplify_window_expression/simplify_window_frame.groovy
@@ -0,0 +1,78 @@
+// 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("simplify_window_frame") {
+ sql "DROP TABLE IF EXISTS test_simplify_window_frame"
+
+ sql """
+ CREATE TABLE test_simplify_window_frame (
+ pk INT NOT NULL,
+ v INT NULL
+ )
+ UNIQUE KEY(pk)
+ DISTRIBUTED BY HASH(pk) BUCKETS 1
+ PROPERTIES (
+ "replication_num" = "1",
+ "enable_unique_key_merge_on_write" = "true"
+ )
+ """
+
+ sql "INSERT INTO test_simplify_window_frame VALUES (1, 7)"
+ sql "SYNC"
+
+ qt_frames_exclude_current_row """
+ SELECT pk,
+ SUM(v) OVER (PARTITION BY pk ORDER BY pk
+ ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS sum_prev,
+ COUNT(*) OVER (PARTITION BY pk ORDER BY pk
+ ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS count_prev,
+ SUM(v) OVER (PARTITION BY pk ORDER BY pk
+ ROWS BETWEEN 1 FOLLOWING AND 1 FOLLOWING) AS sum_next,
+ COUNT(*) OVER (PARTITION BY pk ORDER BY pk
+ ROWS BETWEEN 1 FOLLOWING AND 1 FOLLOWING) AS count_next
+ FROM test_simplify_window_frame
+ ORDER BY pk
+ """
+
+ qt_frames_exclude_current_row_shape """
+ EXPLAIN SHAPE PLAN
+ SELECT SUM(v) OVER (PARTITION BY pk ORDER BY pk
+ ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS sum_prev,
+ COUNT(*) OVER (PARTITION BY pk ORDER BY pk
+ ROWS BETWEEN 1 FOLLOWING AND 1 FOLLOWING) AS count_next
+ FROM test_simplify_window_frame
+ """
+
+ qt_frames_contain_current_row """
+ SELECT pk,
+ SUM(v) OVER (PARTITION BY pk ORDER BY pk
+ ROWS BETWEEN CURRENT ROW AND CURRENT ROW) AS sum_cur,
+ COUNT(*) OVER (PARTITION BY pk ORDER BY pk
+ ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS count_centered
+ FROM test_simplify_window_frame
+ ORDER BY pk
+ """
+
+ qt_frames_contain_current_row_shape """
+ EXPLAIN SHAPE PLAN
+ SELECT SUM(v) OVER (PARTITION BY pk ORDER BY pk
+ ROWS BETWEEN CURRENT ROW AND CURRENT ROW) AS sum_cur,
+ COUNT(*) OVER (PARTITION BY pk ORDER BY pk
+ ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS count_centered
+ FROM test_simplify_window_frame
+ """
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]