davidm-db commented on code in PR #49726: URL: https://github.com/apache/spark/pull/49726#discussion_r1938482763
########## sql/core/src/main/scala/org/apache/spark/sql/scripting/SqlScriptingExecutionNode.scala: ########## @@ -966,3 +994,85 @@ class ForStatementExec( body.reset() } } + +/** + * Executable node for ErrorHandlerStatement. + * @param body Executable CompoundBody of the error handler. + * @param handlerType Handler type: EXIT, CONTINUE. + * @param scopeLabel Label of the scope where handler is defined. + */ +class ErrorHandlerExec( + val body: CompoundBodyExec, + val handlerType: HandlerType, + val scopeLabel: Option[String]) extends NonLeafStatementExec { + + override def getTreeIterator: Iterator[CompoundStatementExec] = body.getTreeIterator + + override def reset(): Unit = body.reset() +} + +/** + * Executable node for Signal Statement. + * @param errorCondition Name of the error condition/SQL State for error that will be thrown. + * @param sqlState SQL State of the error that will be thrown. + * @param message Error message (either string or variable name). + * @param session Spark session that SQL script is executed within. + */ +class SignalStatementExec( + val errorCondition: Option[String] = None, + val sqlState: Option[String] = None, + val message: Either[String, UnresolvedAttribute], + val session: SparkSession) + extends LeafStatementExec + with ColumnResolutionHelper { + + override def catalogManager: CatalogManager = session.sessionState.catalogManager + override def conf: SQLConf = session.sessionState.conf + + def getMessageText: String = { + message match { + case Left(v) => v + case Right(u) => + val varReference = getVariableReference(u, u.nameParts) + + if (!varReference.dataType.sameType(StringType)) { + throw QueryCompilationErrors.invalidExecuteImmediateVariableType(varReference.dataType) + } + + // Call eval with null value passed instead of a row. + // This is ok as this is variable and invoking eval should + // be independent of row value. + val varReferenceValue = varReference.eval(null) + + if (varReferenceValue == null) { + throw QueryCompilationErrors.nullSQLStringExecuteImmediate(u.name) + } + + varReferenceValue.toString + } + } + + private def getVariableReference(expr: Expression, nameParts: Seq[String]): VariableReference = { + lookupVariable(nameParts) match { + case Some(variable) => variable + case _ => + throw QueryCompilationErrors + .unresolvedVariableError( + nameParts, + Seq(CatalogManager.SYSTEM_CATALOG_NAME, CatalogManager.SESSION_NAMESPACE), + expr.origin) + } + } + + private[scripting] def getException: SqlScriptingRuntimeException = { + new SqlScriptingRuntimeException( + condition = errorCondition.getOrElse("USER_RAISED_EXCEPTION"), + sqlState = sqlState, + message = getMessageText, + cause = null, + origin = CurrentOrigin.get Review Comment: this ain't right, will update the comment tomorrow, writing just so it doesn't get forgotten -- 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: reviews-unsubscr...@spark.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: reviews-unsubscr...@spark.apache.org For additional commands, e-mail: reviews-h...@spark.apache.org