summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorKristofer Pettersson <kristofer.pettersson@sun.com>2009-05-29 16:25:22 +0200
committerKristofer Pettersson <kristofer.pettersson@sun.com>2009-05-29 16:25:22 +0200
commitb34227cee613026221c0741746eb2c946b83a5a4 (patch)
tree5566185984017249f8ad2015c503e38086168976 /sql
parentb674d2c908cb7593abb9fcf00772d2f44168a6a9 (diff)
parent66e0ee6639e068f5f713a639d9001a81a7bd1013 (diff)
downloadmariadb-git-b34227cee613026221c0741746eb2c946b83a5a4.tar.gz
Automerge
Diffstat (limited to 'sql')
-rw-r--r--sql/sp.cc28
-rw-r--r--sql/sp.h4
-rw-r--r--sql/sql_acl.cc82
-rw-r--r--sql/sql_acl.h4
-rw-r--r--sql/sql_class.cc29
-rw-r--r--sql/sql_class.h30
-rw-r--r--sql/sql_parse.cc4
7 files changed, 112 insertions, 69 deletions
diff --git a/sql/sp.cc b/sql/sp.cc
index 8c8149d0afc..069cb722c2d 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -1308,13 +1308,20 @@ sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp,
/**
This is used by sql_acl.cc:mysql_routine_grant() and is used to find
the routines in 'routines'.
+
+ @param thd Thread handler
+ @param routines List of needles in the hay stack
+ @param any Any of the needles are good enough
+
+ @return
+ @retval FALSE Found.
+ @retval TRUE Not found
*/
-int
-sp_exist_routines(THD *thd, TABLE_LIST *routines, bool any, bool no_error)
+bool
+sp_exist_routines(THD *thd, TABLE_LIST *routines, bool any)
{
TABLE_LIST *routine;
- bool result= 0;
bool sp_object_found;
DBUG_ENTER("sp_exists_routine");
for (routine= routines; routine; routine= routine->next_global)
@@ -1336,21 +1343,16 @@ sp_exist_routines(THD *thd, TABLE_LIST *routines, bool any, bool no_error)
if (sp_object_found)
{
if (any)
- DBUG_RETURN(1);
- result= 1;
+ break;
}
else if (!any)
{
- if (!no_error)
- {
- my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION or PROCEDURE",
- routine->table_name);
- DBUG_RETURN(-1);
- }
- DBUG_RETURN(0);
+ my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION or PROCEDURE",
+ routine->table_name);
+ DBUG_RETURN(TRUE);
}
}
- DBUG_RETURN(result);
+ DBUG_RETURN(FALSE);
}
diff --git a/sql/sp.h b/sql/sp.h
index 75088ea0b83..75c6856f64b 100644
--- a/sql/sp.h
+++ b/sql/sp.h
@@ -39,8 +39,8 @@ sp_head *
sp_find_routine(THD *thd, int type, sp_name *name,
sp_cache **cp, bool cache_only);
-int
-sp_exist_routines(THD *thd, TABLE_LIST *procs, bool any, bool no_error);
+bool
+sp_exist_routines(THD *thd, TABLE_LIST *procs, bool any);
int
sp_routine_exists_in_table(THD *thd, int type, sp_name *name);
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 4d4e4d24684..e6655856969 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -3198,26 +3198,24 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
}
-/*
+/**
Store routine level grants in the privilege tables
- SYNOPSIS
- mysql_routine_grant()
- thd Thread handle
- table_list List of routines to give grant
- is_proc true indicates routine list are procedures
- user_list List of users to give grant
- rights Table level grant
- revoke_grant Set to 1 if this is a REVOKE command
+ @param thd Thread handle
+ @param table_list List of routines to give grant
+ @param is_proc Is this a list of procedures?
+ @param user_list List of users to give grant
+ @param rights Table level grant
+ @param revoke_grant Is this is a REVOKE command?
- RETURN
- 0 ok
- 1 error
+ @return
+ @retval FALSE Success.
+ @retval TRUE An error occurred.
*/
bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
List <LEX_USER> &user_list, ulong rights,
- bool revoke_grant, bool no_error)
+ bool revoke_grant, bool write_to_binlog)
{
List_iterator <LEX_USER> str_list (user_list);
LEX_USER *Str, *tmp_Str;
@@ -3228,22 +3226,20 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
if (!initialized)
{
- if (!no_error)
- my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
- "--skip-grant-tables");
+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
+ "--skip-grant-tables");
DBUG_RETURN(TRUE);
}
if (rights & ~PROC_ACLS)
{
- if (!no_error)
- my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER(ER_ILLEGAL_GRANT_FOR_TABLE),
- MYF(0));
+ my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER(ER_ILLEGAL_GRANT_FOR_TABLE),
+ MYF(0));
DBUG_RETURN(TRUE);
}
if (!revoke_grant)
{
- if (sp_exist_routines(thd, table_list, is_proc, no_error)<0)
+ if (sp_exist_routines(thd, table_list, is_proc))
DBUG_RETURN(TRUE);
}
@@ -3324,9 +3320,8 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
{
if (revoke_grant)
{
- if (!no_error)
- my_error(ER_NONEXISTING_PROC_GRANT, MYF(0),
- Str->user.str, Str->host.str, table_name);
+ my_error(ER_NONEXISTING_PROC_GRANT, MYF(0),
+ Str->user.str, Str->host.str, table_name);
result= TRUE;
continue;
}
@@ -3351,16 +3346,14 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
}
thd->mem_root= old_root;
pthread_mutex_unlock(&acl_cache->lock);
- if (!result && !no_error)
+
+ if (write_to_binlog)
{
write_bin_log(thd, TRUE, thd->query, thd->query_length);
}
rw_unlock(&LOCK_grant);
- if (!result && !no_error)
- my_ok(thd);
-
/* Tables are automatically closed */
DBUG_RETURN(result);
}
@@ -6157,21 +6150,20 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name,
}
-/*
+/**
Grant EXECUTE,ALTER privilege for a stored procedure
- SYNOPSIS
- sp_grant_privileges()
- thd The current thread.
- db DB of the stored procedure
- name Name of the stored procedure
+ @param thd The current thread.
+ @param sp_db
+ @param sp_name
+ @param is_proc
- RETURN
- 0 OK.
- < 0 Error. Error message not yet sent.
+ @return
+ @retval FALSE Success
+ @retval TRUE An error occured. Error message not yet sent.
*/
-int sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
+bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
bool is_proc)
{
Security_context *sctx= thd->security_ctx;
@@ -6181,6 +6173,7 @@ int sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
bool result;
ACL_USER *au;
char passwd_buff[SCRAMBLED_PASSWORD_CHAR_LENGTH+1];
+ Dummy_error_handler error_handler;
DBUG_ENTER("sp_grant_privileges");
if (!(combo=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
@@ -6231,8 +6224,11 @@ int sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
}
else
{
- my_error(ER_PASSWD_LENGTH, MYF(0), SCRAMBLED_PASSWORD_CHAR_LENGTH);
- return -1;
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_PASSWD_LENGTH,
+ ER(ER_PASSWD_LENGTH),
+ SCRAMBLED_PASSWORD_CHAR_LENGTH);
+ return TRUE;
}
combo->password.str= passwd_buff;
}
@@ -6248,8 +6244,14 @@ int sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
thd->lex->ssl_type= SSL_TYPE_NOT_SPECIFIED;
bzero((char*) &thd->lex->mqh, sizeof(thd->lex->mqh));
+ /*
+ Only care about whether the operation failed or succeeded
+ as all errors will be handled later.
+ */
+ thd->push_internal_handler(&error_handler);
result= mysql_routine_grant(thd, tables, is_proc, user_list,
- DEFAULT_CREATE_PROC_ACLS, 0, 1);
+ DEFAULT_CREATE_PROC_ACLS, FALSE, FALSE);
+ thd->pop_internal_handler();
DBUG_RETURN(result);
}
diff --git a/sql/sql_acl.h b/sql/sql_acl.h
index 9ae17a4bf02..a8090fba2e7 100644
--- a/sql/sql_acl.h
+++ b/sql/sql_acl.h
@@ -233,7 +233,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table, List <LEX_USER> &user_list,
bool revoke);
bool mysql_routine_grant(THD *thd, TABLE_LIST *table, bool is_proc,
List <LEX_USER> &user_list, ulong rights,
- bool revoke, bool no_error);
+ bool revoke, bool write_to_binlog);
my_bool grant_init();
void grant_free(void);
my_bool grant_reload(THD *thd);
@@ -264,7 +264,7 @@ void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant,
const char *db, const char *table);
bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name,
bool is_proc);
-int sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
+bool sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
bool is_proc);
bool check_routine_level_acl(THD *thd, const char *db, const char *name,
bool is_proc);
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index cf5fdcf27a7..a853ad103ea 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -674,31 +674,40 @@ THD::THD()
void THD::push_internal_handler(Internal_error_handler *handler)
{
- /*
- TODO: The current implementation is limited to 1 handler at a time only.
- THD and sp_rcontext need to be modified to use a common handler stack.
- */
- DBUG_ASSERT(m_internal_handler == NULL);
- m_internal_handler= handler;
+ if (m_internal_handler)
+ {
+ handler->m_prev_internal_handler= m_internal_handler;
+ m_internal_handler= handler;
+ }
+ else
+ {
+ m_internal_handler= handler;
+ }
}
bool THD::handle_error(uint sql_errno, const char *message,
MYSQL_ERROR::enum_warning_level level)
{
- if (m_internal_handler)
+ if (!m_internal_handler)
+ return FALSE;
+
+ for (Internal_error_handler *error_handler= m_internal_handler;
+ error_handler;
+ error_handler= m_internal_handler->m_prev_internal_handler)
{
- return m_internal_handler->handle_error(sql_errno, message, level, this);
+ if (error_handler->handle_error(sql_errno, message, level, this))
+ return TRUE;
}
- return FALSE; // 'FALSE', as per coding style
+ return FALSE;
}
void THD::pop_internal_handler()
{
DBUG_ASSERT(m_internal_handler != NULL);
- m_internal_handler= NULL;
+ m_internal_handler= m_internal_handler->m_prev_internal_handler;
}
extern "C"
diff --git a/sql/sql_class.h b/sql/sql_class.h
index ce4524fb982..4e9322dee05 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1036,7 +1036,10 @@ show_system_thread(enum_thread_type thread)
class Internal_error_handler
{
protected:
- Internal_error_handler() {}
+ Internal_error_handler() :
+ m_prev_internal_handler(NULL)
+ {}
+
virtual ~Internal_error_handler() {}
public:
@@ -1069,6 +1072,28 @@ public:
const char *message,
MYSQL_ERROR::enum_warning_level level,
THD *thd) = 0;
+private:
+ Internal_error_handler *m_prev_internal_handler;
+ friend class THD;
+};
+
+
+/**
+ Implements the trivial error handler which cancels all error states
+ and prevents an SQLSTATE to be set.
+*/
+
+class Dummy_error_handler : public Internal_error_handler
+{
+public:
+ bool handle_error(uint sql_errno,
+ const char *message,
+ MYSQL_ERROR::enum_warning_level level,
+ THD *thd)
+ {
+ /* Ignore error */
+ return TRUE;
+ }
};
@@ -2210,6 +2235,9 @@ public:
thd_scheduler scheduler;
public:
+ inline Internal_error_handler *get_internal_handler()
+ { return m_internal_handler; }
+
/**
Add an internal error handler to the thread execution context.
@param handler the exception handler to add
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 8f1d3842245..438ce2bad28 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -3880,7 +3880,9 @@ end_with_restore_list:
res= mysql_routine_grant(thd, all_tables,
lex->type == TYPE_ENUM_PROCEDURE,
lex->users_list, grants,
- lex->sql_command == SQLCOM_REVOKE, 0);
+ lex->sql_command == SQLCOM_REVOKE, TRUE);
+ if (!res)
+ my_ok(thd);
}
else
{