This is an automated email from the ASF dual-hosted git repository.

dongjoon pushed a commit to branch branch-3.1
in repository https://gitbox.apache.org/repos/asf/spark.git


The following commit(s) were added to refs/heads/branch-3.1 by this push:
     new 970fc64  [SPARK-33667][SQL] Respect the `spark.sql.caseSensitive` 
config while resolving partition spec in v1 `SHOW PARTITIONS`
970fc64 is described below

commit 970fc6406d190ecd4602e3e987339bc451aade7a
Author: Max Gekk <[email protected]>
AuthorDate: Sun Dec 6 02:56:08 2020 -0800

    [SPARK-33667][SQL] Respect the `spark.sql.caseSensitive` config while 
resolving partition spec in v1 `SHOW PARTITIONS`
    
    ### What changes were proposed in this pull request?
    Preprocess the partition spec passed to the V1 SHOW PARTITIONS 
implementation `ShowPartitionsCommand`, 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 SHOW PARTITIONS 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 tbl1 (price int, qty int, year int, month int)
             > USING parquet
             > PARTITIONED BY (year, month);
    spark-sql> INSERT INTO tbl1 PARTITION(year = 2015, month = 1) SELECT 1, 1;
    spark-sql> SHOW PARTITIONS tbl1 PARTITION(YEAR = 2015, Month = 1);
    Error in query: Non-partitioning column(s) [YEAR, Month] are specified for 
SHOW PARTITIONS;
    ```
    The `SHOW PARTITIONS` command must show the partition `year = 2015, month = 
