[to #46045492] fix serval signal/resignal issues
This commit is contained in:
parent
4d6995673a
commit
4226320168
@ -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_));
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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_; }
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user