Skip to content

Commit c2305ed

Browse files
vladimirg-dbMaxGekk
authored andcommitted
[SPARK-51900][SQL] Properly throw datatype mismatch in single-pass Analyzer
### What changes were proposed in this pull request? Properly throw datatype mismatch in single-pass Analyzer. Currently we don't have a way to pass a resolved operator to `failOnTypeCheckResult`, so we pass `None` - this simply omits the `issueFixedIfAnsiOff` functionality. ### Why are the changes needed? This improves error message reporting in single-pass Analyzer. ### Does this PR introduce _any_ user-facing change? No. ### How was this patch tested? Existing tests. ### Was this patch authored or co-authored using generative AI tooling? No. Closes #50697 from vladimirg-db/vladimir-golubev_data/throw-datatype-mismatch-in-single-pass-analyzer. Authored-by: Vladimir Golubev <vladimir.golubev@databricks.com> Signed-off-by: Max Gekk <max.gekk@gmail.com>
1 parent 1c1d80f commit c2305ed

File tree

3 files changed

+8
-3
lines changed

3 files changed

+8
-3
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ trait CheckAnalysis extends LookupCatalog with QueryErrorsBase with PlanToString
409409
throw QueryCompilationErrors.windowSpecificationNotDefinedError(windowName)
410410

411411
case e: Expression if e.checkInputDataTypes().isFailure =>
412-
TypeCoercionValidation.failOnTypeCheckResult(e, operator)
412+
TypeCoercionValidation.failOnTypeCheckResult(e, Some(operator))
413413

414414
case c: Cast if !c.resolved =>
415415
throw SparkException.internalError(

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@ import org.apache.spark.sql.types.DataType
2727
object TypeCoercionValidation extends QueryErrorsBase {
2828
private val DATA_TYPE_MISMATCH_ERROR = TreeNodeTag[Unit]("dataTypeMismatchError")
2929

30-
def failOnTypeCheckResult(e: Expression, operator: LogicalPlan): Nothing = {
30+
def failOnTypeCheckResult(e: Expression, operator: Option[LogicalPlan] = None): Nothing = {
3131
e.checkInputDataTypes() match {
3232
case checkRes: TypeCheckResult.DataTypeMismatch =>
3333
e.setTagValue(DATA_TYPE_MISMATCH_ERROR, ())
3434
e.dataTypeMismatch(e, checkRes)
3535
case TypeCheckResult.TypeCheckFailure(message) =>
3636
e.setTagValue(DATA_TYPE_MISMATCH_ERROR, ())
37-
val extraHint = TypeCoercionValidation.getHintForExpressionCoercion(operator)
37+
val extraHint = operator.map(getHintForExpressionCoercion(_)).getOrElse("")
3838
e.failAnalysis(
3939
errorClass = "DATATYPE_MISMATCH.TYPE_CHECK_FAILURE_WITH_HINT",
4040
messageParameters = Map("sqlExpr" -> toSQLExpr(e), "msg" -> message, "hint" -> extraHint)

sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/resolver/ExpressionResolver.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import org.apache.spark.sql.catalyst.analysis.{
2828
withPosition,
2929
FunctionResolution,
3030
GetViewColumnByNameAndOrdinal,
31+
TypeCoercionValidation,
3132
UnresolvedAlias,
3233
UnresolvedAttribute,
3334
UnresolvedFunction,
@@ -984,6 +985,10 @@ class ExpressionResolver(
984985
}
985986

986987
private def validateResolvedExpressionGenerically(resolvedExpression: Expression): Unit = {
988+
if (resolvedExpression.checkInputDataTypes().isFailure) {
989+
TypeCoercionValidation.failOnTypeCheckResult(resolvedExpression)
990+
}
991+
987992
if (!resolvedExpression.resolved) {
988993
throwSinglePassFailedToResolveExpression(resolvedExpression)
989994
}

0 commit comments

Comments
 (0)