davidm-db commented on code in PR #49427:
URL: https://github.com/apache/spark/pull/49427#discussion_r1916568838


##########
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 would say this depends on how "statement defined in its own body" is 
interpreted from the perspective of nested handlers:
   - if it means only statements from the handler, and not from the nested ones 
(which I think doesn't make sense), then the search for the handler should 
start from the second to last frame (i.e. skipping the frame of the current 
handler).
   - if it means all statements that are descendants of the handler, than the 
search should start from the parent scope of the scope where the first handler 
is defined. I think this makes most sense and easily solves all the problems.
   
   Let's see what @srielau has to say on the interpretation of this rule.



-- 
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]

Reply via email to