miland-db commented on code in PR #49427:
URL: https://github.com/apache/spark/pull/49427#discussion_r1930566230
##########
sql/core/src/main/scala/org/apache/spark/sql/scripting/SqlScriptingExecutionContext.scala:
##########
@@ -81,12 +124,97 @@ class SqlScriptingExecutionFrame(
scopes.remove(scopes.length - 1)
}
}
+
+ // TODO: Introduce a separate class for different frame types (Script,
Stored Procedure,
+ // Error Handler) implementing SqlScriptingExecutionFrame interface.
+ def findHandler(
+ condition: String,
+ sqlState: String,
+ firstHandlerScopeLabel: Option[String]): Option[ErrorHandlerExec] = {
+
+ val searchScopes = if (frameType == SqlScriptingFrameType.HANDLER) {
+ // If the frame is a handler, search for the handler in its body. Don't
skip any scopes.
+ scopes.reverseIterator
+ } else if (firstHandlerScopeLabel.isEmpty) {
+ // If no handler is active, search for the handler from the current
scope.
+ // Don't skip any scopes.
+ scopes.reverseIterator
+ } else {
+ // Drop all scopes until the first most outer scope where an active
handler is defined.
+ // Drop one more scope to start searching from the surrounding scope.
+ scopes.reverseIterator.dropWhile(_.label !=
firstHandlerScopeLabel.get).drop(1)
+ }
+
+ // In the remaining scopes, try to find the most appropriate handler.
+ searchScopes.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 triggerHandlerMap
+ * Object holding condition/sqlState/sqlexception/not found to handler
mapping.
*/
-class SqlScriptingExecutionScope(val label: String)
+class SqlScriptingExecutionScope(
+ val label: String,
+ val triggerHandlerMap: TriggerHandlerMap) {
+
+ /**
+ * 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.
+ var errorHandler: Option[ErrorHandlerExec] = None
+
+ errorHandler = triggerHandlerMap.getHandlerForCondition(condition)
Review Comment:
Let's add improvements in follow-up PRs. I did it this way for clarity so
everyone can be sure what we are trying to achieve. I agree that more
scala-idiomatic code is better, but I would leave this change for some other
PR. @dusantism-db
--
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]