From fd9a01c2dbad3ebdd7188aaec9a75838eff97813 Mon Sep 17 00:00:00 2001 From: Vladimir Golubev Date: Mon, 16 Sep 2024 08:50:11 +0000 Subject: [PATCH] Add a nice user-facing error for scalar subqueries inside VALUES clause --- .../src/main/resources/error/error-conditions.json | 6 ++++++ .../spark/sql/catalyst/analysis/CheckAnalysis.scala | 11 +++++++++++ .../spark/sql/errors/QueryCompilationErrors.scala | 8 ++++++++ 3 files changed, 25 insertions(+) diff --git a/common/utils/src/main/resources/error/error-conditions.json b/common/utils/src/main/resources/error/error-conditions.json index 38472f44fb599..466728ea58a1f 100644 --- a/common/utils/src/main/resources/error/error-conditions.json +++ b/common/utils/src/main/resources/error/error-conditions.json @@ -1821,6 +1821,12 @@ ], "sqlState" : "42704" }, + "INLINE_TABLE_CONTAINS_SCALAR_SUBQUERY" : { + "message" : [ + "Scalar subqueries inside VALUES clause are not supported" + ], + "sqlState" : "0A000" + }, "INSERT_COLUMN_ARITY_MISMATCH" : { "message" : [ "Cannot write to , the reason is" 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 a9fbe548ba39e..cb4bf491fded1 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 @@ -250,6 +250,9 @@ trait CheckAnalysis extends PredicateHelper with LookupCatalog with QueryErrorsB context = u.origin.getQueryContext, summary = u.origin.context.summary) + case u: UnresolvedInlineTable if unresolvedInlineTableContainsScalarSubquery(u) => + throw QueryCompilationErrors.inlineTableContainsScalarSubquery(u) + case command: V2PartitionCommand => command.table match { case r @ ResolvedTable(_, _, table, _) => table match { @@ -1559,6 +1562,14 @@ trait CheckAnalysis extends PredicateHelper with LookupCatalog with QueryErrorsB case _ => } } + + private def unresolvedInlineTableContainsScalarSubquery( + unresolvedInlineTable: UnresolvedInlineTable + ) = { + unresolvedInlineTable.rows.exists { row => + row.exists { _.isInstanceOf[ScalarSubquery] } + } + } } // a heap of the preempted error that only keeps the top priority element, representing the sole diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryCompilationErrors.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryCompilationErrors.scala index f1f8be3d15751..202897b3c48ac 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryCompilationErrors.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryCompilationErrors.scala @@ -4112,4 +4112,12 @@ private[sql] object QueryCompilationErrors extends QueryErrorsBase with Compilat "expr" -> expr.toString), origin = expr.origin) } + + def inlineTableContainsScalarSubquery(inlineTable: LogicalPlan): Throwable = { + new AnalysisException( + errorClass = "INLINE_TABLE_CONTAINS_SCALAR_SUBQUERY", + messageParameters = Map(), + origin = inlineTable.origin + ) + } }