diff --git a/src/observer/virtual_table/ob_mysql_proc_table.cpp b/src/observer/virtual_table/ob_mysql_proc_table.cpp index 1b5cecc4fe..8fadc46e25 100644 --- a/src/observer/virtual_table/ob_mysql_proc_table.cpp +++ b/src/observer/virtual_table/ob_mysql_proc_table.cpp @@ -99,6 +99,19 @@ int ObMySQLProcTable::inner_get_next_row(common::ObNewRow *&row) } common::ObArenaAllocator local_allocator; + ParseNode *create_node = nullptr; + + if (OB_FAIL(ret)) { + // do nothing + } else if (routine_info->get_routine_body().prefix_match_ci("procedure") + || routine_info->get_routine_body().prefix_match_ci("function")) { + if (OB_FAIL(extract_create_node_from_routine_info( + local_allocator, *routine_info, exec_env, create_node))) { + SERVER_LOG(WARN, "failed to extract create node from routine info", + K(ret), K(*routine_info), K(exec_env), K(create_node)); + } + } + for (int64_t col_idx = 0; OB_SUCC(ret) && col_idx < output_column_ids_.count(); ++col_idx) { const uint64_t col_id = output_column_ids_.at(col_idx); switch (col_id) { @@ -123,26 +136,51 @@ int ObMySQLProcTable::inner_get_next_row(common::ObNewRow *&row) break; } case (PARAM_LIST): { - char *param_list_buf = NULL; - int64_t param_list_buf_size = OB_MAX_VARCHAR_LENGTH; - if (OB_UNLIKELY(NULL == (param_list_buf - = static_cast(local_allocator.alloc(param_list_buf_size))))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - SERVER_LOG(ERROR, "fail to alloc param_list_buf", K(ret)); - } else { - ObSchemaPrinter schema_printer(*schema_guard_); - int64_t pos = 0; - if (OB_FAIL(schema_printer.print_routine_definition_param(*routine_info, - NULL, - param_list_buf, - OB_MAX_VARCHAR_LENGTH, - pos, - TZ_INFO(session_)))) { - SERVER_LOG(WARN, "Generate table definition failed"); + if (nullptr != create_node) { + if (T_SP_CREATE != create_node->type_ && T_SF_CREATE != create_node->type_ && OB_ISNULL(create_node->children_[2])) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "unexpected parse node type of routine body", K(create_node->type_)); } else { - ObString value_str(static_cast(pos), static_cast(pos), param_list_buf); - cells[col_idx].set_varchar(value_str); - cells[col_idx].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + ParseNode *param_node = create_node->children_[2]; + ObString value_str; + if (param_node != nullptr) { + if (OB_FAIL(ob_write_string( + *allocator_, + ObString(min(OB_MAX_VARCHAR_LENGTH, param_node->str_len_), + param_node->str_value_), + value_str))) { + SERVER_LOG(WARN, "failed to ob_write_string", + K(ret), + K(param_node->str_len_), + K(param_node->str_value_), + K(value_str)); + } + } + OX (cells[col_idx].set_varchar(value_str)); + OX (cells[col_idx].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset()))); + } + } else { + char *param_list_buf = NULL; + int64_t param_list_buf_size = OB_MAX_VARCHAR_LENGTH; + if (OB_UNLIKELY(NULL == (param_list_buf + = static_cast(allocator_->alloc(param_list_buf_size))))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + SERVER_LOG(WARN, "fail to alloc param_list_buf", K(ret)); + } else { + ObSchemaPrinter schema_printer(*schema_guard_); + int64_t pos = 0; + if (OB_FAIL(schema_printer.print_routine_definition_param_v1(*routine_info, + NULL, + param_list_buf, + OB_MAX_VARCHAR_LENGTH, + pos, + TZ_INFO(session_)))) { + SERVER_LOG(WARN, "Generate table definition failed"); + } else { + ObString value_str(static_cast(pos), static_cast(pos), param_list_buf); + cells[col_idx].set_varchar(value_str); + cells[col_idx].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + } } } break; @@ -151,9 +189,9 @@ int ObMySQLProcTable::inner_get_next_row(common::ObNewRow *&row) char *returns_buf = NULL; int64_t returns_buf_size = OB_MAX_VARCHAR_LENGTH; int64_t pos = 0; - if (OB_UNLIKELY(NULL == (returns_buf = static_cast(local_allocator.alloc(returns_buf_size))))) { + if (OB_UNLIKELY(NULL == (returns_buf = static_cast(allocator_->alloc(returns_buf_size))))) { ret = OB_ALLOCATE_MEMORY_FAILED; - SERVER_LOG(ERROR, "fail to alloc returns_buf", K(ret)); + SERVER_LOG(WARN, "fail to alloc returns_buf", K(ret)); } else { if (routine_info->is_function()) { if (OB_FAIL(ob_sql_type_str(returns_buf, @@ -225,6 +263,36 @@ int ObMySQLProcTable::inner_get_next_row(common::ObNewRow *&row) cells[col_idx].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); break; } + case (BODY): + case (BODY_UTF8): { + if (nullptr != create_node) { + ParseNode *body_node = nullptr; + if (T_SP_CREATE != create_node->type_ && T_SF_CREATE != create_node->type_) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "unexpected parse node type of routine body", K(create_node->type_)); + } else if (FALSE_IT(body_node = create_node->type_ == T_SP_CREATE ? create_node->children_[4] : create_node->children_[5])) { + // do nothing + } else if (OB_ISNULL(body_node) || OB_ISNULL(body_node->raw_text_)) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "unexpected empty routine body", K(routine_info->get_routine_body())); + } else { + ObString value_str; + if (OB_FAIL(ob_write_string(*allocator_, + ObString(min(OB_MAX_VARCHAR_LENGTH, body_node->text_len_), body_node->raw_text_), + value_str))) { + SERVER_LOG(WARN, "failed to ob_write_string", K(ret), K(ObString(body_node->text_len_, body_node->raw_text_))); + } else { + cells[col_idx].set_varchar(value_str); + cells[col_idx].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + } + } + } else { + const ObString &body = routine_info->get_routine_body(); + cells[col_idx].set_varchar(body); + cells[col_idx].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + } + break; + } #define COLUMN_SET_WITH_TYPE(COL_NAME, TYPE, VALUE) \ case (COL_NAME): { \ @@ -239,11 +307,9 @@ case (COL_NAME): { \ COLUMN_SET_WITH_TYPE(LANGUAGE, varchar, "SQL") COLUMN_SET_WITH_TYPE(IS_DETERMINISTIC, varchar, routine_info->is_deterministic() ? "YES" : "NO") COLUMN_SET_WITH_TYPE(SECURITY_TYPE, varchar, routine_info->is_invoker_right() ? "INVOKER" : "DEFINER") - COLUMN_SET_WITH_TYPE(BODY, varchar, routine_info->get_routine_body()) COLUMN_SET_WITH_TYPE(CREATED, timestamp, OB_INVALID_TIMESTAMP) COLUMN_SET_WITH_TYPE(MODIFIED, timestamp, OB_INVALID_TIMESTAMP) COLUMN_SET_WITH_TYPE(COMMENT, varchar, routine_info->get_comment()) - COLUMN_SET_WITH_TYPE(BODY_UTF8, varchar, routine_info->get_routine_body()) #undef COLUMN_SET_WITH_TYPE @@ -284,6 +350,48 @@ case (COL_NAME): { \ return ret; } +int ObMySQLProcTable::extract_create_node_from_routine_info(ObIAllocator &alloc, const ObRoutineInfo &routine_info, const sql::ObExecEnv &exec_env, ParseNode *&create_node) { + int ret = OB_SUCCESS; + + ParseResult parse_result; + ObString routine_stmt; + pl::ObPLParser parser(alloc, CS_TYPE_UTF8MB4_BIN, exec_env.get_sql_mode()); + const ObString &routine_body = routine_info.get_routine_body(); + const char prefix[] = "CREATE\n"; + int64_t prefix_len = STRLEN(prefix); + int64_t buf_sz = prefix_len + routine_body.length(); + char *stmt_buf = static_cast(alloc.alloc(buf_sz)); + if (OB_ISNULL(stmt_buf)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + SERVER_LOG(WARN, "failed to allocate memory for routine body buffer", + K(buf_sz)); + } else { + MEMCPY(stmt_buf, prefix, prefix_len); + MEMCPY(stmt_buf + prefix_len, routine_body.ptr(), routine_body.length()); + routine_stmt.assign_ptr(stmt_buf, buf_sz); + } + + if (OB_FAIL(ret)) { + // do nothing + } else if (OB_FAIL(parser.parse(routine_stmt, routine_stmt, parse_result, true))) { + SERVER_LOG(WARN, "failed to parse mysql routine body", + K(ret), K(routine_info), K(routine_body)); + } + + if OB_SUCC(ret) { + if (OB_NOT_NULL(parse_result.result_tree_) && + T_STMT_LIST == parse_result.result_tree_->type_ && + 1 == parse_result.result_tree_->num_child_) { + create_node = parse_result.result_tree_->children_[0]; + } else { + create_node = nullptr; + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "unexpected parse node of mysql routine body", K(routine_info), K(routine_body), K(parse_result.result_tree_)); + } + } + + return ret; +} } } diff --git a/src/observer/virtual_table/ob_mysql_proc_table.h b/src/observer/virtual_table/ob_mysql_proc_table.h index dcc6bee7c3..02a88d4283 100644 --- a/src/observer/virtual_table/ob_mysql_proc_table.h +++ b/src/observer/virtual_table/ob_mysql_proc_table.h @@ -60,6 +60,8 @@ private: uint64_t tenant_id_; private: DISALLOW_COPY_AND_ASSIGN(ObMySQLProcTable); + + static int extract_create_node_from_routine_info(ObIAllocator &alloc, const ObRoutineInfo &routine_info, const sql::ObExecEnv &exec_env, ParseNode *&create_node); }; } } diff --git a/src/observer/virtual_table/ob_show_create_procedure.cpp b/src/observer/virtual_table/ob_show_create_procedure.cpp index cbb1d2aa78..72748e949c 100644 --- a/src/observer/virtual_table/ob_show_create_procedure.cpp +++ b/src/observer/virtual_table/ob_show_create_procedure.cpp @@ -151,24 +151,33 @@ int ObShowCreateProcedure::fill_row_cells(uint64_t show_procedure_id, const ObRo } case OB_APP_MIN_COLUMN_ID + 2: { // create_routine - ObSchemaPrinter schema_printer(*schema_guard_); - int64_t pos = 0; - if (OB_FAIL(schema_printer.print_routine_definition(effective_tenant_id_, - show_procedure_id, - routine_def_buf, - OB_MAX_VARCHAR_LENGTH, - pos, - TZ_INFO(session_)))) { - SERVER_LOG(WARN, "Generate table definition failed"); - } - if (OB_FAIL(ret)) { + bool sql_quote_show_create = true; + bool ansi_quotes = false; + if (OB_FAIL(session_->get_sql_quote_show_create(sql_quote_show_create))) { + SERVER_LOG(WARN, "failed to get sql_quote_show_create", K(ret), K(session_)); + } else if (FALSE_IT(IS_ANSI_QUOTES(session_->get_sql_mode(), ansi_quotes))) { // do nothing } else { - cur_row_.cells_[cell_idx].set_lob_value(ObLongTextType, - routine_def_buf, static_cast(pos)); + ObSchemaPrinter schema_printer(*schema_guard_, false, sql_quote_show_create, ansi_quotes); + int64_t pos = 0; + if (OB_FAIL(schema_printer.print_routine_definition(effective_tenant_id_, + show_procedure_id, + exec_env, + routine_def_buf, + OB_MAX_VARCHAR_LENGTH, + pos, + TZ_INFO(session_)))) { + SERVER_LOG(WARN, "Generate routine definition failed"); + } + if (OB_FAIL(ret)) { + // do nothing + } else { + cur_row_.cells_[cell_idx].set_lob_value(ObLongTextType, + routine_def_buf, static_cast(pos)); + } + OX (cur_row_.cells_[cell_idx].set_collation_type( + ObCharset::get_default_collation(ObCharset::get_default_charset()))); } - OX (cur_row_.cells_[cell_idx].set_collation_type( - ObCharset::get_default_collation(ObCharset::get_default_charset()))); break; } case OB_APP_MIN_COLUMN_ID + 3: { diff --git a/src/pl/parser/pl_parser_mysql_mode.y b/src/pl/parser/pl_parser_mysql_mode.y index bc73be32da..255c8ada28 100644 --- a/src/pl/parser/pl_parser_mysql_mode.y +++ b/src/pl/parser/pl_parser_mysql_mode.y @@ -556,6 +556,38 @@ call_sp_stmt: } $$ = $2; } + | CALL PROCEDURE sp_name '(' opt_sp_param_list ')' sp_create_chistics procedure_body + { + if (!parse_ctx->is_inner_parse_) { + obpl_mysql_yyerror(&@2, parse_ctx, "Syntax Error\n"); + YYERROR; //生成一个语法错误 + } + $$ = $8; + } + | CALL PROCEDURE sp_name '(' opt_sp_param_list ')' procedure_body + { + if (!parse_ctx->is_inner_parse_) { + obpl_mysql_yyerror(&@2, parse_ctx, "Syntax Error\n"); + YYERROR; //生成一个语法错误 + } + $$ = $7; + } + | CALL FUNCTION sp_name '(' opt_sp_fparam_list ')' RETURNS sp_data_type sp_create_chistics function_body + { + if (!parse_ctx->is_inner_parse_) { + obpl_mysql_yyerror(&@2, parse_ctx, "Syntax Error\n"); + YYERROR; //生成一个语法错误 + } + $$ = $10; + } + | CALL FUNCTION sp_name '(' opt_sp_fparam_list ')' RETURNS sp_data_type function_body + { + if (!parse_ctx->is_inner_parse_) { + obpl_mysql_yyerror(&@2, parse_ctx, "Syntax Error\n"); + YYERROR; //生成一个语法错误 + } + $$ = $9; + } ; opt_sp_cparam_list: @@ -1082,21 +1114,39 @@ create_procedure_stmt: check_ptr($9); ParseNode *sp_clause_node = NULL; merge_nodes(sp_clause_node, parse_ctx->mem_pool_, T_SP_CLAUSE_LIST, $8); - const char *stmt_str = parse_ctx->stmt_str_ + @9.first_column; - int32_t str_len = @9.last_column - @9.first_column + 1; + const char *stmt_str = parse_ctx->stmt_str_ + @3.first_column; + int32_t str_len = @9.last_column - @3.first_column + 1; $9->str_value_ = parse_strndup(stmt_str, str_len, parse_ctx->mem_pool_); check_ptr($9->str_value_); $9->str_len_ = str_len; + $9->raw_text_ = $9->str_value_ + @9.first_column - @3.first_column; + $9->text_len_ = str_len - (@9.first_column - @3.first_column); + if (NULL != $6) { + const char *param_str = parse_ctx->stmt_str_ + @5.first_column + 1; + int32_t param_len = @7.last_column - @5.last_column - 1; + $6->str_value_ = parse_strndup(param_str, param_len, parse_ctx->mem_pool_); + check_ptr($6->str_value_); + $6->str_len_ = param_len; + } malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_CREATE, 5, $2, $4, $6, sp_clause_node, $9); } - | CREATE opt_sp_definer PROCEDURE sp_name '('opt_sp_param_list ')' procedure_body + | CREATE opt_sp_definer PROCEDURE sp_name '(' opt_sp_param_list ')' procedure_body { check_ptr($8); - const char *stmt_str = parse_ctx->stmt_str_ + @8.first_column; - int32_t str_len = @8.last_column - @8.first_column + 1; + const char *stmt_str = parse_ctx->stmt_str_ + @3.first_column; + int32_t str_len = @8.last_column - @3.first_column + 1; $8->str_value_ = parse_strndup(stmt_str, str_len, parse_ctx->mem_pool_); check_ptr($8->str_value_); $8->str_len_ = str_len; + $8->raw_text_ = $8->str_value_ + @8.first_column - @3.first_column; + $8->text_len_ = str_len - (@8.first_column - @3.first_column); + if (NULL != $6) { + const char *param_str = parse_ctx->stmt_str_ + @5.first_column + 1; + int32_t param_len = @7.last_column - @5.last_column - 1; + $6->str_value_ = parse_strndup(param_str, param_len, parse_ctx->mem_pool_); + check_ptr($6->str_value_); + $6->str_len_ = param_len; + } malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SP_CREATE, 5, $2, $4, $6, NULL, $8); } ; @@ -1107,21 +1157,39 @@ create_function_stmt: check_ptr($11); ParseNode *sp_clause_node = NULL; merge_nodes(sp_clause_node, parse_ctx->mem_pool_, T_SP_CLAUSE_LIST, $10); - const char *stmt_str = parse_ctx->stmt_str_ + @11.first_column; - int32_t str_len = @11.last_column - @11.first_column + 1; + const char *stmt_str = parse_ctx->stmt_str_ + @3.first_column; + int32_t str_len = @11.last_column - @3.first_column + 1; $11->str_value_ = parse_strndup(stmt_str, str_len, parse_ctx->mem_pool_); check_ptr($11->str_value_); $11->str_len_ = str_len; + $11->raw_text_ = $11->str_value_ + @11.first_column - @3.first_column; + $11->text_len_ = str_len - (@11.first_column - @3.first_column); + if (NULL != $6) { + const char *param_str = parse_ctx->stmt_str_ + @5.first_column + 1; + int32_t param_len = @7.last_column - @5.last_column - 1; + $6->str_value_ = parse_strndup(param_str, param_len, parse_ctx->mem_pool_); + check_ptr($6->str_value_); + $6->str_len_ = param_len; + } malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SF_CREATE, 6, $2, $4, $6, $9, sp_clause_node, $11); } | CREATE opt_sp_definer FUNCTION sp_name '(' opt_sp_fparam_list ')' RETURNS sp_data_type function_body { check_ptr($10); - const char *stmt_str = parse_ctx->stmt_str_ + @10.first_column; - int32_t str_len = @10.last_column - @10.first_column + 1; + const char *stmt_str = parse_ctx->stmt_str_ + @3.first_column; + int32_t str_len = @10.last_column - @3.first_column + 1; $10->str_value_ = parse_strndup(stmt_str, str_len, parse_ctx->mem_pool_); check_ptr($10->str_value_); $10->str_len_ = str_len; + $10->raw_text_ = $10->str_value_ + @10.first_column - @3.first_column; + $10->text_len_ = str_len - (@10.first_column - @3.first_column); + if (NULL != $6) { + const char *param_str = parse_ctx->stmt_str_ + @5.first_column + 1; + int32_t param_len = @7.last_column - @5.last_column - 1; + $6->str_value_ = parse_strndup(param_str, param_len, parse_ctx->mem_pool_); + check_ptr($6->str_value_); + $6->str_len_ = param_len; + } malloc_non_terminal_node($$, parse_ctx->mem_pool_, T_SF_CREATE, 6, $2, $4, $6, $9, NULL, $10); } ; diff --git a/src/share/schema/ob_schema_printer.cpp b/src/share/schema/ob_schema_printer.cpp index f81fad0bbc..866bb5ca40 100644 --- a/src/share/schema/ob_schema_printer.cpp +++ b/src/share/schema/ob_schema_printer.cpp @@ -3900,7 +3900,7 @@ int ObSchemaPrinter::print_routine_param_type(const ObRoutineParam *param, return ret; } -int ObSchemaPrinter::print_routine_definition_param(const ObRoutineInfo &routine_info, +int ObSchemaPrinter::print_routine_definition_param_v1(const ObRoutineInfo &routine_info, const ObStmtNodeTree *param_list, char* buf, const int64_t& buf_len, @@ -3978,7 +3978,7 @@ int ObSchemaPrinter::print_routine_definition_param(const ObRoutineInfo &routine return ret; } -int ObSchemaPrinter::print_routine_definition(const ObRoutineInfo *routine_info, +int ObSchemaPrinter::print_routine_definition_v1(const ObRoutineInfo *routine_info, const ObStmtNodeTree *param_list, const ObStmtNodeTree *return_type, const ObString &body, @@ -4017,7 +4017,7 @@ int ObSchemaPrinter::print_routine_definition(const ObRoutineInfo *routine_info, OZ (databuff_printf(buf, buf_len, pos, "\n")); if (OB_SUCC(ret) && routine_info->get_param_count() > 0) { OZ (databuff_printf(buf, buf_len, pos, "(\n")); - OZ (print_routine_definition_param(*routine_info, param_list, buf, buf_len, pos, tz_info)); + OZ (print_routine_definition_param_v1(*routine_info, param_list, buf, buf_len, pos, tz_info)); OZ (databuff_printf(buf, buf_len, pos, "\n)")); } else { if (lib::is_mysql_mode()) { @@ -4060,6 +4060,7 @@ int ObSchemaPrinter::print_routine_definition(const ObRoutineInfo *routine_info, int ObSchemaPrinter::print_routine_definition( const uint64_t tenant_id, const uint64_t routine_id, + const sql::ObExecEnv &exec_env, char* buf, const int64_t& buf_len, int64_t& pos, @@ -4067,13 +4068,82 @@ int ObSchemaPrinter::print_routine_definition( { int ret = OB_SUCCESS; const ObRoutineInfo *routine_info = NULL; + bool use_v1 = true; OZ (schema_guard_.get_routine_info(tenant_id, routine_id, routine_info), routine_id); if (OB_SUCC(ret) && OB_ISNULL(routine_info)) { ret = OB_ERR_SP_DOES_NOT_EXIST; SHARE_SCHEMA_LOG(WARN, "Unknow routine", K(ret), K(routine_id)); + } + + if (OB_SUCC(ret)) { + ObArenaAllocator allocator; + ObString routine_stmt; + ParseResult parse_result; + const ObString &routine_body = routine_info->get_routine_body(); + CK(!routine_body.empty()); + + // TODO: disable Oracle mode for OB-JDBC compatibility, will enable it soon + if (OB_FAIL(ret) || lib::is_oracle_mode()) { + // do nothing + } else if (routine_info->get_routine_body().prefix_match_ci("procedure") + || routine_info->get_routine_body().prefix_match_ci("function")) { + use_v1 = false; + + pl::ObPLParser parser(allocator, CS_TYPE_UTF8MB4_BIN, exec_env.get_sql_mode()); + + if (lib::is_mysql_mode()) { + const char prefix[] = "CREATE\n"; + int64_t prefix_len = STRLEN(prefix); + int64_t buf_sz = prefix_len + routine_body.length(); + char *stmt_buf = static_cast(allocator.alloc(buf_sz)); + if (OB_ISNULL(stmt_buf)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to allocate memory for routine body buffer", K(buf_sz)); + } else { + MEMCPY(stmt_buf, prefix, prefix_len); + MEMCPY(stmt_buf + prefix_len, routine_body.ptr(), routine_body.length()); + + routine_stmt.assign_ptr(stmt_buf, buf_sz); + } + } else { // oracle mode + routine_stmt = routine_body; + } + CK(!routine_stmt.empty()); + + OZ (parser.parse(routine_stmt, routine_stmt, parse_result, true)); + } + + if (OB_SUCC(ret) && !use_v1) { + if (lib::is_mysql_mode()) { // mysql mode + if (OB_FAIL(print_routine_definition_v2_mysql( + *routine_info, + parse_result.result_tree_, + exec_env, + buf, + buf_len, + pos, + tz_info))) { + LOG_WARN("failed to print definition for mysql routine", K(*routine_info)); + } + } else { // TODO: oracle mode, never use this branch for now + if (OB_FAIL(print_routine_definition_v2_oracle( + *routine_info, + parse_result.result_tree_, + buf, + buf_len, + pos, + tz_info))) { + LOG_WARN("failed to print definition for oracle routine", K(*routine_info)); + } + } + } + } + + if (OB_FAIL(ret) || !use_v1) { + //do nothing } else if (lib::is_mysql_mode()) { ObString clause; - OZ (print_routine_definition(routine_info, NULL, NULL, routine_info->get_routine_body(), clause, buf, buf_len, pos, tz_info)); + OZ (print_routine_definition_v1(routine_info, NULL, NULL, routine_info->get_routine_body(), clause, buf, buf_len, pos, tz_info)); } else { // oracle mode ObString routine_body = routine_info->get_routine_body(); ObString actully_body; @@ -4123,11 +4193,173 @@ int ObSchemaPrinter::print_routine_definition( OX (param_list = routine_tree->children_[1]); OX (return_type = (routine_info->is_function() ? routine_tree->children_[2] : NULL)); CK (!actully_body.empty()); - OZ (print_routine_definition(routine_info, param_list, return_type, actully_body, routine_clause, buf, buf_len, pos, tz_info)); + OZ (print_routine_definition_v1(routine_info, param_list, return_type, actully_body, routine_clause, buf, buf_len, pos, tz_info)); } return ret; } +int ObSchemaPrinter::print_routine_definition_v2_mysql( + const ObRoutineInfo &routine_info, + const ObStmtNodeTree *parse_tree, + const ObExecEnv &exec_env, + char* buf, + const int64_t& buf_len, + int64_t& pos, + const common::ObTimeZoneInfo *tz_info) const +{ + UNUSED(tz_info); + int ret = OB_SUCCESS; + + ObString priv_user; + ObString user_name; + ObString host_name; + + ParseNode *create_node = nullptr; + ParseNode *body_node = nullptr; + + bool is_ansi_quote = false; + IS_ANSI_QUOTES(exec_env.get_sql_mode(), is_ansi_quote); + + // the quote character is determined by SQL_MODE ANSI_QUOTES of routine creation + const char *quote_char = is_ansi_quote ? "\"" : "`"; + + // use quote or not is determined by SQL_QUOTE_SHOW_CREATE variable of the SHOW CREATE statement execution + const char *quote = sql_quote_show_create_ ? quote_char : ""; + + CK (OB_NOT_NULL(parse_tree) && T_STMT_LIST == parse_tree->type_ && 1 == parse_tree->num_child_); + OX (create_node = parse_tree->children_[0]); + CK (OB_NOT_NULL(create_node)); + CK (T_SP_CREATE == create_node->type_ || T_SF_CREATE == create_node->type_); + OX (body_node = routine_info.is_procedure() ? create_node->children_[4] + : create_node->children_[5]); + CK (OB_NOT_NULL(body_node)); + CK (OB_NOT_NULL(body_node->raw_text_)); + + OX (priv_user = routine_info.get_priv_user()); + OX (user_name = priv_user.split_on('@')); + OX (host_name = priv_user); + + // quote around username is controlled by SQL_QUOTE_SHOW_CREATE variable, + // but quote around hostname is always shown, no matter what SQL_QUOTE_SHOW_CREATE is. + OZ (databuff_printf(buf, buf_len, pos, "CREATE DEFINER = %s%.*s%s@%s%.*s%s %s ", + quote, + user_name.length(), + user_name.ptr(), + quote, + quote_char, + host_name.length(), + host_name.ptr(), + quote_char, + routine_info.is_procedure() ? "PROCEDURE" : "FUNCTION")); + + OZ (databuff_printf(buf, buf_len, pos, "%s%.*s%s", + quote, + routine_info.get_routine_name().length(), + routine_info.get_routine_name().ptr(), + quote), + K(buf), K(buf_len), K(routine_info)); + + if (OB_FAIL(ret)) { + // do nothing + } else if (create_node->children_[2] != nullptr) { + const ParseNode ¶m_node = *create_node->children_[2]; + OZ (databuff_printf(buf, buf_len, pos, "(%.*s)", + static_cast(param_node.str_len_), + param_node.str_value_), + K(buf), K(buf_len), K(routine_info), K(param_node.str_value_), K(param_node.str_len_)); + } else { + OZ (databuff_printf(buf, buf_len, pos, "()"), + K(buf), K(buf_len), K(routine_info)); + } + + if (OB_SUCC(ret) && routine_info.is_function()) { + const ObRoutineParam *return_type = nullptr; + OZ (databuff_printf(buf, buf_len, pos, " RETURNS")); + OX (return_type = + static_cast(routine_info.get_ret_info())); + OZ (print_routine_param_type(return_type, nullptr, buf, buf_len, pos, tz_info), + K(buf), K(buf_len), K(routine_info)); + } + + if (OB_SUCC(ret)) { + if (routine_info.is_no_sql()) { + OZ (databuff_printf(buf, buf_len, pos, "\n NO SQL")); + } else if (routine_info.is_reads_sql_data()) { + OZ (databuff_printf(buf, buf_len, pos, "\n READS SQL DATA")); + } else if (routine_info.is_modifies_sql_data()) { + OZ (databuff_printf(buf, buf_len, pos, "\n MODIFIES SQL DATA")); + } + OZ (databuff_printf(buf, buf_len, pos, "%s", + routine_info.is_deterministic() ? "\n DETERMINISTIC" : "")); + OZ (databuff_printf(buf, buf_len, pos, "%s", + routine_info.is_invoker_right() ? "\n INVOKER" : "")); + if (OB_SUCC(ret) && OB_NOT_NULL(routine_info.get_comment())) { + OZ (databuff_printf(buf, buf_len, pos, "\n COMMENT '%.*s'", + routine_info.get_comment().length(), + routine_info.get_comment().ptr())); + } + } + + OZ (databuff_printf(buf, buf_len, pos, "\n%.*s", + static_cast(body_node->text_len_), + body_node->raw_text_), + K(buf), K(buf_len), K(routine_info), K(body_node->raw_text_), K(body_node->text_len_)); + + return ret; +} + +int ObSchemaPrinter::print_routine_definition_v2_oracle( + const ObRoutineInfo &routine_info, + const ObStmtNodeTree *parse_tree, + char* buf, + const int64_t& buf_len, + int64_t& pos, + const common::ObTimeZoneInfo *tz_info) const +{ + UNUSED(tz_info); + int ret = OB_SUCCESS; + const ParseNode *routine_tree = nullptr; + ObArenaAllocator allocator; + CK (OB_NOT_NULL(parse_tree) && T_STMT_LIST == parse_tree->type_ && 1 == parse_tree->num_child_); + CK (OB_NOT_NULL(parse_tree->children_[0])); + OX (routine_tree = parse_tree->children_[0]); + if (OB_SUCC(ret) && T_SP_PRE_STMTS == routine_tree->type_) { + OZ (pl::ObPLResolver::resolve_condition_compile( + allocator, + NULL, + &schema_guard_, + NULL, + NULL, + &(routine_info.get_exec_env()), + routine_tree, + routine_tree, + true /*inner_parse*/)); + } + CK (OB_NOT_NULL(routine_tree)); + CK (T_SP_SOURCE == routine_tree->type_ || T_SF_SOURCE == routine_tree->type_ || T_SF_AGGREGATE_SOURCE == routine_tree->type_); + + const ObString db_name; + const ObDatabaseSchema *db_schema = nullptr; + OZ (schema_guard_.get_database_schema(routine_info.get_tenant_id(), + routine_info.get_database_id(), db_schema), routine_info); + if (OB_SUCC(ret) && OB_ISNULL(db_schema)) { + ret = OB_ERR_BAD_DATABASE; + SHARE_SCHEMA_LOG(WARN, "Unknow database", K(ret), K(routine_info.get_database_id())); + } + OZ (databuff_printf( + buf, buf_len, pos, " CREATE OR REPLACE %s %s \"%.*s\".\"%.*s\" %.*s", + routine_info.is_noneditionable() ? "NONEDITIONABLE" : "EDITIONABLE", + routine_info.is_procedure() ? "PROCEDURE" : "FUNCTION", + db_schema->get_database_name_str().length(), + db_schema->get_database_name_str().ptr(), + routine_info.get_routine_name().length(), + routine_info.get_routine_name().ptr(), + static_cast(routine_tree->str_len_), + routine_tree->str_value_)); + + return ret; +} + int ObSchemaPrinter::print_foreign_key_definition( const uint64_t tenant_id, const ObForeignKeyInfo &foreign_key_info, diff --git a/src/share/schema/ob_schema_printer.h b/src/share/schema/ob_schema_printer.h index 4d79620c7b..4b16c93e34 100644 --- a/src/share/schema/ob_schema_printer.h +++ b/src/share/schema/ob_schema_printer.h @@ -21,6 +21,10 @@ namespace oceanbase { +namespace sql +{ + class ObExecEnv; +} namespace common { class ObTimeZoneInfo; @@ -329,7 +333,7 @@ public: const int64_t& buf_len, int64_t& pos, bool is_agent_mode = false) const; - int print_routine_definition(const ObRoutineInfo *routine_info, + int print_routine_definition_v1(const ObRoutineInfo *routine_info, const ObStmtNodeTree *param_list, const ObStmtNodeTree *return_type, const common::ObString &body, @@ -340,17 +344,31 @@ public: const common::ObTimeZoneInfo *tz_info) const; int print_routine_definition(const uint64_t tenant_id, const uint64_t routine_id, + const sql::ObExecEnv &exec_env, char* buf, const int64_t& buf_len, int64_t& pos, const common::ObTimeZoneInfo *tz_info) const; + int print_routine_definition_v2_mysql(const ObRoutineInfo &routine_info, + const ObStmtNodeTree *parse_tree, + const sql::ObExecEnv &exec_env, + char* buf, + const int64_t& buf_len, + int64_t& pos, + const common::ObTimeZoneInfo *tz_info) const; + int print_routine_definition_v2_oracle(const ObRoutineInfo &routine_info, + const ObStmtNodeTree *parse_tree, + char* buf, + const int64_t& buf_len, + int64_t& pos, + const common::ObTimeZoneInfo *tz_info) const; int print_routine_param_type(const ObRoutineParam *param, const ObStmtNodeTree *param_type, char *buf, const int64_t &buf_len, int64_t &pos, const common::ObTimeZoneInfo *tz_info) const; - int print_routine_definition_param(const ObRoutineInfo &routine_info, + int print_routine_definition_param_v1(const ObRoutineInfo &routine_info, const ObStmtNodeTree *param_list, char* buf, const int64_t& buf_len, diff --git a/src/sql/session/ob_basic_session_info.h b/src/sql/session/ob_basic_session_info.h index ecffcabb68..6b7c80c314 100644 --- a/src/sql/session/ob_basic_session_info.h +++ b/src/sql/session/ob_basic_session_info.h @@ -2416,7 +2416,7 @@ public: int load(ObBasicSessionInfo &session, ObIAllocator *alloc = NULL); int store(ObBasicSessionInfo &session); - ObSQLMode get_sql_mode() { return sql_mode_; } + ObSQLMode get_sql_mode() const { return sql_mode_; } ObCharsetType get_charset_client() { return ObCharset::charset_type_by_coll(charset_client_); } ObCollationType get_collation_connection() { return collation_connection_; } ObCollationType get_collation_database() { return collation_database_; } diff --git a/tools/deploy/mysql_test/test_suite/pl/r/mysql/sp_mysql.result b/tools/deploy/mysql_test/test_suite/pl/r/mysql/sp_mysql.result index d9008b64cb..1b93304eaf 100644 --- a/tools/deploy/mysql_test/test_suite/pl/r/mysql/sp_mysql.result +++ b/tools/deploy/mysql_test/test_suite/pl/r/mysql/sp_mysql.result @@ -783,12 +783,10 @@ comment 'Characteristics procedure test' insert into t1 values ("chistics", 1)| show create procedure chistics| Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation -chistics STRICT_ALL_TABLES CREATE DEFINER = admin@% PROCEDURE `test`.`chistics` -() - -MODIFIES SQL DATA -COMMENT `Characteristics procedure test` - insert into t1 values ("chistics", 1) utf8mb4 utf8mb4_general_ci utf8mb4_general_ci +chistics STRICT_ALL_TABLES CREATE DEFINER = `admin`@`%` PROCEDURE `chistics`() + MODIFIES SQL DATA + COMMENT 'Characteristics procedure test' +insert into t1 values ("chistics", 1) utf8mb4 utf8mb4_general_ci utf8mb4_general_ci call chistics()| select * from t1| id data @@ -797,13 +795,11 @@ delete from t1| alter procedure chistics sql security invoker| show create procedure chistics| Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation -chistics STRICT_ALL_TABLES CREATE DEFINER = admin@% PROCEDURE `test`.`chistics` -() - -MODIFIES SQL DATA -INVOKER -COMMENT `Characteristics procedure test` - insert into t1 values ("chistics", 1) utf8mb4 utf8mb4_general_ci utf8mb4_general_ci +chistics STRICT_ALL_TABLES CREATE DEFINER = `admin`@`%` PROCEDURE `chistics`() + MODIFIES SQL DATA + INVOKER + COMMENT 'Characteristics procedure test' +insert into t1 values ("chistics", 1) utf8mb4 utf8mb4_general_ci utf8mb4_general_ci drop procedure chistics| drop function if exists chistics| create function chistics() returns int @@ -814,13 +810,11 @@ comment 'Characteristics procedure test' return 42| show create function chistics| Function sql_mode Create Function character_set_client collation_connection Database Collation -chistics STRICT_ALL_TABLES CREATE DEFINER = admin@% FUNCTION `test`.`chistics` -() - RETURNS int(11) -DETERMINISTIC -INVOKER -COMMENT `Characteristics procedure test` - return 42 utf8mb4 utf8mb4_general_ci utf8mb4_general_ci +chistics STRICT_ALL_TABLES CREATE DEFINER = `admin`@`%` FUNCTION `chistics`() RETURNS int(11) + DETERMINISTIC + INVOKER + COMMENT 'Characteristics procedure test' +return 42 utf8mb4 utf8mb4_general_ci utf8mb4_general_ci select chistics()| chistics() 42 @@ -829,14 +823,12 @@ no sql comment 'Characteristics function test'| show create function chistics| Function sql_mode Create Function character_set_client collation_connection Database Collation -chistics STRICT_ALL_TABLES CREATE DEFINER = admin@% FUNCTION `test`.`chistics` -() - RETURNS int(11) -NO SQL -DETERMINISTIC -INVOKER -COMMENT `Characteristics function test` - return 42 utf8mb4 utf8mb4_general_ci utf8mb4_general_ci +chistics STRICT_ALL_TABLES CREATE DEFINER = `admin`@`%` FUNCTION `chistics`() RETURNS int(11) + NO SQL + DETERMINISTIC + INVOKER + COMMENT 'Characteristics function test' +return 42 utf8mb4 utf8mb4_general_ci utf8mb4_general_ci drop function chistics| set @@sql_mode=@old_mode| insert into t1 values ("foo", 1), ("bar", 2), ("zip", 3)| @@ -1241,11 +1233,9 @@ end while; end| show create procedure opp| Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation -opp CREATE DEFINER = admin@% PROCEDURE `test`.`opp` -( - IN `n` bigint(20) unsigned, OUT `pp` tinyint(1) -) -READS SQL DATA begin +opp CREATE DEFINER = `admin`@`%` PROCEDURE `opp`(n bigint unsigned, out pp bool) + READS SQL DATA +begin declare r double; declare b, s bigint unsigned default 0; set r = sqrt(n); @@ -1297,13 +1287,10 @@ alter procedure bar comment "3333333333"| alter procedure bar| show create procedure bar| Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation -bar CREATE DEFINER = admin@% PROCEDURE `test`.`bar` -( - IN `x` char(16), IN `y` int(11) -) -MODIFIES SQL DATA -COMMENT `3333333333` - insert into test.t1 values (x, y) utf8mb4 utf8mb4_general_ci utf8mb4_general_ci +bar CREATE DEFINER = `admin`@`%` PROCEDURE `bar`(x char(16), y int) + MODIFIES SQL DATA + COMMENT '3333333333' +insert into test.t1 values (x, y) utf8mb4 utf8mb4_general_ci utf8mb4_general_ci show procedure status like 'bar'| Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation test bar PROCEDURE root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINER 3333333333 utf8mb4 utf8mb4_general_ci utf8mb4_general_ci @@ -1876,16 +1863,14 @@ Db Name Type Definer Modified Created Security_type Comment character_set_client test bug2267_4 FUNCTION 'admin'@'%' 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINER NULL utf8mb4 utf8mb4_general_ci utf8mb4_general_ci call bug2267_3()| Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation -bug2267_1 CREATE DEFINER = admin@% PROCEDURE `test`.`bug2267_1` -() - begin +bug2267_1 CREATE DEFINER = `admin`@`%` PROCEDURE `bug2267_1`() +begin show procedure status where db='test'; end utf8mb4 utf8mb4_general_ci utf8mb4_general_ci call bug2267_4()| Function sql_mode Create Function character_set_client collation_connection Database Collation -bug2267_4 CREATE DEFINER = admin@% FUNCTION `test`.`bug2267_4` -() - RETURNS int(11) return 100 utf8mb4 utf8mb4_general_ci utf8mb4_general_ci +bug2267_4 CREATE DEFINER = `admin`@`%` FUNCTION `bug2267_4`() RETURNS int(11) +return 100 utf8mb4 utf8mb4_general_ci utf8mb4_general_ci drop procedure bug2267_1| drop procedure bug2267_2| drop procedure bug2267_3| @@ -2091,30 +2076,23 @@ return x || y$ set @@sql_mode = ''| show create procedure bug2564_1| Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation -bug2564_1 CREATE DEFINER = admin@% PROCEDURE `test`.`bug2564_1` -() - -MODIFIES SQL DATA -COMMENT `Joe's procedure` - insert into `t1` values ("foo", 1) utf8mb4 utf8mb4_general_ci utf8mb4_general_ci +bug2564_1 CREATE DEFINER = `admin`@`%` PROCEDURE `bug2564_1`() + MODIFIES SQL DATA + COMMENT 'Joe's procedure' +insert into `t1` values ("foo", 1) utf8mb4 utf8mb4_general_ci utf8mb4_general_ci show create procedure bug2564_2| Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation -bug2564_2 ANSI_QUOTES CREATE DEFINER = admin@% PROCEDURE `test`.`bug2564_2` -() - -MODIFIES SQL DATA insert into "t1" values ('foo', 1) utf8mb4 utf8mb4_general_ci utf8mb4_general_ci +bug2564_2 ANSI_QUOTES CREATE DEFINER = "admin"@"%" PROCEDURE "bug2564_2"() + MODIFIES SQL DATA +insert into "t1" values ('foo', 1) utf8mb4 utf8mb4_general_ci utf8mb4_general_ci show create function bug2564_3| Function sql_mode Create Function character_set_client collation_connection Database Collation -bug2564_3 CREATE DEFINER = admin@% FUNCTION `test`.`bug2564_3` -( - `x` int(11), `y` int(11) -) RETURNS int(11) return x || y utf8mb4 utf8mb4_general_ci utf8mb4_general_ci +bug2564_3 CREATE DEFINER = `admin`@`%` FUNCTION `bug2564_3`(x int, y int) RETURNS int(11) +return x || y utf8mb4 utf8mb4_general_ci utf8mb4_general_ci show create function bug2564_4| Function sql_mode Create Function character_set_client collation_connection Database Collation -bug2564_4 REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI CREATE DEFINER = admin@% FUNCTION `test`.`bug2564_4` -( - `x` int(11), `y` int(11) -) RETURNS int(11) return x || y utf8mb4 utf8mb4_general_ci utf8mb4_general_ci +bug2564_4 REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI CREATE DEFINER = "admin"@"%" FUNCTION "bug2564_4"(x int, y int) RETURNS int(11) +return x || y utf8mb4 utf8mb4_general_ci utf8mb4_general_ci drop procedure bug2564_1| drop procedure bug2564_2| drop function bug2564_3| @@ -3134,23 +3112,20 @@ call bug7088_2()| set character set default| show create procedure bug6063| Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation -bug6063 CREATE DEFINER = admin@% PROCEDURE `test`.`bug6063` -() - begin +bug6063 CREATE DEFINER = `admin`@`%` PROCEDURE `bug6063`() +begin lâbel: begin end; label: begin end; label1: begin end; end utf8mb4 utf8mb4_general_ci utf8mb4_general_ci show create procedure bug7088_1| Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation -bug7088_1 CREATE DEFINER = admin@% PROCEDURE `test`.`bug7088_1` -() - label1: begin end label1 utf8mb4 utf8mb4_general_ci utf8mb4_general_ci +bug7088_1 CREATE DEFINER = `admin`@`%` PROCEDURE `bug7088_1`() +label1: begin end label1 utf8mb4 utf8mb4_general_ci utf8mb4_general_ci show create procedure bug7088_2| Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation -bug7088_2 CREATE DEFINER = admin@% PROCEDURE `test`.`bug7088_2` -() - läbel1: begin end utf8mb4 utf8mb4_general_ci utf8mb4_general_ci +bug7088_2 CREATE DEFINER = `admin`@`%` PROCEDURE `bug7088_2`() +läbel1: begin end utf8mb4 utf8mb4_general_ci utf8mb4_general_ci drop procedure bug6063| drop procedure bug7088_1| drop procedure bug7088_2| @@ -4614,24 +4589,20 @@ CREATE FUNCTION mysqltest2.bug16211_f4() RETURNS CHAR(10) CHARSET binary RETURN ""| SHOW CREATE FUNCTION bug16211_f1| Function sql_mode Create Function character_set_client collation_connection Database Collation -bug16211_f1 CREATE DEFINER = admin@% FUNCTION `mysqltest1`.`bug16211_f1` -() - RETURNS char(10) RETURN "" utf8mb4 utf8mb4_general_ci utf8mb4_general_ci +bug16211_f1 CREATE DEFINER = `admin`@`%` FUNCTION `bug16211_f1`() RETURNS char(10) +RETURN "" utf8mb4 utf8mb4_general_ci utf8mb4_general_ci SHOW CREATE FUNCTION bug16211_f2| Function sql_mode Create Function character_set_client collation_connection Database Collation -bug16211_f2 CREATE DEFINER = admin@% FUNCTION `mysqltest1`.`bug16211_f2` -() - RETURNS binary(10) RETURN "" utf8mb4 utf8mb4_general_ci utf8mb4_general_ci +bug16211_f2 CREATE DEFINER = `admin`@`%` FUNCTION `bug16211_f2`() RETURNS binary(10) +RETURN "" utf8mb4 utf8mb4_general_ci utf8mb4_general_ci SHOW CREATE FUNCTION mysqltest2.bug16211_f3| Function sql_mode Create Function character_set_client collation_connection Database Collation -bug16211_f3 CREATE DEFINER = admin@% FUNCTION `mysqltest2`.`bug16211_f3` -() - RETURNS char(10) RETURN "" utf8mb4 utf8mb4_general_ci utf8mb4_general_ci +bug16211_f3 CREATE DEFINER = `admin`@`%` FUNCTION `bug16211_f3`() RETURNS char(10) +RETURN "" utf8mb4 utf8mb4_general_ci utf8mb4_general_ci SHOW CREATE FUNCTION mysqltest2.bug16211_f4| Function sql_mode Create Function character_set_client collation_connection Database Collation -bug16211_f4 CREATE DEFINER = admin@% FUNCTION `mysqltest2`.`bug16211_f4` -() - RETURNS binary(10) RETURN "" utf8mb4 utf8mb4_general_ci utf8mb4_general_ci +bug16211_f4 CREATE DEFINER = `admin`@`%` FUNCTION `bug16211_f4`() RETURNS binary(10) +RETURN "" utf8mb4 utf8mb4_general_ci utf8mb4_general_ci SELECT dtd_identifier FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA = "mysqltest1" AND ROUTINE_NAME = "bug16211_f1"| @@ -4672,24 +4643,20 @@ ERROR 42000: Unknown character set: 'cp1251' ALTER DATABASE mysqltest2 CHARACTER SET utf8mb4| SHOW CREATE FUNCTION bug16211_f1| Function sql_mode Create Function character_set_client collation_connection Database Collation -bug16211_f1 CREATE DEFINER = admin@% FUNCTION `mysqltest1`.`bug16211_f1` -() - RETURNS char(10) RETURN "" utf8mb4 utf8mb4_general_ci utf8mb4_general_ci +bug16211_f1 CREATE DEFINER = `admin`@`%` FUNCTION `bug16211_f1`() RETURNS char(10) +RETURN "" utf8mb4 utf8mb4_general_ci utf8mb4_general_ci SHOW CREATE FUNCTION bug16211_f2| Function sql_mode Create Function character_set_client collation_connection Database Collation -bug16211_f2 CREATE DEFINER = admin@% FUNCTION `mysqltest1`.`bug16211_f2` -() - RETURNS binary(10) RETURN "" utf8mb4 utf8mb4_general_ci utf8mb4_general_ci +bug16211_f2 CREATE DEFINER = `admin`@`%` FUNCTION `bug16211_f2`() RETURNS binary(10) +RETURN "" utf8mb4 utf8mb4_general_ci utf8mb4_general_ci SHOW CREATE FUNCTION mysqltest2.bug16211_f3| Function sql_mode Create Function character_set_client collation_connection Database Collation -bug16211_f3 CREATE DEFINER = admin@% FUNCTION `mysqltest2`.`bug16211_f3` -() - RETURNS char(10) RETURN "" utf8mb4 utf8mb4_general_ci utf8mb4_general_ci +bug16211_f3 CREATE DEFINER = `admin`@`%` FUNCTION `bug16211_f3`() RETURNS char(10) +RETURN "" utf8mb4 utf8mb4_general_ci utf8mb4_general_ci SHOW CREATE FUNCTION mysqltest2.bug16211_f4| Function sql_mode Create Function character_set_client collation_connection Database Collation -bug16211_f4 CREATE DEFINER = admin@% FUNCTION `mysqltest2`.`bug16211_f4` -() - RETURNS binary(10) RETURN "" utf8mb4 utf8mb4_general_ci utf8mb4_general_ci +bug16211_f4 CREATE DEFINER = `admin`@`%` FUNCTION `bug16211_f4`() RETURNS binary(10) +RETURN "" utf8mb4 utf8mb4_general_ci utf8mb4_general_ci SELECT dtd_identifier FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA = "mysqltest1" AND ROUTINE_NAME = "bug16211_f1"| @@ -4957,9 +4924,8 @@ drop procedure if exists bug21416| create procedure bug21416() show create procedure bug21416| call bug21416()| Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation -bug21416 CREATE DEFINER = admin@% PROCEDURE `test`.`bug21416` -() - show create procedure bug21416 utf8mb4 utf8mb4_general_ci utf8mb4_general_ci +bug21416 CREATE DEFINER = `admin`@`%` PROCEDURE `bug21416`() +show create procedure bug21416 utf8mb4 utf8mb4_general_ci utf8mb4_general_ci drop procedure bug21416| DROP PROCEDURE IF EXISTS bug21414| CREATE PROCEDURE bug21414() SELECT 1| @@ -5747,9 +5713,8 @@ drop procedure if exists proc_21513| create procedure proc_21513()`my_label`:BEGIN END| show create procedure proc_21513| Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation -proc_21513 CREATE DEFINER = admin@% PROCEDURE `test`.`proc_21513` -() - `my_label`:BEGIN END utf8mb4 utf8mb4_general_ci utf8mb4_general_ci +proc_21513 CREATE DEFINER = `admin`@`%` PROCEDURE `proc_21513`() +`my_label`:BEGIN END utf8mb4 utf8mb4_general_ci utf8mb4_general_ci drop procedure proc_21513| End of 5.0 tests. drop table t1,t2; @@ -5907,10 +5872,9 @@ end $$ show create procedure proc_25411_a; Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation -proc_25411_a CREATE DEFINER = admin@% PROCEDURE `test`.`proc_25411_a` -() - -READS SQL DATA begin +proc_25411_a CREATE DEFINER = `admin`@`%` PROCEDURE `proc_25411_a`() + READS SQL DATA +begin /* real comment */ select 1; /*! select 2; */ @@ -5931,11 +5895,14 @@ call proc_25411_a(); 5 show create procedure proc_25411_b; Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation -proc_25411_b CREATE DEFINER = admin@% PROCEDURE `test`.`proc_25411_b` -( - IN `p1` int(11), IN `p2` int(11), IN `p3` int(11) +proc_25411_b CREATE DEFINER = `admin`@`%` PROCEDURE `proc_25411_b`( +/* real comment */ +/*! p1 int, */ +/*!00000 p2 int */ +/*!99999 ,p3 int */ ) -READS SQL DATA begin + READS SQL DATA +begin select p1, p2; end utf8mb4 utf8mb4_general_ci utf8mb4_general_ci select name, param_list, body from mysql.proc where name like "%25411%"; @@ -5948,7 +5915,12 @@ select 3; /*!00000 select 4; */ /*!99999 select 5; */ end -proc_25411_b IN `p1` int(11), IN `p2` int(11), IN `p3` int(11) begin +proc_25411_b +/* real comment */ +/*! p1 int, */ +/*!00000 p2 int */ +/*!99999 ,p3 int */ + begin select p1, p2; end proc_25411_c begin @@ -5962,10 +5934,9 @@ call proc_25411_b(10, 20); ERROR 42000: Incorrect number of arguments show create procedure proc_25411_c; Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation -proc_25411_c CREATE DEFINER = admin@% PROCEDURE `test`.`proc_25411_c` -() - -READS SQL DATA begin +proc_25411_c CREATE DEFINER = `admin`@`%` PROCEDURE `proc_25411_c`() + READS SQL DATA +begin select 1/*!,2*//*!00000,3*//*!99999,4*/; select 1/*! ,2*//*!00000 ,3*//*!99999 ,4*/; select 1/*!,2 *//*!00000,3 *//*!99999,4 */; @@ -5991,10 +5962,9 @@ create procedure proc_26302() select 1 /* testing */; show create procedure proc_26302; Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation -proc_26302 CREATE DEFINER = admin@% PROCEDURE `test`.`proc_26302` -() - -READS SQL DATA select 1 /* testing */ utf8mb4 utf8mb4_general_ci utf8mb4_general_ci +proc_26302 CREATE DEFINER = `admin`@`%` PROCEDURE `proc_26302`() + READS SQL DATA +select 1 /* testing */ utf8mb4 utf8mb4_general_ci utf8mb4_general_ci select ROUTINE_NAME, ROUTINE_DEFINITION from information_schema.ROUTINES where ROUTINE_NAME = "proc_26302"; ROUTINE_NAME ROUTINE_DEFINITION @@ -6485,10 +6455,8 @@ Another_very_long_enum_element_identifier SHOW CREATE FUNCTION f1; Function sql_mode Create Function character_set_client collation_connection Database Collation -f1 CREATE DEFINER = admin@% FUNCTION `test`.`f1` -( - `p` int(11) -) RETURNS enum BEGIN +f1 CREATE DEFINER = `admin`@`%` FUNCTION `f1`(p INT) RETURNS enum +BEGIN CASE p WHEN 1 THEN RETURN 'Very_long_enum_element_identifier';