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:
147
sql/sql_parse.cc
147
sql/sql_parse.cc
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user