[to #46045492] fix serval signal/resignal issues

This commit is contained in:
obdev 2022-12-28 03:11:50 +00:00 committed by ob-robot
parent 4d6995673a
commit 4226320168
8 changed files with 115 additions and 52 deletions

View File

@ -2290,30 +2290,30 @@ int ObPLCodeGenerateVisitor::visit(const ObPLSignalStmt &s)
OZ (generator_.generate_goto_label(s));
ObLLVMBasicBlock normal;
ObLLVMType unwind_exception_type, unwind_exception_pointer_type;
ObLLVMType condition_type;
ObLLVMType condition_pointer_type;
ObLLVMValue unwindException = generator_.get_saved_exception();
ObLLVMValue ob_error_code = generator_.get_saved_ob_error();
ObLLVMValue unwind_exception_header;
ObLLVMValue condition;
ObLLVMValue sql_state;
ObLLVMValue error_code;
OZ (generator_.get_adt_service().get_unwind_exception(unwind_exception_type));
OZ (unwind_exception_type.get_pointer_to(unwind_exception_pointer_type));
OZ (generator_.get_adt_service().get_pl_condition_value(condition_type));
OZ (condition_type.get_pointer_to(condition_pointer_type));
if (OB_FAIL(ret)) {
} else if (s.is_signal_null()) {
ObLLVMValue null_sql_state, status;
ObLLVMValue unwindException = generator_.get_saved_exception();
ObLLVMValue ob_error_code = generator_.get_saved_ob_error();
ObLLVMType unwind_exception_type, unwind_exception_pointer_type;
ObLLVMValue unwind_exception_header;
ObLLVMType condition_type;
ObLLVMType condition_pointer_type;
ObLLVMValue condition;
ObLLVMValue sql_state;
ObLLVMValue error_code;
ObLLVMValue status;
CK (OB_NOT_NULL(generator_.get_saved_exception().get_v()));
CK (OB_NOT_NULL(generator_.get_saved_ob_error().get_v()));
OZ (generator_.extract_status_from_context(generator_.get_vars().at(generator_.CTX_IDX), status));
OZ (generator_.get_helper().create_store(ob_error_code, status));
OZ (generator_.get_adt_service().get_unwind_exception(unwind_exception_type));
OZ (unwind_exception_type.get_pointer_to(unwind_exception_pointer_type));
OZ (generator_.get_helper().create_const_gep1_64(ObString("extract_unwind_exception_header"),
unwindException,
generator_.get_eh_service().pl_exception_base_offset_,
unwind_exception_header));
OZ (generator_.get_adt_service().get_pl_condition_value(condition_type));
OZ (condition_type.get_pointer_to(condition_pointer_type));
OZ (generator_.get_helper().create_pointer_cast(ObString("cast_header"),
unwind_exception_header,
condition_pointer_type,
@ -2328,16 +2328,19 @@ int ObPLCodeGenerateVisitor::visit(const ObPLSignalStmt &s)
s.get_block()->in_notfound(), s.get_block()->in_warning(), true));
OZ (generator_.set_current(normal));
} else {
ObLLVMValue type, ob_err_code, err_code, sql_state, str_len, is_signal, stmt_id, loc;
ObLLVMValue type, ob_err_code, err_code, sql_state, str_len, is_signal, stmt_id, loc, err_code_ptr;
if (lib::is_mysql_mode() && (s.is_resignal_stmt() || s.get_cond_type() != ERROR_CODE)) {
ObLLVMValue int_value;
ObLLVMType int_type;
ObLLVMType int_type, int32_type, int32_type_ptr;
ObSEArray<ObLLVMValue, 5> args;
int64_t *err_idx = const_cast<int64_t *>(s.get_expr_idx(
static_cast<int64_t>(SignalCondInfoItem::DIAG_MYSQL_ERRNO)));
int64_t *msg_idx = const_cast<int64_t *>(s.get_expr_idx(
static_cast<int64_t>(SignalCondInfoItem::DIAG_MESSAGE_TEXT)));
OZ (generator_.get_helper().get_llvm_type(ObIntType, int_type));
OZ (generator_.get_helper().get_llvm_type(ObInt32Type, int32_type));
OZ (int32_type.get_pointer_to(int32_type_ptr));
OZ (args.push_back(generator_.get_vars().at(generator_.CTX_IDX)));
OZ (generator_.generate_pointer(NULL != err_idx ? generator_.get_expr(*err_idx) : NULL, int_value));
OZ (args.push_back(int_value));
@ -2345,14 +2348,38 @@ int ObPLCodeGenerateVisitor::visit(const ObPLSignalStmt &s)
OZ (args.push_back(int_value));
OZ (generator_.generate_string(ObString(s.get_str_len(), s.get_sql_state()), sql_state, str_len));
OZ (args.push_back(sql_state));
OZ (generator_.get_helper().create_alloca(ObString("error_code"), int_type, err_code_ptr));
if (s.is_resignal_stmt()) {
// ObLLVMValue code_ptr;
CK (OB_NOT_NULL(generator_.get_saved_exception().get_v()));
CK (OB_NOT_NULL(generator_.get_saved_ob_error().get_v()));
OZ (generator_.get_helper().create_const_gep1_64(ObString("extract_unwind_exception_header"),
unwindException,
generator_.get_eh_service().pl_exception_base_offset_,
unwind_exception_header));
OZ (generator_.get_helper().create_pointer_cast(ObString("cast_header"),
unwind_exception_header,
condition_pointer_type,
condition));
OZ (generator_.extract_name_from_condition_value(condition, sql_state));
OZ (generator_.extract_code_from_condition_value(condition, error_code));
OZ (generator_.get_helper().create_store(error_code, err_code_ptr));
} else {
OZ (generator_.get_helper().get_int64(OB_SUCCESS, err_code));
OZ (generator_.get_helper().create_store(err_code, err_code_ptr));
}
OZ (args.push_back(err_code_ptr));
OZ (args.push_back(sql_state));
OZ (generator_.get_helper().get_int8(!s.is_resignal_stmt(), is_signal));
OZ (args.push_back(is_signal));
OZ (generator_.get_helper().create_call(ObString("spi_process_resignal"),
generator_.get_spi_service().spi_process_resignal_error_,
args,
ob_err_code));
OZ (generator_.get_helper().get_llvm_type(ObIntType, int_type));
OZ (generator_.get_helper().create_sext(ObString("sext to int64"), ob_err_code, int_type, err_code));
OZ (generator_.check_success(ob_err_code, s.get_stmt_id(), s.get_block()->in_notfound(), s.get_block()->in_warning()));
OZ (generator_.get_helper().create_load(ObString("load_error_code"), err_code_ptr, err_code));
OZ (generator_.get_helper().create_bit_cast(ObString("cast_int64_to_int32"), err_code_ptr, int32_type_ptr, err_code_ptr));
OZ (generator_.get_helper().create_load(ObString("load_error_code"), err_code_ptr, ob_err_code));
} else {
OZ (generator_.get_helper().get_int32(s.get_ob_error_code(), ob_err_code));
OZ (generator_.get_helper().get_int64(s.get_error_code(), err_code));
@ -3803,6 +3830,8 @@ int ObPLCodeGenerator::init_spi_service()
OZ (arg_types.push_back(int64_type));
OZ (arg_types.push_back(int64_type));
OZ (arg_types.push_back(char_type));
OZ (arg_types.push_back(int_pointer_type));
OZ (arg_types.push_back(char_type));
OZ (arg_types.push_back(bool_type));
OZ (ObLLVMFunctionType::get(int32_type, arg_types, ft));
OZ (helper_.create_function(ObString("spi_process_resignal"), ft, spi_service_.spi_process_resignal_error_));

View File

@ -81,16 +81,30 @@ int ObPLEH::eh_convert_exception(bool oracle_mode, int oberr, ObPLConditionType
*error_code = oberr;
*type = ERROR_CODE;
} else {
if (oberr < 0) {
*error_code = ob_mysql_errno(oberr);
if (-1 == *error_code) {
if (OB_SP_RAISE_APPLICATION_ERROR == oberr) {
ObWarningBuffer *wb = NULL;
CK (OB_NOT_NULL(wb = common::ob_get_tsi_warning_buffer()));
OX (*error_code = wb->get_err_code());
OX (*sql_state = wb->get_sql_state());
OX (*str_len = STRLEN(*sql_state));
if (OB_FAIL(ret)) {
} else if (-1 == *error_code) {
*type = SQL_STATE;
} else {
*type = ERROR_CODE;
}
} else {
*error_code = oberr;
*type = SQL_STATE;
if (oberr < 0) {
*error_code = ob_mysql_errno(oberr);
if (-1 == *error_code) {
*type = SQL_STATE;
} else {
*type = ERROR_CODE;
}
} else {
*error_code = oberr;
*type = SQL_STATE;
}
}
}
}

View File

@ -5182,13 +5182,21 @@ int ObPLResolver::resolve_declare_handler(const ObStmtNodeTree *parse_tree, ObPL
LOG_WARN("Invalid else node", K(parse_tree->children_[1]->type_), K(ret));
} else {
ObPLStmtBlock *body_block = NULL;
int64_t top_continue = handler_analyzer_.get_continue();
++current_level_;
handler_analyzer_.set_continue(OB_INVALID_INDEX);
if (OB_FAIL(resolve_stmt_list(parse_tree->children_[1],
body_block,
func,
true,/*stop scarch label*/
true /*in exception handler scope*/))) {
LOG_WARN("failed to resolve stmt list", K(parse_tree->children_[1]->type_), K(ret));
} else if (OB_FAIL(handler_analyzer_.reset_handlers(current_level_))) {
LOG_WARN("failed to reset handlers", K(ret), K(current_level_));
} else {
--current_level_;
handler_analyzer_.reset_notfound_and_warning(current_level_);
handler_analyzer_.set_continue(top_continue);
desc->set_body(body_block);
}
}

View File

@ -153,6 +153,7 @@ public:
inline void set_warning(int64_t level) { top_warning_level_ = level; }
inline int64_t get_continue() { return top_continue_; }
inline void set_continue() { top_continue_ = handler_stack_.count() - 1; }
inline void set_continue(int64_t top_continue) { top_continue_ = top_continue; }
inline int64_t get_stack_depth() { return handler_stack_.count(); }
inline bool in_continue() { return OB_INVALID_INDEX != top_continue_; }
inline bool in_notfound() { return OB_INVALID_INDEX != top_notfound_level_; }

View File

@ -993,7 +993,7 @@ int ObPLBlockNS::add_label(const ObString &name,
LOG_USER_ERROR(OB_ERR_IDENTIFIER_TOO_LONG, name.length(), name.ptr());
} else {
bool is_dup = false;
if (OB_FAIL(check_dup_label(name, is_dup, true))) {
if (OB_FAIL(check_dup_label(name, is_dup))) {
LOG_INFO("check dup label fail. ", K(ret), K(name));
} else if (is_dup) {
ret = OB_ERR_REDEFINE_LABEL;
@ -1218,29 +1218,29 @@ int ObPLBlockNS::check_dup_symbol(const ObString &name, const ObPLDataType &type
return ret;
}
int ObPLBlockNS::check_dup_label(const ObString &name, bool &is_dup, bool check_parent) const
int ObPLBlockNS::check_dup_label(const ObString &name, bool &is_dup) const
{
int ret = OB_SUCCESS;
is_dup = false;
if (lib::is_oracle_mode()) {
// do nothing
} else if (OB_ISNULL(label_table_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("label table is NULL", K(ret));
} else {
const ObPLBlockNS *ns = check_parent ? pre_ns_ : this;
while (NULL != ns && !is_dup && !ns->stop_search_label()) {
const ObPLBlockNS *ns = this;
while (NULL != ns && !is_dup) {
for (int64_t i = 0; OB_SUCC(ret) && !is_dup && i < ns->get_labels().count(); ++i) {
if (OB_ISNULL(ns->get_label_table()->get_label(ns->get_labels().at(i)))) {
if (OB_ISNULL(ns->get_label_table())
|| OB_ISNULL(ns->get_label_table()->get_label(ns->get_labels().at(i)))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("label is NULL", K(i), K(ns->get_labels().at(i)), K(ret));
} else if (*ns->get_label_table()->get_label(ns->get_labels().at(i)) == name &&
ns->get_label_table()->is_ended(ns->get_labels().at(i)) == false) {
} else if (*ns->get_label_table()->get_label(ns->get_labels().at(i)) == name
&& ns->get_label_table()->is_ended(ns->get_labels().at(i)) == false) {
is_dup = true;
} else { /*do nothing*/ }
}
}
if (!is_dup && check_parent) {
if (!is_dup && !ns->stop_search_label()) {
ns = ns->get_pre_ns();
} else {
break;
}
}
}

View File

@ -1281,7 +1281,7 @@ public:
inline const ObPLExternalNS *get_external_ns() const { return external_ns_; }
inline void set_external_ns(ObPLExternalNS *external_ns) { external_ns_ = external_ns; }
int check_dup_symbol(const ObString &name, const ObPLDataType &type, bool &is_dup) const;
int check_dup_label(const ObString &name, bool &is_dup, bool check_parent) const;
int check_dup_label(const ObString &name, bool &is_dup) const;
int check_dup_goto_label(const ObString &name, bool &is_dup) const;
int check_dup_condition(const ObString &name, bool &is_dup, const void *&dup_item) const;
int check_dup_cursor(const ObString &name, bool &is_dup) const;

View File

@ -4168,10 +4168,12 @@ int ObSPIService::spi_raise_application_error(pl::ObPLExecCtx *ctx,
}
int ObSPIService::spi_process_resignal(pl::ObPLExecCtx *ctx,
const ObSqlExpression *errcode_expr,
const ObSqlExpression *errmsg_expr,
const char *sql_state,
bool is_signal)
const ObSqlExpression *errcode_expr,
const ObSqlExpression *errmsg_expr,
const char *sql_state,
int *error_code,
const char *resignal_sql_state,
bool is_signal)
{
int ret = OB_SUCCESS;
ObObjParam result;
@ -4187,6 +4189,7 @@ int ObSPIService::spi_process_resignal(pl::ObPLExecCtx *ctx,
CK (OB_NOT_NULL(session_info = ctx->exec_ctx_->get_my_session()));
CK (OB_NOT_NULL(sqlcode_info = ctx->exec_ctx_->get_my_session()->get_pl_sqlcode_info()));
CK (OB_NOT_NULL(wb = common::ob_get_tsi_warning_buffer()));
CK (OB_NOT_NULL(error_code));
#define CALC(expr, type, result) \
do { \
@ -4197,17 +4200,22 @@ int ObSPIService::spi_process_resignal(pl::ObPLExecCtx *ctx,
OX (expected_type.set_collation_type(tmp.get_collation_type())); \
OZ (spi_convert(ctx->exec_ctx_->get_my_session(), ctx->allocator_, tmp, expected_type, result)); \
} while(0)
if (OB_SUCC(ret)) {
type = ObPLEH::eh_classify_exception(sql_state);
cur_err_code = wb->get_err_code();
}
if (OB_ISNULL(errcode_expr)) {
if (type == ObPLConditionType::NOT_FOUND) {
sqlcode_info->set_sqlcode(ER_SIGNAL_NOT_FOUND);
if (OB_FAIL(ret)) {
} else if (OB_ISNULL(errcode_expr)) {
if (!is_signal && *error_code != -1 && NULL == sql_state) {
sqlcode_info->set_sqlcode(*error_code);
} else {
sqlcode_info->set_sqlcode(ER_SIGNAL_EXCEPTION);
if (type == ObPLConditionType::NOT_FOUND) {
sqlcode_info->set_sqlcode(ER_SIGNAL_NOT_FOUND);
} else {
sqlcode_info->set_sqlcode(ER_SIGNAL_EXCEPTION);
}
}
LOG_INFO("error code is not set", K(ret));
} else {
CALC(errcode_expr, int32, result);
if (OB_SUCC(ret)) {
@ -4269,7 +4277,6 @@ int ObSPIService::spi_process_resignal(pl::ObPLExecCtx *ctx,
sqlcode_info->set_sqlcode(OB_SUCCESS);
wb->reset_err();
}
ret = OB_SUCCESS;
} else {
if (is_signal) {
LOG_MYSQL_USER_ERROR(OB_SP_RAISE_APPLICATION_ERROR,
@ -4279,9 +4286,11 @@ int ObSPIService::spi_process_resignal(pl::ObPLExecCtx *ctx,
wb->set_sql_state(sql_state);
} else {
wb->set_error(err_msg, sqlcode_info->get_sqlcode());
wb->set_sql_state(sql_state != NULL ? sql_state : ob_sqlstate(cur_err_code));
wb->set_sql_state(sql_state != NULL
? sql_state
: (resignal_sql_state != NULL) ? resignal_sql_state : ob_sqlstate(cur_err_code));
}
ret = sqlcode_info->get_sqlcode();
*error_code = sqlcode_info->get_sqlcode();
}
}
return ret;

View File

@ -388,10 +388,12 @@ public:
const ObSqlExpression *errmsg_expr);
static int spi_process_resignal(pl::ObPLExecCtx *ctx,
const ObSqlExpression *errcode_expr,
const ObSqlExpression *errmsg_expr,
const char *sql_state = NULL,
bool is_signal = false);
const ObSqlExpression *errcode_expr,
const ObSqlExpression *errmsg_expr,
const char *sql_state,
int *error_code,
const char *resignal_sql_state,
bool is_signal);
static int spi_delete_collection(pl::ObPLExecCtx *ctx,
const ObSqlExpression *collection_expr,