1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

Merge 5.0.80 release and 5.0 community. Version left at 5.0.80.

This commit is contained in:
Chad MILLER
2009-04-14 13:20:13 -04:00
397 changed files with 11101 additions and 8316 deletions

View File

@ -250,7 +250,7 @@ static int get_or_create_user_conn(THD *thd, const char *user,
USER_RESOURCES *mqh)
{
int return_val= 0;
uint temp_len, user_len;
size_t temp_len, user_len;
char temp_user[USER_HOST_BUFF_SIZE];
struct user_conn *uc;
@ -261,7 +261,7 @@ static int get_or_create_user_conn(THD *thd, const char *user,
temp_len= (strmov(strmov(temp_user, user)+1, host) - temp_user)+1;
(void) pthread_mutex_lock(&LOCK_user_conn);
if (!(uc = (struct user_conn *) hash_search(&hash_user_connections,
(byte*) temp_user, temp_len)))
(byte*) temp_user, (uint) temp_len)))
{
/* First connection for user; Create a user connection object */
if (!(uc= ((struct user_conn*)
@ -275,7 +275,7 @@ static int get_or_create_user_conn(THD *thd, const char *user,
uc->user=(char*) (uc+1);
memcpy(uc->user,temp_user,temp_len+1);
uc->host= uc->user + user_len + 1;
uc->len= temp_len;
uc->len= (uint) temp_len;
uc->connections= uc->questions= uc->updates= uc->conn_per_hour= 0;
uc->user_resources= *mqh;
uc->intime= thd->thr_create_time;
@ -328,7 +328,7 @@ int check_user(THD *thd, enum enum_server_command command,
bool check_count)
{
DBUG_ENTER("check_user");
LEX_STRING db_str= { (char *) db, db ? strlen(db) : 0 };
LEX_STRING db_str= { (char *) db, db ? (uint) strlen(db) : 0 };
#ifdef NO_EMBEDDED_ACCESS_CHECKS
thd->main_security_ctx.master_access= GLOBAL_ACLS; // Full rights
@ -1036,7 +1036,7 @@ static int check_connection(THD *thd)
char *user= end;
char *passwd= strend(user)+1;
uint user_len= passwd - user - 1;
size_t user_len= passwd - user - 1;
char *db= passwd;
char db_buff[NAME_LEN + 1]; // buffer to store db in utf8
char user_buff[USERNAME_LENGTH + 1]; // buffer to store user in utf8
@ -1051,10 +1051,10 @@ static int check_connection(THD *thd)
*passwd > 127 and become 2**32-127 after casting to uint.
*/
uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
(uchar)(*passwd++) : strlen(passwd);
(uchar)(*passwd++) : (uint) strlen(passwd);
db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ?
db + passwd_len + 1 : 0;
uint db_len= db ? strlen(db) : 0;
size_t db_len= db ? strlen(db) : 0;
if (passwd + passwd_len + db_len > (char *)net->read_pos + pkt_len)
{
@ -1067,13 +1067,13 @@ static int check_connection(THD *thd)
{
db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
system_charset_info,
db, db_len,
db, (uint) db_len,
thd->charset(), &dummy_errors)]= 0;
db= db_buff;
}
user_buff[user_len= copy_and_convert(user_buff, sizeof(user_buff)-1,
system_charset_info, user, user_len,
system_charset_info, user, (uint) user_len,
thd->charset(), &dummy_errors)]= '\0';
user= user_buff;
@ -1789,7 +1789,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
statistic_increment(thd->status_var.com_stat[SQLCOM_CHANGE_DB],
&LOCK_status);
thd->convert_string(&tmp, system_charset_info,
packet, strlen(packet), thd->charset());
packet, (uint) strlen(packet), thd->charset());
if (!mysql_change_db(thd, &tmp, FALSE))
{
mysql_log.write(thd,command,"%s",thd->db);
@ -1852,7 +1852,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
*/
char db_buff[NAME_LEN+1]; // buffer to store db in utf8
char *db= passwd;
uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
size_t passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
(uchar)(*passwd++) : strlen(passwd);
db+= passwd_len + 1;
#ifndef EMBEDDED_LIBRARY
@ -1866,7 +1866,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
/* Convert database name to utf8 */
uint dummy_errors;
db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
system_charset_info, db, strlen(db),
system_charset_info, db, (uint) strlen(db),
thd->charset(), &dummy_errors)]= 0;
db= db_buff;
@ -1885,7 +1885,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
/* Clear variables that are allocated */
thd->user_connect= 0;
int res= check_user(thd, COM_CHANGE_USER, passwd, passwd_len, db, FALSE);
int res= check_user(thd, COM_CHANGE_USER, passwd, (uint) passwd_len, db, FALSE);
if (res)
{
@ -2041,7 +2041,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
table_list.schema_table= schema_table;
}
thd->query_length= strlen(packet); // for simplicity: don't optimize
thd->query_length= (uint) strlen(packet); // for simplicity: don't optimize
if (!(thd->query=fields=thd->memdup(packet,thd->query_length+1)))
break;
mysql_log.write(thd,command,"%s %s",table_list.table_name, fields);
@ -2363,8 +2363,9 @@ void log_slow_statement(THD *thd)
{
thd_proc_info(thd, "logging slow query");
if ((ulong) (thd->start_time - thd->time_after_lock) >
thd->variables.long_query_time ||
if ((thd->start_time > thd->time_after_lock &&
(ulong) (thd->start_time - thd->time_after_lock) >
thd->variables.long_query_time) ||
(thd->server_status &
(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) &&
opt_log_queries_not_using_indexes &&
@ -2623,6 +2624,10 @@ mysql_execute_command(THD *thd)
TABLE_LIST *all_tables;
/* most outer SELECT_LEX_UNIT of query */
SELECT_LEX_UNIT *unit= &lex->unit;
#ifdef HAVE_REPLICATION
/* have table map for update for multi-update statement (BUG#37051) */
bool have_table_map_for_update= FALSE;
#endif
/* Saved variable value */
DBUG_ENTER("mysql_execute_command");
thd->net.no_send_error= 0;
@ -2702,6 +2707,48 @@ mysql_execute_command(THD *thd)
// force searching in slave.cc:tables_ok()
all_tables->updating= 1;
}
/*
For fix of BUG#37051, the master stores the table map for update
in the Query_log_event, and the value is assigned to
thd->variables.table_map_for_update before executing the update
query.
If thd->variables.table_map_for_update is set, then we are
replicating from a new master, we can use this value to apply
filter rules without opening all the tables. However If
thd->variables.table_map_for_update is not set, then we are
replicating from an old master, so we just skip this and
continue with the old method. And of course, the bug would still
exist for old masters.
*/
if (lex->sql_command == SQLCOM_UPDATE_MULTI &&
thd->table_map_for_update)
{
have_table_map_for_update= TRUE;
table_map table_map_for_update= thd->table_map_for_update;
uint nr= 0;
TABLE_LIST *table;
for (table=all_tables; table; table=table->next_global, nr++)
{
if (table_map_for_update & ((table_map)1 << nr))
table->updating= TRUE;
else
table->updating= FALSE;
}
if (all_tables_not_ok(thd, all_tables))
{
/* we warn the slave SQL thread */
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
if (thd->one_shot_set)
reset_one_shot_variables(thd);
DBUG_RETURN(0);
}
for (table=all_tables; table; table=table->next_global)
table->updating= TRUE;
}
/*
Check if statment should be skipped because of slave filtering
@ -3217,6 +3264,42 @@ mysql_execute_command(THD *thd)
}
if (select_lex->item_list.elements) // With select
{
/*
If:
a) we inside an SP and there was NAME_CONST substitution,
b) binlogging is on,
c) we log the SP as separate statements
raise a warning, as it may cause problems
(see 'NAME_CONST issues' in 'Binary Logging of Stored Programs')
*/
if (thd->query_name_consts &&
mysql_bin_log.is_open() &&
!mysql_bin_log.is_query_in_union(thd, thd->query_id))
{
List_iterator_fast<Item> it(select_lex->item_list);
Item *item;
uint splocal_refs= 0;
/* Count SP local vars in the top-level SELECT list */
while ((item= it++))
{
if (item->is_splocal())
splocal_refs++;
}
/*
If it differs from number of NAME_CONST substitution applied,
we may have a SOME_FUNC(NAME_CONST()) in the SELECT list,
that may cause a problem with binary log (see BUG#35383),
raise a warning.
*/
if (splocal_refs != thd->query_name_consts)
push_warning(thd,
MYSQL_ERROR::WARN_LEVEL_WARN,
ER_UNKNOWN_ERROR,
"Invoked routine ran a statement that may cause problems with "
"binary log, see 'NAME_CONST issues' in 'Binary Logging of Stored Programs' "
"section of the manual.");
}
select_result *sel_result;
select_lex->options|= SELECT_NO_UNLOCK;
@ -3660,7 +3743,7 @@ end_with_restore_list:
#ifdef HAVE_REPLICATION
/* Check slave filtering rules */
if (unlikely(thd->slave_thread))
if (unlikely(thd->slave_thread && !have_table_map_for_update))
{
if (all_tables_not_ok(thd, all_tables))
{
@ -3969,7 +4052,7 @@ end_with_restore_list:
#endif
case SQLCOM_CHANGE_DB:
{
LEX_STRING db_str= { (char *) select_lex->db, strlen(select_lex->db) };
LEX_STRING db_str= { (char *) select_lex->db, (uint) strlen(select_lex->db) };
if (!mysql_change_db(thd, &db_str, FALSE))
send_ok(thd);
@ -6202,7 +6285,7 @@ void create_select_for_variable(const char *var_name)
mysql_init_select(lex);
lex->sql_command= SQLCOM_SELECT;
tmp.str= (char*) var_name;
tmp.length=strlen(var_name);
tmp.length=(uint) strlen(var_name);
bzero((char*) &null_lex_string.str, sizeof(null_lex_string));
/*
We set the name of Item to @@session.var_name because that then is used
@ -6211,7 +6294,7 @@ void create_select_for_variable(const char *var_name)
if ((var= get_system_var(thd, OPT_SESSION, tmp, null_lex_string)))
{
end= strxmov(buff, "@@session.", var_name, NullS);
var->set_name(buff, end-buff, system_charset_info);
var->set_name(buff, (uint) (end - buff), system_charset_info);
add_item_to_list(thd, var);
}
DBUG_VOID_RETURN;
@ -7394,8 +7477,26 @@ void kill_one_thread(THD *thd, ulong id, bool only_kill_query)
VOID(pthread_mutex_unlock(&LOCK_thread_count));
if (tmp)
{
/*
If we're SUPER, we can KILL anything, including system-threads.
No further checks.
KILLer: thd->security_ctx->user could in theory be NULL while
we're still in "unauthenticated" state. This is a theoretical
case (the code suggests this could happen, so we play it safe).
KILLee: tmp->security_ctx->user will be NULL for system threads.
We need to check so Jane Random User doesn't crash the server
when trying to kill a) system threads or b) unauthenticated users'
threads (Bug#43748).
If user of both killer and killee are non-NULL, proceed with
slayage if both are string-equal.
*/
if ((thd->security_ctx->master_access & SUPER_ACL) ||
!strcmp(thd->security_ctx->user, tmp->security_ctx->user))
thd->security_ctx->user_matches(tmp->security_ctx))
{
tmp->awake(only_kill_query ? THD::KILL_QUERY : THD::KILL_CONNECTION);
error=0;
@ -7954,10 +8055,10 @@ void get_default_definer(THD *thd, LEX_USER *definer)
const Security_context *sctx= thd->security_ctx;
definer->user.str= (char *) sctx->priv_user;
definer->user.length= strlen(definer->user.str);
definer->user.length= (uint) strlen(definer->user.str);
definer->host.str= (char *) sctx->priv_host;
definer->host.length= strlen(definer->host.str);
definer->host.length= (uint) strlen(definer->host.str);
}