diff options
Diffstat (limited to 'sql/hive/src/main')
-rw-r--r-- | sql/hive/src/main/scala/org/apache/spark/sql/hive/client/HiveClientImpl.scala | 50 |
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 } } |