diff --git a/src/pl/ob_pl_code_generator.cpp b/src/pl/ob_pl_code_generator.cpp index 57f486954..5f18621b9 100644 --- a/src/pl/ob_pl_code_generator.cpp +++ b/src/pl/ob_pl_code_generator.cpp @@ -408,6 +408,18 @@ int ObPLCodeGenerateVisitor::visit(const ObPLAssignStmt &s) p_result_obj))) { LOG_WARN("failed to generate calc_expr func", K(ret)); } + if (lib::is_mysql_mode()) { + ObLLVMValue ret_err; + ObSEArray args; + OZ (args.push_back(generator_.get_vars().at(generator_.CTX_IDX))); + OZ (generator_.get_helper().create_call(ObString("spi_clear_diagnostic_area"), + generator_.get_spi_service().spi_clear_diagnostic_area_, + args, + ret_err)); + OZ (generator_.check_success(ret_err, s.get_stmt_id(), + s.get_block()->in_notfound(), + s.get_block()->in_warning())); + } } if (OB_FAIL(ret)) { } else if (OB_FAIL(ObObjAccessIdx::datum_need_copy(into_expr, value_expr, alloc_scop))) { diff --git a/src/sql/engine/cmd/ob_get_diagnostics_executor.cpp b/src/sql/engine/cmd/ob_get_diagnostics_executor.cpp index da7f56572..ebf2f65b1 100644 --- a/src/sql/engine/cmd/ob_get_diagnostics_executor.cpp +++ b/src/sql/engine/cmd/ob_get_diagnostics_executor.cpp @@ -403,14 +403,14 @@ int ObGetDiagnosticsExecutor::execute(ObExecContext &ctx, ObGetDiagnosticsStmt & LOG_TRACE("condition num is invalid"); LOG_USER_WARN(OB_ERR_INVALID_CONDITION_NUMBER); } else { + int err_ret; + ObString err_msg, err_msg_c, sqlstate, sqlstate_c; ObSqlString query_virtual; if (OB_FAIL(query_virtual.assign_fmt( "select message, ori_code, sql_state from %s.%s limit %ld, 1", OB_SYS_DATABASE_NAME, OB_TENANT_VIRTUAL_WARNING_TNAME, restored_arg - 1))) { LOG_WARN("assign fmt failed", K(ret)); } else { - int err_ret; - ObString err_msg, err_msg_c, sqlstate, sqlstate_c; SMART_VAR(ObISQLClient::ReadResult, res) { common::sqlclient::ObMySQLResult *result = NULL; if (OB_FAIL(conn->execute_read(tenant_id, query_virtual.ptr(), res))) { @@ -423,7 +423,7 @@ int ObGetDiagnosticsExecutor::execute(ObExecContext &ctx, ObGetDiagnosticsStmt & EXTRACT_INT_FIELD_MYSQL(*result, "ori_code", err_ret, int); EXTRACT_VARCHAR_FIELD_MYSQL(*result, "sql_state", sqlstate); if (OB_FAIL(ret)) { - } else if (OB_FAIL(ob_write_string(ctx.get_allocator(), err_msg, err_msg_c, true))) { + } else if (OB_FAIL(ob_write_string(ctx.get_allocator(), err_msg, err_msg_c, true))) { //when using ptr(), char *'s end should be '\0' LOG_WARN("ob write string failed", K(ret)); } else if (OB_FAIL(ob_write_string(ctx.get_allocator(), sqlstate, sqlstate_c, true))) { @@ -432,8 +432,8 @@ int ObGetDiagnosticsExecutor::execute(ObExecContext &ctx, ObGetDiagnosticsStmt & } } } - OZ (assign_condition_val(ctx, stmt, session_info, conn, err_ret, err_msg_c, sqlstate_c)); } + OZ (assign_condition_val(ctx, stmt, session_info, conn, err_ret, err_msg_c, sqlstate_c)); } } else if (stmt.get_diagnostics_type() == DiagnosticsType::GET_STACKED_COND) { int64_t restored_arg = 0; diff --git a/src/sql/ob_spi.cpp b/src/sql/ob_spi.cpp index 16e24dd58..4eb5b77a5 100644 --- a/src/sql/ob_spi.cpp +++ b/src/sql/ob_spi.cpp @@ -802,6 +802,8 @@ int ObSPIService::spi_calc_expr(ObPLExecCtx *ctx, } if (OB_SUCC(ret)) { result->set_is_pl_mock_default_param(expr->get_is_pl_mock_default_expr()); + } else if (lib::is_mysql_mode()) { + ctx->exec_ctx_->get_my_session()->set_show_warnings_buf(ret); } SET_SPI_STATUS; return ret; @@ -3207,6 +3209,9 @@ int ObSPIService::spi_cursor_open(ObPLExecCtx *ctx, } } } + if (OB_FAIL(ret) && lib::is_mysql_mode()) { + ctx->exec_ctx_->get_my_session()->set_show_warnings_buf(ret); + } SET_SPI_STATUS; return ret; } @@ -3725,6 +3730,10 @@ int ObSPIService::spi_cursor_fetch(ObPLExecCtx *ctx, is_bulk, limit)); + if (OB_FAIL(ret) && lib::is_mysql_mode()) { + ctx->exec_ctx_->get_my_session()->set_show_warnings_buf(ret); + } + if (lib::is_mysql_mode() || OB_READ_NOTHING != ret) { //Oracle模式的cursor发生NOT FOUND错误的时候不对外报错,而是把错误信息记录在CURSOR上,PL的CG会吞掉这个错误 SET_SPI_STATUS; diff --git a/src/sql/parser/parse_define.h b/src/sql/parser/parse_define.h index 1c64e6245..628a5ab6a 100644 --- a/src/sql/parser/parse_define.h +++ b/src/sql/parser/parse_define.h @@ -35,4 +35,5 @@ static const int32_t OB_PARSER_ERR_NO_ATTR_FOUND = -9650; static const int32_t OB_PARSER_ERR_NON_INT_LITERAL = -9605; static const int32_t OB_PARSER_ERR_NUMERIC_OR_VALUE_ERROR = -5677; static const int32_t OB_PARSER_ERR_NON_INTEGRAL_NUMERIC_LITERAL = -9670; +static const int32_t OB_PARSER_ERR_UNDECLARED_VAR = -5543; #endif /*OCEANBASE_SQL_PARSER_PARSE_DEFINE_*/ diff --git a/src/sql/parser/sql_parser_base.h b/src/sql/parser/sql_parser_base.h index 435aea1c9..cd29e5414 100644 --- a/src/sql/parser/sql_parser_base.h +++ b/src/sql/parser/sql_parser_base.h @@ -111,6 +111,16 @@ int add_alias_name(ParseNode *node, ParseResult *result, int end); return ERROR; \ } while(0) +#define YYABORT_UNDECLARE_VAR \ + do { \ + if (OB_UNLIKELY(NULL == result)) { \ + (void)fprintf(stderr, "ERROR : result is NULL\n"); \ + } else if (0 == result->extra_errno_) { \ + result->extra_errno_ = OB_PARSER_ERR_UNDECLARED_VAR;\ + } else {/*do nothing*/} \ + YYABORT; \ + } while(0) + #define YYABORT_NOT_VALID_ROUTINE_NAME \ do { \ if (OB_UNLIKELY(NULL == result)) { \ @@ -386,7 +396,7 @@ do { } while (0) //查找pl变量,并把该变量替换成:int形式 -#define lookup_pl_exec_symbol(node, result, start, end, is_trigger_new, is_add_alas_name) \ +#define lookup_pl_exec_symbol(node, result, start, end, is_trigger_new, is_add_alas_name, is_report_error) \ do { \ if (OB_UNLIKELY((NULL == node || NULL == result || NULL == node->str_value_))) { \ yyerror(NULL, result, "invalid var node: %p\n", node); \ @@ -430,6 +440,8 @@ do { result->no_param_sql_[result->no_param_sql_len_++] = ':'; \ result->no_param_sql_len_ += sprintf(result->no_param_sql_ + result->no_param_sql_len_, "%ld", idx); \ store_pl_symbol(node, result->param_nodes_, result->tail_param_node_); \ + } else if (is_report_error) { \ + YYABORT_UNDECLARE_VAR; \ } else { /*do nothing*/ } \ } \ } while (0) diff --git a/src/sql/parser/sql_parser_mysql_mode.y b/src/sql/parser/sql_parser_mysql_mode.y index 584f14f54..701cc2fff 100644 --- a/src/sql/parser/sql_parser_mysql_mode.y +++ b/src/sql/parser/sql_parser_mysql_mode.y @@ -753,7 +753,7 @@ column_name malloc_non_terminal_node($$, result->malloc_pool_, T_COLUMN_REF, 3, NULL, NULL, $1); dup_node_string($1, $$, result->malloc_pool_); #ifndef SQL_PARSER_COMPILATION - lookup_pl_exec_symbol($$, result, @1.first_column, @1.last_column, false, false); + lookup_pl_exec_symbol($$, result, @1.first_column, @1.last_column, false, false, false); #endif } | relation_name '.' column_name @@ -763,7 +763,7 @@ column_name #ifndef SQL_PARSER_COMPILATION if (3 == $1->str_len_) { if (0 == strcasecmp("NEW", $1->str_value_) || 0 == strcasecmp("OLD", $1->str_value_)) { - lookup_pl_exec_symbol($$, result, @1.first_column, @3.last_column, true, false); + lookup_pl_exec_symbol($$, result, @1.first_column, @3.last_column, true, false, false); } } #endif @@ -848,7 +848,7 @@ column_name malloc_non_terminal_node($$, result->malloc_pool_, T_COLUMN_REF, 3, NULL, NULL, col_name); dup_node_string(col_name, $$, result->malloc_pool_); #ifndef SQL_PARSER_COMPILATION - lookup_pl_exec_symbol($$, result, @1.first_column, @1.last_column, false, false); + lookup_pl_exec_symbol($$, result, @1.first_column, @1.last_column, false, false, false); #endif } else { yyerror(&@1, result, "force key work can be used to be name in PL\n"); @@ -862,7 +862,7 @@ column_name malloc_non_terminal_node($$, result->malloc_pool_, T_COLUMN_REF, 3, NULL, NULL, col_name); dup_node_string(col_name, $$, result->malloc_pool_); #ifndef SQL_PARSER_COMPILATION - lookup_pl_exec_symbol($$, result, @1.first_column, @1.last_column, false, false); + lookup_pl_exec_symbol($$, result, @1.first_column, @1.last_column, false, false, false); #endif } else { yyerror(&@1, result, "cascade key work can be used to be name in PL\n"); @@ -9085,7 +9085,7 @@ expr %prec LOWER_PARENS NULL != $1->children_[2] && T_STAR == $1->children_[2]->type_) { /* do nothing */ } else { - lookup_pl_exec_symbol($$, result, @1.first_column, @1.last_column, false, true); + lookup_pl_exec_symbol($$, result, @1.first_column, @1.last_column, false, true, false); } #endif } @@ -10578,7 +10578,7 @@ INTNUM $$ = $1; if (result->pl_parse_info_.is_pl_parse_) { #ifndef SQL_PARSER_COMPILATION - lookup_pl_exec_symbol($$, result, @1.first_column, @1.last_column, false, false); + lookup_pl_exec_symbol($$, result, @1.first_column, @1.last_column, false, false, false); #endif } } @@ -10683,7 +10683,7 @@ column_name $$ = $1; if (result->pl_parse_info_.is_pl_parse_) { #ifndef SQL_PARSER_COMPILATION - lookup_pl_exec_symbol($$, result, @1.first_column, @1.last_column, false, false); + lookup_pl_exec_symbol($$, result, @1.first_column, @1.last_column, false, false, true); #endif } } @@ -15733,7 +15733,7 @@ new_or_old_column_ref: malloc_non_terminal_node($$, result->malloc_pool_, T_COLUMN_REF, 3, NULL, $1, $3); dup_node_string($3, $$, result->malloc_pool_); #ifndef SQL_PARSER_COMPILATION - lookup_pl_exec_symbol($$, result, @1.first_column, @3.last_column, true, false); + lookup_pl_exec_symbol($$, result, @1.first_column, @3.last_column, true, false, false); #endif } diff --git a/src/sql/resolver/cmd/ob_get_diagnostics_resolver.cpp b/src/sql/resolver/cmd/ob_get_diagnostics_resolver.cpp index f82cbb5f1..9463c19e1 100644 --- a/src/sql/resolver/cmd/ob_get_diagnostics_resolver.cpp +++ b/src/sql/resolver/cmd/ob_get_diagnostics_resolver.cpp @@ -116,7 +116,7 @@ int ObGetDiagnosticsResolver::resolve(const ParseNode &parse_tree) OB_ISNULL(var = item->children_[0]) || OB_ISNULL(val = item->children_[1])) { ret = OB_ERR_UNEXPECTED; LOG_WARN("parser tree is wrong", K(ret)); - } else if (NULL == session_info_->get_pl_context() && T_IDENT == var->type_) { + } else if (T_IDENT == var->type_) { ret = OB_ERR_SP_UNDECLARED_VAR; LOG_WARN("undeclared var", K(ret)); LOG_USER_ERROR(OB_ERR_SP_UNDECLARED_VAR, static_cast(var->str_len_), var->str_value_);