1` specified by `YEAR = 2015, Month = 1`.
    
    ### Does this PR introduce _any_ user-facing change?
    Yes. After the changes, the command above works as expected:
    ```sql
    spark-sql> SHOW PARTITIONS tbl1 PARTITION(YEAR = 2015, Month = 1);
    year=2015/month=1
    ```
    
    ### How was this patch tested?
    By running the affected test suites:
    - `v1/ShowPartitionsSuite`
    - `v2/ShowPartitionsSuite`
    
    Closes #30615 from MaxGekk/show-partitions-case-sensitivity-test.
    
    Authored-by: Max Gekk <[email protected]>
    Signed-off-by: Dongjoon Hyun <[email protected]>
    (cherry picked from commit 48297818f37a8e02cc02ba6fa9ec04fe37540aca)
    Signed-off-by: Dongjoon Hyun <[email protected]>
---
 .../spark/sql/execution/command/tables.scala       | 18 +++++++-------
 .../command/ShowPartitionsSuiteBase.scala          | 28 ++++++++++++++++++++--
 .../execution/command/v1/ShowPartitionsSuite.scala |  4 ----
 .../execution/command/v2/ShowPartitionsSuite.scala |  4 ----
 4 files changed, 34 insertions(+), 20 deletions(-)

diff --git 
a/sql/core/src/main/scala/org/apache/spark/sql/execution/command/tables.scala 
b/sql/core/src/main/scala/org/apache/spark/sql/execution/command/tables.scala
index 9e3ca3c..59adb7d 100644
--- 
a/sql/core/src/main/scala/org/apache/spark/sql/execution/command/tables.scala
+++ 
b/sql/core/src/main/scala/org/apache/spark/sql/execution/command/tables.scala
@@ -1006,20 +1006,18 @@ case class ShowPartitionsCommand(
     DDLUtils.verifyPartitionProviderIsHive(sparkSession, table, "SHOW 
PARTITIONS")
 
     /**
-     * Validate the partitioning spec by making sure all the referenced 
columns are
+     * Normalizes the partition spec w.r.t the partition columns and case 
sensitivity settings,
+     * and validates the spec by making sure all the referenced columns are
      * defined as partitioning columns in table definition. An 
AnalysisException exception is
      * thrown if the partitioning spec is invalid.
      */
-    if (spec.isDefined) {
-      val badColumns = 
spec.get.keySet.filterNot(table.partitionColumnNames.contains)
-      if (badColumns.nonEmpty) {
-        val badCols = badColumns.mkString("[", ", ", "]")
-        throw new AnalysisException(
-          s"Non-partitioning column(s) $badCols are specified for SHOW 
PARTITIONS")
-      }
-    }
+    val normalizedSpec = spec.map(partitionSpec => 
PartitioningUtils.normalizePartitionSpec(
+      partitionSpec,
+      table.partitionColumnNames,
+      table.identifier.quotedString,
+      sparkSession.sessionState.conf.resolver))
 
-    val partNames = catalog.listPartitionNames(tableName, spec)
+    val partNames = catalog.listPartitionNames(tableName, normalizedSpec)
     partNames.map(Row(_))
   }
 }
diff --git 
a/sql/core/src/test/scala/org/apache/spark/sql/execution/command/ShowPartitionsSuiteBase.scala
 
b/sql/core/src/test/scala/org/apache/spark/sql/execution/command/ShowPartitionsSuiteBase.scala
index 82457f9..b695dec 100644
--- 
a/sql/core/src/test/scala/org/apache/spark/sql/execution/command/ShowPartitionsSuiteBase.scala
+++ 
b/sql/core/src/test/scala/org/apache/spark/sql/execution/command/ShowPartitionsSuiteBase.scala
@@ -21,6 +21,7 @@ import org.scalactic.source.Position
 import org.scalatest.Tag
 
 import org.apache.spark.sql.{AnalysisException, QueryTest, Row}
+import org.apache.spark.sql.internal.SQLConf
 import org.apache.spark.sql.test.SQLTestUtils
 import org.apache.spark.sql.types.{StringType, StructType}
 
@@ -28,7 +29,6 @@ trait ShowPartitionsSuiteBase extends QueryTest with 
SQLTestUtils {
   protected def version: String
   protected def catalog: String
   protected def defaultUsing: String
-  protected def wrongPartitionColumnsError(columns: String*): String
   // Gets the schema of `SHOW PARTITIONS`
   private val showSchema: StructType = new StructType().add("partition", 
StringType, false)
   protected def runShowPartitionsSql(sqlText: String, expected: Seq[Row]): 
Unit = {
@@ -94,7 +94,7 @@ trait ShowPartitionsSuiteBase extends QueryTest with 
SQLTestUtils {
         val errMsg = intercept[AnalysisException] {
           sql(s"SHOW PARTITIONS $table PARTITION(abcd=2015, xyz=1)")
         }.getMessage
-        assert(errMsg.contains(wrongPartitionColumnsError("abcd", "xyz")))
+        assert(errMsg.contains("abcd is not a valid partition column"))
       }
     }
   }
@@ -149,4 +149,28 @@ trait ShowPartitionsSuiteBase extends QueryTest with 
SQLTestUtils {
       }
     }
   }
+
+  test("SPARK-33667: case sensitivity of partition spec") {
+    withNamespace(s"$catalog.ns") {
+      sql(s"CREATE NAMESPACE $catalog.ns")
+      val t = s"$catalog.ns.part_table"
+      withTable(t) {
+        sql(s"""
+          |CREATE TABLE $t (price int, qty int, year int, month int)
+          |$defaultUsing
+          |PARTITIONED BY (year, month)""".stripMargin)
+        sql(s"INSERT INTO $t PARTITION(year = 2015, month = 1) SELECT 1, 1")
+        Seq(
+          true -> "PARTITION(year = 2015, month = 1)",
+          false -> "PARTITION(YEAR = 2015, Month = 1)"
+        ).foreach { case (caseSensitive, partitionSpec) =>
+          withSQLConf(SQLConf.CASE_SENSITIVE.key -> caseSensitive.toString) {
+            runShowPartitionsSql(
+              s"SHOW PARTITIONS $t $partitionSpec",
+              Row("year=2015/month=1") :: Nil)
+          }
+        }
+      }
+    }
+  }
 }
diff --git 
a/sql/core/src/test/scala/org/apache/spark/sql/execution/command/v1/ShowPartitionsSuite.scala
 
b/sql/core/src/test/scala/org/apache/spark/sql/execution/command/v1/ShowPartitionsSuite.scala
index 2b2bc9e..c752a5f 100644
--- 
a/sql/core/src/test/scala/org/apache/spark/sql/execution/command/v1/ShowPartitionsSuite.scala
+++ 
b/sql/core/src/test/scala/org/apache/spark/sql/execution/command/v1/ShowPartitionsSuite.scala
@@ -27,10 +27,6 @@ trait ShowPartitionsSuiteBase extends 
command.ShowPartitionsSuiteBase {
   override def catalog: String = CatalogManager.SESSION_CATALOG_NAME
   override def defaultUsing: String = "USING parquet"
 
-  override protected def wrongPartitionColumnsError(columns: String*): String 
= {
-    s"Non-partitioning column(s) ${columns.mkString("[", ", ", "]")} are 
specified"
-  }
-
   test("show everything in the default database") {
     val table = "dateTable"
     withTable(table) {
diff --git 
a/sql/core/src/test/scala/org/apache/spark/sql/execution/command/v2/ShowPartitionsSuite.scala
 
b/sql/core/src/test/scala/org/apache/spark/sql/execution/command/v2/ShowPartitionsSuite.scala
index ca47a71..55985a3 100644
--- 
a/sql/core/src/test/scala/org/apache/spark/sql/execution/command/v2/ShowPartitionsSuite.scala
+++ 
b/sql/core/src/test/scala/org/apache/spark/sql/execution/command/v2/ShowPartitionsSuite.scala
@@ -32,10 +32,6 @@ class ShowPartitionsSuite extends 
command.ShowPartitionsSuiteBase with SharedSpa
     .set(s"spark.sql.catalog.$catalog", 
classOf[InMemoryPartitionTableCatalog].getName)
     .set(s"spark.sql.catalog.non_part_$catalog", 
classOf[InMemoryTableCatalog].getName)
 
-  override protected def wrongPartitionColumnsError(columns: String*): String 
= {
-    s"${columns.head} is not a valid partition column"
-  }
-
   test("a table does not support partitioning") {
     val table = s"non_part_$catalog.tab1"
     withTable(table) {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to