Yibo Dong created SPARK-59608:
---------------------------------

             Summary: OptimizeWindowFunctions drops FILTER when rewriting 
first_value to nth_value
                 Key: SPARK-59608
                 URL: https://issues.apache.org/jira/browse/SPARK-59608
             Project: Spark
          Issue Type: Bug
          Components: Optimizer, SQL
    Affects Versions: 5.0.0
         Environment: {code}
Spark: 5.0.0-SNAPSHOT
Commit: 9b4e4f7547c07c5eba3d2b0822a6d3dbb023a150
Java: OpenJDK 17.0.17
OS: macOS 15.7.4
{code}
            Reporter: Yibo Dong


h2. What happened

{{first_value}} with a {{FILTER}} clause returns different results depending on 
whether {{OptimizeWindowFunctions}} is enabled.

With the optimizer rule enabled, the filter condition is ignored and Spark 
returns the first unfiltered value in the window frame. When only 
{{OptimizeWindowFunctions}} is excluded, Spark returns the expected filtered 
result.

h2. How to reproduce

Run the following SQL:

{code:sql}
SELECT id, grp, v, flag,
first_value(v) FILTER (WHERE flag) OVER (
PARTITION BY grp
ORDER BY id
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS first_flagged
FROM VALUES
(1, 1, 10, false),
(2, 1, 20, true),
(3, 1, 30, false),
(1, 2, 40, false),
(2, 2, 50, true)
AS t(id, grp, v, flag)
ORDER BY grp, id;
{code}

Run it once with the default optimizer configuration:

{code:bash}
spark-sql 
--master 'local[2]' 
--conf spark.ui.enabled=false 
--conf spark.sql.adaptive.enabled=false 
--conf spark.sql.shuffle.partitions=1 
-f repro.sql
{code}

Then run the same query with only {{OptimizeWindowFunctions}} excluded:

{code:bash}
spark-sql 
--master 'local[2]' 
--conf spark.ui.enabled=false 
--conf spark.sql.adaptive.enabled=false 
--conf spark.sql.shuffle.partitions=1 
--conf 
spark.sql.optimizer.excludedRules=org.apache.spark.sql.catalyst.optimizer.OptimizeWindowFunctions
 
-f repro.sql
{code}

h2. Expected result

The {{FILTER (WHERE flag)}} condition should be applied before selecting the 
first value in each window frame.

The query should return:

|| id || grp || v || flag || first_flagged ||
| 1 | 1 | 10 | false | NULL |
| 2 | 1 | 20 | true  | 20 |
| 3 | 1 | 30 | false | 20 |
| 1 | 2 | 40 | false | NULL |
| 2 | 2 | 50 | true  | 50 |

Both optimizer configurations should produce the same result.

h2. Actual result

With {{OptimizeWindowFunctions}} enabled, Spark returns:

|| id || grp || v || flag || first_flagged ||
| 1 | 1 | 10 | false | 10 |
| 2 | 1 | 20 | true  | 10 |
| 3 | 1 | 30 | false | 10 |
| 1 | 2 | 40 | false | 40 |
| 2 | 2 | 50 | true  | 40 |

With only {{OptimizeWindowFunctions}} excluded, Spark returns the expected 
result:

|| id || grp || v || flag || first_flagged ||
| 1 | 1 | 10 | false | NULL |
| 2 | 1 | 20 | true  | 20 |
| 3 | 1 | 30 | false | 20 |
| 1 | 2 | 40 | false | NULL |
| 2 | 2 | 50 | true  | 50 |

The only changed setting between the two runs is:

{code}
spark.sql.optimizer.excludedRules=org.apache.spark.sql.catalyst.optimizer.OptimizeWindowFunctions
{code}

The observed result is consistent with the {{FILTER}} condition being lost when 
{{OptimizeWindowFunctions}} rewrites the windowed {{first_value}} expression.




--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to