Github user rxin commented on a diff in the pull request:
https://github.com/apache/spark/pull/7348#discussion_r34648784
--- Diff:
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/HiveTypeCoercion.scala
---
@@ -672,20 +659,44 @@ object HiveTypeCoercion {
}
/**
- * Casts types according to the expected input types for Expressions
that have the trait
- * [[ExpectsInputTypes]].
+ * Casts types according to the expected input types for [[Expression]]s.
*/
object ImplicitTypeCasts extends Rule[LogicalPlan] {
def apply(plan: LogicalPlan): LogicalPlan = plan
transformAllExpressions {
// Skip nodes who's children have not been resolved yet.
case e if !e.childrenResolved => e
- case e: ExpectsInputTypes if (e.inputTypes.nonEmpty) =>
+ case b @ BinaryOperator(left, right) if left.dataType !=
right.dataType =>
+ findTightestCommonTypeOfTwo(left.dataType, right.dataType).map {
commonType =>
+ if (b.inputType.acceptsType(commonType)) {
+ // If the expression accepts the tighest common type, cast to
that.
+ val newLeft = if (left.dataType == commonType) left else
Cast(left, commonType)
+ val newRight = if (right.dataType == commonType) right else
Cast(right, commonType)
+ b.makeCopy(Array(newLeft, newRight))
+ } else {
+ // Otherwise, don't do anything with the expression.
+ b
+ }
+ }.getOrElse(b) // If there is no applicable conversion, leave
expression unchanged.
+
+ case e: ImplicitCastInputTypes if e.inputTypes.nonEmpty =>
val children: Seq[Expression] = e.children.zip(e.inputTypes).map {
case (in, expected) =>
// If we cannot do the implicit cast, just use the original
input.
implicitCast(in, expected).getOrElse(in)
}
e.withNewChildren(children)
+
+ case e: ExpectsInputTypes if e.inputTypes.nonEmpty =>
+ // Convert NullType into some specific target type for
ExpectsInputTypes that don't do
+ // general implicit casting.
+ val children: Seq[Expression] = e.children.zip(e.inputTypes).map {
case (in, expected) =>
+ if (in.dataType == NullType && !expected.acceptsType(NullType)) {
+ Cast(in, expected.defaultConcreteType)
+ } else {
--- End diff --
that happens during CheckAnalysis when we report errors.
---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at [email protected] or file a JIRA ticket
with INFRA.
---
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]