summaryrefslogtreecommitdiff
path: root/sql/sp.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sp.cc')
-rw-r--r--sql/sp.cc134
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",