Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import org.apache.spark.sql.catalyst.InternalRow
import org.apache.spark.sql.catalyst.expressions.Attribute
import org.apache.spark.sql.catalyst.plans.physical.Partitioning
import org.apache.spark.sql.execution.{SparkPlan, UnaryExecNode}
import org.apache.spark.sql.execution.command.{AlterTableAddPartitionCommand, AlterTableDropPartitionCommand}
import org.apache.spark.sql.hive._
import org.apache.spark.sql.hive.HiveShim.{ShimFileSinkDesc => FileSinkDesc}
import org.apache.spark.SparkException
Expand Down Expand Up @@ -257,7 +258,31 @@ case class InsertIntoHiveTable(
table.catalogTable.identifier.table,
partitionSpec)

var doOverwrite = overwrite

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: doHiveOverwrite?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok. updated.


if (oldPart.isEmpty || !ifNotExists) {
// SPARK-18107: Insert overwrite runs much slower than hive-client.
// Newer Hive largely improves insert overwrite performance. As Spark uses older Hive
// version and we may not want to catch up new Hive version every time. We delete the
// Hive partition first and then load data file into the Hive partition.
if (oldPart.nonEmpty && overwrite) {
oldPart.get.storage.locationUri.map { uri =>
val partitionPath = new Path(uri)
val fs = partitionPath.getFileSystem(hadoopConf)
if (fs.exists(partitionPath)) {
val pathPermission = fs.getFileStatus(partitionPath).getPermission()
if (!fs.delete(partitionPath, true)) {
throw new RuntimeException(
"Cannot remove partition directory '" + partitionPath.toString)
} else {
fs.mkdirs(partitionPath, pathPermission)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the mkdir necessary?

@viirya viirya Nov 1, 2016

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking Hive will complain if the dir is not existing. But looks like it won't. Let me remove this and see if all tests can be passed.

}
// Don't let Hive do overwrite operation since it is slower.
doOverwrite = false
}
}
}

// inheritTableSpecs is set to true. It should be set to false for an IMPORT query
// which is currently considered as a Hive native command.
val inheritTableSpecs = true
Expand All @@ -266,7 +291,7 @@ case class InsertIntoHiveTable(
table.catalogTable.identifier.table,
outputPath.toString,
partitionSpec,
isOverwrite = overwrite,
isOverwrite = doOverwrite,
holdDDLTime = holdDDLTime,
inheritTableSpecs = inheritTableSpecs)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1947,6 +1947,39 @@ class SQLQuerySuite extends QueryTest with SQLTestUtils with TestHiveSingleton {
}
}

test("Insert overwrite with partition") {
withTable("tableWithPartition") {
sql(
"""
|CREATE TABLE tableWithPartition (key int, value STRING)
|PARTITIONED BY (part STRING)
""".stripMargin)
sql(
"""
|INSERT OVERWRITE TABLE tableWithPartition PARTITION (part = '1')
|SELECT * FROM default.src
""".stripMargin)
checkAnswer(
sql("SELECT part, key, value FROM tableWithPartition"),
sql("SELECT '1' AS part, key, value FROM default.src")
)

sql(
"""
|INSERT OVERWRITE TABLE tableWithPartition PARTITION (part = '1')
|SELECT * FROM VALUES (1, "one"), (2, "two"), (3, null) AS data(key, value)
""".stripMargin)
checkAnswer(
sql("SELECT part, key, value FROM tableWithPartition"),
sql(
"""
|SELECT '1' AS part, key, value FROM VALUES
|(1, "one"), (2, "two"), (3, null) AS data(key, value)
""".stripMargin)
)
}
}

def testCommandAvailable(command: String): Boolean = {
val attempt = Try(Process(command).run(ProcessLogger(_ => ())).exitValue())
attempt.isSuccess && attempt.get == 0
Expand Down