aboutsummaryrefslogtreecommitdiff
path: root/sql/catalyst/src/main
diff options
context:
space:
mode:
authorWenchen Fan <wenchen@databricks.com>2016-11-22 09:16:20 -0800
committerHerman van Hovell <hvanhovell@databricks.com>2016-11-22 09:16:20 -0800
commitbb152cdfbb8d02130c71d2326ae81939725c2cf0 (patch)
treedeffec4de973299610a2bf932cb5d9783ebf0ec5 /sql/catalyst/src/main
parent933a6548d423cf17448207a99299cf36fc1a95f6 (diff)
downloadspark-bb152cdfbb8d02130c71d2326ae81939725c2cf0.tar.gz
spark-bb152cdfbb8d02130c71d2326ae81939725c2cf0.tar.bz2
spark-bb152cdfbb8d02130c71d2326ae81939725c2cf0.zip
[SPARK-18519][SQL] map type can not be used in EqualTo
## What changes were proposed in this pull request? Technically map type is not orderable, but can be used in equality comparison. However, due to the limitation of the current implementation, map type can't be used in equality comparison so that it can't be join key or grouping key. This PR makes this limitation explicit, to avoid wrong result. ## How was this patch tested? updated tests. Author: Wenchen Fan <wenchen@databricks.com> Closes #15956 from cloud-fan/map-type.
Diffstat (limited to 'sql/catalyst/src/main')
-rw-r--r--sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/CheckAnalysis.scala15
-rw-r--r--sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/predicates.scala30
2 files changed, 30 insertions, 15 deletions
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/CheckAnalysis.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/CheckAnalysis.scala
index 98e50d0d3c..80e577e5c4 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/CheckAnalysis.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/CheckAnalysis.scala
@@ -183,21 +183,6 @@ trait CheckAnalysis extends PredicateHelper {
s"join condition '${condition.sql}' " +
s"of type ${condition.dataType.simpleString} is not a boolean.")
- case j @ Join(_, _, _, Some(condition)) =>
- def checkValidJoinConditionExprs(expr: Expression): Unit = expr match {
- case p: Predicate =>
- p.asInstanceOf[Expression].children.foreach(checkValidJoinConditionExprs)
- case e if e.dataType.isInstanceOf[BinaryType] =>
- failAnalysis(s"binary type expression ${e.sql} cannot be used " +
- "in join conditions")
- case e if e.dataType.isInstanceOf[MapType] =>
- failAnalysis(s"map type expression ${e.sql} cannot be used " +
- "in join conditions")
- case _ => // OK
- }
-
- checkValidJoinConditionExprs(condition)
-
case Aggregate(groupingExprs, aggregateExprs, child) =>
def checkValidAggregateExpression(expr: Expression): Unit = expr match {
case aggExpr: AggregateExpression =>
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/predicates.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/predicates.scala
index 7946c201f4..2ad452b6a9 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/predicates.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/predicates.scala
@@ -412,6 +412,21 @@ case class EqualTo(left: Expression, right: Expression)
override def inputType: AbstractDataType = AnyDataType
+ override def checkInputDataTypes(): TypeCheckResult = {
+ super.checkInputDataTypes() match {
+ case TypeCheckResult.TypeCheckSuccess =>
+ // TODO: although map type is not orderable, technically map type should be able to be used
+ // in equality comparison, remove this type check once we support it.
+ if (left.dataType.existsRecursively(_.isInstanceOf[MapType])) {
+ TypeCheckResult.TypeCheckFailure("Cannot use map type in EqualTo, but the actual " +
+ s"input type is ${left.dataType.catalogString}.")
+ } else {
+ TypeCheckResult.TypeCheckSuccess
+ }
+ case failure => failure
+ }
+ }
+
override def symbol: String = "="
protected override def nullSafeEval(input1: Any, input2: Any): Any = {
@@ -440,6 +455,21 @@ case class EqualNullSafe(left: Expression, right: Expression) extends BinaryComp
override def inputType: AbstractDataType = AnyDataType
+ override def checkInputDataTypes(): TypeCheckResult = {
+ super.checkInputDataTypes() match {
+ case TypeCheckResult.TypeCheckSuccess =>
+ // TODO: although map type is not orderable, technically map type should be able to be used
+ // in equality comparison, remove this type check once we support it.
+ if (left.dataType.existsRecursively(_.isInstanceOf[MapType])) {
+ TypeCheckResult.TypeCheckFailure("Cannot use map type in EqualNullSafe, but the actual " +
+ s"input type is ${left.dataType.catalogString}.")
+ } else {
+ TypeCheckResult.TypeCheckSuccess
+ }
+ case failure => failure
+ }
+ }
+
override def symbol: String = "<=>"
override def nullable: Boolean = false