Github user gatorsmile commented on a diff in the pull request:
https://github.com/apache/spark/pull/14874#discussion_r76842003
--- Diff:
sql/core/src/main/scala/org/apache/spark/sql/execution/command/views.scala ---
@@ -202,3 +196,67 @@ case class CreateViewCommand(
)
}
}
+
+/**
+ * Alter a view with given query plan. If the view name contains database
prefix, this command will
+ * alter a permanent view matching the given name, or throw an exception
if view not exist. Else,
+ * this command will try to alter a temporary view first, if view not
exist, try permanent view
+ * next, if still not exist, throw an exception.
+ *
+ * @param name the name of this view.
+ * @param originalText the original SQL text of this view. Note that we
can only alter a view by
+ * SQL API, which means we always have originalText.
+ * @param query the logical plan that represents the view; this is used to
generate a canonicalized
+ * version of the SQL that can be saved in the catalog.
+ */
+case class AlterViewCommand(
+ name: TableIdentifier,
+ originalText: String,
+ query: LogicalPlan) extends RunnableCommand {
+
+ override protected def innerChildren: Seq[QueryPlan[_]] = Seq(query)
+
+ override def run(session: SparkSession): Seq[Row] = {
+ // If the plan cannot be analyzed, throw an exception and don't
proceed.
+ val qe = session.sessionState.executePlan(query)
+ qe.assertAnalyzed()
+ val analyzedPlan = qe.analyzed
+
+ val tableMeta = session.sessionState.catalog.getTableMetadata(name)
+ if (tableMeta.tableType != CatalogTableType.VIEW) {
+ throw new AnalysisException(s"${tableMeta.identifier} is not a
view.")
+ }
+
+ if (name.database.isDefined) {
+ alterPermanentView(session, analyzedPlan)
+ } else if (session.sessionState.catalog.isTemporaryTable(name)) {
+ session.sessionState.catalog.createTempView(name.table,
analyzedPlan, overrideIfExists = true)
+ } else {
+ alterPermanentView(session, analyzedPlan)
+ }
+
+ Seq.empty[Row]
+ }
+
+ private def alterPermanentView(session: SparkSession, analyzedPlan:
LogicalPlan): Unit = {
+ val viewSQL: String = new SQLBuilder(analyzedPlan).toSQL
+ // Validate the view SQL - make sure we can parse it and analyze it.
+ // If we cannot analyze the generated query, there is probably a bug
in SQL generation.
+ try {
+ session.sql(viewSQL).queryExecution.assertAnalyzed()
+ } catch {
+ case NonFatal(e) =>
+ throw new RuntimeException(s"Failed to analyze the canonicalized
SQL: $viewSQL", e)
+ }
+
+ val viewTableMeta = CatalogTable(
+ identifier = name,
+ tableType = CatalogTableType.VIEW,
+ storage = CatalogStorageFormat.empty,
+ schema = analyzedPlan.schema,
+ viewOriginalText = Some(originalText),
+ viewText = Some(viewSQL))
--- End diff --
Since we are doing the alter view, we should not lose the existing fields,
e.g., comment and table properties.
---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at [email protected] or file a JIRA ticket
with INFRA.
---
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]