diff options
Diffstat (limited to 'sql/sp.cc')
-rw-r--r-- | sql/sp.cc | 79 |
1 files changed, 52 insertions, 27 deletions
diff --git a/sql/sp.cc b/sql/sp.cc index 6ec59143720..3cc24089c40 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -34,6 +34,10 @@ #include <my_user.h> +/* Used in error handling only */ +#define SP_TYPE_STRING(type) \ + (type == TYPE_ENUM_FUNCTION ? "FUNCTION" : "PROCEDURE") + static int db_load_routine(THD *thd, stored_procedure_type type, sp_name *name, sp_head **sphp, @@ -1007,15 +1011,16 @@ sp_drop_routine_internal(THD *thd, stored_procedure_type type, followed by an implicit grant (sp_grant_privileges()) and this subsequent call opens and closes mysql.procs_priv. - @return Error code. SP_OK is returned on success. Other - SP_ constants are used to indicate about errors. + @return Error status. + @retval FALSE on success + @retval TRUE on error */ -int +bool sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp) { LEX *lex= thd->lex; - int ret; + bool ret= TRUE; TABLE *table; char definer_buf[USER_HOST_BUFF_SIZE]; LEX_STRING definer; @@ -1040,7 +1045,22 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp) /* Grab an exclusive MDL lock. */ if (lock_object_name(thd, mdl_type, sp->m_db.str, sp->m_name.str)) - DBUG_RETURN(SP_OPEN_TABLE_FAILED); + { + my_error(ER_BAD_DB_ERROR, MYF(0), sp->m_db.str); + DBUG_RETURN(TRUE); + } + + /* + Check that a database directory with this name + exists. Design note: This won't work on virtual databases + like information_schema. + */ + if (check_db_dir_existence(sp->m_db.str)) + { + my_error(ER_BAD_DB_ERROR, MYF(0), sp->m_db.str); + DBUG_RETURN(TRUE); + } + /* Reset sql_mode during data dictionary operations. */ thd->variables.sql_mode= 0; @@ -1049,7 +1069,9 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp) thd->count_cuted_fields= CHECK_FIELD_WARN; if (!(table= open_proc_table_for_update(thd))) - ret= SP_OPEN_TABLE_FAILED; + { + my_error(ER_SP_STORE_FAILED, MYF(0), SP_TYPE_STRING(type),sp->m_name.str); + } else { /* Checking if the routine already exists */ @@ -1065,11 +1087,10 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp) push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, ER_SP_ALREADY_EXISTS, ER_THD(thd, ER_SP_ALREADY_EXISTS), - type == TYPE_ENUM_FUNCTION ? - "FUNCTION" : "PROCEDURE", + SP_TYPE_STRING(type), lex->spname->m_name.str); - ret= SP_OK; + ret= FALSE; // Setting retstr as it is used for logging. if (sp->m_type == TYPE_ENUM_FUNCTION) @@ -1078,7 +1099,8 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp) } else { - ret= SP_WRITE_ROW_FAILED; + my_error(ER_SP_ALREADY_EXISTS, MYF(0), + SP_TYPE_STRING(type), sp->m_name.str); goto done; } } @@ -1090,7 +1112,8 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp) if (table->s->fields < MYSQL_PROC_FIELD_COUNT) { - ret= SP_GET_FIELD_FAILED; + my_error(ER_SP_STORE_FAILED, MYF(0), + SP_TYPE_STRING(type), sp->m_name.str); goto done; } @@ -1099,12 +1122,12 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp) sp->m_name.str+sp->m_name.length) > table->field[MYSQL_PROC_FIELD_NAME]->char_length()) { - ret= SP_BAD_IDENTIFIER; + my_error(ER_TOO_LONG_IDENT, MYF(0), sp->m_name.str); goto done; } if (sp->m_body.length > table->field[MYSQL_PROC_FIELD_BODY]->field_length) { - ret= SP_BODY_TOO_LONG; + my_error(ER_TOO_LONG_BODY, MYF(0), sp->m_name.str); goto done; } @@ -1193,17 +1216,13 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp) if (access == SP_CONTAINS_SQL || access == SP_MODIFIES_SQL_DATA) { - my_message(ER_BINLOG_UNSAFE_ROUTINE, - ER_THD(thd, ER_BINLOG_UNSAFE_ROUTINE), MYF(0)); - ret= SP_INTERNAL_ERROR; + my_error(ER_BINLOG_UNSAFE_ROUTINE, MYF(0)); goto done; } } if (!(thd->security_ctx->master_access & SUPER_ACL)) { - my_message(ER_BINLOG_CREATE_ROUTINE_NEED_SUPER, - ER_THD(thd, ER_BINLOG_CREATE_ROUTINE_NEED_SUPER), MYF(0)); - ret= SP_INTERNAL_ERROR; + my_error(ER_BINLOG_CREATE_ROUTINE_NEED_SUPER,MYF(0)); goto done; } } @@ -1234,22 +1253,24 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp) if (store_failed) { - ret= SP_FLD_STORE_FAILED; + my_error(ER_CANT_CREATE_SROUTINE, MYF(0), sp->m_name.str); goto done; } - ret= SP_OK; if (table->file->ha_write_row(table->record[0])) - ret= SP_WRITE_ROW_FAILED; + { + my_error(ER_SP_ALREADY_EXISTS, MYF(0), + SP_TYPE_STRING(type), sp->m_name.str); + goto done; + } /* Make change permanent and avoid 'table is marked as crashed' errors */ table->file->extra(HA_EXTRA_FLUSH); - if (ret == SP_OK) - sp_cache_invalidate(); + sp_cache_invalidate(); } log: - if (ret == SP_OK && mysql_bin_log.is_open()) + if (mysql_bin_log.is_open()) { thd->clear_error(); @@ -1268,7 +1289,7 @@ log: &(thd->lex->definer->host), saved_mode)) { - ret= SP_INTERNAL_ERROR; + my_error(ER_OUT_OF_RESOURCES, MYF(0)); goto done; } /* restore sql_mode when binloging */ @@ -1277,9 +1298,13 @@ log: if (thd->binlog_query(THD::STMT_QUERY_TYPE, log_query.ptr(), log_query.length(), FALSE, FALSE, FALSE, 0)) - ret= SP_INTERNAL_ERROR; + { + my_error(ER_ERROR_ON_WRITE, MYF(MY_WME), "binary log", -1); + goto done; + } thd->variables.sql_mode= 0; } + ret= FALSE; done: thd->count_cuted_fields= saved_count_cuted_fields; |