Skip to content

Commit cb77e4f

Browse files
committed
Improve error reporting for expression data type mismatch
1 parent a0e46a0 commit cb77e4f

File tree

9 files changed

+276
-250
lines changed

9 files changed

+276
-250
lines changed

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,15 @@ trait CheckAnalysis {
6262
val from = operator.inputSet.map(_.name).mkString(", ")
6363
a.failAnalysis(s"cannot resolve '${a.prettyString}' given input columns $from")
6464

65+
case e: Expression if !e.validInputTypes =>
66+
e.failAnalysis(
67+
s"cannot resolve '${t.prettyString}' due to data type mismatch: " +
68+
e.typeMismatchErrorMessage.get)
69+
6570
case c: Cast if !c.resolved =>
6671
failAnalysis(
6772
s"invalid cast from ${c.child.dataType.simpleString} to ${c.dataType.simpleString}")
6873

69-
case b: BinaryExpression if !b.resolved =>
70-
failAnalysis(
71-
s"invalid expression ${b.prettyString} " +
72-
s"between ${b.left.dataType.simpleString} and ${b.right.dataType.simpleString}")
73-
7474
case WindowExpression(UnresolvedWindowFunction(name, _), _) =>
7575
failAnalysis(
7676
s"Could not resolve window function '$name'. " +

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ trait HiveTypeCoercion {
407407
Union(newLeft, newRight)
408408

409409
// fix decimal precision for expressions
410-
case q => q.transformExpressions {
410+
case q => q.transformExpressionsUp {
411411
// Skip nodes whose children have not been resolved yet
412412
case e if !e.childrenResolved => e
413413

sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Expression.scala

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,16 @@ abstract class Expression extends TreeNode[Expression] {
8686
case (i1, i2) => i1 == i2
8787
}
8888
}
89+
90+
def typeMismatchErrorMessage: Option[String] = None
91+
92+
def validInputTypes: Boolean = typeMismatchErrorMessage.isEmpty
8993
}
9094

9195
abstract class BinaryExpression extends Expression with trees.BinaryNode[Expression] {
9296
self: Product =>
9397

94-
def symbol: String
98+
def symbol: String = sys.error(s"BinaryExpressions must either override toString or symbol")
9599

96100
override def foldable: Boolean = left.foldable && right.foldable
97101

@@ -106,6 +110,10 @@ abstract class LeafExpression extends Expression with trees.LeafNode[Expression]
106110

107111
abstract class UnaryExpression extends Expression with trees.UnaryNode[Expression] {
108112
self: Product =>
113+
114+
override def foldable: Boolean = child.foldable
115+
116+
override def nullable: Boolean = child.nullable
109117
}
110118

111119
// TODO Semantically we probably not need GroupExpression
@@ -125,7 +133,9 @@ case class GroupExpression(children: Seq[Expression]) extends Expression {
125133
* so that the proper type conversions can be performed in the analyzer.
126134
*/
127135
trait ExpectsInputTypes {
136+
self: Expression =>
128137

129138
def expectedChildTypes: Seq[DataType]
130139

140+
override def validInputTypes: Boolean = children.map(_.dataType) == expectedChildTypes
131141
}

0 commit comments

Comments
 (0)