mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
merge of Bug#33204 (backport)
This commit is contained in:
202
sql/sql_class.cc
202
sql/sql_class.cc
@ -91,7 +91,9 @@ extern "C" void free_user_var(user_var_entry *entry)
|
||||
|
||||
bool Key_part_spec::operator==(const Key_part_spec& other) const
|
||||
{
|
||||
return length == other.length && !strcmp(field_name, other.field_name);
|
||||
return length == other.length &&
|
||||
!my_strcasecmp(system_charset_info, field_name.str,
|
||||
other.field_name.str);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -258,7 +260,7 @@ const char *set_thd_proc_info(THD *thd, const char *info,
|
||||
const char *old_info= thd->proc_info;
|
||||
DBUG_PRINT("proc_info", ("%s:%d %s", calling_file, calling_line,
|
||||
(info != NULL) ? info : "(null)"));
|
||||
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
|
||||
#if defined(ENABLED_PROFILING)
|
||||
thd->profiling.status_change(info, calling_function, calling_file, calling_line);
|
||||
#endif
|
||||
thd->proc_info= info;
|
||||
@ -272,12 +274,7 @@ const char* thd_enter_cond(MYSQL_THD thd, pthread_cond_t *cond,
|
||||
if (!thd)
|
||||
thd= current_thd;
|
||||
|
||||
const char* old_msg = thd->proc_info;
|
||||
safe_mutex_assert_owner(mutex);
|
||||
thd->mysys_var->current_mutex = mutex;
|
||||
thd->mysys_var->current_cond = cond;
|
||||
thd->proc_info = msg;
|
||||
return old_msg;
|
||||
return thd->enter_cond(cond, mutex, msg);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
@ -286,18 +283,7 @@ void thd_exit_cond(MYSQL_THD thd, const char *old_msg)
|
||||
if (!thd)
|
||||
thd= current_thd;
|
||||
|
||||
/*
|
||||
Putting the mutex unlock in thd_exit_cond() ensures that
|
||||
mysys_var->current_mutex is always unlocked _before_ mysys_var->mutex is
|
||||
locked (if that would not be the case, you'll get a deadlock if someone
|
||||
does a THD::awake() on you).
|
||||
*/
|
||||
pthread_mutex_unlock(thd->mysys_var->current_mutex);
|
||||
pthread_mutex_lock(&thd->mysys_var->mutex);
|
||||
thd->mysys_var->current_mutex = 0;
|
||||
thd->mysys_var->current_cond = 0;
|
||||
thd->proc_info = old_msg;
|
||||
pthread_mutex_unlock(&thd->mysys_var->mutex);
|
||||
thd->exit_cond(old_msg);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -399,14 +385,14 @@ char *thd_security_context(THD *thd, char *buffer, unsigned int length,
|
||||
str.append(proc_info);
|
||||
}
|
||||
|
||||
if (thd->query)
|
||||
if (thd->query())
|
||||
{
|
||||
if (max_query_len < 1)
|
||||
len= thd->query_length;
|
||||
len= thd->query_length();
|
||||
else
|
||||
len= min(thd->query_length, max_query_len);
|
||||
len= min(thd->query_length(), max_query_len);
|
||||
str.append('\n');
|
||||
str.append(thd->query, len);
|
||||
str.append(thd->query(), len);
|
||||
}
|
||||
if (str.c_ptr_safe() == buffer)
|
||||
return buffer;
|
||||
@ -425,7 +411,7 @@ char *thd_security_context(THD *thd, char *buffer, unsigned int length,
|
||||
|
||||
|
||||
/**
|
||||
Implementation of Drop_table_error_handler::handle_error().
|
||||
Implementation of Drop_table_error_handler::handle_condition().
|
||||
The reason in having this implementation is to silence technical low-level
|
||||
warnings during DROP TABLE operation. Currently we don't want to expose
|
||||
the following warnings during DROP TABLE:
|
||||
@ -503,7 +489,7 @@ THD::THD()
|
||||
killed= NOT_KILLED;
|
||||
col_access=0;
|
||||
is_slave_error= thread_specific_used= FALSE;
|
||||
hash_clear(&handler_tables_hash);
|
||||
my_hash_clear(&handler_tables_hash);
|
||||
tmp_table=0;
|
||||
used_tables=0;
|
||||
cuted_fields= 0L;
|
||||
@ -536,9 +522,6 @@ THD::THD()
|
||||
net.vio=0;
|
||||
#endif
|
||||
client_capabilities= 0; // minimalistic client
|
||||
#ifdef HAVE_QUERY_CACHE
|
||||
query_cache_init_query(&net); // If error on boot
|
||||
#endif
|
||||
ull=0;
|
||||
system_thread= NON_SYSTEM_THREAD;
|
||||
cleanup_done= abort_on_warning= no_warnings_for_error= 0;
|
||||
@ -559,13 +542,13 @@ THD::THD()
|
||||
*scramble= '\0';
|
||||
|
||||
init();
|
||||
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
|
||||
#if defined(ENABLED_PROFILING)
|
||||
profiling.set_thd(this);
|
||||
#endif
|
||||
user_connect=(USER_CONN *)0;
|
||||
hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
|
||||
(hash_get_key) get_var_key,
|
||||
(hash_free_key) free_user_var, 0);
|
||||
my_hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
|
||||
(my_hash_get_key) get_var_key,
|
||||
(my_hash_free_key) free_user_var, 0);
|
||||
|
||||
sp_proc_cache= NULL;
|
||||
sp_func_cache= NULL;
|
||||
@ -831,7 +814,7 @@ THD::raise_condition_no_handler(uint sql_errno,
|
||||
MYSQL_ERROR *cond= NULL;
|
||||
DBUG_ENTER("THD::raise_condition_no_handler");
|
||||
|
||||
query_cache_abort(& net);
|
||||
query_cache_abort(&query_cache_tls);
|
||||
|
||||
/* FIXME: broken special case */
|
||||
if (no_warnings_for_error && (level == MYSQL_ERROR::WARN_LEVEL_ERROR))
|
||||
@ -985,9 +968,9 @@ void THD::change_user(void)
|
||||
cleanup_done= 0;
|
||||
init();
|
||||
stmt_map.reset();
|
||||
hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
|
||||
(hash_get_key) get_var_key,
|
||||
(hash_free_key) free_user_var, 0);
|
||||
my_hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
|
||||
(my_hash_get_key) get_var_key,
|
||||
(my_hash_free_key) free_user_var, 0);
|
||||
sp_cache_clear(&sp_proc_cache);
|
||||
sp_cache_clear(&sp_func_cache);
|
||||
}
|
||||
@ -1024,7 +1007,7 @@ void THD::cleanup(void)
|
||||
|
||||
mysql_ha_cleanup(this);
|
||||
delete_dynamic(&user_var_events);
|
||||
hash_free(&user_vars);
|
||||
my_hash_free(&user_vars);
|
||||
close_temporary_tables(this);
|
||||
my_free((char*) variables.time_format, MYF(MY_ALLOW_ZERO_PTR));
|
||||
my_free((char*) variables.date_format, MYF(MY_ALLOW_ZERO_PTR));
|
||||
@ -1542,8 +1525,8 @@ int THD::send_explain_fields(select_result *result)
|
||||
}
|
||||
item->maybe_null= 1;
|
||||
field_list.push_back(new Item_empty_string("Extra", 255, cs));
|
||||
return (result->send_fields(field_list,
|
||||
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF));
|
||||
return (result->send_result_set_metadata(field_list,
|
||||
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF));
|
||||
}
|
||||
|
||||
#ifdef SIGNAL_WITH_VIO_CLOSE
|
||||
@ -1670,10 +1653,10 @@ bool sql_exchange::escaped_given(void)
|
||||
}
|
||||
|
||||
|
||||
bool select_send::send_fields(List<Item> &list, uint flags)
|
||||
bool select_send::send_result_set_metadata(List<Item> &list, uint flags)
|
||||
{
|
||||
bool res;
|
||||
if (!(res= thd->protocol->send_fields(&list, flags)))
|
||||
if (!(res= thd->protocol->send_result_set_metadata(&list, flags)))
|
||||
is_result_set_started= 1;
|
||||
return res;
|
||||
}
|
||||
@ -1714,10 +1697,13 @@ void select_send::cleanup()
|
||||
|
||||
bool select_send::send_data(List<Item> &items)
|
||||
{
|
||||
Protocol *protocol= thd->protocol;
|
||||
DBUG_ENTER("select_send::send_data");
|
||||
|
||||
if (unit->offset_limit_cnt)
|
||||
{ // using limit offset,count
|
||||
unit->offset_limit_cnt--;
|
||||
return 0;
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1727,36 +1713,18 @@ bool select_send::send_data(List<Item> &items)
|
||||
*/
|
||||
ha_release_temporary_latches(thd);
|
||||
|
||||
List_iterator_fast<Item> li(items);
|
||||
Protocol *protocol= thd->protocol;
|
||||
char buff[MAX_FIELD_WIDTH];
|
||||
String buffer(buff, sizeof(buff), &my_charset_bin);
|
||||
DBUG_ENTER("select_send::send_data");
|
||||
|
||||
protocol->prepare_for_resend();
|
||||
Item *item;
|
||||
while ((item=li++))
|
||||
{
|
||||
if (item->send(protocol, &buffer))
|
||||
{
|
||||
protocol->free(); // Free used buffer
|
||||
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
|
||||
break;
|
||||
}
|
||||
/*
|
||||
Reset buffer to its original state, as it may have been altered in
|
||||
Item::send().
|
||||
*/
|
||||
buffer.set(buff, sizeof(buff), &my_charset_bin);
|
||||
}
|
||||
thd->sent_row_count++;
|
||||
if (thd->is_error())
|
||||
if (protocol->send_result_set_row(&items))
|
||||
{
|
||||
protocol->remove_last_row();
|
||||
DBUG_RETURN(1);
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
thd->sent_row_count++;
|
||||
|
||||
if (thd->vio_ok())
|
||||
DBUG_RETURN(protocol->write());
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
@ -2530,12 +2498,12 @@ Statement::Statement(LEX *lex_arg, MEM_ROOT *mem_root_arg,
|
||||
id(id_arg),
|
||||
mark_used_columns(MARK_COLUMNS_READ),
|
||||
lex(lex_arg),
|
||||
query(0),
|
||||
query_length(0),
|
||||
cursor(0),
|
||||
db(NULL),
|
||||
db_length(0)
|
||||
{
|
||||
query_string.length= 0;
|
||||
query_string.str= NULL;
|
||||
name.str= NULL;
|
||||
}
|
||||
|
||||
@ -2551,8 +2519,7 @@ void Statement::set_statement(Statement *stmt)
|
||||
id= stmt->id;
|
||||
mark_used_columns= stmt->mark_used_columns;
|
||||
lex= stmt->lex;
|
||||
query= stmt->query;
|
||||
query_length= stmt->query_length;
|
||||
query_string= stmt->query_string;
|
||||
cursor= stmt->cursor;
|
||||
}
|
||||
|
||||
@ -2576,6 +2543,15 @@ void Statement::restore_backup_statement(Statement *stmt, Statement *backup)
|
||||
}
|
||||
|
||||
|
||||
/** Assign a new value to thd->query. */
|
||||
|
||||
void Statement::set_query_inner(char *query_arg, uint32 query_length_arg)
|
||||
{
|
||||
query_string.str= query_arg;
|
||||
query_string.length= query_length_arg;
|
||||
}
|
||||
|
||||
|
||||
void THD::end_statement()
|
||||
{
|
||||
/* Cleanup SQL processing state to reuse this statement in next query. */
|
||||
@ -2654,12 +2630,12 @@ Statement_map::Statement_map() :
|
||||
START_STMT_HASH_SIZE = 16,
|
||||
START_NAME_HASH_SIZE = 16
|
||||
};
|
||||
hash_init(&st_hash, &my_charset_bin, START_STMT_HASH_SIZE, 0, 0,
|
||||
get_statement_id_as_hash_key,
|
||||
delete_statement_as_hash_key, MYF(0));
|
||||
hash_init(&names_hash, system_charset_info, START_NAME_HASH_SIZE, 0, 0,
|
||||
(hash_get_key) get_stmt_name_hash_key,
|
||||
NULL,MYF(0));
|
||||
my_hash_init(&st_hash, &my_charset_bin, START_STMT_HASH_SIZE, 0, 0,
|
||||
get_statement_id_as_hash_key,
|
||||
delete_statement_as_hash_key, MYF(0));
|
||||
my_hash_init(&names_hash, system_charset_info, START_NAME_HASH_SIZE, 0, 0,
|
||||
(my_hash_get_key) get_stmt_name_hash_key,
|
||||
NULL,MYF(0));
|
||||
}
|
||||
|
||||
|
||||
@ -2724,9 +2700,9 @@ int Statement_map::insert(THD *thd, Statement *statement)
|
||||
|
||||
err_max:
|
||||
if (statement->name.str)
|
||||
hash_delete(&names_hash, (uchar*) statement);
|
||||
my_hash_delete(&names_hash, (uchar*) statement);
|
||||
err_names_hash:
|
||||
hash_delete(&st_hash, (uchar*) statement);
|
||||
my_hash_delete(&st_hash, (uchar*) statement);
|
||||
err_st_hash:
|
||||
return 1;
|
||||
}
|
||||
@ -2747,9 +2723,9 @@ void Statement_map::erase(Statement *statement)
|
||||
if (statement == last_found_statement)
|
||||
last_found_statement= 0;
|
||||
if (statement->name.str)
|
||||
hash_delete(&names_hash, (uchar *) statement);
|
||||
my_hash_delete(&names_hash, (uchar *) statement);
|
||||
|
||||
hash_delete(&st_hash, (uchar *) statement);
|
||||
my_hash_delete(&st_hash, (uchar *) statement);
|
||||
pthread_mutex_lock(&LOCK_prepared_stmt_count);
|
||||
DBUG_ASSERT(prepared_stmt_count > 0);
|
||||
prepared_stmt_count--;
|
||||
@ -2779,8 +2755,8 @@ Statement_map::~Statement_map()
|
||||
prepared_stmt_count-= st_hash.records;
|
||||
pthread_mutex_unlock(&LOCK_prepared_stmt_count);
|
||||
|
||||
hash_free(&names_hash);
|
||||
hash_free(&st_hash);
|
||||
my_hash_free(&names_hash);
|
||||
my_hash_free(&st_hash);
|
||||
}
|
||||
|
||||
bool select_dumpvar::send_data(List<Item> &items)
|
||||
@ -2811,9 +2787,11 @@ bool select_dumpvar::send_data(List<Item> &items)
|
||||
else
|
||||
{
|
||||
Item_func_set_user_var *suv= new Item_func_set_user_var(mv->s, item);
|
||||
suv->fix_fields(thd, 0);
|
||||
if (suv->fix_fields(thd, 0))
|
||||
DBUG_RETURN (1);
|
||||
suv->save_item_result(item);
|
||||
suv->update();
|
||||
if (suv->update())
|
||||
DBUG_RETURN (1);
|
||||
}
|
||||
}
|
||||
DBUG_RETURN(thd->is_error());
|
||||
@ -3089,9 +3067,24 @@ extern "C" struct charset_info_st *thd_charset(MYSQL_THD thd)
|
||||
return(thd->charset());
|
||||
}
|
||||
|
||||
/**
|
||||
OBSOLETE : there's no way to ensure the string is null terminated.
|
||||
Use thd_query_string instead()
|
||||
*/
|
||||
extern "C" char **thd_query(MYSQL_THD thd)
|
||||
{
|
||||
return(&thd->query);
|
||||
return(&thd->query_string.str);
|
||||
}
|
||||
|
||||
/**
|
||||
Get the current query string for the thread.
|
||||
|
||||
@param The MySQL internal thread pointer
|
||||
@return query string and length. May be non-null-terminated.
|
||||
*/
|
||||
extern "C" LEX_STRING * thd_query_string (MYSQL_THD thd)
|
||||
{
|
||||
return(&thd->query_string);
|
||||
}
|
||||
|
||||
extern "C" int thd_slave_thread(const MYSQL_THD thd)
|
||||
@ -3116,6 +3109,11 @@ extern "C" void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all)
|
||||
{
|
||||
mark_transaction_to_rollback(thd, all);
|
||||
}
|
||||
|
||||
extern "C" bool thd_binlog_filter_ok(const MYSQL_THD thd)
|
||||
{
|
||||
return binlog_filter->db_ok(thd->db);
|
||||
}
|
||||
#endif // INNODB_COMPATIBILITY_HOOKS */
|
||||
|
||||
/****************************************************************************
|
||||
@ -3270,8 +3268,7 @@ void THD::set_statement(Statement *stmt)
|
||||
void THD::set_query(char *query_arg, uint32 query_length_arg)
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_thd_data);
|
||||
query= query_arg;
|
||||
query_length= query_length_arg;
|
||||
set_query_inner(query_arg, query_length_arg);
|
||||
pthread_mutex_unlock(&LOCK_thd_data);
|
||||
}
|
||||
|
||||
@ -3289,6 +3286,16 @@ void mark_transaction_to_rollback(THD *thd, bool all)
|
||||
{
|
||||
thd->is_fatal_sub_stmt_error= TRUE;
|
||||
thd->transaction_rollback_request= all;
|
||||
/*
|
||||
Aborted transactions can not be IGNOREd.
|
||||
Switch off the IGNORE flag for the current
|
||||
SELECT_LEX. This should allow my_error()
|
||||
to report the error and abort the execution
|
||||
flow, even in presence
|
||||
of IGNORE clause.
|
||||
*/
|
||||
if (thd->lex->current_select)
|
||||
thd->lex->current_select->no_error= FALSE;
|
||||
}
|
||||
}
|
||||
/***************************************************************************
|
||||
@ -3317,15 +3324,15 @@ void xid_free_hash(void *ptr)
|
||||
bool xid_cache_init()
|
||||
{
|
||||
pthread_mutex_init(&LOCK_xid_cache, MY_MUTEX_INIT_FAST);
|
||||
return hash_init(&xid_cache, &my_charset_bin, 100, 0, 0,
|
||||
xid_get_hash_key, xid_free_hash, 0) != 0;
|
||||
return my_hash_init(&xid_cache, &my_charset_bin, 100, 0, 0,
|
||||
xid_get_hash_key, xid_free_hash, 0) != 0;
|
||||
}
|
||||
|
||||
void xid_cache_free()
|
||||
{
|
||||
if (hash_inited(&xid_cache))
|
||||
if (my_hash_inited(&xid_cache))
|
||||
{
|
||||
hash_free(&xid_cache);
|
||||
my_hash_free(&xid_cache);
|
||||
pthread_mutex_destroy(&LOCK_xid_cache);
|
||||
}
|
||||
}
|
||||
@ -3333,7 +3340,8 @@ void xid_cache_free()
|
||||
XID_STATE *xid_cache_search(XID *xid)
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_xid_cache);
|
||||
XID_STATE *res=(XID_STATE *)hash_search(&xid_cache, xid->key(), xid->key_length());
|
||||
XID_STATE *res=(XID_STATE *)my_hash_search(&xid_cache, xid->key(),
|
||||
xid->key_length());
|
||||
pthread_mutex_unlock(&LOCK_xid_cache);
|
||||
return res;
|
||||
}
|
||||
@ -3344,7 +3352,7 @@ bool xid_cache_insert(XID *xid, enum xa_states xa_state)
|
||||
XID_STATE *xs;
|
||||
my_bool res;
|
||||
pthread_mutex_lock(&LOCK_xid_cache);
|
||||
if (hash_search(&xid_cache, xid->key(), xid->key_length()))
|
||||
if (my_hash_search(&xid_cache, xid->key(), xid->key_length()))
|
||||
res=0;
|
||||
else if (!(xs=(XID_STATE *)my_malloc(sizeof(*xs), MYF(MY_WME))))
|
||||
res=1;
|
||||
@ -3363,8 +3371,8 @@ bool xid_cache_insert(XID *xid, enum xa_states xa_state)
|
||||
bool xid_cache_insert(XID_STATE *xid_state)
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_xid_cache);
|
||||
DBUG_ASSERT(hash_search(&xid_cache, xid_state->xid.key(),
|
||||
xid_state->xid.key_length())==0);
|
||||
DBUG_ASSERT(my_hash_search(&xid_cache, xid_state->xid.key(),
|
||||
xid_state->xid.key_length())==0);
|
||||
my_bool res=my_hash_insert(&xid_cache, (uchar*)xid_state);
|
||||
pthread_mutex_unlock(&LOCK_xid_cache);
|
||||
return res;
|
||||
@ -3374,7 +3382,7 @@ bool xid_cache_insert(XID_STATE *xid_state)
|
||||
void xid_cache_delete(XID_STATE *xid_state)
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_xid_cache);
|
||||
hash_delete(&xid_cache, (uchar *)xid_state);
|
||||
my_hash_delete(&xid_cache, (uchar *)xid_state);
|
||||
pthread_mutex_unlock(&LOCK_xid_cache);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user