You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spark.apache.org by we...@apache.org on 2026/08/21 18:42:52 UTC

(spark) branch master updated: [SPARK-58894][SQL] Detect cyclic view references in nested subqueries

This is an automated email from the ASF dual-hosted git repository.

cloud-fan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark.git


The following commit(s) were added to refs/heads/master by this push:
     new 02c21a6f9c87 [SPARK-58894][SQL] Detect cyclic view references in nested subqueries
02c21a6f9c87 is described below

commit 02c21a6f9c87b70fa166b34c131353f74e1b7dc9
Author: Manu Zhang <ma...@apache.org>
AuthorDate: Sat Aug 22 02:42:36 2026 +0800

    [SPARK-58894][SQL] Detect cyclic view references in nested subqueries
    
    ### What changes were proposed in this pull request?
    
    Update `ViewHelper.checkCyclicViewReference` to traverse complete expression trees when
    looking for subquery expressions. Add a regression case where a scalar subquery that
    references the altered view is nested below an equality predicate.
    
    ### Why are the changes needed?
    
    The current check only inspects top-level plan expressions. It detects an `EXISTS`
    subquery when the subquery is the expression root, but misses scalar and other subqueries
    nested inside larger expressions. A recursive view definition can therefore be accepted
    and fail later during view resolution with the maximum nested-view-depth error.
    
    ### Does this PR introduce _any_ user-facing change?
    
    Yes. `CREATE OR REPLACE VIEW` and `ALTER VIEW` now reject recursive references from
    subqueries nested inside larger expressions with `RECURSIVE_VIEW`, matching root-level
    subquery behavior.
    
    ### How was this patch tested?
    
    Added a regression assertion to `SimpleSQLViewSuite` and ran:
    
    ```
    SPARK_LOCAL_IP=127.0.0.1 build/sbt \
      'sql/testOnly org.apache.spark.sql.execution.SimpleSQLViewSuite -- -z "correctly handle a cyclic view reference"'
    build/sbt 'sql/scalastyle' 'sql/Test/scalastyle'
    ```
    
    ### Was this patch authored or co-authored using generative AI tooling?
    
    Generated-by: Codex (GPT-5)
    
    Closes #58146 from manuzhang/codex/fix-nested-view-cycle.
    
    Authored-by: Manu Zhang <ma...@apache.org>
    Signed-off-by: Wenchen Fan <we...@databricks.com>
---
 .../org/apache/spark/sql/execution/command/views.scala      |  4 ++--
 .../scala/org/apache/spark/sql/execution/SQLViewSuite.scala | 13 +++++++++++++
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/sql/core/src/main/scala/org/apache/spark/sql/execution/command/views.scala b/sql/core/src/main/scala/org/apache/spark/sql/execution/command/views.scala
index 411682f35f6d..4338bd367fe0 100644
--- a/sql/core/src/main/scala/org/apache/spark/sql/execution/command/views.scala
+++ b/sql/core/src/main/scala/org/apache/spark/sql/execution/command/views.scala
@@ -599,9 +599,9 @@ object ViewHelper extends SQLConfHelper with Logging with CapturesConfig {
         plan.children.foreach(child => checkCyclicViewReference(child, path, viewIdent))
     }
 
-    // Detect cyclic references from subqueries.
+    // Detect cyclic references from subqueries nested in expressions.
     plan.expressions.foreach { expr =>
-      expr match {
+      expr.foreach {
         case s: SubqueryExpression =>
           checkCyclicViewReference(s.plan, path, viewIdent)
         case _ => // Do nothing.
diff --git a/sql/core/src/test/scala/org/apache/spark/sql/execution/SQLViewSuite.scala b/sql/core/src/test/scala/org/apache/spark/sql/execution/SQLViewSuite.scala
index 3fb54d7c43d5..aef97c2a9314 100644
--- a/sql/core/src/test/scala/org/apache/spark/sql/execution/SQLViewSuite.scala
+++ b/sql/core/src/test/scala/org/apache/spark/sql/execution/SQLViewSuite.scala
@@ -1018,6 +1018,19 @@ abstract class SQLViewSuite extends QueryTest {
             s"`$SESSION_CATALOG_NAME`.`default`.`view2` -> " +
             s"`$SESSION_CATALOG_NAME`.`default`.`view1`"))
       )
+
+      // Detect cyclic view references from subqueries nested in larger expressions.
+      checkError(
+        exception = intercept[AnalysisException] {
+          sql("ALTER VIEW view1 AS SELECT * FROM jt WHERE id = (SELECT id FROM view2)")
+        },
+        condition = "RECURSIVE_VIEW",
+        parameters = Map(
+          "viewIdent" -> s"`$SESSION_CATALOG_NAME`.`default`.`view1`",
+          "newPath" -> (s"`$SESSION_CATALOG_NAME`.`default`.`view1` -> " +
+            s"`$SESSION_CATALOG_NAME`.`default`.`view2` -> " +
+            s"`$SESSION_CATALOG_NAME`.`default`.`view1`"))
+      )
     }
   }
 


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