aboutsummaryrefslogtreecommitdiff
path: root/sql/catalyst
diff options
context:
space:
mode:
authorWenchen Fan <wenchen@databricks.com>2016-10-25 15:00:33 +0800
committerWenchen Fan <wenchen@databricks.com>2016-10-25 15:00:33 +0800
commit6f31833dbe0b766dfe4540a240fe92ebb7e14737 (patch)
tree4547b60b8fc57abe061ecc790bc71e86bb1e7cb1 /sql/catalyst
parent78d740a08a04b74b49b5cba4bb6a821631390ab4 (diff)
downloadspark-6f31833dbe0b766dfe4540a240fe92ebb7e14737.tar.gz
spark-6f31833dbe0b766dfe4540a240fe92ebb7e14737.tar.bz2
spark-6f31833dbe0b766dfe4540a240fe92ebb7e14737.zip
[SPARK-18026][SQL] should not always lowercase partition columns of partition spec in parser
## What changes were proposed in this pull request? Currently we always lowercase the partition columns of partition spec in parser, with the assumption that table partition columns are always lowercased. However, this is not true for data source tables, which are case preserving. It's safe for now because data source tables don't store partition spec in metastore and don't support `ADD PARTITION`, `DROP PARTITION`, `RENAME PARTITION`, but we should make our code future-proof. This PR makes partition spec case preserving at parser, and improve the `PreprocessTableInsertion` analyzer rule to normalize the partition columns in partition spec, w.r.t. the table partition columns. ## How was this patch tested? existing tests. Author: Wenchen Fan <wenchen@databricks.com> Closes #15566 from cloud-fan/partition-spec.
Diffstat (limited to 'sql/catalyst')
-rw-r--r--sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala6
-rw-r--r--sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/logical/basicLogicalOperators.scala20
2 files changed, 6 insertions, 20 deletions
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala
index 929c1c4f2d..38e9bb6c16 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala
@@ -192,11 +192,13 @@ class AstBuilder extends SqlBaseBaseVisitor[AnyRef] with Logging {
override def visitPartitionSpec(
ctx: PartitionSpecContext): Map[String, Option[String]] = withOrigin(ctx) {
val parts = ctx.partitionVal.asScala.map { pVal =>
- val name = pVal.identifier.getText.toLowerCase
+ val name = pVal.identifier.getText
val value = Option(pVal.constant).map(visitStringConstant)
name -> value
}
- // Check for duplicate partition columns in one spec.
+ // Before calling `toMap`, we check duplicated keys to avoid silently ignore partition values
+ // in partition spec like PARTITION(a='1', b='2', a='3'). The real semantical check for
+ // partition columns will be done in analyzer.
checkDuplicateKeys(parts, ctx)
parts.toMap
}
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/logical/basicLogicalOperators.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/logical/basicLogicalOperators.scala
index 64a787a7ae..a48974c632 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/logical/basicLogicalOperators.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/logical/basicLogicalOperators.scala
@@ -356,26 +356,10 @@ case class InsertIntoTable(
override def children: Seq[LogicalPlan] = child :: Nil
override def output: Seq[Attribute] = Seq.empty
- lazy val expectedColumns = {
- if (table.output.isEmpty) {
- None
- } else {
- // Note: The parser (visitPartitionSpec in AstBuilder) already turns
- // keys in partition to their lowercase forms.
- val staticPartCols = partition.filter(_._2.isDefined).keySet
- Some(table.output.filterNot(a => staticPartCols.contains(a.name)))
- }
- }
-
assert(overwrite || !ifNotExists)
assert(partition.values.forall(_.nonEmpty) || !ifNotExists)
- override lazy val resolved: Boolean =
- childrenResolved && table.resolved && expectedColumns.forall { expected =>
- child.output.size == expected.size && child.output.zip(expected).forall {
- case (childAttr, tableAttr) =>
- DataType.equalsIgnoreCompatibleNullability(childAttr.dataType, tableAttr.dataType)
- }
- }
+
+ override lazy val resolved: Boolean = childrenResolved && table.resolved
}
/**