diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala index 7769850ee427..bf8ee4169809 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala @@ -895,7 +895,8 @@ class Analyzer(override val catalogManager: CatalogManager) } case u @ UnresolvedTable(ident, cmd, _) => lookupTempView(ident).foreach { _ => - throw QueryCompilationErrors.expectTableNotTempViewError(ident.quoted, cmd, u) + throw QueryCompilationErrors.expectTableNotViewError( + ResolvedView(ident.asIdentifier, isTemp = true), cmd, u.relationTypeMismatchHint, u) } u case u @ UnresolvedView(ident, cmd, allowTemp, _) => diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryCompilationErrors.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryCompilationErrors.scala index 5cb9ac7e373a..87542c64effd 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryCompilationErrors.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryCompilationErrors.scala @@ -192,11 +192,6 @@ private[spark] object QueryCompilationErrors { s"$quoted as it's not a data source v2 relation.") } - def expectTableNotTempViewError(quoted: String, cmd: String, t: TreeNode[_]): Throwable = { - new AnalysisException(s"$quoted is a temp view. '$cmd' expects a table", - t.origin.line, t.origin.startPosition) - } - def expectTableOrPermanentViewNotTempViewError( quoted: String, cmd: String, t: TreeNode[_]): Throwable = { new AnalysisException(s"$quoted is a temp view. '$cmd' expects a table or permanent view.", 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 b7fd441b203f..d672a75a21a8 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 @@ -140,39 +140,50 @@ abstract class SQLViewSuite extends QueryTest with SQLTestUtils { val viewName = "testView" withTempView(viewName) { spark.range(10).createTempView(viewName) - assertAnalysisError( + assertErrorForAlterTableOnTempView( s"ALTER TABLE $viewName SET SERDE 'whatever'", - s"$viewName is a temp view. 'ALTER TABLE ... SET [SERDE|SERDEPROPERTIES]' expects a table") - assertAnalysisError( + viewName, + "ALTER TABLE ... SET [SERDE|SERDEPROPERTIES]") + assertErrorForAlterTableOnTempView( s"ALTER TABLE $viewName PARTITION (a=1, b=2) SET SERDE 'whatever'", - s"$viewName is a temp view. 'ALTER TABLE ... SET [SERDE|SERDEPROPERTIES]' expects a table") - assertAnalysisError( + viewName, + "ALTER TABLE ... SET [SERDE|SERDEPROPERTIES]") + assertErrorForAlterTableOnTempView( s"ALTER TABLE $viewName SET SERDEPROPERTIES ('p' = 'an')", - s"$viewName is a temp view. 'ALTER TABLE ... SET [SERDE|SERDEPROPERTIES]' expects a table") - assertAnalysisError( + viewName, + "ALTER TABLE ... SET [SERDE|SERDEPROPERTIES]") + assertErrorForAlterTableOnTempView( s"ALTER TABLE $viewName PARTITION (a='4') RENAME TO PARTITION (a='5')", - s"$viewName is a temp view. 'ALTER TABLE ... RENAME TO PARTITION' expects a table") - assertAnalysisError( + viewName, + "ALTER TABLE ... RENAME TO PARTITION") + assertErrorForAlterTableOnTempView( s"ALTER TABLE $viewName RECOVER PARTITIONS", - s"$viewName is a temp view. 'ALTER TABLE ... RECOVER PARTITIONS' expects a table") - assertAnalysisError( + viewName, + "ALTER TABLE ... RECOVER PARTITIONS") + assertErrorForAlterTableOnTempView( s"ALTER TABLE $viewName SET LOCATION '/path/to/your/lovely/heart'", - s"$viewName is a temp view. 'ALTER TABLE ... SET LOCATION ...' expects a table") - assertAnalysisError( + viewName, + "ALTER TABLE ... SET LOCATION ...") + assertErrorForAlterTableOnTempView( s"ALTER TABLE $viewName PARTITION (a='4') SET LOCATION '/path/to/home'", - "testView is a temp view. 'ALTER TABLE ... SET LOCATION ...' expects a table") - assertAnalysisError( + viewName, + "ALTER TABLE ... SET LOCATION ...") + assertErrorForAlterTableOnTempView( s"ALTER TABLE $viewName ADD IF NOT EXISTS PARTITION (a='4', b='8')", - s"$viewName is a temp view. 'ALTER TABLE ... ADD PARTITION ...' expects a table") - assertAnalysisError( + viewName, + "ALTER TABLE ... ADD PARTITION ...") + assertErrorForAlterTableOnTempView( s"ALTER TABLE $viewName DROP PARTITION (a='4', b='8')", - s"$viewName is a temp view. 'ALTER TABLE ... DROP PARTITION ...' expects a table") - assertAnalysisError( + viewName, + "ALTER TABLE ... DROP PARTITION ...") + assertErrorForAlterTableOnTempView( s"ALTER TABLE $viewName SET TBLPROPERTIES ('p' = 'an')", - s"$viewName is a temp view. 'ALTER TABLE ... SET TBLPROPERTIES' expects a table") - assertAnalysisError( + viewName, + "ALTER TABLE ... SET TBLPROPERTIES") + assertErrorForAlterTableOnTempView( s"ALTER TABLE $viewName UNSET TBLPROPERTIES ('p')", - s"$viewName is a temp view. 'ALTER TABLE ... UNSET TBLPROPERTIES' expects a table") + viewName, + "ALTER TABLE ... UNSET TBLPROPERTIES") } } @@ -220,6 +231,13 @@ abstract class SQLViewSuite extends QueryTest with SQLTestUtils { assert(e.message.contains(message)) } + private def assertErrorForAlterTableOnTempView( + sqlText: String, viewName: String, cmdName: String): Unit = { + assertAnalysisError( + sqlText, + s"$viewName is a temp view. '$cmdName' expects a table. Please use ALTER VIEW instead.") + } + test("error handling: insert/load table commands against a view") { val viewName = "testView" withView(viewName) {