Commit a4732af9 authored by unknown's avatar unknown

Merge work:/my/mysql-4.0 into mashka.mysql.fi:/home/my/mysql-4.0


Docs/manual.texi:
  Auto merged
parents 2047f3e1 92dd0393
...@@ -50448,6 +50448,9 @@ each individual 4.0.x release. ...@@ -50448,6 +50448,9 @@ each individual 4.0.x release.
@itemize @bullet @itemize @bullet
@item @item
@code{SET PASSWORD FOR ...} closed the connection in case of errors (bug
from 4.0.3).
@item
Increased max possible @code{max_allowed_packet} in @code{mysqld} to 1G. Increased max possible @code{max_allowed_packet} in @code{mysqld} to 1G.
@item @item
Fixed bug when doing a multi-line @code{INSERT} on a table with an Fixed bug when doing a multi-line @code{INSERT} on a table with an
...@@ -51252,10 +51255,16 @@ not yet 100% confident in this code. ...@@ -51252,10 +51255,16 @@ not yet 100% confident in this code.
@item @item
Fixed core dump bug when using the @code{BINARY} cast on a @code{NULL} value. Fixed core dump bug when using the @code{BINARY} cast on a @code{NULL} value.
@item @item
Fixed race condition when someone did a @code{GRANT} at the same time a new
user logged in or did a @code{USE DATABASE}.
@item
Fixed bug in @code{ALTER TABLE} and @code{RENAME TABLE} when running with Fixed bug in @code{ALTER TABLE} and @code{RENAME TABLE} when running with
@code{-O lower_case_table_names=1} (typically on windows) when giving the @code{-O lower_case_table_names=1} (typically on windows) when giving the
table name in uppercase. table name in uppercase.
@item @item
Fixed that @code{-O lower_case_table_names=1} also converts database
names to lower case.
@item
Fixed unlikely core dump with @code{SELECT ... ORDER BY ... LIMIT}. Fixed unlikely core dump with @code{SELECT ... ORDER BY ... LIMIT}.
@item @item
Changed @code{AND/OR} to report that they can return NULL. This fixes a Changed @code{AND/OR} to report that they can return NULL. This fixes a
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
#include <signal.h> #include <signal.h>
#include <violite.h> #include <violite.h>
const char *VER= "12.13"; const char *VER= "12.14";
/* Don't try to make a nice table if the data is too big */ /* Don't try to make a nice table if the data is too big */
#define MAX_COLUMN_LENGTH 1024 #define MAX_COLUMN_LENGTH 1024
...@@ -476,7 +476,8 @@ static struct my_option my_long_options[] = ...@@ -476,7 +476,8 @@ static struct my_option my_long_options[] =
{"ignore-space", 'i', "Ignore space after function names.", 0, 0, 0, {"ignore-space", 'i', "Ignore space after function names.", 0, 0, 0,
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"local-infile", OPT_LOCAL_INFILE, "Enable/disable LOAD DATA LOCAL INFILE.", {"local-infile", OPT_LOCAL_INFILE, "Enable/disable LOAD DATA LOCAL INFILE.",
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, (gptr*) &opt_local_infile,
(gptr*) &opt_local_infile, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"no-beep", 'b', "Turn off beep on error.", (gptr*) &opt_nobeep, {"no-beep", 'b', "Turn off beep on error.", (gptr*) &opt_nobeep,
(gptr*) &opt_nobeep, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, (gptr*) &opt_nobeep, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"host", 'h', "Connect to host.", (gptr*) &current_host, {"host", 'h', "Connect to host.", (gptr*) &current_host,
...@@ -609,7 +610,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), ...@@ -609,7 +610,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
break; break;
case OPT_LOCAL_INFILE: case OPT_LOCAL_INFILE:
using_opt_local_infile=1; using_opt_local_infile=1;
opt_local_infile= test(!argument || atoi(argument)>0);
break; break;
case OPT_TEE: case OPT_TEE:
if (argument == disabled_my_option) if (argument == disabled_my_option)
......
...@@ -454,6 +454,8 @@ fi ...@@ -454,6 +454,8 @@ fi
NOINST_LDFLAGS= NOINST_LDFLAGS=
static_nss="" static_nss=""
STATIC_NSS_FLAGS=""
OTHER_LIBC_LIB=""
AC_ARG_WITH(other-libc, AC_ARG_WITH(other-libc,
[ --with-other-libc=DIR Link against libc and other standard libraries [ --with-other-libc=DIR Link against libc and other standard libraries
installed in the specified non-standard location installed in the specified non-standard location
...@@ -479,6 +481,7 @@ AC_ARG_WITH(other-libc, ...@@ -479,6 +481,7 @@ AC_ARG_WITH(other-libc,
# we need special flags, but we will have to add those later # we need special flags, but we will have to add those later
STATIC_NSS_FLAGS="-Wl,--start-group -lc -lnss_files -lnss_dns -lresolv \ STATIC_NSS_FLAGS="-Wl,--start-group -lc -lnss_files -lnss_dns -lresolv \
-Wl,--end-group" -Wl,--end-group"
OTHER_LIBC_LIB="-L$other_libc_lib"
static_nss=1 static_nss=1
else else
# this is a dirty hack. We if we detect static nss glibc in the special # this is a dirty hack. We if we detect static nss glibc in the special
...@@ -2390,7 +2393,7 @@ fi ...@@ -2390,7 +2393,7 @@ fi
if test "$static_nss" = "1" if test "$static_nss" = "1"
then then
LDFLAGS="$LDFLAGS -static -L$other_libc_lib " LDFLAGS="$LDFLAGS -static $OTHER_LIBC_LIB"
LIBS="$LIBS $STATIC_NSS_FLAGS" LIBS="$LIBS $STATIC_NSS_FLAGS"
fi fi
......
...@@ -80,4 +80,4 @@ select count(*) from t3 where n >= 4; ...@@ -80,4 +80,4 @@ select count(*) from t3 where n >= 4;
count(*) count(*)
100 100
unlock tables; unlock tables;
drop table if exists t1,t2,t3; drop table if exists t1,t2,t3,t4;
...@@ -139,7 +139,7 @@ select count(*) from t3 where n >= 4; ...@@ -139,7 +139,7 @@ select count(*) from t3 where n >= 4;
unlock tables; unlock tables;
#clean up #clean up
connection master; connection master;
drop table if exists t1,t2,t3; drop table if exists t1,t2,t3,t4;
save_master_pos; save_master_pos;
connection slave; connection slave;
sync_with_master; sync_with_master;
...@@ -160,7 +160,7 @@ then ...@@ -160,7 +160,7 @@ then
echo "" echo ""
echo "Updating new privileges in MySQL 4.0.2 from old ones" echo "Updating new privileges in MySQL 4.0.2 from old ones"
@bindir@/mysql --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA @bindir@/mysql --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA
update user set show_db_priv= select_priv, super_priv=process_priv, execute_priv=process_priv, create_tmp_table_priv='Y', Lock_tables_priv='Y', Repl_slave_priv=file_priv, Repl_client_priv=file_priv; update user set show_db_priv= select_priv, super_priv=process_priv, execute_priv=process_priv, create_tmp_table_priv='Y', Lock_tables_priv='Y', Repl_slave_priv=file_priv, Repl_client_priv=file_priv where user<>"";
END_OF_DATA END_OF_DATA
echo "" echo ""
fi fi
......
...@@ -896,7 +896,7 @@ byte *sys_var_thd_enum::value_ptr(THD *thd, enum_var_type type) ...@@ -896,7 +896,7 @@ byte *sys_var_thd_enum::value_ptr(THD *thd, enum_var_type type)
bool sys_var_thd_bit::update(THD *thd, set_var *var) bool sys_var_thd_bit::update(THD *thd, set_var *var)
{ {
bool res= (*update_func)(thd, var); int res= (*update_func)(thd, var);
thd->lex.select_lex.options=thd->options; thd->lex.select_lex.options=thd->options;
return res; return res;
} }
...@@ -1010,7 +1010,7 @@ byte *sys_var_insert_id::value_ptr(THD *thd, enum_var_type type) ...@@ -1010,7 +1010,7 @@ byte *sys_var_insert_id::value_ptr(THD *thd, enum_var_type type)
bool sys_var_slave_skip_counter::check(THD *thd, set_var *var) bool sys_var_slave_skip_counter::check(THD *thd, set_var *var)
{ {
bool result=0; int result= 0;
LOCK_ACTIVE_MI; LOCK_ACTIVE_MI;
pthread_mutex_lock(&active_mi->rli.run_lock); pthread_mutex_lock(&active_mi->rli.run_lock);
if (active_mi->rli.slave_running) if (active_mi->rli.slave_running)
...@@ -1236,26 +1236,24 @@ sys_var *find_sys_var(const char *str, uint length) ...@@ -1236,26 +1236,24 @@ sys_var *find_sys_var(const char *str, uint length)
RETURN VALUE RETURN VALUE
0 ok 0 ok
1 Something got wrong (normally no variables was updated) 1 ERROR, message sent (normally no variables was updated)
-1 ERROR, message not sent
*/ */
bool sql_set_variables(THD *thd, List<set_var_base> *var_list) int sql_set_variables(THD *thd, List<set_var_base> *var_list)
{ {
bool error=0; int error= 0;
List_iterator<set_var_base> it(*var_list); List_iterator<set_var_base> it(*var_list);
set_var_base *var; set_var_base *var;
while ((var=it++)) while ((var=it++))
{ {
if (var->check(thd)) if ((error=var->check(thd)))
return 1; return error;
} }
it.rewind(); it.rewind();
while ((var=it++)) while ((var=it++))
{ error|= var->update(thd); // Returns 0, -1 or 1
if (var->update(thd))
error=1;
}
return error; return error;
} }
...@@ -1264,14 +1262,14 @@ bool sql_set_variables(THD *thd, List<set_var_base> *var_list) ...@@ -1264,14 +1262,14 @@ bool sql_set_variables(THD *thd, List<set_var_base> *var_list)
Functions to handle SET mysql_internal_variable=const_expr Functions to handle SET mysql_internal_variable=const_expr
*****************************************************************************/ *****************************************************************************/
bool set_var::check(THD *thd) int set_var::check(THD *thd)
{ {
if (var->check_type(type)) if (var->check_type(type))
{ {
my_error(type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE, my_error(type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE,
MYF(0), MYF(0),
var->name); var->name);
return 1; return -1;
} }
if ((type == OPT_GLOBAL && check_global_access(thd, SUPER_ACL))) if ((type == OPT_GLOBAL && check_global_access(thd, SUPER_ACL)))
return 1; return 1;
...@@ -1282,28 +1280,29 @@ bool set_var::check(THD *thd) ...@@ -1282,28 +1280,29 @@ bool set_var::check(THD *thd)
if (var->check_default(type)) if (var->check_default(type))
{ {
my_error(ER_NO_DEFAULT, MYF(0), var->name); my_error(ER_NO_DEFAULT, MYF(0), var->name);
return 1; return -1;
} }
return 0; return 0;
} }
if (value->fix_fields(thd,0)) if (value->fix_fields(thd,0))
return 1; return -1;
if (var->check_update_type(value->result_type())) if (var->check_update_type(value->result_type()))
{ {
my_error(ER_WRONG_TYPE_FOR_VAR, MYF(0), var->name); my_error(ER_WRONG_TYPE_FOR_VAR, MYF(0), var->name);
return 1; return -1;
} }
return var->check(thd, this); return var->check(thd, this) ? -1 : 0;
} }
bool set_var::update(THD *thd) int set_var::update(THD *thd)
{ {
int error;
if (!value) if (!value)
var->set_default(thd, type); var->set_default(thd, type);
else if (var->update(thd, this)) else if (var->update(thd, this))
return 1; // should never happen return -1; // should never happen
if (var->after_update) if (var->after_update)
(*var->after_update)(thd, type); (*var->after_update)(thd, type);
return 0; return 0;
...@@ -1314,19 +1313,19 @@ bool set_var::update(THD *thd) ...@@ -1314,19 +1313,19 @@ bool set_var::update(THD *thd)
Functions to handle SET @user_variable=const_expr Functions to handle SET @user_variable=const_expr
*****************************************************************************/ *****************************************************************************/
bool set_var_user::check(THD *thd) int set_var_user::check(THD *thd)
{ {
return user_var_item->fix_fields(thd,0); return user_var_item->fix_fields(thd,0) ? -1 : 0;
} }
bool set_var_user::update(THD *thd) int set_var_user::update(THD *thd)
{ {
if (user_var_item->update()) if (user_var_item->update())
{ {
/* Give an error if it's not given already */ /* Give an error if it's not given already */
send_error(&thd->net, ER_SET_CONSTANTS_ONLY); my_error(ER_SET_CONSTANTS_ONLY, MYF(0));
return 1; return -1;
} }
return 0; return 0;
} }
...@@ -1336,16 +1335,19 @@ bool set_var_user::update(THD *thd) ...@@ -1336,16 +1335,19 @@ bool set_var_user::update(THD *thd)
Functions to handle SET PASSWORD Functions to handle SET PASSWORD
*****************************************************************************/ *****************************************************************************/
bool set_var_password::check(THD *thd) int set_var_password::check(THD *thd)
{ {
if (!user->host.str) if (!user->host.str)
user->host.str= (char*) thd->host_or_ip; user->host.str= (char*) thd->host_or_ip;
return check_change_password(thd, user->host.str, user->user.str); /* Returns 1 as the function sends error to client */
return check_change_password(thd, user->host.str, user->user.str) ? 1 : 0;
} }
bool set_var_password::update(THD *thd) int set_var_password::update(THD *thd)
{ {
return change_password(thd, user->host.str, user->user.str, password); /* Returns 1 as the function sends error to client */
return (change_password(thd, user->host.str, user->user.str, password) ?
1 : 0);
} }
/**************************************************************************** /****************************************************************************
......
...@@ -359,8 +359,8 @@ class set_var_base :public Sql_alloc ...@@ -359,8 +359,8 @@ class set_var_base :public Sql_alloc
public: public:
set_var_base() {} set_var_base() {}
virtual ~set_var_base() {} virtual ~set_var_base() {}
virtual bool check(THD *thd)=0; /* To check privileges etc. */ virtual int check(THD *thd)=0; /* To check privileges etc. */
virtual bool update(THD *thd)=0; /* To set the value */ virtual int update(THD *thd)=0; /* To set the value */
}; };
...@@ -394,8 +394,8 @@ public: ...@@ -394,8 +394,8 @@ public:
else else
value=value_arg; value=value_arg;
} }
bool check(THD *thd); int check(THD *thd);
bool update(THD *thd); int update(THD *thd);
}; };
...@@ -408,8 +408,8 @@ public: ...@@ -408,8 +408,8 @@ public:
set_var_user(Item_func_set_user_var *item) set_var_user(Item_func_set_user_var *item)
:user_var_item(item) :user_var_item(item)
{} {}
bool check(THD *thd); int check(THD *thd);
bool update(THD *thd); int update(THD *thd);
}; };
/* For SET PASSWORD */ /* For SET PASSWORD */
...@@ -422,8 +422,8 @@ public: ...@@ -422,8 +422,8 @@ public:
set_var_password(LEX_USER *user_arg,char *password_arg) set_var_password(LEX_USER *user_arg,char *password_arg)
:user(user_arg), password(password_arg) :user(user_arg), password(password_arg)
{} {}
bool check(THD *thd); int check(THD *thd);
bool update(THD *thd); int update(THD *thd);
}; };
...@@ -434,7 +434,7 @@ public: ...@@ -434,7 +434,7 @@ public:
void set_var_init(); void set_var_init();
void set_var_free(); void set_var_free();
sys_var *find_sys_var(const char *str, uint length=0); sys_var *find_sys_var(const char *str, uint length=0);
bool sql_set_variables(THD *thd, List<set_var_base> *var_list); int sql_set_variables(THD *thd, List<set_var_base> *var_list);
void fix_delay_key_write(THD *thd, enum_var_type type); void fix_delay_key_write(THD *thd, enum_var_type type);
extern sys_var_str sys_charset; extern sys_var_str sys_charset;
...@@ -741,11 +741,25 @@ static void acl_update_db(const char *user, const char *host, const char *db, ...@@ -741,11 +741,25 @@ static void acl_update_db(const char *user, const char *host, const char *db,
} }
/*
Insert a user/db/host combination into the global acl_cache
SYNOPSIS
acl_insert_db()
user User name
host Host name
db Database name
privileges Bitmap of privileges
NOTES
acl_cache->lock must be locked when calling this
*/
static void acl_insert_db(const char *user, const char *host, const char *db, static void acl_insert_db(const char *user, const char *host, const char *db,
ulong privileges) ulong privileges)
{ {
ACL_DB acl_db; ACL_DB acl_db;
/* The acl_cache mutex is locked by mysql_grant */ safe_mutex_assert_owner(&acl_cache->lock);
acl_db.user=strdup_root(&mem,user); acl_db.user=strdup_root(&mem,user);
update_hostname(&acl_db.host,strdup_root(&mem,host)); update_hostname(&acl_db.host,strdup_root(&mem,host));
acl_db.db=strdup_root(&mem,db); acl_db.db=strdup_root(&mem,db);
...@@ -769,7 +783,6 @@ ulong acl_get(const char *host, const char *ip, const char *bin_ip, ...@@ -769,7 +783,6 @@ ulong acl_get(const char *host, const char *ip, const char *bin_ip,
db_access=0; host_access= ~0; db_access=0; host_access= ~0;
char key[ACL_KEY_LENGTH],*tmp_db,*end; char key[ACL_KEY_LENGTH],*tmp_db,*end;
acl_entry *entry; acl_entry *entry;
THD *thd= current_thd;
VOID(pthread_mutex_lock(&acl_cache->lock)); VOID(pthread_mutex_lock(&acl_cache->lock));
memcpy_fixed(&key,bin_ip,sizeof(struct in_addr)); memcpy_fixed(&key,bin_ip,sizeof(struct in_addr));
...@@ -1001,6 +1014,21 @@ bool check_change_password(THD *thd, const char *host, const char *user) ...@@ -1001,6 +1014,21 @@ bool check_change_password(THD *thd, const char *host, const char *user)
} }
/*
Change a password for a user
SYNOPSIS
change_password()
thd Thread handle
host Hostname
user User name
new_password New password for host@user
RETURN VALUES
0 ok
1 ERROR; In this case the error is sent to the client.
*/
bool change_password(THD *thd, const char *host, const char *user, bool change_password(THD *thd, const char *host, const char *user,
char *new_password) char *new_password)
{ {
...@@ -1217,6 +1245,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, ...@@ -1217,6 +1245,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
char *password,empty_string[1]; char *password,empty_string[1];
char what= (revoke_grant) ? 'N' : 'Y'; char what= (revoke_grant) ? 'N' : 'Y';
DBUG_ENTER("replace_user_table"); DBUG_ENTER("replace_user_table");
safe_mutex_assert_owner(&acl_cache->lock);
password=empty_string; password=empty_string;
empty_string[0]=0; empty_string[0]=0;
...@@ -1240,7 +1269,6 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, ...@@ -1240,7 +1269,6 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
{ {
if (!create_user) if (!create_user)
{ {
THD *thd=current_thd;
if (what == 'N') if (what == 'N')
my_printf_error(ER_NONEXISTING_GRANT,ER(ER_NONEXISTING_GRANT), my_printf_error(ER_NONEXISTING_GRANT,ER(ER_NONEXISTING_GRANT),
MYF(0),combo.user.str,combo.host.str); MYF(0),combo.user.str,combo.host.str);
...@@ -1621,6 +1649,7 @@ static GRANT_TABLE *table_hash_search(const char *host,const char* ip, ...@@ -1621,6 +1649,7 @@ static GRANT_TABLE *table_hash_search(const char *host,const char* ip,
char helping [NAME_LEN*2+USERNAME_LENGTH+3]; char helping [NAME_LEN*2+USERNAME_LENGTH+3];
uint len; uint len;
GRANT_TABLE *grant_table,*found=0; GRANT_TABLE *grant_table,*found=0;
safe_mutex_assert_owner(&LOCK_grant);
len = (uint) (strmov(strmov(strmov(helping,user)+1,db)+1,tname)-helping)+ 1; len = (uint) (strmov(strmov(strmov(helping,user)+1,db)+1,tname)-helping)+ 1;
for (grant_table=(GRANT_TABLE*) hash_search(&hash_tables,(byte*) helping, for (grant_table=(GRANT_TABLE*) hash_search(&hash_tables,(byte*) helping,
...@@ -1828,6 +1857,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, ...@@ -1828,6 +1857,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
int error=0; int error=0;
ulong store_table_rights, store_col_rights; ulong store_table_rights, store_col_rights;
DBUG_ENTER("replace_table_table"); DBUG_ENTER("replace_table_table");
safe_mutex_assert_owner(&LOCK_grant);
strxmov(grantor, thd->user, "@", thd->host_or_ip, NullS); strxmov(grantor, thd->user, "@", thd->host_or_ip, NullS);
...@@ -2017,6 +2047,7 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list, ...@@ -2017,6 +2047,7 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list,
while ((Str = str_list++)) while ((Str = str_list++))
{ {
int error;
GRANT_TABLE *grant_table; GRANT_TABLE *grant_table;
if (!Str->host.str) if (!Str->host.str)
{ {
...@@ -2031,8 +2062,11 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list, ...@@ -2031,8 +2062,11 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list,
continue; continue;
} }
/* Create user if needed */ /* Create user if needed */
if (replace_user_table(thd, tables[0].table, *Str, pthread_mutex_lock(&acl_cache->lock);
0, revoke_grant, create_new_users)) error=replace_user_table(thd, tables[0].table, *Str,
0, revoke_grant, create_new_users);
pthread_mutex_unlock(&acl_cache->lock);
if (error)
{ {
result= -1; // Remember error result= -1; // Remember error
continue; // Add next user continue; // Add next user
...@@ -2048,7 +2082,7 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list, ...@@ -2048,7 +2082,7 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list,
{ {
my_printf_error(ER_NONEXISTING_TABLE_GRANT, my_printf_error(ER_NONEXISTING_TABLE_GRANT,
ER(ER_NONEXISTING_TABLE_GRANT),MYF(0), ER(ER_NONEXISTING_TABLE_GRANT),MYF(0),
Str->user.str, Str->host.str, table_list->alias); Str->user.str, Str->host.str, table_list->real_name);
result= -1; result= -1;
continue; continue;
} }
...@@ -2577,6 +2611,7 @@ bool check_grant_db(THD *thd,const char *db) ...@@ -2577,6 +2611,7 @@ bool check_grant_db(THD *thd,const char *db)
ulong get_table_grant(THD *thd, TABLE_LIST *table) ulong get_table_grant(THD *thd, TABLE_LIST *table)
{ {
uint privilege;
char *user = thd->priv_user; char *user = thd->priv_user;
const char *db = table->db ? table->db : thd->db; const char *db = table->db ? table->db : thd->db;
GRANT_TABLE *grant_table; GRANT_TABLE *grant_table;
...@@ -2588,8 +2623,9 @@ ulong get_table_grant(THD *thd, TABLE_LIST *table) ...@@ -2588,8 +2623,9 @@ ulong get_table_grant(THD *thd, TABLE_LIST *table)
table->grant.version=grant_version; table->grant.version=grant_version;
if (grant_table) if (grant_table)
table->grant.privilege|= grant_table->privs; table->grant.privilege|= grant_table->privs;
privilege= table->grant.privilege;
pthread_mutex_unlock(&LOCK_grant); pthread_mutex_unlock(&LOCK_grant);
return table->grant.privilege; return privilege;
} }
...@@ -2700,6 +2736,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) ...@@ -2700,6 +2736,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
if (send_fields(thd,field_list,1)) if (send_fields(thd,field_list,1))
DBUG_RETURN(-1); DBUG_RETURN(-1);
pthread_mutex_lock(&LOCK_grant);
VOID(pthread_mutex_lock(&acl_cache->lock)); VOID(pthread_mutex_lock(&acl_cache->lock));
/* Add first global access grants */ /* Add first global access grants */
...@@ -2955,13 +2992,16 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) ...@@ -2955,13 +2992,16 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
thd->packet.length())) thd->packet.length()))
{ {
error=-1; error=-1;
goto end; break;
} }
} }
} }
} }
end: end:
VOID(pthread_mutex_unlock(&acl_cache->lock)); VOID(pthread_mutex_unlock(&acl_cache->lock));
pthread_mutex_unlock(&LOCK_grant);
send_eof(&thd->net); send_eof(&thd->net);
DBUG_RETURN(error); DBUG_RETURN(error);
} }
......
...@@ -332,7 +332,7 @@ bool mysql_change_db(THD *thd,const char *name) ...@@ -332,7 +332,7 @@ bool mysql_change_db(THD *thd,const char *name)
int length, db_length; int length, db_length;
char *dbname=my_strdup((char*) name,MYF(MY_WME)); char *dbname=my_strdup((char*) name,MYF(MY_WME));
char path[FN_REFLEN]; char path[FN_REFLEN];
uint db_access; ulong db_access;
DBUG_ENTER("mysql_change_db"); DBUG_ENTER("mysql_change_db");
if (!dbname || !(db_length=strip_sp(dbname))) if (!dbname || !(db_length=strip_sp(dbname)))
......
...@@ -2202,9 +2202,7 @@ mysql_execute_command(void) ...@@ -2202,9 +2202,7 @@ mysql_execute_command(void)
break; break;
} }
case SQLCOM_SET_OPTION: case SQLCOM_SET_OPTION:
if (sql_set_variables(thd, &lex->var_list)) if (!(res=sql_set_variables(thd, &lex->var_list)))
res= -1;
else
send_ok(&thd->net); send_ok(&thd->net);
break; break;
case SQLCOM_UNLOCK_TABLES: case SQLCOM_UNLOCK_TABLES:
......
...@@ -424,7 +424,7 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild) ...@@ -424,7 +424,7 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild)
/*************************************************************************** /***************************************************************************
** List all columns in a table ** List all columns in a table_list->real_name
***************************************************************************/ ***************************************************************************/
int int
......
...@@ -141,7 +141,7 @@ void udf_init() ...@@ -141,7 +141,7 @@ void udf_init()
new_thd->db_length=5; new_thd->db_length=5;
bzero((gptr) &tables,sizeof(tables)); bzero((gptr) &tables,sizeof(tables));
tables.alias= tables.real_name = (char*) "func"; tables.alias= tables.real_name= (char*) "func";
tables.lock_type = TL_READ; tables.lock_type = TL_READ;
tables.db=new_thd->db; tables.db=new_thd->db;
......
...@@ -304,7 +304,7 @@ safe_query("revoke GRANT OPTION on $opt_database.test from $user",1); ...@@ -304,7 +304,7 @@ safe_query("revoke GRANT OPTION on $opt_database.test from $user",1);
# #
safe_query("grant select(a) on $opt_database.test to $user"); safe_query("grant select(a) on $opt_database.test to $user");
user_query("show columns from test"); user_query("show full columns from test");
safe_query("grant insert (b), update (b) on $opt_database.test to $user"); safe_query("grant insert (b), update (b) on $opt_database.test to $user");
user_query("select count(a) from test"); user_query("select count(a) from test");
...@@ -435,8 +435,9 @@ user_connect(0); ...@@ -435,8 +435,9 @@ user_connect(0);
user_query("LOCK TABLES $opt_database.test3 READ"); user_query("LOCK TABLES $opt_database.test3 READ");
user_query("UNLOCK TABLES"); user_query("UNLOCK TABLES");
safe_query("revoke SELECT,INSERT,UPDATE,DELETE on $opt_database.test3 from $user"); safe_query("revoke SELECT,INSERT,UPDATE,DELETE on $opt_database.test3 from $user");
user_connect(1); user_connect(0);
safe_query("revoke LOCK TABLES on *.* from $user"); safe_query("revoke LOCK TABLES on *.* from $user");
user_connect(1);
safe_query("drop table $opt_database.test3"); safe_query("drop table $opt_database.test3");
# #
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment