[SPARK-34543][SQL] Respect the spark.sql.caseSensitive
config while resolving partition spec in v1 SET LOCATION
### What changes were proposed in this pull request? Preprocess the partition spec passed to the V1 `ALTER TABLE .. SET LOCATION` implementation `AlterTableSetLocationCommand`, and normalize the passed spec according to the partition columns w.r.t the case sensitivity flag **spark.sql.caseSensitive**. ### Why are the changes needed? V1 `ALTER TABLE .. SET LOCATION` is case sensitive in fact, and doesn't respect the SQL config **spark.sql.caseSensitive** which is false by default, for instance: ```sql spark-sql> CREATE TABLE tbl (id INT, part INT) PARTITIONED BY (part); spark-sql> INSERT INTO tbl PARTITION (part=0) SELECT 0; spark-sql> SHOW TABLE EXTENDED LIKE 'tbl' PARTITION (part=0); Location: file:/Users/maximgekk/proj/set-location-case-sense/spark-warehouse/tbl/part=0 spark-sql> ALTER TABLE tbl ADD PARTITION (part=1); spark-sql> SELECT * FROM tbl; 0 0 ``` Create new partition folder in the file system: ``` $ cp -r /Users/maximgekk/proj/set-location-case-sense/spark-warehouse/tbl/part=0 /Users/maximgekk/proj/set-location-case-sense/spark-warehouse/tbl/aaa ``` Set new location for the partition part=1: ```sql spark-sql> ALTER TABLE tbl PARTITION (part=1) SET LOCATION '/Users/maximgekk/proj/set-location-case-sense/spark-warehouse/tbl/aaa'; spark-sql> SELECT * FROM tbl; 0 0 0 1 spark-sql> ALTER TABLE tbl ADD PARTITION (PART=2); spark-sql> SELECT * FROM tbl; 0 0 0 1 ``` Set location for a partition in the upper case: ``` $ cp -r /Users/maximgekk/proj/set-location-case-sense/spark-warehouse/tbl/part=0 /Users/maximgekk/proj/set-location-case-sense/spark-warehouse/tbl/bbb ``` ```sql spark-sql> ALTER TABLE tbl PARTITION (PART=2) SET LOCATION '/Users/maximgekk/proj/set-location-case-sense/spark-warehouse/tbl/bbb'; Error in query: Partition spec is invalid. The spec (PART) must match the partition spec (part) defined in table '`default`.`tbl`' ``` ### Does this PR introduce _any_ user-facing change? Yes. After the changes, the command above works as expected: ```sql spark-sql> ALTER TABLE tbl PARTITION (PART=2) SET LOCATION '/Users/maximgekk/proj/set-location-case-sense/spark-warehouse/tbl/bbb'; spark-sql> SELECT * FROM tbl; 0 0 0 1 0 2 ``` ### How was this patch tested? By running the modified test suite: ``` $ build/sbt -Phive-2.3 -Phive-thriftserver "test:testOnly *CatalogedDDLSuite" ``` Closes #31651 from MaxGekk/set-location-case-sense. Authored-by: Max Gekk <max.gekk@gmail.com> Signed-off-by: Wenchen Fan <wenchen@databricks.com>
This commit is contained in:
parent
4d428a821b
commit
5c7d019b60
|
@ -848,7 +848,12 @@ case class AlterTableSetLocationCommand(
|
|||
DDLUtils.verifyPartitionProviderIsHive(
|
||||
sparkSession, table, "ALTER TABLE ... SET LOCATION")
|
||||
// Partition spec is specified, so we set the location only for this partition
|
||||
val part = catalog.getPartition(table.identifier, spec)
|
||||
val normalizedSpec = PartitioningUtils.normalizePartitionSpec(
|
||||
spec,
|
||||
table.partitionSchema,
|
||||
table.identifier.quotedString,
|
||||
sparkSession.sessionState.conf.resolver)
|
||||
val part = catalog.getPartition(table.identifier, normalizedSpec)
|
||||
val newPart = part.copy(storage = part.storage.copy(locationUri = Some(locUri)))
|
||||
catalog.alterPartitions(table.identifier, Seq(newPart))
|
||||
case None =>
|
||||
|
|
|
@ -1261,6 +1261,17 @@ abstract class DDLSuite extends QueryTest with SQLTestUtils {
|
|||
// set table partition location
|
||||
sql("ALTER TABLE dbx.tab1 PARTITION (a='1', b='2') SET LOCATION '/path/to/part/ways'")
|
||||
verifyLocation(new URI("/path/to/part/ways"), Some(partSpec))
|
||||
// set location for partition spec in the upper case
|
||||
withSQLConf(SQLConf.CASE_SENSITIVE.key -> "false") {
|
||||
sql("ALTER TABLE dbx.tab1 PARTITION (A='1', B='2') SET LOCATION '/path/to/part/ways2'")
|
||||
verifyLocation(new URI("/path/to/part/ways2"), Some(partSpec))
|
||||
}
|
||||
withSQLConf(SQLConf.CASE_SENSITIVE.key -> "true") {
|
||||
val errMsg = intercept[AnalysisException] {
|
||||
sql("ALTER TABLE dbx.tab1 PARTITION (A='1', B='2') SET LOCATION '/path/to/part/ways3'")
|
||||
}.getMessage
|
||||
assert(errMsg.contains("not a valid partition column"))
|
||||
}
|
||||
// set table location without explicitly specifying database
|
||||
catalog.setCurrentDatabase("dbx")
|
||||
sql("ALTER TABLE tab1 SET LOCATION '/swanky/steak/place'")
|
||||
|
|
Loading…
Reference in a new issue