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 @@ -300,12 +300,21 @@ class AstBuilder extends DataTypeAstBuilder
parsingCtx)
} else {
// If there is no compound body, then there must be a statement or set statement.
// Single-statement handler bodies need a label for the CompoundBody, just like
// BEGIN-END blocks do (see visitBeginEndCompoundBlockImpl). Generate a random UUID
// label since no explicit label is defined.
val labelText = parsingCtx.labelContext.enterLabeledScope(
beginLabelCtx = None,
endLabelCtx = None
)
val statement = Option(ctx.statement().asInstanceOf[ParserRuleContext])
.orElse(Option(ctx.setStatementInsideSqlScript().asInstanceOf[ParserRuleContext]))
.map { s =>
SingleStatement(parsedPlan = visit(s).asInstanceOf[LogicalPlan])
}
CompoundBody(Seq(statement.get), None, isScope = false)
val compoundBody = CompoundBody(Seq(statement.get), Some(labelText), isScope = false)
parsingCtx.labelContext.exitLabeledScope(None)
compoundBody
}

ExceptionHandler(exceptionHandlerTriggers, body, handlerType)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1323,6 +1323,89 @@ class SqlScriptingExecutionSuite extends QueryTest with SharedSparkSession {
verifySqlScriptResult(sqlScript, expected = expected)
}

test("exit handler body without BEGIN-END propagates error properly") {
val sqlScript =
"""
|BEGIN
| DECLARE EXIT HANDLER FOR SQLEXCEPTION
| INSERT INTO test_table_non_existing VALUES(1, 2, 3);
|
| SELECT 1/0;
|END
|""".stripMargin
val exception = intercept[AnalysisException] {
verifySqlScriptResult(sqlScript, Seq.empty)
}
checkError(
exception = exception,
condition = "TABLE_OR_VIEW_NOT_FOUND",
sqlState = Some("42P01"),
parameters = Map("relationName" -> toSQLId("test_table_non_existing")),
context = ExpectedContext(
fragment = "test_table_non_existing",
start = 63,
stop = 85)
)
}

test("continue handler body without BEGIN-END propagates error properly") {
val sqlScript =
"""
|BEGIN
| DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
| INSERT INTO test_table_non_existing VALUES(1, 2, 3);
|
| SELECT 1/0;
|END
|""".stripMargin
val exception = intercept[AnalysisException] {
verifySqlScriptResult(sqlScript, Seq.empty)
}
checkError(
exception = exception,
condition = "TABLE_OR_VIEW_NOT_FOUND",
sqlState = Some("42P01"),
parameters = Map("relationName" -> toSQLId("test_table_non_existing")),
context = ExpectedContext(
fragment = "test_table_non_existing",
start = 67,
stop = 89)
)
}

test("exit handler body without BEGIN-END executes properly") {
val sqlScript =
"""
|BEGIN
| DECLARE EXIT HANDLER FOR SQLEXCEPTION
| SELECT 1;
|
| SELECT 1/0;
| SELECT 2;
|END
|""".stripMargin
val expected = Seq(Seq(Row(1)))
verifySqlScriptResult(sqlScript, expected)
}

test("continue handler body without BEGIN-END executes properly") {
val sqlScript =
"""
|BEGIN
| DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
| SELECT 1;
|
| SELECT 1/0;
| SELECT 2;
|END
|""".stripMargin
val expected = Seq(
Seq(Row(1)), // select from handler
Seq(Row(2)) // select
)
verifySqlScriptResult(sqlScript, expected)
}

// Tests
test("multi statement - simple") {
withTable("t") {
Expand Down