diff options
Diffstat (limited to 'sql/sp.cc')
| -rw-r--r-- | sql/sp.cc | 134 |
1 files changed, 59 insertions, 75 deletions
diff --git a/sql/sp.cc b/sql/sp.cc index 42f7e2d0433..4a878d00664 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -15,6 +15,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ +#include <my_global.h> #include "sql_priv.h" #include "unireg.h" #include "sp.h" @@ -51,7 +52,8 @@ db_load_routine(THD *thd, stored_procedure_type type, sp_name *name, sp_head **sphp, ulonglong sql_mode, const char *params, const char *returns, const char *body, st_sp_chistics &chistics, - const char *definer, longlong created, longlong modified, + LEX_STRING *definer_user_name, LEX_STRING *definer_host_name, + longlong created, longlong modified, Stored_program_creation_ctx *creation_ctx); static const @@ -169,7 +171,7 @@ TABLE_FIELD_TYPE proc_table_fields[MYSQL_PROC_FIELD_COUNT] = }; static const TABLE_FIELD_DEF - proc_table_def= {MYSQL_PROC_FIELD_COUNT, proc_table_fields}; +proc_table_def= {MYSQL_PROC_FIELD_COUNT, proc_table_fields, 0, (uint*) 0 }; /*************************************************************************/ @@ -326,7 +328,7 @@ Stored_routine_creation_ctx::load_from_db(THD *thd, if (invalid_creation_ctx) { push_warning_printf(thd, - MYSQL_ERROR::WARN_LEVEL_WARN, + Sql_condition::WARN_LEVEL_WARN, ER_SR_INVALID_CREATION_CTX, ER(ER_SR_INVALID_CREATION_CTX), (const char *) db_name, @@ -375,10 +377,10 @@ void Proc_table_intact::report_error(uint code, const char *fmt, ...) my_vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); - if (code == ER_COL_COUNT_DOESNT_MATCH_CORRUPTED) + if (code) my_message(code, buf, MYF(0)); else - my_error(ER_CANNOT_LOAD_FROM_TABLE, MYF(0), "proc"); + my_error(ER_CANNOT_LOAD_FROM_TABLE_V2, MYF(0), "mysql", "proc"); if (m_print_once) { @@ -549,6 +551,10 @@ db_find_routine(THD *thd, stored_procedure_type type, sp_name *name, ulonglong sql_mode, saved_mode= thd->variables.sql_mode; Open_tables_backup open_tables_state_backup; Stored_program_creation_ctx *creation_ctx; + char definer_user_name_holder[USERNAME_LENGTH + 1]; + LEX_STRING definer_user_name= { definer_user_name_holder, USERNAME_LENGTH }; + char definer_host_name_holder[HOSTNAME_LENGTH + 1]; + LEX_STRING definer_host_name= { definer_host_name_holder, HOSTNAME_LENGTH }; DBUG_ENTER("db_find_routine"); DBUG_PRINT("enter", ("type: %d name: %.*s", @@ -658,9 +664,19 @@ db_find_routine(THD *thd, stored_procedure_type type, sp_name *name, close_system_tables(thd, &open_tables_state_backup); table= 0; + if (parse_user(definer, strlen(definer), + definer_user_name.str, &definer_user_name.length, + definer_host_name.str, &definer_host_name.length) && + definer_user_name.length && !definer_host_name.length) + { + // 'user@' -> 'user@%' + definer_host_name= host_not_specified; + } + ret= db_load_routine(thd, type, name, sphp, sql_mode, params, returns, body, chistics, - definer, created, modified, creation_ctx); + &definer_user_name, &definer_host_name, + created, modified, creation_ctx); done: /* Restore the time zone flag as the timezone usage in proc table @@ -684,9 +700,9 @@ public: virtual bool handle_condition(THD *thd, uint sql_errno, const char* sqlstate, - MYSQL_ERROR::enum_warning_level level, + Sql_condition::enum_warning_level level, const char* msg, - MYSQL_ERROR ** cond_hdl); + Sql_condition ** cond_hdl); }; bool @@ -694,13 +710,13 @@ Silence_deprecated_warning::handle_condition( THD *, uint sql_errno, const char*, - MYSQL_ERROR::enum_warning_level level, + Sql_condition::enum_warning_level level, const char*, - MYSQL_ERROR ** cond_hdl) + Sql_condition ** cond_hdl) { *cond_hdl= NULL; if (sql_errno == ER_WARN_DEPRECATED_SYNTAX && - level == MYSQL_ERROR::WARN_LEVEL_WARN) + level == Sql_condition::WARN_LEVEL_WARN) return TRUE; return FALSE; @@ -773,9 +789,9 @@ public: virtual bool handle_condition(THD *thd, uint sql_errno, const char* sqlstate, - MYSQL_ERROR::enum_warning_level level, + Sql_condition::enum_warning_level level, const char* message, - MYSQL_ERROR ** cond_hdl); + Sql_condition ** cond_hdl); bool error_caught() const { return m_error_caught; } @@ -787,9 +803,9 @@ bool Bad_db_error_handler::handle_condition(THD *thd, uint sql_errno, const char* sqlstate, - MYSQL_ERROR::enum_warning_level level, + Sql_condition::enum_warning_level level, const char* message, - MYSQL_ERROR ** cond_hdl) + Sql_condition ** cond_hdl) { if (sql_errno == ER_BAD_DB_ERROR) { @@ -805,7 +821,8 @@ db_load_routine(THD *thd, stored_procedure_type type, sp_name *name, sp_head **sphp, ulonglong sql_mode, const char *params, const char *returns, const char *body, st_sp_chistics &chistics, - const char *definer, longlong created, longlong modified, + LEX_STRING *definer_user_name, LEX_STRING *definer_host_name, + longlong created, longlong modified, Stored_program_creation_ctx *creation_ctx) { LEX *old_lex= thd->lex, newlex; @@ -815,22 +832,12 @@ db_load_routine(THD *thd, stored_procedure_type type, { saved_cur_db_name_buf, sizeof(saved_cur_db_name_buf) }; bool cur_db_changed; Bad_db_error_handler db_not_exists_handler; - char definer_user_name_holder[USERNAME_LENGTH + 1]; - LEX_STRING definer_user_name= { definer_user_name_holder, - USERNAME_LENGTH }; - - char definer_host_name_holder[HOSTNAME_LENGTH + 1]; - LEX_STRING definer_host_name= { definer_host_name_holder, HOSTNAME_LENGTH }; int ret= 0; thd->lex= &newlex; newlex.current_select= NULL; - parse_user(definer, strlen(definer), - definer_user_name.str, &definer_user_name.length, - definer_host_name.str, &definer_host_name.length); - defstr.set_charset(creation_ctx->get_client_cs()); /* @@ -846,7 +853,7 @@ db_load_routine(THD *thd, stored_procedure_type type, params, strlen(params), returns, strlen(returns), body, strlen(body), - &chistics, &definer_user_name, &definer_host_name, + &chistics, definer_user_name, definer_host_name, sql_mode)) { ret= SP_INTERNAL_ERROR; @@ -896,7 +903,7 @@ db_load_routine(THD *thd, stored_procedure_type type, goto end; } - (*sphp)->set_definer(&definer_user_name, &definer_host_name); + (*sphp)->set_definer(definer_user_name, definer_host_name); (*sphp)->set_info(created, modified, &chistics, sql_mode); (*sphp)->set_creation_ctx(creation_ctx); (*sphp)->optimize(); @@ -975,7 +982,8 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp) { int ret; TABLE *table; - char definer[USER_HOST_BUFF_SIZE]; + char definer_buf[USER_HOST_BUFF_SIZE]; + LEX_STRING definer; ulonglong saved_mode= thd->variables.sql_mode; MDL_key::enum_mdl_namespace mdl_type= type == TYPE_ENUM_FUNCTION ? MDL_key::FUNCTION : MDL_key::PROCEDURE; @@ -985,9 +993,6 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp) enum_check_fields saved_count_cuted_fields; bool store_failed= FALSE; - - bool save_binlog_row_based; - DBUG_ENTER("sp_create_routine"); DBUG_PRINT("enter", ("type: %d name: %.*s", (int) type, (int) sp->m_name.length, @@ -1005,14 +1010,6 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp) /* Reset sql_mode during data dictionary operations. */ thd->variables.sql_mode= 0; - /* - This statement will be replicated as a statement, even when using - row-based replication. The flag will be reset at the end of the - statement. - */ - if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row())) - thd->clear_current_stmt_binlog_format_row(); - saved_count_cuted_fields= thd->count_cuted_fields; thd->count_cuted_fields= CHECK_FIELD_WARN; @@ -1023,8 +1020,7 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp) restore_record(table, s->default_values); // Get default values for fields /* NOTE: all needed privilege checks have been already done. */ - strxnmov(definer, sizeof(definer)-1, thd->lex->definer->user.str, "@", - thd->lex->definer->host.str, NullS); + thd->lex->definer->set_lex_string(&definer, definer_buf); if (table->s->fields < MYSQL_PROC_FIELD_COUNT) { @@ -1099,7 +1095,7 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp) store_failed= store_failed || table->field[MYSQL_PROC_FIELD_DEFINER]-> - store(definer, (uint)strlen(definer), system_charset_info); + store(definer.str, definer.length, system_charset_info); ((Field_timestamp *)table->field[MYSQL_PROC_FIELD_CREATED])->set_time(); ((Field_timestamp *)table->field[MYSQL_PROC_FIELD_MODIFIED])->set_time(); @@ -1179,6 +1175,9 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp) ret= SP_OK; if (table->file->ha_write_row(table->record[0])) ret= SP_WRITE_ROW_FAILED; + /* Make change permanent and avoid 'table is marked as crashed' errors */ + table->file->extra(HA_EXTRA_FLUSH); + if (ret == SP_OK) sp_cache_invalidate(); @@ -1218,10 +1217,7 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp) done: thd->count_cuted_fields= saved_count_cuted_fields; thd->variables.sql_mode= saved_mode; - /* Restore the state of binlog format */ DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(ret); } @@ -1246,7 +1242,6 @@ sp_drop_routine(THD *thd, stored_procedure_type type, sp_name *name) { TABLE *table; int ret; - bool save_binlog_row_based; MDL_key::enum_mdl_namespace mdl_type= type == TYPE_ENUM_FUNCTION ? MDL_key::FUNCTION : MDL_key::PROCEDURE; DBUG_ENTER("sp_drop_routine"); @@ -1268,13 +1263,12 @@ sp_drop_routine(THD *thd, stored_procedure_type type, sp_name *name) row-based replication. The flag will be reset at the end of the statement. */ - if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row())) - thd->clear_current_stmt_binlog_format_row(); - if ((ret= db_find_routine_aux(thd, type, name, table)) == SP_OK) { if (table->file->ha_delete_row(table->record[0])) ret= SP_DELETE_ROW_FAILED; + /* Make change permanent and avoid 'table is marked as crashed' errors */ + table->file->extra(HA_EXTRA_FLUSH); } if (ret == SP_OK) @@ -1297,10 +1291,7 @@ sp_drop_routine(THD *thd, stored_procedure_type type, sp_name *name) sp_cache_flush_obsolete(spc, &sp); } } - /* Restore the state of binlog format */ DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(ret); } @@ -1328,7 +1319,6 @@ sp_update_routine(THD *thd, stored_procedure_type type, sp_name *name, { TABLE *table; int ret; - bool save_binlog_row_based; MDL_key::enum_mdl_namespace mdl_type= type == TYPE_ENUM_FUNCTION ? MDL_key::FUNCTION : MDL_key::PROCEDURE; DBUG_ENTER("sp_update_routine"); @@ -1346,14 +1336,6 @@ sp_update_routine(THD *thd, stored_procedure_type type, sp_name *name, if (!(table= open_proc_table_for_update(thd))) DBUG_RETURN(SP_OPEN_TABLE_FAILED); - /* - This statement will be replicated as a statement, even when using - row-based replication. The flag will be reset at the end of the - statement. - */ - if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row())) - thd->clear_current_stmt_binlog_format_row(); - if ((ret= db_find_routine_aux(thd, type, name, table)) == SP_OK) { if (type == TYPE_ENUM_FUNCTION && ! trust_function_creators && @@ -1381,7 +1363,6 @@ sp_update_routine(THD *thd, stored_procedure_type type, sp_name *name, } store_record(table,record[1]); - table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET; ((Field_timestamp *)table->field[MYSQL_PROC_FIELD_MODIFIED])->set_time(); if (chistics->suid != SP_IS_DEFAULT_SUID) table->field[MYSQL_PROC_FIELD_SECURITY_TYPE]-> @@ -1398,6 +1379,8 @@ sp_update_routine(THD *thd, stored_procedure_type type, sp_name *name, ret= SP_WRITE_ROW_FAILED; else ret= 0; + /* Make change permanent and avoid 'table is marked as crashed' errors */ + table->file->extra(HA_EXTRA_FLUSH); } if (ret == SP_OK) @@ -1407,10 +1390,7 @@ sp_update_routine(THD *thd, stored_procedure_type type, sp_name *name, sp_cache_invalidate(); } err: - /* Restore the state of binlog format */ DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row()); - if (save_binlog_row_based) - thd->set_current_stmt_binlog_format_row(); DBUG_RETURN(ret); } @@ -1425,15 +1405,15 @@ public: bool handle_condition(THD *thd, uint sql_errno, const char* sqlstate, - MYSQL_ERROR::enum_warning_level level, + Sql_condition::enum_warning_level level, const char* msg, - MYSQL_ERROR ** cond_hdl) + Sql_condition ** cond_hdl) { if (sql_errno == ER_NO_SUCH_TABLE || sql_errno == ER_NO_SUCH_TABLE_IN_ENGINE || - sql_errno == ER_CANNOT_LOAD_FROM_TABLE || + sql_errno == ER_CANNOT_LOAD_FROM_TABLE_V2 || sql_errno == ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE || - sql_errno == ER_COL_COUNT_DOESNT_MATCH_CORRUPTED) + sql_errno == ER_COL_COUNT_DOESNT_MATCH_CORRUPTED_V2) return true; return false; } @@ -1459,6 +1439,8 @@ bool lock_db_routines(THD *thd, char *db) uchar keybuf[MAX_KEY_LENGTH]; DBUG_ENTER("lock_db_routines"); + DBUG_ASSERT(ok_for_lower_case_names(db)); + /* mysql.proc will be re-opened during deletion, so we can ignore errors when opening the table here. The error handler is @@ -1578,7 +1560,11 @@ sp_drop_db_routines(THD *thd, char *db) if (nxtres != HA_ERR_END_OF_FILE) ret= SP_KEY_NOT_FOUND; if (deleted) + { sp_cache_invalidate(); + /* Make change permanent and avoid 'table is marked as crashed' errors */ + table->file->extra(HA_EXTRA_FLUSH); + } } table->file->ha_index_end(); @@ -1686,7 +1672,6 @@ sp_find_routine(THD *thd, stored_procedure_type type, sp_name *name, ulong level; sp_head *new_sp; const char *returns= ""; - char definer[USER_HOST_BUFF_SIZE]; /* String buffer for RETURNS data type must have system charset; @@ -1723,8 +1708,6 @@ sp_find_routine(THD *thd, stored_procedure_type type, sp_name *name, DBUG_RETURN(0); } - strxmov(definer, sp->m_definer_user.str, "@", - sp->m_definer_host.str, NullS); if (type == TYPE_ENUM_FUNCTION) { sp_returns_type(thd, retstr, sp); @@ -1732,7 +1715,8 @@ sp_find_routine(THD *thd, stored_procedure_type type, sp_name *name, } if (db_load_routine(thd, type, name, &new_sp, sp->m_sql_mode, sp->m_params.str, returns, - sp->m_body.str, *sp->m_chistics, definer, + sp->m_body.str, *sp->m_chistics, + &sp->m_definer_user, &sp->m_definer_host, sp->m_created, sp->m_modified, sp->get_creation_ctx()) == SP_OK) { @@ -1798,7 +1782,7 @@ sp_exist_routines(THD *thd, TABLE_LIST *routines, bool is_proc) sp_find_routine(thd, TYPE_ENUM_FUNCTION, name, &thd->sp_func_cache, FALSE) != NULL; - thd->warning_info->clear_warning_info(thd->query_id); + thd->get_stmt_da()->clear_warning_info(thd->query_id); if (! sp_object_found) { my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION or PROCEDURE", |
