aboutsummaryrefslogtreecommitdiff
path: root/sql/hive
diff options
context:
space:
mode:
authorwindpiger <songjun@outlook.com>2017-03-06 22:36:43 -0800
committerWenchen Fan <wenchen@databricks.com>2017-03-06 22:36:43 -0800
commite52499ea9c32326b399b50bf0e3f26278da3feb2 (patch)
tree8c65eee723d2cb2784d41620c198f9a8aab5a6d4 /sql/hive
parent1f6c090c15f355a0c2aad736f8291fcdee5c556d (diff)
downloadspark-e52499ea9c32326b399b50bf0e3f26278da3feb2.tar.gz
spark-e52499ea9c32326b399b50bf0e3f26278da3feb2.tar.bz2
spark-e52499ea9c32326b399b50bf0e3f26278da3feb2.zip
[SPARK-19832][SQL] DynamicPartitionWriteTask get partitionPath should escape the partition name
## What changes were proposed in this pull request? Currently in DynamicPartitionWriteTask, when we get the paritionPath of a parition, we just escape the partition value, not escape the partition name. this will cause some problems for some special partition name situation, for example : 1) if the partition name contains '%' etc, there will be two partition path created in the filesytem, one is for escaped path like '/path/a%25b=1', another is for unescaped path like '/path/a%b=1'. and the data inserted stored in unescaped path, while the show partitions table will return 'a%25b=1' which the partition name is escaped. So here it is not consist. And I think the data should be stored in the escaped path in filesystem, which Hive2.0.0 also have the same action. 2) if the partition name contains ':', there will throw exception that new Path("/path","a:b"), this is illegal which has a colon in the relative path. ``` java.lang.IllegalArgumentException: java.net.URISyntaxException: Relative path in absolute URI: a:b at org.apache.hadoop.fs.Path.initialize(Path.java:205) at org.apache.hadoop.fs.Path.<init>(Path.java:171) at org.apache.hadoop.fs.Path.<init>(Path.java:88) ... 48 elided Caused by: java.net.URISyntaxException: Relative path in absolute URI: a:b at java.net.URI.checkPath(URI.java:1823) at java.net.URI.<init>(URI.java:745) at org.apache.hadoop.fs.Path.initialize(Path.java:202) ... 50 more ``` ## How was this patch tested? unit test added Author: windpiger <songjun@outlook.com> Closes #17173 from windpiger/fixDatasourceSpecialCharPartitionName.
Diffstat (limited to 'sql/hive')
-rw-r--r--sql/hive/src/test/scala/org/apache/spark/sql/hive/execution/HiveDDLSuite.scala35
1 files changed, 34 insertions, 1 deletions
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 e956c9abae..df2c1cee94 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
@@ -27,7 +27,7 @@ import org.scalatest.BeforeAndAfterEach
import org.apache.spark.SparkException
import org.apache.spark.sql.{AnalysisException, QueryTest, Row, SaveMode}
import org.apache.spark.sql.catalyst.analysis.{NoSuchPartitionException, TableAlreadyExistsException}
-import org.apache.spark.sql.catalyst.catalog.{CatalogDatabase, CatalogTable, CatalogTableType, CatalogUtils}
+import org.apache.spark.sql.catalyst.catalog.{CatalogDatabase, CatalogTable, CatalogTableType, CatalogUtils, ExternalCatalogUtils}
import org.apache.spark.sql.catalyst.TableIdentifier
import org.apache.spark.sql.execution.command.DDLUtils
import org.apache.spark.sql.hive.HiveExternalCatalog
@@ -1690,6 +1690,39 @@ class HiveDDLSuite
}
}
+ Seq("parquet", "hive").foreach { datasource =>
+ Seq("a b", "a:b", "a%b", "a,b").foreach { specialChars =>
+ test(s"partition column name of $datasource table containing $specialChars") {
+ withTable("t") {
+ withTempDir { dir =>
+ spark.sql(
+ s"""
+ |CREATE TABLE t(a string, `$specialChars` string)
+ |USING $datasource
+ |PARTITIONED BY(`$specialChars`)
+ |LOCATION '$dir'
+ """.stripMargin)
+
+ assert(dir.listFiles().isEmpty)
+ spark.sql(s"INSERT INTO TABLE t PARTITION(`$specialChars`=2) SELECT 1")
+ val partEscaped = s"${ExternalCatalogUtils.escapePathName(specialChars)}=2"
+ val partFile = new File(dir, partEscaped)
+ assert(partFile.listFiles().length >= 1)
+ checkAnswer(spark.table("t"), Row("1", "2") :: Nil)
+
+ withSQLConf("hive.exec.dynamic.partition.mode" -> "nonstrict") {
+ spark.sql(s"INSERT INTO TABLE t PARTITION(`$specialChars`) SELECT 3, 4")
+ val partEscaped1 = s"${ExternalCatalogUtils.escapePathName(specialChars)}=4"
+ val partFile1 = new File(dir, partEscaped1)
+ assert(partFile1.listFiles().length >= 1)
+ checkAnswer(spark.table("t"), Row("1", "2") :: Row("3", "4") :: Nil)
+ }
+ }
+ }
+ }
+ }
+ }
+
Seq("a b", "a:b", "a%b").foreach { specialChars =>
test(s"datasource table: location uri contains $specialChars") {
withTable("t", "t1") {