aboutsummaryrefslogtreecommitdiff
path: root/sql/hive/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'sql/hive/src/main')
-rw-r--r--sql/hive/src/main/scala/org/apache/spark/sql/hive/client/HiveClientImpl.scala50
1 files changed, 37 insertions, 13 deletions
diff --git a/sql/hive/src/main/scala/org/apache/spark/sql/hive/client/HiveClientImpl.scala b/sql/hive/src/main/scala/org/apache/spark/sql/hive/client/HiveClientImpl.scala
index bb32459202..78c457b6c2 100644
--- a/sql/hive/src/main/scala/org/apache/spark/sql/hive/client/HiveClientImpl.scala
+++ b/sql/hive/src/main/scala/org/apache/spark/sql/hive/client/HiveClientImpl.scala
@@ -20,6 +20,7 @@ package org.apache.spark.sql.hive.client
import java.io.{File, PrintStream}
import scala.collection.JavaConverters._
+import scala.collection.mutable.ArrayBuffer
import scala.language.reflectiveCalls
import org.apache.hadoop.conf.Configuration
@@ -405,20 +406,43 @@ private[hive] class HiveClientImpl(
ignoreIfNotExists: Boolean): Unit = withHiveState {
// TODO: figure out how to drop multiple partitions in one call
val hiveTable = client.getTable(db, table, true /* throw exception */)
- specs.foreach { s =>
- // The provided spec here can be a partial spec, i.e. it will match all partitions
- // whose specs are supersets of this partial spec. E.g. If a table has partitions
- // (b='1', c='1') and (b='1', c='2'), a partial spec of (b='1') will match both.
- val matchingParts = client.getPartitions(hiveTable, s.asJava).asScala
- if (matchingParts.isEmpty && !ignoreIfNotExists) {
- throw new AnalysisException(
- s"partition to drop '$s' does not exist in table '$table' database '$db'")
- }
- matchingParts.foreach { hivePartition =>
- val dropOptions = new PartitionDropOptions
- dropOptions.ifExists = ignoreIfNotExists
- client.dropPartition(db, table, hivePartition.getValues, dropOptions)
+ // do the check at first and collect all the matching partitions
+ val matchingParts =
+ specs.flatMap { s =>
+ // The provided spec here can be a partial spec, i.e. it will match all partitions
+ // whose specs are supersets of this partial spec. E.g. If a table has partitions
+ // (b='1', c='1') and (b='1', c='2'), a partial spec of (b='1') will match both.
+ val parts = client.getPartitions(hiveTable, s.asJava).asScala
+ if (parts.isEmpty && !ignoreIfNotExists) {
+ throw new AnalysisException(
+ s"No partition is dropped. One partition spec '$s' does not exist in table '$table' " +
+ s"database '$db'")
+ }
+ parts.map(_.getValues)
+ }.distinct
+ var droppedParts = ArrayBuffer.empty[java.util.List[String]]
+ matchingParts.foreach { partition =>
+ val dropOptions = new PartitionDropOptions
+ dropOptions.ifExists = ignoreIfNotExists
+ try {
+ client.dropPartition(db, table, partition, dropOptions)
+ } catch {
+ case e: Exception =>
+ val remainingParts = matchingParts.toBuffer -- droppedParts
+ logError(
+ s"""
+ |======================
+ |Attempt to drop the partition specs in table '$table' database '$db':
+ |${specs.mkString("\n")}
+ |In this attempt, the following partitions have been dropped successfully:
+ |${droppedParts.mkString("\n")}
+ |The remaining partitions have not been dropped:
+ |${remainingParts.mkString("\n")}
+ |======================
+ """.stripMargin)
+ throw e
}
+ droppedParts += partition
}
}