提交 7e5730a2 编写于 作者: O obdev 提交者: wangzelin.wzl

[to #45186814] fix continue handler in mysql pl

上级 a3f0115f
......@@ -421,7 +421,12 @@ int ObPLResolver::resolve(const ObStmtNodeTree *parse_tree, ObPLFunctionAST &fun
LOG_WARN("fail to check decalre order", K(ret));
} else if (OB_FAIL(resolve_declare_handler(parse_tree, static_cast<ObPLDeclareHandlerStmt*>(NULL == stmt ? current_block_->get_eh() : stmt), func))) {
LOG_WARN("failed to resolve declare handler stmt", K(parse_tree), K(stmt), K(ret));
} else {
} else if (stmt != NULL && static_cast<ObPLDeclareHandlerStmt*>(stmt)->get_handlers().count() <= 0) {
// continue handler will record into handler_analyzer_,
// so here handlers may null, do not add null handler to current block.
stmt = NULL;
}
if (OB_SUCC(ret)) {
func.set_is_all_sql_stmt(false);
}
}
......@@ -645,7 +650,7 @@ int ObPLResolver::resolve(const ObStmtNodeTree *parse_tree, ObPLFunctionAST &fun
}
if (OB_SUCC(ret) && handler_analyzer_.in_continue() && NULL != stmt && !NO_EXCEPTION_STMT(stmt->get_type())) {
//如果自己在continue里,那么把栈里的handler都加到block里
// for continue handler, should add handler to every stmt, here, make a new block, consturct new block with handler and stmt.
ObPLStmtBlock *block = NULL;
if (OB_FAIL(make_block(func, current_block_, block))) {
LOG_WARN("failed to make block", K(current_block_), K(ret));
......@@ -990,10 +995,22 @@ int ObPLResolver::check_declare_order(ObPLStmtType type)
CK(PL_VAR == type || PL_COND == type || PL_HANDLER == type || PL_CURSOR == type);
if (is_oracle_mode()) {
// oracle compatible, do nothing ...
} else if (OB_NOT_NULL(current_block_) && current_block_->get_stmts().count() != 0) {
ObPLStmtType pre_type =
current_block_->get_stmts().at(current_block_->get_stmts().count() - 1)->get_type();
if ((PL_VAR == type || PL_COND == type)
} else {
ObPLStmtType pre_type = INVALID_PL_STMT;
if (OB_NOT_NULL(current_block_) && (current_block_->get_stmts().count() != 0)) {
pre_type =
current_block_->get_stmts().at(current_block_->get_stmts().count() - 1)->get_type();
}
if (handler_analyzer_.get_stack_depth() > 0) {
ObPLDeclareHandlerStmt::DeclareHandler info;
if (OB_FAIL(handler_analyzer_.get_handler(handler_analyzer_.get_stack_depth() - 1, info))) {
LOG_WARN("failed to get last handler", K(ret));
} else if (info.get_level() == current_level_) {
pre_type = PL_HANDLER;
}
}
if (OB_FAIL(ret)) {
} else if ((PL_VAR == type || PL_COND == type)
&& (PL_HANDLER == pre_type || PL_CURSOR == pre_type)) {
ret = OB_ER_SP_VARCOND_AFTER_CURSHNDLR;
LOG_USER_ERROR(OB_ER_SP_VARCOND_AFTER_CURSHNDLR);
......@@ -5202,15 +5219,16 @@ int ObPLResolver::resolve_declare_handler(const ObStmtNodeTree *parse_tree, ObPL
ret = OB_ERR_NO_CHOICES;
LOG_WARN("no choices may appear with choice OTHERS in an exception handler",
K(ret));
} else if (OB_FAIL(desc->add_condition(value))) {
LOG_WARN("failed to add condition for delcare handler desc", K(ret), K(value));
} else {
desc->add_condition(value);
if (NOT_FOUND == actual_type && !handler_analyzer_.in_notfound()) {
handler_analyzer_.set_notfound(current_level_);
current_block_->set_notfound();
} else if (SQL_WARNING == actual_type && !handler_analyzer_.in_warning()) {
handler_analyzer_.set_warning(current_level_);
current_block_->set_warning();
} else { /*do nothing*/ }
}
}
}
}
......@@ -5235,17 +5253,19 @@ int ObPLResolver::resolve_declare_handler(const ObStmtNodeTree *parse_tree, ObPL
}
}
if (OB_SUCC(ret)) {
if (OB_SUCC(ret) && !desc->is_continue()) {
ObPLDeclareHandlerStmt::DeclareHandler handler;
handler.set_desc(desc);
OZ (stmt->add_handler(handler));
if (OB_FAIL(stmt->add_handler(handler))) {
LOG_WARN("failed to add handler", K(ret));
}
}
if (OB_SUCC(ret)) {
if (OB_ISNULL(current_block_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("Symbol table is NULL", K(current_block_), K(ret));
} else {
} else if (stmt->get_handlers().count() > 0) {
current_block_->set_eh(stmt);
}
}
......@@ -12194,7 +12214,7 @@ int ObPLResolver::check_duplicate_condition(const ObPLDeclareHandlerStmt &stmt,
{
int ret = OB_SUCCESS;
dup = false;
for (int64_t i = 0; !dup && i < stmt.get_handlers().count(); ++i) {
for (int64_t i = 0; OB_SUCC(ret) && !dup && i < stmt.get_handlers().count(); ++i) {
ObPLDeclareHandlerStmt::DeclareHandler::HandlerDesc *desc = stmt.get_handler(i).get_desc();
if (OB_ISNULL(desc)) {
ret = OB_ERR_UNEXPECTED;
......@@ -12210,6 +12230,29 @@ int ObPLResolver::check_duplicate_condition(const ObPLDeclareHandlerStmt &stmt,
}
}
}
for (int64_t i = handler_analyzer_.get_stack_depth() - 1; OB_SUCC(ret) && !dup && i >= 0; --i) {
ObPLDeclareHandlerStmt::DeclareHandler handler;
if (OB_FAIL(handler_analyzer_.get_handler(i, handler))) {
LOG_WARN("failed to get handler from handler analyzer", K(ret), K(i));
} else if (handler.get_level() == current_level_) {
ObPLDeclareHandlerStmt::DeclareHandler::HandlerDesc *desc = handler.get_desc();
if (OB_ISNULL(desc)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("Handler desc is NULL", K(ret), K(i), K(handler));
} else if (desc->is_continue()) {
for (int64_t j = 0; !dup && j < desc->get_conditions().count(); ++j) {
if (value.type_ == desc->get_condition(j).type_ &&
value.error_code_ == desc->get_condition(j).error_code_ &&
value.str_len_ == desc->get_condition(j).str_len_ &&
0 == STRNCMP(value.sql_state_, desc->get_condition(j).sql_state_, value.str_len_)) {
dup = true;
}
}
}
} else {
break;
}
}
return ret;
}
......@@ -12431,7 +12474,12 @@ int ObPLResolver::HandlerAnalyzer::reset_handlers(int64_t level)
int ret = OB_SUCCESS;
for (int64_t i = handler_stack_.count() - 1; OB_SUCC(ret) && i >= 0; --i) {
if (handler_stack_.at(i).get_level() == level) {
handler_stack_.pop_back();
if (i != handler_stack_.count() -1) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("failed to reset handlers with level", K(ret), K(level), K(i), K(handler_stack_.at(i)));
} else {
handler_stack_.pop_back();
}
}
}
if (OB_SUCC(ret) && handler_stack_.count() - 1 < top_continue_) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册