From 6e804e2e20c62264c8650dfe2d03073e9999ce40 Mon Sep 17 00:00:00 2001 From: Aman Omer Date: Wed, 30 Oct 2019 14:15:17 +0530 Subject: [PATCH 01/10] [SPARK-29628] Initial commit --- .../spark/sql/execution/command/views.scala | 48 +++++++++++-------- .../spark/sql/execution/SQLViewSuite.scala | 15 ++---- 2 files changed, 33 insertions(+), 30 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 b31514827220e..10fb6224dfa69 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 @@ -110,19 +110,26 @@ case class CreateViewCommand( private def isTemporary = viewType == LocalTempView || viewType == GlobalTempView - // Disallows 'CREATE TEMPORARY VIEW IF NOT EXISTS' to be consistent with 'CREATE TEMPORARY TABLE' - if (allowExisting && isTemporary) { - throw new AnalysisException( - "It is not allowed to define a TEMPORARY view with IF NOT EXISTS.") - } + if(isTemporary) verifyTempView() + + private def verifyTempView(): Unit = { + // Disallows 'CREATE TEMPORARY VIEW IF NOT EXISTS' + // to be consistent with 'CREATE TEMPORARY TABLE' + if (allowExisting) { + throw new AnalysisException( + "It is not allowed to define a TEMPORARY view with IF NOT EXISTS.") + } - // Temporary view names should NOT contain database prefix like "database.table" - if (isTemporary && name.database.isDefined) { - val database = name.database.get - throw new AnalysisException( - s"It is not allowed to add database prefix `$database` for the TEMPORARY view name.") + // Temporary view names should NOT contain database prefix like "database.table" + if (name.database.isDefined) { + val database = name.database.get + throw new AnalysisException( + s"It is not allowed to add database prefix `$database` for the TEMPORARY view name.") + } } + private var isTempReferred = false + override def run(sparkSession: SparkSession): Seq[Row] = { // If the plan cannot be analyzed, throw an exception and don't proceed. val qe = sparkSession.sessionState.executePlan(child) @@ -130,18 +137,17 @@ case class CreateViewCommand( val analyzedPlan = qe.analyzed if (userSpecifiedColumns.nonEmpty && - userSpecifiedColumns.length != analyzedPlan.output.length) { + userSpecifiedColumns.length != analyzedPlan.output.length) { throw new AnalysisException(s"The number of columns produced by the SELECT clause " + s"(num: `${analyzedPlan.output.length}`) does not match the number of column names " + s"specified by CREATE VIEW (num: `${userSpecifiedColumns.length}`).") } - // When creating a permanent view, not allowed to reference temporary objects. // This should be called after `qe.assertAnalyzed()` (i.e., `child` can be resolved) verifyTemporaryObjectsNotExists(sparkSession) val catalog = sparkSession.sessionState.catalog - if (viewType == LocalTempView) { + if (viewType == LocalTempView || isTempReferred) { val aliasedPlan = aliasPlan(sparkSession, analyzedPlan) catalog.createTempView(name.table, aliasedPlan, overrideIfExists = replace) } else if (viewType == GlobalTempView) { @@ -178,7 +184,8 @@ case class CreateViewCommand( } /** - * Permanent views are not allowed to reference temp objects, including temp function and views + * Permanent views are not allowed to reference temp function. When permanent view + * has a reference of temp view, it will be created as temp view [SPARK-29628]. */ private def verifyTemporaryObjectsNotExists(sparkSession: SparkSession): Unit = { import sparkSession.sessionState.analyzer.AsTableIdentifier @@ -191,12 +198,15 @@ case class CreateViewCommand( // 2) The temp functions are represented by multiple classes. Most are inaccessible from this // package (e.g., HiveGenericUDF). child.collect { - // Disallow creating permanent views based on temporary views. + // Permanent views will be created as temporary view if based on temporary view. case UnresolvedRelation(AsTableIdentifier(ident)) - if sparkSession.sessionState.catalog.isTemporaryTable(ident) => - // temporary views are only stored in the session catalog - throw new AnalysisException(s"Not allowed to create a permanent view $name by " + - s"referencing a temporary view $ident") + if sparkSession.sessionState.catalog.isTemporaryTable(ident) => + // Temporary views are only stored in the session catalog + logInfo(s"View $name is based on temporary view $ident." + + s" $name will be created as temporary view") + verifyTempView() + isTempReferred = true + case other if !other.resolved => other.expressions.flatMap(_.collect { // Disallow creating permanent views based on temporary UDFs. case e: UnresolvedFunction 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 8ff293146127a..8896442327bc0 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 @@ -72,23 +72,16 @@ abstract class SQLViewSuite extends QueryTest with SQLTestUtils { } test("create a permanent view on a temp view") { - withView("jtv1") { + withTempView("jtv1") { withTempView("temp_jtv1") { withGlobalTempView("global_temp_jtv1") { sql("CREATE TEMPORARY VIEW temp_jtv1 AS SELECT * FROM jt WHERE id > 3") - var e = intercept[AnalysisException] { - sql("CREATE VIEW jtv1 AS SELECT * FROM temp_jtv1 WHERE id < 6") - }.getMessage - assert(e.contains("Not allowed to create a permanent view `jtv1` by " + - "referencing a temporary view `temp_jtv1`")) + sql("CREATE VIEW jtv1 AS SELECT * FROM temp_jtv1 WHERE id < 6") val globalTempDB = spark.sharedState.globalTempViewManager.database sql("CREATE GLOBAL TEMP VIEW global_temp_jtv1 AS SELECT * FROM jt WHERE id > 0") - e = intercept[AnalysisException] { - sql(s"CREATE VIEW jtv1 AS SELECT * FROM $globalTempDB.global_temp_jtv1 WHERE id < 6") - }.getMessage - assert(e.contains(s"Not allowed to create a permanent view `jtv1` by referencing " + - s"a temporary view `global_temp`.`global_temp_jtv1`")) + sql(s"CREATE VIEW jtv2 AS SELECT * FROM $globalTempDB.global_temp_jtv1 WHERE id < 6") + } } } From ff1174c30934e40e861e213a32d8ce5ad8033fe4 Mon Sep 17 00:00:00 2001 From: Aman Omer Date: Wed, 30 Oct 2019 14:15:17 +0530 Subject: [PATCH 02/10] [SPARK-29628] Initial commit --- .../spark/sql/execution/command/views.scala | 48 +++++++++++-------- .../spark/sql/execution/SQLViewSuite.scala | 15 ++---- 2 files changed, 33 insertions(+), 30 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 b31514827220e..10fb6224dfa69 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 @@ -110,19 +110,26 @@ case class CreateViewCommand( private def isTemporary = viewType == LocalTempView || viewType == GlobalTempView - // Disallows 'CREATE TEMPORARY VIEW IF NOT EXISTS' to be consistent with 'CREATE TEMPORARY TABLE' - if (allowExisting && isTemporary) { - throw new AnalysisException( - "It is not allowed to define a TEMPORARY view with IF NOT EXISTS.") - } + if(isTemporary) verifyTempView() + + private def verifyTempView(): Unit = { + // Disallows 'CREATE TEMPORARY VIEW IF NOT EXISTS' + // to be consistent with 'CREATE TEMPORARY TABLE' + if (allowExisting) { + throw new AnalysisException( + "It is not allowed to define a TEMPORARY view with IF NOT EXISTS.") + } - // Temporary view names should NOT contain database prefix like "database.table" - if (isTemporary && name.database.isDefined) { - val database = name.database.get - throw new AnalysisException( - s"It is not allowed to add database prefix `$database` for the TEMPORARY view name.") + // Temporary view names should NOT contain database prefix like "database.table" + if (name.database.isDefined) { + val database = name.database.get + throw new AnalysisException( + s"It is not allowed to add database prefix `$database` for the TEMPORARY view name.") + } } + private var isTempReferred = false + override def run(sparkSession: SparkSession): Seq[Row] = { // If the plan cannot be analyzed, throw an exception and don't proceed. val qe = sparkSession.sessionState.executePlan(child) @@ -130,18 +137,17 @@ case class CreateViewCommand( val analyzedPlan = qe.analyzed if (userSpecifiedColumns.nonEmpty && - userSpecifiedColumns.length != analyzedPlan.output.length) { + userSpecifiedColumns.length != analyzedPlan.output.length) { throw new AnalysisException(s"The number of columns produced by the SELECT clause " + s"(num: `${analyzedPlan.output.length}`) does not match the number of column names " + s"specified by CREATE VIEW (num: `${userSpecifiedColumns.length}`).") } - // When creating a permanent view, not allowed to reference temporary objects. // This should be called after `qe.assertAnalyzed()` (i.e., `child` can be resolved) verifyTemporaryObjectsNotExists(sparkSession) val catalog = sparkSession.sessionState.catalog - if (viewType == LocalTempView) { + if (viewType == LocalTempView || isTempReferred) { val aliasedPlan = aliasPlan(sparkSession, analyzedPlan) catalog.createTempView(name.table, aliasedPlan, overrideIfExists = replace) } else if (viewType == GlobalTempView) { @@ -178,7 +184,8 @@ case class CreateViewCommand( } /** - * Permanent views are not allowed to reference temp objects, including temp function and views + * Permanent views are not allowed to reference temp function. When permanent view + * has a reference of temp view, it will be created as temp view [SPARK-29628]. */ private def verifyTemporaryObjectsNotExists(sparkSession: SparkSession): Unit = { import sparkSession.sessionState.analyzer.AsTableIdentifier @@ -191,12 +198,15 @@ case class CreateViewCommand( // 2) The temp functions are represented by multiple classes. Most are inaccessible from this // package (e.g., HiveGenericUDF). child.collect { - // Disallow creating permanent views based on temporary views. + // Permanent views will be created as temporary view if based on temporary view. case UnresolvedRelation(AsTableIdentifier(ident)) - if sparkSession.sessionState.catalog.isTemporaryTable(ident) => - // temporary views are only stored in the session catalog - throw new AnalysisException(s"Not allowed to create a permanent view $name by " + - s"referencing a temporary view $ident") + if sparkSession.sessionState.catalog.isTemporaryTable(ident) => + // Temporary views are only stored in the session catalog + logInfo(s"View $name is based on temporary view $ident." + + s" $name will be created as temporary view") + verifyTempView() + isTempReferred = true + case other if !other.resolved => other.expressions.flatMap(_.collect { // Disallow creating permanent views based on temporary UDFs. case e: UnresolvedFunction 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 8ff293146127a..8896442327bc0 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 @@ -72,23 +72,16 @@ abstract class SQLViewSuite extends QueryTest with SQLTestUtils { } test("create a permanent view on a temp view") { - withView("jtv1") { + withTempView("jtv1") { withTempView("temp_jtv1") { withGlobalTempView("global_temp_jtv1") { sql("CREATE TEMPORARY VIEW temp_jtv1 AS SELECT * FROM jt WHERE id > 3") - var e = intercept[AnalysisException] { - sql("CREATE VIEW jtv1 AS SELECT * FROM temp_jtv1 WHERE id < 6") - }.getMessage - assert(e.contains("Not allowed to create a permanent view `jtv1` by " + - "referencing a temporary view `temp_jtv1`")) + sql("CREATE VIEW jtv1 AS SELECT * FROM temp_jtv1 WHERE id < 6") val globalTempDB = spark.sharedState.globalTempViewManager.database sql("CREATE GLOBAL TEMP VIEW global_temp_jtv1 AS SELECT * FROM jt WHERE id > 0") - e = intercept[AnalysisException] { - sql(s"CREATE VIEW jtv1 AS SELECT * FROM $globalTempDB.global_temp_jtv1 WHERE id < 6") - }.getMessage - assert(e.contains(s"Not allowed to create a permanent view `jtv1` by referencing " + - s"a temporary view `global_temp`.`global_temp_jtv1`")) + sql(s"CREATE VIEW jtv2 AS SELECT * FROM $globalTempDB.global_temp_jtv1 WHERE id < 6") + } } } From cd2833ca7f562116385fba9a51b742d7ad6f4f16 Mon Sep 17 00:00:00 2001 From: Aman Omer Date: Wed, 30 Oct 2019 16:55:01 +0530 Subject: [PATCH 03/10] Handled review comment --- .../scala/org/apache/spark/sql/execution/command/views.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 10fb6224dfa69..c32a4ef12b2ec 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 @@ -110,7 +110,7 @@ case class CreateViewCommand( private def isTemporary = viewType == LocalTempView || viewType == GlobalTempView - if(isTemporary) verifyTempView() + if (isTemporary) verifyTempView() private def verifyTempView(): Unit = { // Disallows 'CREATE TEMPORARY VIEW IF NOT EXISTS' From d04292b551f67ec541afd71cde6878e33d33c1b9 Mon Sep 17 00:00:00 2001 From: Aman Omer Date: Wed, 30 Oct 2019 22:22:17 +0530 Subject: [PATCH 04/10] Handled review comments --- .../scala/org/apache/spark/sql/execution/command/views.scala | 4 ++-- 1 file changed, 2 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 c32a4ef12b2ec..ef29feaacb23a 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 @@ -137,7 +137,7 @@ case class CreateViewCommand( val analyzedPlan = qe.analyzed if (userSpecifiedColumns.nonEmpty && - userSpecifiedColumns.length != analyzedPlan.output.length) { + userSpecifiedColumns.length != analyzedPlan.output.length) { throw new AnalysisException(s"The number of columns produced by the SELECT clause " + s"(num: `${analyzedPlan.output.length}`) does not match the number of column names " + s"specified by CREATE VIEW (num: `${userSpecifiedColumns.length}`).") @@ -200,7 +200,7 @@ case class CreateViewCommand( child.collect { // Permanent views will be created as temporary view if based on temporary view. case UnresolvedRelation(AsTableIdentifier(ident)) - if sparkSession.sessionState.catalog.isTemporaryTable(ident) => + if sparkSession.sessionState.catalog.isTemporaryTable(ident) => // Temporary views are only stored in the session catalog logInfo(s"View $name is based on temporary view $ident." + s" $name will be created as temporary view") From 937da508d4a86f5f66381ce6281c92c21bf8af04 Mon Sep 17 00:00:00 2001 From: Aman Omer Date: Wed, 30 Oct 2019 22:29:18 +0530 Subject: [PATCH 05/10] Removed extra line from test suite. --- .../test/scala/org/apache/spark/sql/execution/SQLViewSuite.scala | 1 - 1 file changed, 1 deletion(-) 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 8896442327bc0..7ca1ed2699dcc 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 @@ -81,7 +81,6 @@ abstract class SQLViewSuite extends QueryTest with SQLTestUtils { val globalTempDB = spark.sharedState.globalTempViewManager.database sql("CREATE GLOBAL TEMP VIEW global_temp_jtv1 AS SELECT * FROM jt WHERE id > 0") sql(s"CREATE VIEW jtv2 AS SELECT * FROM $globalTempDB.global_temp_jtv1 WHERE id < 6") - } } } From 18dad1ca6fb1598a1f067cd1e0adb78dbfc073ad Mon Sep 17 00:00:00 2001 From: Aman Omer Date: Mon, 4 Nov 2019 23:10:21 +0530 Subject: [PATCH 06/10] Handled review comments --- .../scala/org/apache/spark/sql/execution/command/views.scala | 5 ++--- 1 file changed, 2 insertions(+), 3 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 ef29feaacb23a..6cf4ee3f04a5e 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 @@ -121,9 +121,8 @@ case class CreateViewCommand( } // Temporary view names should NOT contain database prefix like "database.table" - if (name.database.isDefined) { - val database = name.database.get - throw new AnalysisException( + name.database.foreach{ + database => throw new AnalysisException( s"It is not allowed to add database prefix `$database` for the TEMPORARY view name.") } } From 3b3aa1d6ba9408500e1828bf336be14532c1b1ab Mon Sep 17 00:00:00 2001 From: Aman Omer Date: Mon, 11 Nov 2019 16:54:45 +0530 Subject: [PATCH 07/10] Use pgSQLDialect --- .../spark/sql/execution/command/views.scala | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 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 6cf4ee3f04a5e..f09d28c70d846 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 @@ -17,17 +17,17 @@ package org.apache.spark.sql.execution.command -import scala.collection.mutable - -import org.apache.spark.sql.{AnalysisException, Row, SparkSession} import org.apache.spark.sql.catalyst.TableIdentifier import org.apache.spark.sql.catalyst.analysis.{UnresolvedFunction, UnresolvedRelation} import org.apache.spark.sql.catalyst.catalog.{CatalogStorageFormat, CatalogTable, CatalogTableType} import org.apache.spark.sql.catalyst.expressions.{Alias, SubqueryExpression} import org.apache.spark.sql.catalyst.plans.QueryPlan import org.apache.spark.sql.catalyst.plans.logical.{LogicalPlan, Project, View} -import org.apache.spark.sql.types.{MetadataBuilder, StructType} +import org.apache.spark.sql.types.MetadataBuilder import org.apache.spark.sql.util.SchemaUtils +import org.apache.spark.sql.{AnalysisException, Row, SparkSession} + +import scala.collection.mutable /** @@ -201,10 +201,16 @@ case class CreateViewCommand( case UnresolvedRelation(AsTableIdentifier(ident)) if sparkSession.sessionState.catalog.isTemporaryTable(ident) => // Temporary views are only stored in the session catalog - logInfo(s"View $name is based on temporary view $ident." - + s" $name will be created as temporary view") - verifyTempView() - isTempReferred = true + if (sparkSession.sqlContext.conf.usePostgreSQLDialect) { + logInfo(s"View $name is based on temporary view $ident." + + s" $name will be created as temporary view") + verifyTempView() + isTempReferred = true + } + else { + throw new AnalysisException(s"Not allowed to create a permanent view $name by " + + s"referencing a temporary view $ident") + } case other if !other.resolved => other.expressions.flatMap(_.collect { // Disallow creating permanent views based on temporary UDFs. From 5d11ddfb4994e44e3315ecdbc6988267e3793b21 Mon Sep 17 00:00:00 2001 From: Aman Omer Date: Mon, 11 Nov 2019 17:19:05 +0530 Subject: [PATCH 08/10] Resolved conflicts --- .../spark/sql/execution/command/views.scala | 49 ++++++++++--------- 1 file changed, 27 insertions(+), 22 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 f09d28c70d846..a70df21de8fe8 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 @@ -196,30 +196,35 @@ case class CreateViewCommand( // added/generated from a temporary view. // 2) The temp functions are represented by multiple classes. Most are inaccessible from this // package (e.g., HiveGenericUDF). - child.collect { - // Permanent views will be created as temporary view if based on temporary view. - case UnresolvedRelation(AsTableIdentifier(ident)) + def verify(child: LogicalPlan) { + child.collect { + // Permanent views will be created as temporary view if based on temporary view. + case UnresolvedRelation(AsTableIdentifier(ident)) if sparkSession.sessionState.catalog.isTemporaryTable(ident) => - // Temporary views are only stored in the session catalog - if (sparkSession.sqlContext.conf.usePostgreSQLDialect) { - logInfo(s"View $name is based on temporary view $ident." - + s" $name will be created as temporary view") - verifyTempView() - isTempReferred = true - } - else { - throw new AnalysisException(s"Not allowed to create a permanent view $name by " + - s"referencing a temporary view $ident") - } - - case other if !other.resolved => other.expressions.flatMap(_.collect { - // Disallow creating permanent views based on temporary UDFs. - case e: UnresolvedFunction - if sparkSession.sessionState.catalog.isTemporaryFunction(e.name) => - throw new AnalysisException(s"Not allowed to create a permanent view $name by " + - s"referencing a temporary function `${e.name}`") - }) + // Temporary views are only stored in the session catalog + if (sparkSession.sqlContext.conf.usePostgreSQLDialect) { + logInfo(s"View $name is based on temporary view $ident." + + s" $name will be created as temporary view") + verifyTempView() + isTempReferred = true + } + else { + throw new AnalysisException(s"Not allowed to create a permanent view $name by " + + s"referencing a temporary view $ident") + } + + case other if !other.resolved => other.expressions.flatMap(_.collect { + // Traverse subquery plan for any unresolved relations. + case e: SubqueryExpression => verify(e.plan) + // Disallow creating permanent views based on temporary UDFs. + case e: UnresolvedFunction + if sparkSession.sessionState.catalog.isTemporaryFunction(e.name) => + throw new AnalysisException(s"Not allowed to create a permanent view $name by " + + s"referencing a temporary function `${e.name}`") + }) + } } + verify(child) } } From 3f12e09c287c1daa0d7b630d8fb218a1d1bc3cbb Mon Sep 17 00:00:00 2001 From: Aman Omer Date: Mon, 11 Nov 2019 17:28:29 +0530 Subject: [PATCH 09/10] Scala style fix --- .../org/apache/spark/sql/execution/command/views.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 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 a70df21de8fe8..8022932ec4e83 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 @@ -17,6 +17,9 @@ package org.apache.spark.sql.execution.command +import scala.collection.mutable + +import org.apache.spark.sql.{AnalysisException, Row, SparkSession} import org.apache.spark.sql.catalyst.TableIdentifier import org.apache.spark.sql.catalyst.analysis.{UnresolvedFunction, UnresolvedRelation} import org.apache.spark.sql.catalyst.catalog.{CatalogStorageFormat, CatalogTable, CatalogTableType} @@ -25,9 +28,6 @@ import org.apache.spark.sql.catalyst.plans.QueryPlan import org.apache.spark.sql.catalyst.plans.logical.{LogicalPlan, Project, View} import org.apache.spark.sql.types.MetadataBuilder import org.apache.spark.sql.util.SchemaUtils -import org.apache.spark.sql.{AnalysisException, Row, SparkSession} - -import scala.collection.mutable /** From 87557e08deec4e6650f16546829b233158b529e5 Mon Sep 17 00:00:00 2001 From: Aman Omer Date: Wed, 13 Nov 2019 21:28:15 +0530 Subject: [PATCH 10/10] nit --- .../scala/org/apache/spark/sql/execution/command/views.scala | 5 ++--- 1 file changed, 2 insertions(+), 3 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 8022932ec4e83..1a3e78cfb09b0 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 @@ -121,7 +121,7 @@ case class CreateViewCommand( } // Temporary view names should NOT contain database prefix like "database.table" - name.database.foreach{ + name.database.foreach { database => throw new AnalysisException( s"It is not allowed to add database prefix `$database` for the TEMPORARY view name.") } @@ -207,8 +207,7 @@ case class CreateViewCommand( + s" $name will be created as temporary view") verifyTempView() isTempReferred = true - } - else { + } else { throw new AnalysisException(s"Not allowed to create a permanent view $name by " + s"referencing a temporary view $ident") }