summaryrefslogtreecommitdiff
path: root/sql/sql_class.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_class.cc')
-rw-r--r--sql/sql_class.cc139
1 files changed, 89 insertions, 50 deletions
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index fc078640a96..e8e39972020 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -192,14 +192,10 @@ void **thd_ha_data(const THD *thd, const struct handlerton *hton)
}
-/*
- Pass nominal parameters to Statement constructor only to ensure that
- the destructor works OK in case of error. The main_mem_root will be
- re-initialized in init().
-*/
THD::THD()
- :Statement(CONVENTIONAL_EXECUTION, 0, ALLOC_ROOT_MIN_BLOCK_SIZE, 0),
+ :Statement(&main_lex, &main_mem_root, CONVENTIONAL_EXECUTION,
+ /* statement id */ 0),
Open_tables_state(refresh_version), rli_fake(0),
lock_id(&main_lock_id),
user_time(0), in_sub_stmt(0),
@@ -214,6 +210,14 @@ THD::THD()
stmt_depends_on_first_successful_insert_id_in_prev_stmt(FALSE),
spcont(NULL)
{
+ ulong tmp;
+
+ /*
+ Pass nominal parameters to init_alloc_root only to ensure that
+ the destructor works OK in case of an error. The main_mem_root
+ will be re-initialized in init_for_queries().
+ */
+ init_sql_alloc(&main_mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0);
stmt_arena= this;
thread_stack= 0;
db= 0;
@@ -241,7 +245,7 @@ THD::THD()
time_after_lock=(time_t) 0;
current_linfo = 0;
slave_thread = 0;
- variables.pseudo_thread_id= 0;
+ thread_id= variables.pseudo_thread_id= 0;
one_shot_set= 0;
file_id = 0;
query_id= 0;
@@ -265,9 +269,6 @@ THD::THD()
cleanup_done= abort_on_warning= no_warnings_for_error= 0;
peer_port= 0; // For SHOW PROCESSLIST
transaction.m_pending_rows_event= 0;
-#ifdef __WIN__
- real_id = 0;
-#endif
#ifdef SIGNAL_WITH_VIO_CLOSE
active_vio = 0;
#endif
@@ -305,11 +306,43 @@ THD::THD()
protocol_binary.init(this);
tablespace_op=FALSE;
- ulong tmp=sql_rnd_with_mutex();
- randominit(&rand, tmp + (ulong) &rand, tmp + (ulong) ::query_id);
+ tmp= sql_rnd_with_mutex();
+ randominit(&rand, tmp + (ulong) &rand, tmp + (ulong) ::global_query_id);
substitute_null_with_insert_id = FALSE;
thr_lock_info_init(&lock_info); /* safety: will be reset after start */
thr_lock_owner_init(&main_lock_id, &lock_info);
+
+ m_internal_handler= NULL;
+}
+
+
+void THD::push_internal_handler(Internal_error_handler *handler)
+{
+ /*
+ TODO: The current implementation is limited to 1 handler at a time only.
+ THD and sp_rcontext need to be modified to use a common handler stack.
+ */
+ DBUG_ASSERT(m_internal_handler == NULL);
+ m_internal_handler= handler;
+}
+
+
+bool THD::handle_error(uint sql_errno,
+ MYSQL_ERROR::enum_warning_level level)
+{
+ if (m_internal_handler)
+ {
+ return m_internal_handler->handle_error(sql_errno, level, this);
+ }
+
+ return FALSE; // 'FALSE', as per coding style
+}
+
+
+void THD::pop_internal_handler()
+{
+ DBUG_ASSERT(m_internal_handler != NULL);
+ m_internal_handler= NULL;
}
@@ -355,6 +388,7 @@ void THD::init(void)
void THD::init_for_queries()
{
+ set_time();
ha_enable_transaction(this,TRUE);
reset_root_defaults(mem_root, variables.query_alloc_block_size,
@@ -399,6 +433,8 @@ void THD::change_user(void)
void THD::cleanup(void)
{
DBUG_ENTER("THD::cleanup");
+ DBUG_ASSERT(cleanup_done == 0);
+
#ifdef ENABLE_WHEN_BINLOG_WILL_BE_ABLE_TO_PREPARE
if (transaction.xid_state.xa_state == XA_PREPARED)
{
@@ -434,7 +470,6 @@ void THD::cleanup(void)
pthread_mutex_lock(&LOCK_user_locks);
item_user_lock_release(ull);
pthread_mutex_unlock(&LOCK_user_locks);
- ull= 0;
}
cleanup_done=1;
@@ -483,6 +518,7 @@ THD::~THD()
delete rli_fake;
#endif
+ free_root(&main_mem_root, MYF(0));
DBUG_VOID_RETURN;
}
@@ -548,7 +584,9 @@ void THD::awake(THD::killed_state state_to_set)
killed= state_to_set;
if (state_to_set != THD::KILL_QUERY)
{
- thr_alarm_kill(real_id);
+ thr_alarm_kill(thread_id);
+ if (!slave_thread)
+ thread_scheduler.post_kill_notification(this);
#ifdef SIGNAL_WITH_VIO_CLOSE
close_active_vio();
#endif
@@ -599,18 +637,19 @@ bool THD::store_globals()
Assert that thread_stack is initialized: it's necessary to be able
to track stack overrun.
*/
- DBUG_ASSERT(this->thread_stack);
+ DBUG_ASSERT(thread_stack);
if (my_pthread_setspecific_ptr(THR_THD, this) ||
my_pthread_setspecific_ptr(THR_MALLOC, &mem_root))
return 1;
mysys_var=my_thread_var;
- dbug_thread_id=my_thread_id();
/*
- By default 'slave_proxy_id' is 'thread_id'. They may later become different
- if this is the slave SQL thread.
+ Let mysqld define the thread id (not mysys)
+ This allows us to move THD to different threads if needed.
*/
- variables.pseudo_thread_id= thread_id;
+ mysys_var->id= thread_id;
+ real_id= pthread_self(); // For debugging
+
/*
We have to call thr_lock_info_init() again here as THD may have been
created in another thread
@@ -993,6 +1032,7 @@ sql_exchange::sql_exchange(char *name,bool flag)
enclosed= line_start= &my_empty_string;
line_term= &default_line_term;
escaped= &default_escaped;
+ cs= NULL;
}
bool select_send::send_fields(List<Item> &list, uint flags)
@@ -1532,7 +1572,7 @@ bool select_max_min_finder_subselect::send_data(List<Item> &items)
bool select_max_min_finder_subselect::cmp_real()
{
- Item *maxmin= ((Item_singlerow_subselect *)item)->el(0);
+ Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
double val1= cache->val_real(), val2= maxmin->val_real();
if (fmax)
return (cache->null_value && !maxmin->null_value) ||
@@ -1545,7 +1585,7 @@ bool select_max_min_finder_subselect::cmp_real()
bool select_max_min_finder_subselect::cmp_int()
{
- Item *maxmin= ((Item_singlerow_subselect *)item)->el(0);
+ Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
longlong val1= cache->val_int(), val2= maxmin->val_int();
if (fmax)
return (cache->null_value && !maxmin->null_value) ||
@@ -1558,7 +1598,7 @@ bool select_max_min_finder_subselect::cmp_int()
bool select_max_min_finder_subselect::cmp_decimal()
{
- Item *maxmin= ((Item_singlerow_subselect *)item)->el(0);
+ Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
my_decimal cval, *cvalue= cache->val_decimal(&cval);
my_decimal mval, *mvalue= maxmin->val_decimal(&mval);
if (fmax)
@@ -1573,7 +1613,7 @@ bool select_max_min_finder_subselect::cmp_decimal()
bool select_max_min_finder_subselect::cmp_str()
{
String *val1, *val2, buf1, buf2;
- Item *maxmin= ((Item_singlerow_subselect *)item)->el(0);
+ Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
/*
as far as both operand is Item_cache buf1 & buf2 will not be used,
but added for safety
@@ -1674,18 +1714,17 @@ void Query_arena::cleanup_stmt()
Statement functions
*/
-Statement::Statement(enum enum_state state_arg, ulong id_arg,
- ulong alloc_block_size, ulong prealloc_size)
- :Query_arena(&main_mem_root, state_arg),
+Statement::Statement(LEX *lex_arg, MEM_ROOT *mem_root_arg,
+ enum enum_state state_arg, ulong id_arg)
+ :Query_arena(mem_root_arg, state_arg),
id(id_arg),
mark_used_columns(MARK_COLUMNS_READ),
- lex(&main_lex),
+ lex(lex_arg),
query(0),
query_length(0),
cursor(0)
{
name.str= NULL;
- init_sql_alloc(&main_mem_root, alloc_block_size, prealloc_size);
}
@@ -1727,7 +1766,7 @@ void Statement::restore_backup_statement(Statement *stmt, Statement *backup)
void THD::end_statement()
{
- /* Cleanup SQL processing state to resuse this statement in next query. */
+ /* Cleanup SQL processing state to reuse this statement in next query. */
lex_end(lex);
delete lex->result;
lex->result= 0;
@@ -1768,12 +1807,6 @@ void THD::restore_active_arena(Query_arena *set, Query_arena *backup)
Statement::~Statement()
{
- /*
- We must free `main_mem_root', not `mem_root' (pointer), to work
- correctly if this statement is used as a backup statement,
- for which `mem_root' may point to some other statement.
- */
- free_root(&main_mem_root, MYF(0));
}
C_MODE_START
@@ -2154,7 +2187,12 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
!current_stmt_binlog_row_based)
{
options&= ~OPTION_BIN_LOG;
- }
+ }
+
+ if ((backup->options & OPTION_BIN_LOG) && is_update_query(lex->sql_command)&&
+ !current_stmt_binlog_row_based)
+ mysql_bin_log.start_union_events(this, this->query_id);
+
/* Disable result sets */
client_capabilities &= ~CLIENT_MULTI_RESULTS;
in_sub_stmt|= new_state;
@@ -2198,6 +2236,10 @@ void THD::restore_sub_statement_state(Sub_statement_state *backup)
sent_row_count= backup->sent_row_count;
client_capabilities= backup->client_capabilities;
+ if ((options & OPTION_BIN_LOG) && is_update_query(lex->sql_command) &&
+ !current_stmt_binlog_row_based)
+ mysql_bin_log.stop_union_events(this);
+
/*
The following is added to the old values as we are interested in the
total complexity of the query
@@ -2407,11 +2449,12 @@ THD::binlog_prepare_pending_rows_event(TABLE*, uint32, MY_BITMAP const*,
my_size_t colcnt, my_size_t, bool,
Update_rows_log_event *);
#endif
+
+#ifdef NOT_USED
static char const*
field_type_name(enum_field_types type)
{
- switch (type)
- {
+ switch (type) {
case MYSQL_TYPE_DECIMAL:
return "MYSQL_TYPE_DECIMAL";
case MYSQL_TYPE_TINY:
@@ -2469,6 +2512,7 @@ field_type_name(enum_field_types type)
}
return "Unknown";
}
+#endif
my_size_t THD::max_row_length_blob(TABLE *table, const byte *data) const
@@ -2507,7 +2551,7 @@ my_size_t THD::pack_row(TABLE *table, MY_BITMAP const* cols, byte *row_data,
if (bitmap_is_set(cols,i))
{
my_ptrdiff_t const offset=
- field->is_null(rec_offset) ? def_offset : rec_offset;
+ field->is_null((uint) rec_offset) ? def_offset : rec_offset;
field->move_field_offset(offset);
ptr= (byte*)field->pack((char *) ptr, field->ptr);
field->move_field_offset(-offset);
@@ -2549,7 +2593,7 @@ namespace {
: m_memory(0)
{
#ifndef DBUG_OFF
- m_alloc_checked= false;
+ m_alloc_checked= FALSE;
#endif
allocate_memory(table, len1);
m_ptr[0]= has_memory() ? m_memory : 0;
@@ -2560,7 +2604,7 @@ namespace {
: m_memory(0)
{
#ifndef DBUG_OFF
- m_alloc_checked= false;
+ m_alloc_checked= FALSE;
#endif
allocate_memory(table, len1 + len2);
m_ptr[0]= has_memory() ? m_memory : 0;
@@ -2581,7 +2625,7 @@ namespace {
*/
bool has_memory() const {
#ifndef DBUG_OFF
- m_alloc_checked= true;
+ m_alloc_checked= TRUE;
#endif
return m_memory != 0;
}
@@ -2590,7 +2634,7 @@ namespace {
{
DBUG_ASSERT(s < sizeof(m_ptr)/sizeof(*m_ptr));
DBUG_ASSERT(m_ptr[s] != 0);
- DBUG_ASSERT(m_alloc_checked == true);
+ DBUG_ASSERT(m_alloc_checked == TRUE);
return m_ptr[s];
}
@@ -2620,12 +2664,12 @@ namespace {
table->write_row_record=
(byte *) alloc_root(&table->mem_root, 2 * maxlen);
m_memory= table->write_row_record;
- m_release_memory_on_destruction= false;
+ m_release_memory_on_destruction= FALSE;
}
else
{
m_memory= (byte *) my_malloc(total_length, MYF(MY_WME));
- m_release_memory_on_destruction= true;
+ m_release_memory_on_destruction= TRUE;
}
}
@@ -2649,8 +2693,6 @@ int THD::binlog_write_row(TABLE* table, bool is_trans,
Pack records into format for transfer. We are allocating more
memory than needed, but that doesn't matter.
*/
- int error= 0;
-
Row_data_memory memory(table, max_row_length(table, record));
if (!memory.has_memory())
return HA_ERR_OUT_OF_MEM;
@@ -2677,7 +2719,6 @@ int THD::binlog_update_row(TABLE* table, bool is_trans,
{
DBUG_ASSERT(current_stmt_binlog_row_based && mysql_bin_log.is_open());
- int error= 0;
my_size_t const before_maxlen = max_row_length(table, before_record);
my_size_t const after_maxlen = max_row_length(table, after_record);
@@ -2727,8 +2768,6 @@ int THD::binlog_delete_row(TABLE* table, bool is_trans,
Pack records into format for transfer. We are allocating more
memory than needed, but that doesn't matter.
*/
- int error= 0;
-
Row_data_memory memory(table, max_row_length(table, record));
if (unlikely(!memory.has_memory()))
return HA_ERR_OUT_OF_MEM;