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

wenchen 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 e0c6b2e  [SPARK-36011][SQL] Disallow altering permanent views based on 
temporary views or UDFs
e0c6b2e is described below

commit e0c6b2e9655331e308a78d972db4a18d24b73e37
Author: RoryQi <1242949...@qq.com>
AuthorDate: Tue Jul 6 14:56:12 2021 +0800

    [SPARK-36011][SQL] Disallow altering permanent views based on temporary 
views or UDFs
    
    ### What changes were proposed in this pull request?
    PR #15764 disabled creating permanent views based on temporary views or 
UDFs.  But AlterViewCommand didn't block temporary objects.
    
    ### Why are the changes needed?
    More robust view canonicalization.
    
    ### Does this PR introduce _any_ user-facing change?
    Yes, now if you alter a permanent view based on temporary views or UDFs, 
the operation will fail.
    
    ### How was this patch tested?
    Add new unit tests.
    
    Closes #33204 from jerqi/alter_view.
    
    Authored-by: RoryQi <1242949...@qq.com>
    Signed-off-by: Wenchen Fan <wenc...@databricks.com>
---
 .../apache/spark/sql/execution/command/views.scala |  6 +++--
 .../spark/sql/execution/SQLViewTestSuite.scala     | 28 ++++++++++++++++++++++
 2 files changed, 32 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 ebcd277..5e92ce2 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
@@ -259,7 +259,10 @@ case class AlterViewAsCommand(
   def markAsAnalyzed(): LogicalPlan = copy(isAnalyzed = true)
 
   override def run(session: SparkSession): Seq[Row] = {
-    if (session.sessionState.catalog.isTempView(name)) {
+    val isTemporary = session.sessionState.catalog.isTempView(name)
+    verifyTemporaryObjectsNotExists(session.sessionState.catalog, isTemporary, 
name, query)
+    verifyAutoGeneratedAliasesNotExists(query, isTemporary, name)
+    if (isTemporary) {
       alterTemporaryView(session, query)
     } else {
       alterPermanentView(session, query)
@@ -286,7 +289,6 @@ case class AlterViewAsCommand(
   }
 
   private def alterPermanentView(session: SparkSession, analyzedPlan: 
LogicalPlan): Unit = {
-    verifyAutoGeneratedAliasesNotExists(analyzedPlan, isTemporary = false, 
name)
     val viewMeta = session.sessionState.catalog.getTableMetadata(name)
 
     // Detect cyclic view reference on ALTER VIEW.
diff --git 
a/sql/core/src/test/scala/org/apache/spark/sql/execution/SQLViewTestSuite.scala 
b/sql/core/src/test/scala/org/apache/spark/sql/execution/SQLViewTestSuite.scala
index 80e9019..bc64f51 100644
--- 
a/sql/core/src/test/scala/org/apache/spark/sql/execution/SQLViewTestSuite.scala
+++ 
b/sql/core/src/test/scala/org/apache/spark/sql/execution/SQLViewTestSuite.scala
@@ -465,4 +465,32 @@ class PersistedViewTestSuite extends SQLViewTestSuite with 
SharedSparkSession {
       }
     }
   }
+
+  test("SPARK-36011: Disallow altering permanent views based on temporary 
views or UDFs") {
+    import testImplicits._
+    withTable("t") {
+      (1 to 10).toDF("id").write.saveAsTable("t")
+      withView("v1") {
+        withTempView("v2") {
+          sql("CREATE VIEW v1 AS SELECT * FROM t")
+          sql("CREATE TEMPORARY VIEW v2 AS  SELECT * FROM t")
+          var e = intercept[AnalysisException] {
+            sql("ALTER VIEW v1 AS SELECT * FROM v2")
+          }.getMessage
+          assert(e.contains("Not allowed to create a permanent view 
`default`.`v1` by " +
+            "referencing a temporary view v2"))
+          val tempFunctionName = "temp_udf"
+          val functionClass = "test.org.apache.spark.sql.MyDoubleAvg"
+          withUserDefinedFunction(tempFunctionName -> true) {
+            sql(s"CREATE TEMPORARY FUNCTION $tempFunctionName AS 
'$functionClass'")
+            e = intercept[AnalysisException] {
+              sql(s"ALTER VIEW v1 AS SELECT $tempFunctionName(id) from t")
+            }.getMessage
+            assert(e.contains("Not allowed to create a permanent view 
`default`.`v1` by " +
+              s"referencing a temporary function `$tempFunctionName`"))
+          }
+        }
+      }
+    }
+  }
 }

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

Reply via email to