You are viewing a plain text version of this content. The canonical link for it is here.
Posted to reviews@spark.apache.org by "sunchao (via GitHub)" <gi...@apache.org> on 2026/03/25 22:28:59 UTC

[PR] [SPARK-31561][SQL] Add QUALIFY Clause [spark]

sunchao opened a new pull request, #55019:
URL: https://github.com/apache/spark/pull/55019

   <!--
   Thanks for sending a pull request!  Here are some tips for you:
     1. If this is your first time, please read our contributor guidelines: https://spark.apache.org/contributing.html
     2. Ensure you have added or run the appropriate tests for your PR: https://spark.apache.org/developer-tools.html
     3. If the PR is unfinished, add '[WIP]' in your PR title, e.g., '[WIP][SPARK-XXXX] Your PR title ...'.
     4. Be sure to keep the PR description updated to reflect all changes.
     5. Please write your PR title to summarize what this PR proposes.
     6. If possible, provide a concise example to reproduce the issue for a faster review.
     7. If you want to add a new configuration, please read the guideline first for naming configurations in
        'core/src/main/scala/org/apache/spark/internal/config/ConfigEntry.scala'.
     8. If you want to add or modify an error type or message, please read the guideline first in
        'common/utils/src/main/resources/error/README.md'.
   -->
   
   ### What changes were proposed in this pull request?
   <!--
   Please clarify what changes you are proposing. The purpose of this section is to outline the changes and how this PR fixes the issue. 
   If possible, please consider writing useful notes for better and faster reviews in your PR. See the examples below.
     1. If you refactor some codes with changing classes, showing the class hierarchy will help reviewers.
     2. If you fix some SQL features, you can provide some references of other DBMSes.
     3. If there is design documentation, please add the link.
     4. If there is a discussion in the mailing list, please add the link.
   -->
   
   This PR adds support for the `QUALIFY` clause in Spark SQL. The implementation updates the SQL parser and AST builder to recognize `QUALIFY`, carries it through analysis with a dedicated marker expression, and rewrites it after window extraction so the predicate is evaluated after window functions are materialized.
   
   In addition to basic `QUALIFY` support, the analyzer enforces the intended semantics for the current query:
   - `QUALIFY` requires at least one window function in the current `SELECT` list or `QUALIFY` predicate.
   - Standalone aggregate functions in the `QUALIFY` predicate are rejected with a targeted error that points at the offending aggregate expression.
   - Aggregate aliases are allowed in `QUALIFY`
   - `HAVING ... QUALIFY ...` is handled correctly so `HAVING` filters grouped rows before window evaluation and `QUALIFY` filters after the window result is computed.
   
   The PR also adds documentation and parser/analyzer coverage for positive and negative cases, including alias-based predicates, non-ANSI keyword handling, and grouped queries.
   
   
   ### Why are the changes needed?
   <!--
   Please clarify why the changes are needed. For instance,
     1. If you propose a new API, clarify the use case for a new API.
     2. If you fix a bug, you can clarify why it is a bug.
   -->
   
   `QUALIFY` is supported by several popular SQL engines including Snowflake, Databricks SQL etc, and users expect it when porting SQL that filters on window-function results. Without it, equivalent Spark queries need an extra subquery or CTE just to filter on a window alias.
   
   This change closes that gap and makes Spark SQL more compatible with existing SQL workloads while preserving clear analyzer rules around window and aggregate semantics.
   
   ### Does this PR introduce _any_ user-facing change?
   <!--
   Note that it means *any* user-facing change including all aspects such as new features, bug fixes, or other behavior changes. Documentation-only updates are not considered user-facing changes.
   
   If yes, please clarify the previous behavior and the change this PR proposes - provide the console output, description and/or an example to show the behavior difference if possible.
   If possible, please also clarify if this is a user-facing change compared to the released Spark versions or within the unreleased branches such as master.
   If no, write 'No'.
   -->
   
   Yes. Spark SQL can now parse and analyze queries that use `QUALIFY`, for example:
   
   ```sql
   SELECT a, ROW_NUMBER() OVER (ORDER BY b) AS rn
   FROM t
   QUALIFY rn = 1
   ```
   
   This PR also introduces user-visible analysis errors for invalid `QUALIFY` usage, such as using aggregate functions directly in the `QUALIFY` predicate.
   
   
   ### How was this patch tested?
   <!--
   If tests were added, say they were added here. Please make sure to add some test cases that check the changes thoroughly including negative and positive cases if possible.
   If it was tested in a way different from regular unit tests, please clarify how you tested step by step, ideally copy and paste-able, so that other reviewers can test and check, and descendants can verify in the future.
   If tests were not added, please describe why they were not added and/or why it was difficult to add.
   If benchmark tests were added, please run the benchmarks in GitHub Actions for the consistent environment, and the instructions could accord to: https://spark.apache.org/developer-tools.html#github-workflow-benchmarks.
   -->
   
   Added new unit tests and e2e tests
   
   
   ### Was this patch authored or co-authored using generative AI tooling?
   <!--
   If generative AI tooling has been used in the process of authoring this patch, please include the
   phrase: 'Generated-by: ' followed by the name of the tool and its version.
   If no, write 'No'.
   Please refer to the [ASF Generative Tooling Guidance](https://www.apache.org/legal/generative-tooling.html) for details.
   -->
   
   Yes. Generated by ChatGPT 5.4 High.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


Re: [PR] [SPARK-31561][SQL] Add QUALIFY Clause [spark]

Posted by "viirya (via GitHub)" <gi...@apache.org>.
viirya commented on code in PR #55019:
URL: https://github.com/apache/spark/pull/55019#discussion_r3069168204


##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala:
##########
@@ -2843,7 +2890,7 @@ class Analyzer(
    *
    * We need to make sure the expressions all fully resolved before looking for aggregate functions
    * and group by expressions from them.
-   */
+  */

Review Comment:
   Unnecessary change and looks incorrect style.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


Re: [PR] [SPARK-31561][SQL] Add QUALIFY Clause [spark]

Posted by "xiaoxuandev (via GitHub)" <gi...@apache.org>.
xiaoxuandev commented on code in PR #55019:
URL: https://github.com/apache/spark/pull/55019#discussion_r3040942168


##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala:
##########
@@ -2843,8 +2874,17 @@ class Analyzer(
    *
    * We need to make sure the expressions all fully resolved before looking for aggregate functions
    * and group by expressions from them.
-   */
+  */
   object ResolveAggregateFunctions extends Rule[LogicalPlan] {
+    private def invalidResolvedQualifyAggregateFunction(expr: Expression): Option[Expression] =

Review Comment:
   `invalidResolvedQualifyAggregateFunction` is duplicated 4 times, worth extracting into a shared helper?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


Re: [PR] [SPARK-31561][SQL] Add QUALIFY Clause [spark]

Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] closed pull request #55019: [SPARK-31561][SQL] Add QUALIFY Clause
URL: https://github.com/apache/spark/pull/55019


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


Re: [PR] [SPARK-31561][SQL] Add QUALIFY Clause [spark]

Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #55019:
URL: https://github.com/apache/spark/pull/55019#issuecomment-5040543083

   We're closing this PR because it hasn't been updated in a while. This isn't a judgement on the merit of the PR in any way. It's just a way of keeping the PR queue manageable.
   If you'd like to revive this PR, please reopen it and ask a committer to remove the Stale tag!


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


Re: [PR] [SPARK-31561][SQL] Add QUALIFY Clause [spark]

Posted by "sunchao (via GitHub)" <gi...@apache.org>.
sunchao commented on PR #55019:
URL: https://github.com/apache/spark/pull/55019#issuecomment-4216335060

   @codex review carefully


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


Re: [PR] [SPARK-31561][SQL] Add QUALIFY Clause [spark]

Posted by "viirya (via GitHub)" <gi...@apache.org>.
viirya commented on code in PR #55019:
URL: https://github.com/apache/spark/pull/55019#discussion_r3069167675


##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala:
##########
@@ -3414,11 +3472,105 @@ class Analyzer(
       Project(windowOps.output ++ newExpressionsWithWindowFunctions, windowOps)
     } // end of addWindow
 
+    private def addQualifyFilter(

Review Comment:
   4 addQualifyFilter overload seems too much. Can we combine them to 1 or 2? Their logic look very close.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


Re: [PR] [SPARK-31561][SQL] Add QUALIFY Clause [spark]

Posted by "xiaoxuandev (via GitHub)" <gi...@apache.org>.
xiaoxuandev commented on code in PR #55019:
URL: https://github.com/apache/spark/pull/55019#discussion_r3040959236


##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala:
##########
@@ -3414,11 +3478,108 @@ class Analyzer(
       Project(windowOps.output ++ newExpressionsWithWindowFunctions, windowOps)
     } // end of addWindow
 
+    private def addQualifyFilter(
+        projectList: Seq[NamedExpression],
+        havingCondition: Expression,
+        qualifyCondition: Expression,
+        child: LogicalPlan): LogicalPlan = {
+      val qualifyAlias = Alias(qualifyCondition, "__qualify_cond")()
+      val (windowExpressions, regularExpressions) = extract(projectList :+ qualifyAlias)
+      val withProject = Project(regularExpressions, child)
+      val extractedFilter = Filter(havingCondition, withProject)
+      val withWindow = addWindow(windowExpressions, extractedFilter)
+      Project(projectList.map(_.toAttribute), Filter(qualifyAlias.toAttribute, withWindow))
+    }
+
+    private def addQualifyFilter(
+        projectList: Seq[NamedExpression],
+        qualifyCondition: Expression,
+        child: LogicalPlan): LogicalPlan = {
+      val qualifyAlias = Alias(qualifyCondition, "__qualify_cond")()
+      val (windowExpressions, regularExpressions) = extract(projectList :+ qualifyAlias)
+      val withProject = Project(regularExpressions, child)
+      val withWindow = addWindow(windowExpressions, withProject)
+      Project(projectList.map(_.toAttribute), Filter(qualifyAlias.toAttribute, withWindow))
+    }
+
+    private def addQualifyFilter(
+        groupingExprs: Seq[Expression],
+        aggregateExprs: Seq[NamedExpression],
+        qualifyCondition: Expression,
+        child: LogicalPlan): LogicalPlan = {
+      val withAggregate = Aggregate(groupingExprs, aggregateExprs, child)
+      validateQualifyAggregateCondition(qualifyCondition)
+
+      val qualifyAlias = Alias(qualifyCondition, "__qualify_cond")()
+      val (windowExpressions, extractedAggregateExprs) = extract(aggregateExprs :+ qualifyAlias)
+      val extractedAggregate = Aggregate(groupingExprs, extractedAggregateExprs, child)
+      val withWindow = addWindow(windowExpressions, extractedAggregate)
+      Project(aggregateExprs.map(_.toAttribute), Filter(qualifyAlias.toAttribute, withWindow))
+    }
+
+    private def addQualifyFilter(
+        groupingExprs: Seq[Expression],
+        aggregateExprs: Seq[NamedExpression],
+        havingCondition: Expression,
+        qualifyCondition: Expression,
+        child: LogicalPlan): LogicalPlan = {
+      val withAggregate = Aggregate(groupingExprs, aggregateExprs, child)
+      val withFilter = Filter(havingCondition, withAggregate)

Review Comment:
   withAggregate / withFilter are constructed but never used, dead code or incomplete logic?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


Re: [PR] [SPARK-31561][SQL] Add QUALIFY Clause [spark]

Posted by "viirya (via GitHub)" <gi...@apache.org>.
viirya commented on code in PR #55019:
URL: https://github.com/apache/spark/pull/55019#discussion_r3069174574


##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala:
##########
@@ -3414,11 +3472,105 @@ class Analyzer(
       Project(windowOps.output ++ newExpressionsWithWindowFunctions, windowOps)
     } // end of addWindow
 
+    private def addQualifyFilter(
+        projectList: Seq[NamedExpression],
+        havingCondition: Expression,
+        qualifyCondition: Expression,
+        child: LogicalPlan): LogicalPlan = {
+      val qualifyAlias = Alias(qualifyCondition, "__qualify_cond")()
+      val (windowExpressions, regularExpressions) = extract(projectList :+ qualifyAlias)
+      val withProject = Project(regularExpressions, child)
+      val extractedFilter = Filter(havingCondition, withProject)
+      val withWindow = addWindow(windowExpressions, extractedFilter)
+      Project(projectList.map(_.toAttribute), Filter(qualifyAlias.toAttribute, withWindow))
+    }
+
+    private def addQualifyFilter(
+        projectList: Seq[NamedExpression],
+        qualifyCondition: Expression,
+        child: LogicalPlan): LogicalPlan = {
+      val qualifyAlias = Alias(qualifyCondition, "__qualify_cond")()
+      val (windowExpressions, regularExpressions) = extract(projectList :+ qualifyAlias)
+      val withProject = Project(regularExpressions, child)
+      val withWindow = addWindow(windowExpressions, withProject)
+      Project(projectList.map(_.toAttribute), Filter(qualifyAlias.toAttribute, withWindow))
+    }
+
+    private def addQualifyFilter(
+        groupingExprs: Seq[Expression],
+        aggregateExprs: Seq[NamedExpression],
+        qualifyCondition: Expression,
+        child: LogicalPlan): LogicalPlan = {
+      validateQualifyAggregateCondition(qualifyCondition)
+
+      val qualifyAlias = Alias(qualifyCondition, "__qualify_cond")()
+      val (windowExpressions, extractedAggregateExprs) = extract(aggregateExprs :+ qualifyAlias)
+      val extractedAggregate = Aggregate(groupingExprs, extractedAggregateExprs, child)
+      val withWindow = addWindow(windowExpressions, extractedAggregate)
+      Project(aggregateExprs.map(_.toAttribute), Filter(qualifyAlias.toAttribute, withWindow))
+    }
+
+    private def addQualifyFilter(
+        groupingExprs: Seq[Expression],
+        aggregateExprs: Seq[NamedExpression],
+        havingCondition: Expression,
+        qualifyCondition: Expression,
+        child: LogicalPlan): LogicalPlan = {
+      validateQualifyAggregateCondition(qualifyCondition)
+
+      val qualifyAlias = Alias(qualifyCondition, "__qualify_cond")()
+      val (windowExpressions, extractedAggregateExprs) = extract(aggregateExprs :+ qualifyAlias)
+      val extractedAggregate = Aggregate(groupingExprs, extractedAggregateExprs, child)
+      val extractedFilter = Filter(havingCondition, extractedAggregate)
+      val withWindow = addWindow(windowExpressions, extractedFilter)
+      Project(aggregateExprs.map(_.toAttribute), Filter(qualifyAlias.toAttribute, withWindow))
+    }
+
     // We have to use transformDown at here to make sure the rule of
     // "Aggregate with Having clause" will be triggered.
     def apply(plan: LogicalPlan): LogicalPlan = plan.resolveOperatorsDownWithPruning(
       _.containsPattern(WINDOW_EXPRESSION), ruleId) {
 
+      case f @ Filter(QualifyExpression(condition, _), a @ Aggregate(groupingExprs, aggregateExprs,
+          child, _))
+        if hasWindowFunction(condition) &&
+          condition.resolved &&
+          child.resolved &&
+          a.expressions.forall(_.resolved) &&
+          !aggregateExprs.exists(_.containsPattern(LATERAL_COLUMN_ALIAS_REFERENCE)) =>
+        addQualifyFilter(groupingExprs, aggregateExprs, condition, child)
+
+      case f @ Filter(QualifyExpression(condition, _),
+          Filter(havingCondition, a @ Aggregate(groupingExprs, aggregateExprs, child, _)))
+        if hasWindowFunction(condition) &&
+          condition.resolved &&
+          child.resolved &&
+          havingCondition.resolved &&
+          a.expressions.forall(_.resolved) &&
+          !aggregateExprs.exists(_.containsPattern(LATERAL_COLUMN_ALIAS_REFERENCE)) =>
+        addQualifyFilter(groupingExprs, aggregateExprs, havingCondition, condition, child)
+
+      case f @ Filter(QualifyExpression(condition, _), p @ Project(projectList, child))
+        if hasWindowFunction(condition) &&
+          condition.resolved &&
+          child.resolved &&
+          p.expressions.forall(_.resolved) &&
+          !projectList.exists(_.containsPattern(LATERAL_COLUMN_ALIAS_REFERENCE)) =>

Review Comment:
   QUALIFY + LATERAL COLUMN ALIAS is skipped but seem not test to verify it?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


Re: [PR] [SPARK-31561][SQL] Add QUALIFY Clause [spark]

Posted by "sunchao (via GitHub)" <gi...@apache.org>.
sunchao commented on code in PR #55019:
URL: https://github.com/apache/spark/pull/55019#discussion_r3060125617


##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala:
##########
@@ -2843,8 +2874,17 @@ class Analyzer(
    *
    * We need to make sure the expressions all fully resolved before looking for aggregate functions
    * and group by expressions from them.
-   */
+  */
   object ResolveAggregateFunctions extends Rule[LogicalPlan] {
+    private def invalidResolvedQualifyAggregateFunction(expr: Expression): Option[Expression] =

Review Comment:
   Updated



##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala:
##########
@@ -3414,11 +3478,108 @@ class Analyzer(
       Project(windowOps.output ++ newExpressionsWithWindowFunctions, windowOps)
     } // end of addWindow
 
+    private def addQualifyFilter(
+        projectList: Seq[NamedExpression],
+        havingCondition: Expression,
+        qualifyCondition: Expression,
+        child: LogicalPlan): LogicalPlan = {
+      val qualifyAlias = Alias(qualifyCondition, "__qualify_cond")()
+      val (windowExpressions, regularExpressions) = extract(projectList :+ qualifyAlias)
+      val withProject = Project(regularExpressions, child)
+      val extractedFilter = Filter(havingCondition, withProject)
+      val withWindow = addWindow(windowExpressions, extractedFilter)
+      Project(projectList.map(_.toAttribute), Filter(qualifyAlias.toAttribute, withWindow))
+    }
+
+    private def addQualifyFilter(
+        projectList: Seq[NamedExpression],
+        qualifyCondition: Expression,
+        child: LogicalPlan): LogicalPlan = {
+      val qualifyAlias = Alias(qualifyCondition, "__qualify_cond")()
+      val (windowExpressions, regularExpressions) = extract(projectList :+ qualifyAlias)
+      val withProject = Project(regularExpressions, child)
+      val withWindow = addWindow(windowExpressions, withProject)
+      Project(projectList.map(_.toAttribute), Filter(qualifyAlias.toAttribute, withWindow))
+    }
+
+    private def addQualifyFilter(
+        groupingExprs: Seq[Expression],
+        aggregateExprs: Seq[NamedExpression],
+        qualifyCondition: Expression,
+        child: LogicalPlan): LogicalPlan = {
+      val withAggregate = Aggregate(groupingExprs, aggregateExprs, child)
+      validateQualifyAggregateCondition(qualifyCondition)
+
+      val qualifyAlias = Alias(qualifyCondition, "__qualify_cond")()
+      val (windowExpressions, extractedAggregateExprs) = extract(aggregateExprs :+ qualifyAlias)
+      val extractedAggregate = Aggregate(groupingExprs, extractedAggregateExprs, child)
+      val withWindow = addWindow(windowExpressions, extractedAggregate)
+      Project(aggregateExprs.map(_.toAttribute), Filter(qualifyAlias.toAttribute, withWindow))
+    }
+
+    private def addQualifyFilter(
+        groupingExprs: Seq[Expression],
+        aggregateExprs: Seq[NamedExpression],
+        havingCondition: Expression,
+        qualifyCondition: Expression,
+        child: LogicalPlan): LogicalPlan = {
+      val withAggregate = Aggregate(groupingExprs, aggregateExprs, child)
+      val withFilter = Filter(havingCondition, withAggregate)

Review Comment:
   Updated



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


Re: [PR] [SPARK-31561][SQL] Add QUALIFY Clause [spark]

Posted by "sunchao (via GitHub)" <gi...@apache.org>.
sunchao commented on PR #55019:
URL: https://github.com/apache/spark/pull/55019#issuecomment-4225399463

   cc @sigmod @allisonwang-db @viirya for review, thanks!


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org