Repository: spark
Updated Branches:
  refs/heads/master e9f97154b -> 776a2c0e9


[SPARK-20439][SQL] Fix Catalog API listTables and getTable when failed to fetch 
table metadata

### What changes were proposed in this pull request?

`spark.catalog.listTables` and `spark.catalog.getTable` does not work if we are 
unable to retrieve table metadata due to any reason (e.g., table serde class is 
not accessible or the table type is not accepted by Spark SQL). After this PR, 
the APIs still return the corresponding Table without the description and 
tableType)

### How was this patch tested?
Added a test case

Author: Xiao Li <[email protected]>

Closes #17730 from gatorsmile/listTables.


Project: http://git-wip-us.apache.org/repos/asf/spark/repo
Commit: http://git-wip-us.apache.org/repos/asf/spark/commit/776a2c0e
Tree: http://git-wip-us.apache.org/repos/asf/spark/tree/776a2c0e
Diff: http://git-wip-us.apache.org/repos/asf/spark/diff/776a2c0e

Branch: refs/heads/master
Commit: 776a2c0e91dfea170ea1c489118e1d42c4121f35
Parents: e9f9715
Author: Xiao Li <[email protected]>
Authored: Mon Apr 24 17:21:42 2017 +0800
Committer: Wenchen Fan <[email protected]>
Committed: Mon Apr 24 17:21:42 2017 +0800

----------------------------------------------------------------------
 .../apache/spark/sql/internal/CatalogImpl.scala | 28 ++++++++++++++++----
 .../spark/sql/hive/execution/HiveDDLSuite.scala |  8 ++++++
 2 files changed, 31 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/spark/blob/776a2c0e/sql/core/src/main/scala/org/apache/spark/sql/internal/CatalogImpl.scala
----------------------------------------------------------------------
diff --git 
a/sql/core/src/main/scala/org/apache/spark/sql/internal/CatalogImpl.scala 
b/sql/core/src/main/scala/org/apache/spark/sql/internal/CatalogImpl.scala
index aebb663..0b8e538 100644
--- a/sql/core/src/main/scala/org/apache/spark/sql/internal/CatalogImpl.scala
+++ b/sql/core/src/main/scala/org/apache/spark/sql/internal/CatalogImpl.scala
@@ -18,6 +18,7 @@
 package org.apache.spark.sql.internal
 
 import scala.reflect.runtime.universe.TypeTag
+import scala.util.control.NonFatal
 
 import org.apache.spark.annotation.Experimental
 import org.apache.spark.sql._
@@ -98,14 +99,27 @@ class CatalogImpl(sparkSession: SparkSession) extends 
Catalog {
     CatalogImpl.makeDataset(tables, sparkSession)
   }
 
+  /**
+   * Returns a Table for the given table/view or temporary view.
+   *
+   * Note that this function requires the table already exists in the Catalog.
+   *
+   * If the table metadata retrieval failed due to any reason (e.g., table 
serde class
+   * is not accessible or the table type is not accepted by Spark SQL), this 
function
+   * still returns the corresponding Table without the description and 
tableType)
+   */
   private def makeTable(tableIdent: TableIdentifier): Table = {
-    val metadata = 
sessionCatalog.getTempViewOrPermanentTableMetadata(tableIdent)
+    val metadata = try {
+      Some(sessionCatalog.getTempViewOrPermanentTableMetadata(tableIdent))
+    } catch {
+      case NonFatal(_) => None
+    }
     val isTemp = sessionCatalog.isTemporaryTable(tableIdent)
     new Table(
       name = tableIdent.table,
-      database = metadata.identifier.database.orNull,
-      description = metadata.comment.orNull,
-      tableType = if (isTemp) "TEMPORARY" else metadata.tableType.name,
+      database = 
metadata.map(_.identifier.database).getOrElse(tableIdent.database).orNull,
+      description = metadata.map(_.comment.orNull).orNull,
+      tableType = if (isTemp) "TEMPORARY" else 
metadata.map(_.tableType.name).orNull,
       isTemporary = isTemp)
   }
 
@@ -197,7 +211,11 @@ class CatalogImpl(sparkSession: SparkSession) extends 
Catalog {
    * `AnalysisException` when no `Table` can be found.
    */
   override def getTable(dbName: String, tableName: String): Table = {
-    makeTable(TableIdentifier(tableName, Option(dbName)))
+    if (tableExists(dbName, tableName)) {
+      makeTable(TableIdentifier(tableName, Option(dbName)))
+    } else {
+      throw new AnalysisException(s"Table or view '$tableName' not found in 
database '$dbName'")
+    }
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/spark/blob/776a2c0e/sql/hive/src/test/scala/org/apache/spark/sql/hive/execution/HiveDDLSuite.scala
----------------------------------------------------------------------
diff --git 
a/sql/hive/src/test/scala/org/apache/spark/sql/hive/execution/HiveDDLSuite.scala
 
b/sql/hive/src/test/scala/org/apache/spark/sql/hive/execution/HiveDDLSuite.scala
index 3906968..16a9932 100644
--- 
a/sql/hive/src/test/scala/org/apache/spark/sql/hive/execution/HiveDDLSuite.scala
+++ 
b/sql/hive/src/test/scala/org/apache/spark/sql/hive/execution/HiveDDLSuite.scala
@@ -1197,6 +1197,14 @@ class HiveDDLSuite
           s"CREATE INDEX $indexName ON TABLE $tabName (a) AS 'COMPACT' WITH 
DEFERRED REBUILD")
         val indexTabName =
           spark.sessionState.catalog.listTables("default", 
s"*$indexName*").head.table
+
+        // Even if index tables exist, listTables and getTable APIs should 
still work
+        checkAnswer(
+          spark.catalog.listTables().toDF(),
+          Row(indexTabName, "default", null, null, false) ::
+            Row(tabName, "default", null, "MANAGED", false) :: Nil)
+        assert(spark.catalog.getTable("default", indexTabName).name === 
indexTabName)
+
         intercept[TableAlreadyExistsException] {
           sql(s"CREATE TABLE $indexTabName(b int)")
         }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to