[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 <1242949407@qq.com>
Signed-off-by: Wenchen Fan <wenchen@databricks.com>
(cherry picked from commit e0c6b2e965
)
Signed-off-by: Wenchen Fan <wenchen@databricks.com>
This commit is contained in:
parent
e09feda1d2
commit
176b055c12
|
@ -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.
|
||||
|
|
|
@ -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`"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue