diff options
Diffstat (limited to 'sql/sql_class.cc')
-rw-r--r-- | sql/sql_class.cc | 139 |
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; |