1
0
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:
Martin Hansson
2009-11-20 13:29:43 +01:00
552 changed files with 20776 additions and 7322 deletions

View File

@ -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);
}