Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,12 @@ class SqlScriptingExecution(

currExecPlan match {
case exec: ConditionalStatementExec =>
exec.interrupted = true
// Only interrupt if the conditional statement is currently evaluating its condition.
// For loop statements, this means we should skip the loop when an exception occurs
// during condition evaluation, but NOT when an exception occurs in the loop body.
if (exec.isInCondition) {
exec.interrupted = true
}
case _ =>
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,22 @@ trait ConditionalStatementExec extends NonLeafStatementExec {
* HANDLER.
*/
protected[scripting] var interrupted: Boolean = false

/**
* Returns true if the conditional statement is currently evaluating its condition,
* false if it's executing its body. This is used by CONTINUE HANDLER to determine
* whether to interrupt the conditional statement when an exception occurs.
*
* For loop statements (WHILE, REPEAT, FOR), this should return true when evaluating
* the loop condition and false when executing the loop body. This distinction is
* critical because:
* - Exception in condition: loop should be skipped (interrupted)
* - Exception in body: loop should continue to next iteration (not interrupted)
*
* For IF/CASE statements, this should return true when evaluating the condition
* expression and false when executing any branch body.
*/
protected[scripting] def isInCondition: Boolean
}

/**
Expand Down Expand Up @@ -481,6 +497,8 @@ class IfElseStatementExec(

override def getTreeIterator: Iterator[CompoundStatementExec] = treeIterator

override protected[scripting] def isInCondition: Boolean = state == IfElseState.Condition

override def reset(): Unit = {
state = IfElseState.Condition
curr = Some(conditions.head)
Expand Down Expand Up @@ -567,6 +585,8 @@ class WhileStatementExec(

override def getTreeIterator: Iterator[CompoundStatementExec] = treeIterator

override protected[scripting] def isInCondition: Boolean = state == WhileState.Condition

override def reset(): Unit = {
state = WhileState.Condition
curr = Some(condition)
Expand Down Expand Up @@ -656,6 +676,8 @@ class SearchedCaseStatementExec(

override def getTreeIterator: Iterator[CompoundStatementExec] = treeIterator

override protected[scripting] def isInCondition: Boolean = state == CaseState.Condition

override def reset(): Unit = {
state = CaseState.Condition
curr = Some(conditions.head)
Expand Down Expand Up @@ -795,6 +817,8 @@ class SimpleCaseStatementExec(

override def getTreeIterator: Iterator[CompoundStatementExec] = treeIterator

override protected[scripting] def isInCondition: Boolean = state == CaseState.Condition

override def reset(): Unit = {
state = CaseState.Condition
bodyExec = None
Expand Down Expand Up @@ -882,6 +906,8 @@ class RepeatStatementExec(

override def getTreeIterator: Iterator[CompoundStatementExec] = treeIterator

override protected[scripting] def isInCondition: Boolean = state == RepeatState.Condition

override def reset(): Unit = {
state = RepeatState.Body
curr = Some(body)
Expand Down Expand Up @@ -1218,6 +1244,8 @@ class ForStatementExec(

override def getTreeIterator: Iterator[CompoundStatementExec] = treeIterator

override protected[scripting] def isInCondition: Boolean = state == ForState.VariableAssignment

override def reset(): Unit = {
state = ForState.VariableAssignment
isResultCacheValid = false
Expand Down
Loading