Skip to content

Commit dcbd58a

Browse files
dilipbiswalmarmbrus
authored andcommitted
[SPARK-8654] [SQL] Fix Analysis exception when using NULL IN (...)
In the analysis phase , while processing the rules for IN predicate, we compare the in-list types to the lhs expression type and generate cast operation if necessary. In the case of NULL [NOT] IN expr1 , we end up generating cast between in list types to NULL like cast (1 as NULL) which is not a valid cast. The fix is to not generate such a cast if the lhs type is a NullType instead we translate the expression to Literal(Null). Author: Dilip Biswal <[email protected]> Closes #8983 from dilipbiswal/spark_8654.
1 parent 5c9fdf7 commit dcbd58a

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/HiveTypeCoercion.scala

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,15 +304,21 @@ object HiveTypeCoercion {
304304
}
305305

306306
/**
307-
* Convert all expressions in in() list to the left operator type
307+
* Convert the value and in list expressions to the common operator type
308+
* by looking at all the argument types and finding the closest one that
309+
* all the arguments can be cast to. When no common operator type is found
310+
* an Analysis Exception is raised.
308311
*/
309312
object InConversion extends Rule[LogicalPlan] {
310313
def apply(plan: LogicalPlan): LogicalPlan = plan resolveExpressions {
311314
// Skip nodes who's children have not been resolved yet.
312315
case e if !e.childrenResolved => e
313316

314317
case i @ In(a, b) if b.exists(_.dataType != a.dataType) =>
315-
i.makeCopy(Array(a, b.map(Cast(_, a.dataType))))
318+
findWiderCommonType(i.children.map(_.dataType)) match {
319+
case Some(finalDataType) => i.withNewChildren(i.children.map(Cast(_, finalDataType)))
320+
case None => i
321+
}
316322
}
317323
}
318324

sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/AnalysisSuite.scala

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,4 +135,25 @@ class AnalysisSuite extends AnalysisTest {
135135
plan = testRelation.select(CreateStructUnsafe(Seq(a, (a + 1).as("a+1"))).as("col"))
136136
checkAnalysis(plan, plan)
137137
}
138+
139+
test("SPARK-8654: invalid CAST in NULL IN(...) expression") {
140+
val plan = Project(Alias(In(Literal(null), Seq(Literal(1), Literal(2))), "a")() :: Nil,
141+
LocalRelation()
142+
)
143+
assertAnalysisSuccess(plan)
144+
}
145+
146+
test("SPARK-8654: different types in inlist but can be converted to a commmon type") {
147+
val plan = Project(Alias(In(Literal(null), Seq(Literal(1), Literal(1.2345))), "a")() :: Nil,
148+
LocalRelation()
149+
)
150+
assertAnalysisSuccess(plan)
151+
}
152+
153+
test("SPARK-8654: check type compatibility error") {
154+
val plan = Project(Alias(In(Literal(null), Seq(Literal(true), Literal(1))), "a")() :: Nil,
155+
LocalRelation()
156+
)
157+
assertAnalysisError(plan, Seq("data type mismatch: Arguments must be same type"))
158+
}
138159
}

0 commit comments

Comments
 (0)