srielau commented on code in PR #49427:
URL: https://github.com/apache/spark/pull/49427#discussion_r1920517706
##########
sql/core/src/main/scala/org/apache/spark/sql/scripting/SqlScriptingExecutionContext.scala:
##########
@@ -81,12 +107,79 @@ class SqlScriptingExecutionFrame(
scopes.remove(scopes.length - 1)
}
}
+
+ def findHandler(condition: String, sqlState: String):
Option[ErrorHandlerExec] = {
+ if (scopes.isEmpty) {
+ throw SparkException.internalError(s"Cannot find handler: no scopes.")
+ }
+
+ scopes.reverseIterator.foreach { scope =>
+ val handler = scope.findHandler(condition, sqlState)
+ if (handler.isDefined) {
+ return handler
+ }
+ }
+ None
+ }
}
/**
* SQL scripting execution scope - keeps track of the current execution scope.
*
* @param label
* Label of the scope.
+ * @param conditionHandlerMap
+ * Map holding condition/sqlState to handler mapping.
+ * @return
+ * Handler for the given condition.
*/
-class SqlScriptingExecutionScope(val label: String)
+class SqlScriptingExecutionScope(
+ val label: String,
+ val conditionHandlerMap: HashMap[String, ErrorHandlerExec]) {
+
+ /**
+ * Finds the most appropriate error handler for exception based on its
condition and SQL state.
+ *
+ * The method follows these rules to determine the most appropriate handler:
+ * 1. Specific named condition handlers (e.g., DIVIDE_BY_ZERO) are checked
first.
+ * 2. If no specific condition handler is found, SQLSTATE handlers are
checked.
+ * 3. For SQLSTATEs starting with '02', a generic NOT FOUND handler is used
if available.
+ * 4. For other SQLSTATEs (except those starting with 'XX' or '02'), a
generic SQLEXCEPTION
+ * handler is used if available.
+ *
+ * Note: Handlers defined in the innermost compound statement where the
exception was raised
+ * are considered.
+ *
+ * @param condition Error condition of the exception to find handler for.
+ * @param sqlState SQLSTATE of the exception to find handler for.
+ *
+ * @return Handler for the given condition if exists.
+ */
+ def findHandler(condition: String, sqlState: String):
Option[ErrorHandlerExec] = {
+ // Check if there is a specific handler for the given condition.
+ conditionHandlerMap.get(condition)
Review Comment:
I found the SQL Ref was poorly worded and I have fixed it as such:
The following are used to decide which condition handler applies to an
exception. This condition handler is called the "most appropriate handler":
1. A condition handler cannot apply to any statement defined in its own body
or the body of any condition handler declared in the same compound statement.
2. The applicable condition handlers defined in the innermost compound
statement within which the exception was raised are appropriate.
3. If more than one appropriate handler is available, the most specific
handler is the most appropriate. For example, a handler on a named condition is
more specific than one on a named SQLSTATE. A generic EXCEPTION or NOT FOUND
handler is the least specific.
Rephrased this means we search from the innermost compound towards the
outermost.
The moment we find at least one applicable handler we stop that that
compound and we pick the most specific of the lot.
So if we have a "divide by zero" named condition handler in an outer
compound and a SQLEXCEPTION in the inner, then the SQLEXCEPTION handler is more
appropriate fro a division by zero exception because it is closer.
If they are defined in teh same compound then the specific condition handler
wins over SQLEXCEPTION.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]