1
/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
/*****************************************************************************
19
** This file implements classes defined in sql_class.h
20
** Especially the classes to handle a result from a select
22
*****************************************************************************/
24
#ifdef USE_PRAGMA_IMPLEMENTATION
25
#pragma implementation // gcc: Class implementation
28
#include "mysql_priv.h"
30
#include "rpl_filter.h"
31
#include "rpl_record.h"
33
#include <my_bitmap.h>
34
#include "log_event.h"
37
#include <thr_alarm.h>
41
#include <mysys_err.h>
43
#include "sp_rcontext.h"
45
#include "debug_sync.h"
48
The following is used to initialise Table_ident with a internal
51
char internal_table_name[2]= "*";
52
char empty_c_string[1]= {0}; /* used for not defined db */
54
const char * const THD::DEFAULT_WHERE= "field list";
57
/*****************************************************************************
58
** Instansiate templates
59
*****************************************************************************/
61
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
63
template class List<Key>;
64
template class List_iterator<Key>;
65
template class List<Key_part_spec>;
66
template class List_iterator<Key_part_spec>;
67
template class List<Alter_drop>;
68
template class List_iterator<Alter_drop>;
69
template class List<Alter_column>;
70
template class List_iterator<Alter_column>;
73
/****************************************************************************
75
****************************************************************************/
77
extern "C" uchar *get_var_key(user_var_entry *entry, size_t *length,
78
my_bool not_used __attribute__((unused)))
80
*length= entry->name.length;
81
return (uchar*) entry->name.str;
84
extern "C" void free_user_var(user_var_entry *entry)
86
char *pos= (char*) entry+ALIGN_SIZE(sizeof(*entry));
87
if (entry->value && entry->value != pos)
88
my_free(entry->value, MYF(0));
89
my_free((char*) entry,MYF(0));
92
bool Key_part_spec::operator==(const Key_part_spec& other) const
94
return length == other.length && !strcmp(field_name, other.field_name);
98
Construct an (almost) deep copy of this key. Only those
99
elements that are known to never change are not copied.
100
If out of memory, a partial copy is returned and an error is set
104
Key::Key(const Key &rhs, MEM_ROOT *mem_root)
106
key_create_info(rhs.key_create_info),
107
columns(rhs.columns, mem_root),
109
generated(rhs.generated)
111
list_copy_and_replace_each_value(columns, mem_root);
115
Construct an (almost) deep copy of this foreign key. Only those
116
elements that are known to never change are not copied.
117
If out of memory, a partial copy is returned and an error is set
121
Foreign_key::Foreign_key(const Foreign_key &rhs, MEM_ROOT *mem_root)
123
ref_table(rhs.ref_table),
124
ref_columns(rhs.ref_columns),
125
delete_opt(rhs.delete_opt),
126
update_opt(rhs.update_opt),
127
match_opt(rhs.match_opt)
129
list_copy_and_replace_each_value(ref_columns, mem_root);
133
Test if a foreign key (= generated key) is a prefix of the given key
134
(ignoring key name, key type and order of columns)
137
This is only used to test if an index for a FOREIGN KEY exists
140
We only compare field names
143
0 Generated key is a prefix of other key
147
bool foreign_key_prefix(Key *a, Key *b)
149
/* Ensure that 'a' is the generated key */
152
if (b->generated && a->columns.elements > b->columns.elements)
153
swap_variables(Key*, a, b); // Put shorter key in 'a'
158
return TRUE; // No foreign key
159
swap_variables(Key*, a, b); // Put generated key in 'a'
162
/* Test if 'a' is a prefix of 'b' */
163
if (a->columns.elements > b->columns.elements)
164
return TRUE; // Can't be prefix
166
List_iterator<Key_part_spec> col_it1(a->columns);
167
List_iterator<Key_part_spec> col_it2(b->columns);
168
const Key_part_spec *col1, *col2;
170
#ifdef ENABLE_WHEN_INNODB_CAN_HANDLE_SWAPED_FOREIGN_KEY_COLUMNS
171
while ((col1= col_it1++))
175
while ((col2= col_it2++))
184
return TRUE; // Error
186
return FALSE; // Is prefix
188
while ((col1= col_it1++))
191
if (!(*col1 == *col2))
194
return FALSE; // Is prefix
199
/****************************************************************************
200
** Thread specific functions
201
****************************************************************************/
203
/** Push an error to the error stack and return TRUE for now. */
206
Reprepare_observer::report_error(THD *thd)
208
my_error(ER_NEED_REPREPARE, MYF(ME_NO_WARNING_FOR_ERROR|ME_NO_SP_HANDLER));
216
Open_tables_state::Open_tables_state(ulong version_arg)
217
:version(version_arg), state_flags(0U)
219
reset_open_tables_state();
223
The following functions form part of the C plugin API
226
extern "C" int mysql_tmpfile(const char *prefix)
228
char filename[FN_REFLEN];
229
File fd = create_temp_file(filename, mysql_tmpdir, prefix,
231
O_BINARY | O_TRUNC | O_SEQUENTIAL |
234
O_CREAT | O_EXCL | O_RDWR | O_TEMPORARY,
239
This can be removed once the following bug is fixed:
240
Bug #28903 create_temp_file() doesn't honor O_TEMPORARY option
241
(file not removed) (Unix)
244
#endif /* !__WIN__ */
252
int thd_in_lock_tables(const THD *thd)
254
return test(thd->in_lock_tables);
259
int thd_tablespace_op(const THD *thd)
261
return test(thd->tablespace_op);
266
const char *set_thd_proc_info(THD *thd, const char *info,
267
const char *calling_function,
268
const char *calling_file,
269
const unsigned int calling_line)
271
const char *old_info= thd->proc_info;
272
DBUG_PRINT("proc_info", ("%s:%d %s", calling_file, calling_line,
273
(info != NULL) ? info : "(null)"));
274
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
275
thd->profiling.status_change(info, calling_function, calling_file, calling_line);
277
thd->proc_info= info;
282
void **thd_ha_data(const THD *thd, const struct handlerton *hton)
284
return (void **) &thd->ha_data[hton->slot].ha_ptr;
288
long long thd_test_options(const THD *thd, long long test_options)
290
return thd->options & test_options;
294
int thd_sql_command(const THD *thd)
296
return (int) thd->lex->sql_command;
300
int thd_tx_isolation(const THD *thd)
302
return (int) thd->variables.tx_isolation;
306
void thd_inc_row_count(THD *thd)
313
Dumps a text description of a thread, its security context
314
(user, host) and the current query.
316
@param thd thread context
317
@param buffer pointer to preferred result buffer
318
@param length length of buffer
319
@param max_query_len how many chars of query to copy (0 for all)
321
@req LOCK_thread_count
323
@note LOCK_thread_count mutex is not necessary when the function is invoked on
324
the currently running thread (current_thd) or if the caller in some other
325
way guarantees that access to thd->query is serialized.
327
@return Pointer to string
331
char *thd_security_context(THD *thd, char *buffer, unsigned int length,
332
unsigned int max_query_len)
334
String str(buffer, length, &my_charset_latin1);
335
const Security_context *sctx= &thd->main_security_ctx;
339
The pointers thd->query and thd->proc_info might change since they are
340
being modified concurrently. This is acceptable for proc_info since its
341
values doesn't have to very accurate and the memory it points to is static,
342
but we need to attempt a snapshot on the pointer values to avoid using NULL
343
values. The pointer to thd->query however, doesn't point to static memory
344
and has to be protected by LOCK_thread_count or risk pointing to
345
uninitialized memory.
347
const char *proc_info= thd->proc_info;
349
len= my_snprintf(header, sizeof(header),
350
"MySQL thread id %lu, query id %lu",
351
thd->thread_id, (ulong) thd->query_id);
353
str.append(header, len);
358
str.append(sctx->host);
364
str.append(sctx->ip);
370
str.append(sctx->user);
376
str.append(proc_info);
379
pthread_mutex_lock(&thd->LOCK_thd_data);
383
if (max_query_len < 1)
384
len= thd->query_length();
386
len= min(thd->query_length(), max_query_len);
388
str.append(thd->query(), len);
391
pthread_mutex_unlock(&thd->LOCK_thd_data);
393
if (str.c_ptr_safe() == buffer)
397
We have to copy the new string to the destination buffer because the string
398
was reallocated to a larger buffer to be able to fit.
400
DBUG_ASSERT(buffer != NULL);
401
length= min(str.length(), length-1);
402
memcpy(buffer, str.c_ptr_quick(), length);
403
/* Make sure that the new string is null terminated */
404
buffer[length]= '\0';
410
Implementation of Drop_table_error_handler::handle_error().
411
The reason in having this implementation is to silence technical low-level
412
warnings during DROP TABLE operation. Currently we don't want to expose
413
the following warnings during DROP TABLE:
414
- Some of table files are missed or invalid (the table is going to be
415
deleted anyway, so why bother that something was missed);
416
- A trigger associated with the table does not have DEFINER (One of the
417
MySQL specifics now is that triggers are loaded for the table being
418
dropped. So, we may have a warning that trigger does not have DEFINER
419
attribute during DROP TABLE operation).
421
@return TRUE if the condition is handled.
423
bool Drop_table_error_handler::handle_error(uint sql_errno,
425
MYSQL_ERROR::enum_warning_level level,
428
return ((sql_errno == EE_DELETE && my_errno == ENOENT) ||
429
sql_errno == ER_TRG_NO_DEFINER);
434
Clear this diagnostics area.
436
Normally called at the end of a statement.
440
Diagnostics_area::reset_diagnostics_area()
443
can_overwrite_status= FALSE;
444
/** Don't take chances in production */
450
m_total_warn_count= 0;
453
/** Tiny reset in debug mode to see garbage right away */
459
Set OK status -- ends commands that do not return a
460
result set, e.g. INSERT/UPDATE/DELETE.
464
Diagnostics_area::set_ok_status(THD *thd, ha_rows affected_rows_arg,
465
ulonglong last_insert_id_arg,
466
const char *message_arg)
468
DBUG_ASSERT(! is_set());
471
In production, refuse to overwrite an error or a custom response
474
if (is_error() || is_disabled())
477
/** Only allowed to report success if has not yet reported an error */
479
m_server_status= thd->server_status;
480
m_total_warn_count= thd->total_warn_count;
481
m_affected_rows= affected_rows_arg;
482
m_last_insert_id= last_insert_id_arg;
484
strmake(m_message, message_arg, sizeof(m_message) - 1);
496
Diagnostics_area::set_eof_status(THD *thd)
498
/** Only allowed to report eof if has not yet reported an error */
500
DBUG_ASSERT(! is_set());
503
In production, refuse to overwrite an error or a custom response
506
if (is_error() || is_disabled())
510
m_server_status= thd->server_status;
512
If inside a stored procedure, do not return the total
513
number of warnings, since they are not available to the client
516
m_total_warn_count= thd->spcont ? 0 : thd->total_warn_count;
526
Diagnostics_area::set_error_status(THD *thd, uint sql_errno_arg,
527
const char *message_arg)
530
Only allowed to report error if has not yet reported a success
531
The only exception is when we flush the message to the client,
532
an error can happen during the flush.
534
DBUG_ASSERT(! is_set() || can_overwrite_status);
537
In production, refuse to overwrite a custom response with an
544
m_sql_errno= sql_errno_arg;
545
strmake(m_message, message_arg, sizeof(m_message) - 1);
552
Mark the diagnostics area as 'DISABLED'.
554
This is used in rare cases when the COM_ command at hand sends a response
555
in a custom format. One example is the query cache, another is
560
Diagnostics_area::disable_status()
562
DBUG_ASSERT(! is_set());
563
m_status= DA_DISABLED;
568
:Statement(&main_lex, &main_mem_root, CONVENTIONAL_EXECUTION,
569
/* statement id */ 0),
570
Open_tables_state(refresh_version), rli_fake(0),
571
lock_id(&main_lock_id),
572
user_time(0), in_sub_stmt(0),
573
sql_log_bin_toplevel(false),
574
binlog_table_maps(0), binlog_flags(0UL),
575
table_map_for_update(0),
576
arg_of_last_insert_id_function(FALSE),
577
first_successful_insert_id_in_prev_stmt(0),
578
first_successful_insert_id_in_prev_stmt_for_binlog(0),
579
first_successful_insert_id_in_cur_stmt(0),
580
stmt_depends_on_first_successful_insert_id_in_prev_stmt(FALSE),
581
examined_row_count(0),
584
transaction_rollback_request(0),
585
is_fatal_sub_stmt_error(0),
590
derived_tables_processing(FALSE),
593
#if defined(ENABLED_DEBUG_SYNC)
594
, debug_sync_control(0)
595
#endif /* defined(ENABLED_DEBUG_SYNC) */
600
Pass nominal parameters to init_alloc_root only to ensure that
601
the destructor works OK in case of an error. The main_mem_root
602
will be re-initialized in init_for_queries().
604
init_sql_alloc(&main_mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0);
607
catalog= (char*)"std"; // the only catalog we have for now
608
main_security_ctx.init();
609
security_ctx= &main_security_ctx;
610
locked=some_tables_deleted=no_errors=password= 0;
612
count_cuted_fields= CHECK_FIELD_IGNORE;
615
is_slave_error= thread_specific_used= FALSE;
616
hash_clear(&handler_tables_hash);
619
cuted_fields= sent_row_count= row_count= 0L;
622
statement_id_counter= 0UL;
623
#ifdef ERROR_INJECT_SUPPORT
624
error_inject_value= 0UL;
626
// Must be reset to handle error with THD's created for init of mysqld
627
lex->current_select= 0;
628
start_time=(time_t) 0;
629
start_utime= prior_thr_create_utime= 0L;
630
utime_after_lock= 0L;
633
bzero(&variables, sizeof(variables));
638
query_name_consts= 0;
640
db_charset= global_system_variables.collation_database;
641
bzero(ha_data, sizeof(ha_data));
643
binlog_evt_union.do_union= FALSE;
646
dbug_sentry=THD_SENTRY_MAGIC;
648
#ifndef EMBEDDED_LIBRARY
651
client_capabilities= 0; // minimalistic client
652
#ifdef HAVE_QUERY_CACHE
653
query_cache_init_query(&net); // If error on boot
656
system_thread= NON_SYSTEM_THREAD;
657
cleanup_done= abort_on_warning= no_warnings_for_error= 0;
658
peer_port= 0; // For SHOW PROCESSLIST
659
transaction.m_pending_rows_event= 0;
661
#ifdef SIGNAL_WITH_VIO_CLOSE
664
pthread_mutex_init(&LOCK_thd_data, MY_MUTEX_INIT_FAST);
666
/* Variables with default values */
668
where= THD::DEFAULT_WHERE;
669
server_id = ::server_id;
675
/* Initialize sub structures */
676
init_sql_alloc(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE);
677
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
678
profiling.set_thd(this);
680
user_connect=(USER_CONN *)0;
681
hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
682
(hash_get_key) get_var_key,
683
(hash_free_key) free_user_var, 0);
688
/* For user vars replication*/
690
my_init_dynamic_array(&user_var_events,
691
sizeof(BINLOG_USER_VAR_EVENT *), 16, 16);
693
bzero((char*) &user_var_events, sizeof(user_var_events));
696
protocol= &protocol_text; // Default protocol
697
protocol_text.init(this);
698
protocol_binary.init(this);
701
tmp= sql_rnd_with_mutex();
702
randominit(&rand, tmp + (ulong) &rand, tmp + (ulong) ::global_query_id);
703
substitute_null_with_insert_id = FALSE;
704
thr_lock_info_init(&lock_info); /* safety: will be reset after start */
705
thr_lock_owner_init(&main_lock_id, &lock_info);
707
m_internal_handler= NULL;
711
void THD::push_internal_handler(Internal_error_handler *handler)
713
if (m_internal_handler)
715
handler->m_prev_internal_handler= m_internal_handler;
716
m_internal_handler= handler;
720
m_internal_handler= handler;
725
bool THD::handle_error(uint sql_errno, const char *message,
726
MYSQL_ERROR::enum_warning_level level)
728
for (Internal_error_handler *error_handler= m_internal_handler;
730
error_handler= error_handler->m_prev_internal_handler)
732
if (error_handler->handle_error(sql_errno, message, level, this))
740
Internal_error_handler *THD::pop_internal_handler()
742
DBUG_ASSERT(m_internal_handler != NULL);
743
Internal_error_handler *popped_handler= m_internal_handler;
744
m_internal_handler= m_internal_handler->m_prev_internal_handler;
745
return popped_handler;
749
void *thd_alloc(MYSQL_THD thd, unsigned int size)
751
return thd->alloc(size);
755
void *thd_calloc(MYSQL_THD thd, unsigned int size)
757
return thd->calloc(size);
761
char *thd_strdup(MYSQL_THD thd, const char *str)
763
return thd->strdup(str);
767
char *thd_strmake(MYSQL_THD thd, const char *str, unsigned int size)
769
return thd->strmake(str, size);
773
LEX_STRING *thd_make_lex_string(THD *thd, LEX_STRING *lex_str,
774
const char *str, unsigned int size,
775
int allocate_lex_string)
777
return thd->make_lex_string(lex_str, str, size,
778
(bool) allocate_lex_string);
782
void *thd_memdup(MYSQL_THD thd, const void* str, unsigned int size)
784
return thd->memdup(str, size);
788
void thd_get_xid(const MYSQL_THD thd, MYSQL_XID *xid)
790
*xid = *(MYSQL_XID *) &thd->transaction.xid_state.xid;
794
extern "C" THD *_current_thd_noinline(void)
796
return my_pthread_getspecific_ptr(THD*,THR_THD);
800
Init common variables that has to be reset on start and on change_user
805
pthread_mutex_lock(&LOCK_global_system_variables);
806
plugin_thdvar_init(this);
807
variables.time_format= date_time_format_copy((THD*) 0,
808
variables.time_format);
809
variables.date_format= date_time_format_copy((THD*) 0,
810
variables.date_format);
811
variables.datetime_format= date_time_format_copy((THD*) 0,
812
variables.datetime_format);
814
variables= global_system_variables above has reset
815
variables.pseudo_thread_id to 0. We need to correct it here to
816
avoid temporary tables replication failure.
818
variables.pseudo_thread_id= thread_id;
819
pthread_mutex_unlock(&LOCK_global_system_variables);
820
server_status= SERVER_STATUS_AUTOCOMMIT;
821
if (variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES)
822
server_status|= SERVER_STATUS_NO_BACKSLASH_ESCAPES;
823
options= thd_startup_options;
825
if (variables.max_join_size == HA_POS_ERROR)
826
options |= OPTION_BIG_SELECTS;
828
options &= ~OPTION_BIG_SELECTS;
830
transaction.all.modified_non_trans_table= transaction.stmt.modified_non_trans_table= FALSE;
831
open_options=ha_open_options;
832
update_lock_default= (variables.low_priority_updates ?
833
TL_WRITE_LOW_PRIORITY :
835
session_tx_isolation= (enum_tx_isolation) variables.tx_isolation;
837
bzero((char*) warn_count, sizeof(warn_count));
840
reset_current_stmt_binlog_row_based();
841
bzero((char *) &status_var, sizeof(status_var));
842
sql_log_bin_toplevel= options & OPTION_BIN_LOG;
844
#if defined(ENABLED_DEBUG_SYNC)
845
/* Initialize the Debug Sync Facility. See debug_sync.cc. */
846
debug_sync_init_thread(this);
847
#endif /* defined(ENABLED_DEBUG_SYNC) */
852
Init THD for query processing.
853
This has to be called once before we call mysql_parse.
854
See also comments in sql_class.h.
857
void THD::init_for_queries()
860
ha_enable_transaction(this,TRUE);
862
reset_root_defaults(mem_root, variables.query_alloc_block_size,
863
variables.query_prealloc_size);
864
#ifdef USING_TRANSACTIONS
865
reset_root_defaults(&transaction.mem_root,
866
variables.trans_alloc_block_size,
867
variables.trans_prealloc_size);
869
transaction.xid_state.xid.null();
870
transaction.xid_state.in_thd=1;
875
Do what's needed when one invokes change user
881
Reset all resources that are connection specific
885
void THD::change_user(void)
887
pthread_mutex_lock(&LOCK_status);
888
add_to_status(&global_status_var, &status_var);
889
pthread_mutex_unlock(&LOCK_status);
896
hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
897
(hash_get_key) get_var_key,
898
(hash_free_key) free_user_var, 0);
899
sp_cache_clear(&sp_proc_cache);
900
sp_cache_clear(&sp_func_cache);
904
/* Do operations that may take a long time */
906
void THD::cleanup(void)
908
DBUG_ENTER("THD::cleanup");
909
DBUG_ASSERT(cleanup_done == 0);
911
killed= KILL_CONNECTION;
912
#ifdef ENABLE_WHEN_BINLOG_WILL_BE_ABLE_TO_PREPARE
913
if (transaction.xid_state.xa_state == XA_PREPARED)
915
#error xid_state in the cache should be replaced by the allocated value
920
xid_cache_delete(&transaction.xid_state);
924
lock=locked_tables; locked_tables=0;
925
close_thread_tables(this);
928
#if defined(ENABLED_DEBUG_SYNC)
929
/* End the Debug Sync Facility. See debug_sync.cc. */
930
debug_sync_end_thread(this);
931
#endif /* defined(ENABLED_DEBUG_SYNC) */
933
mysql_ha_cleanup(this);
934
delete_dynamic(&user_var_events);
935
hash_free(&user_vars);
936
close_temporary_tables(this);
937
my_free((char*) variables.time_format, MYF(MY_ALLOW_ZERO_PTR));
938
my_free((char*) variables.date_format, MYF(MY_ALLOW_ZERO_PTR));
939
my_free((char*) variables.datetime_format, MYF(MY_ALLOW_ZERO_PTR));
941
sp_cache_clear(&sp_proc_cache);
942
sp_cache_clear(&sp_func_cache);
944
if (global_read_lock)
945
unlock_global_read_lock(this);
948
pthread_mutex_lock(&LOCK_user_locks);
949
item_user_lock_release(ull);
950
pthread_mutex_unlock(&LOCK_user_locks);
961
THD_CHECK_SENTRY(this);
962
DBUG_ENTER("~THD()");
963
/* Ensure that no one is using THD */
964
pthread_mutex_lock(&LOCK_thd_data);
965
pthread_mutex_unlock(&LOCK_thd_data);
966
add_to_status(&global_status_var, &status_var);
968
/* Close connection */
969
#ifndef EMBEDDED_LIBRARY
976
stmt_map.reset(); /* close all prepared statements */
977
DBUG_ASSERT(lock_info.n_cursors == 0);
981
ha_close_connection(this);
982
plugin_thdvar_cleanup(this);
984
DBUG_PRINT("info", ("freeing security context"));
985
main_security_ctx.destroy();
987
free_root(&warn_root,MYF(0));
988
#ifdef USING_TRANSACTIONS
989
free_root(&transaction.mem_root,MYF(0));
991
mysys_var=0; // Safety (shouldn't be needed)
992
pthread_mutex_destroy(&LOCK_thd_data);
994
dbug_sentry= THD_SENTRY_GONE;
996
#ifndef EMBEDDED_LIBRARY
1004
free_root(&main_mem_root, MYF(0));
1010
Add all status variables to another status variable array
1014
to_var add to this array
1015
from_var from this array
1018
This function assumes that all variables are long/ulong.
1019
If this assumption will change, then we have to explictely add
1020
the other variables after the while loop
1023
void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var)
1025
ulong *end= (ulong*) ((uchar*) to_var +
1026
offsetof(STATUS_VAR, last_system_status_var) +
1028
ulong *to= (ulong*) to_var, *from= (ulong*) from_var;
1031
*(to++)+= *(from++);
1035
Add the difference between two status variable arrays to another one.
1039
to_var add to this array
1040
from_var from this array
1041
dec_var minus this array
1044
This function assumes that all variables are long/ulong.
1047
void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
1048
STATUS_VAR *dec_var)
1050
ulong *end= (ulong*) ((uchar*) to_var + offsetof(STATUS_VAR,
1051
last_system_status_var) +
1053
ulong *to= (ulong*) to_var, *from= (ulong*) from_var, *dec= (ulong*) dec_var;
1056
*(to++)+= *(from++) - *(dec++);
1060
void THD::awake(THD::killed_state state_to_set)
1062
DBUG_ENTER("THD::awake");
1063
DBUG_PRINT("enter", ("this: 0x%lx", (long) this));
1064
THD_CHECK_SENTRY(this);
1065
safe_mutex_assert_owner(&LOCK_thd_data);
1067
killed= state_to_set;
1068
if (state_to_set != THD::KILL_QUERY)
1070
thr_alarm_kill(thread_id);
1072
thread_scheduler.post_kill_notification(this);
1073
#ifdef SIGNAL_WITH_VIO_CLOSE
1074
if (this != current_thd)
1077
In addition to a signal, let's close the socket of the thread that
1078
is being killed. This is to make sure it does not block if the
1079
signal is lost. This needs to be done only on platforms where
1080
signals are not a reliable interruption mechanism.
1082
If we're killing ourselves, we know that we're not blocked, so this
1092
pthread_mutex_lock(&mysys_var->mutex);
1093
if (!system_thread) // Don't abort locks
1096
This broadcast could be up in the air if the victim thread
1097
exits the cond in the time between read and broadcast, but that is
1098
ok since all we want to do is to make the victim thread get out
1099
of waiting on current_cond.
1100
If we see a non-zero current_cond: it cannot be an old value (because
1101
then exit_cond() should have run and it can't because we have mutex); so
1102
it is the true value but maybe current_mutex is not yet non-zero (we're
1103
in the middle of enter_cond() and there is a "memory order
1104
inversion"). So we test the mutex too to not lock 0.
1106
Note that there is a small chance we fail to kill. If victim has locked
1107
current_mutex, but hasn't yet entered enter_cond() (which means that
1108
current_cond and current_mutex are 0), then the victim will not get
1109
a signal and it may wait "forever" on the cond (until
1110
we issue a second KILL or the status it's waiting for happens).
1111
It's true that we have set its thd->killed but it may not
1112
see it immediately and so may have time to reach the cond_wait().
1114
if (mysys_var->current_cond && mysys_var->current_mutex)
1116
pthread_mutex_lock(mysys_var->current_mutex);
1117
pthread_cond_broadcast(mysys_var->current_cond);
1118
pthread_mutex_unlock(mysys_var->current_mutex);
1120
pthread_mutex_unlock(&mysys_var->mutex);
1126
Remember the location of thread info, the structure needed for
1127
sql_alloc() and the structure for the net buffer
1130
bool THD::store_globals()
1133
Assert that thread_stack is initialized: it's necessary to be able
1134
to track stack overrun.
1136
DBUG_ASSERT(thread_stack);
1138
if (my_pthread_setspecific_ptr(THR_THD, this) ||
1139
my_pthread_setspecific_ptr(THR_MALLOC, &mem_root))
1141
mysys_var=my_thread_var;
1143
Let mysqld define the thread id (not mysys)
1144
This allows us to move THD to different threads if needed.
1146
mysys_var->id= thread_id;
1147
real_id= pthread_self(); // For debugging
1150
We have to call thr_lock_info_init() again here as THD may have been
1151
created in another thread
1153
thr_lock_info_init(&lock_info);
1159
Cleanup after query.
1162
THD::cleanup_after_query()
1165
This function is used to reset thread data to its default state.
1168
This function is not suitable for setting thread data to some
1169
non-default values, as there is only one replication thread, so
1170
different master threads may overwrite data of each other on
1174
void THD::cleanup_after_query()
1177
Reset rand_used so that detection of calls to rand() will save random
1178
seeds if needed by the slave.
1180
Do not reset rand_used if inside a stored function or trigger because
1181
only the call to these operations is logged. Thus only the calling
1182
statement needs to detect rand() calls made by its substatements. These
1183
substatements must not set rand_used to 0 because it would remove the
1184
detection of rand() by the calling statement.
1186
if (!in_sub_stmt) /* stored functions and triggers are a special case */
1188
/* Forget those values, for next binlogger: */
1189
stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
1190
auto_inc_intervals_in_cur_stmt_for_binlog.empty();
1193
if (first_successful_insert_id_in_cur_stmt > 0)
1195
/* set what LAST_INSERT_ID() will return */
1196
first_successful_insert_id_in_prev_stmt=
1197
first_successful_insert_id_in_cur_stmt;
1198
first_successful_insert_id_in_cur_stmt= 0;
1199
substitute_null_with_insert_id= TRUE;
1201
arg_of_last_insert_id_function= 0;
1202
/* Free Items that were created during this execution */
1205
where= THD::DEFAULT_WHERE;
1206
/* reset table map for multi-table update */
1207
table_map_for_update= 0;
1212
Create a LEX_STRING in this connection.
1214
@param lex_str pointer to LEX_STRING object to be initialized
1215
@param str initializer to be copied into lex_str
1216
@param length length of str, in bytes
1217
@param allocate_lex_string if TRUE, allocate new LEX_STRING object,
1218
instead of using lex_str value
1219
@return NULL on failure, or pointer to the LEX_STRING object
1221
LEX_STRING *THD::make_lex_string(LEX_STRING *lex_str,
1222
const char* str, uint length,
1223
bool allocate_lex_string)
1225
if (allocate_lex_string)
1226
if (!(lex_str= (LEX_STRING *)alloc(sizeof(LEX_STRING))))
1228
if (!(lex_str->str= strmake_root(mem_root, str, length)))
1230
lex_str->length= length;
1236
Convert a string to another character set
1240
to Store new allocated string here
1241
to_cs New character set for allocated string
1242
from String to convert
1243
from_length Length of string to convert
1244
from_cs Original character set
1247
to will be 0-terminated to make it easy to pass to system funcs
1252
In this case to->str will point to 0 and to->length will be 0.
1255
bool THD::convert_string(LEX_STRING *to, CHARSET_INFO *to_cs,
1256
const char *from, uint from_length,
1257
CHARSET_INFO *from_cs)
1259
DBUG_ENTER("convert_string");
1260
size_t new_length= to_cs->mbmaxlen * from_length;
1262
if (!(to->str= (char*) alloc(new_length+1)))
1264
to->length= 0; // Safety fix
1265
DBUG_RETURN(1); // EOM
1267
to->length= copy_and_convert((char*) to->str, new_length, to_cs,
1268
from, from_length, from_cs, &dummy_errors);
1269
to->str[to->length]=0; // Safety
1275
Convert string from source character set to target character set inplace.
1281
Convert string using convert_buffer - buffer for character set
1282
conversion shared between all protocols.
1289
bool THD::convert_string(String *s, CHARSET_INFO *from_cs, CHARSET_INFO *to_cs)
1292
if (convert_buffer.copy(s->ptr(), s->length(), from_cs, to_cs, &dummy_errors))
1294
/* If convert_buffer >> s copying is more efficient long term */
1295
if (convert_buffer.alloced_length() >= convert_buffer.length() * 2 ||
1298
return s->copy(convert_buffer);
1300
s->swap(convert_buffer);
1306
Update some cache variables when character set changes
1309
void THD::update_charset()
1312
charset_is_system_charset= !String::needs_conversion(0,charset(),
1313
system_charset_info,
1315
charset_is_collation_connection=
1316
!String::needs_conversion(0,charset(),variables.collation_connection,
1318
charset_is_character_set_filesystem=
1319
!String::needs_conversion(0, charset(),
1320
variables.character_set_filesystem, ¬_used);
1324
/* routings to adding tables to list of changed in transaction tables */
1326
inline static void list_include(CHANGED_TABLE_LIST** prev,
1327
CHANGED_TABLE_LIST* curr,
1328
CHANGED_TABLE_LIST* new_table)
1333
(*prev)->next = curr;
1337
/* add table to list of changed in transaction tables */
1339
void THD::add_changed_table(TABLE *table)
1341
DBUG_ENTER("THD::add_changed_table(table)");
1343
DBUG_ASSERT((options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
1344
table->file->has_transactions());
1345
add_changed_table(table->s->table_cache_key.str,
1346
(long) table->s->table_cache_key.length);
1351
void THD::add_changed_table(const char *key, long key_length)
1353
DBUG_ENTER("THD::add_changed_table(key)");
1354
CHANGED_TABLE_LIST **prev_changed = &transaction.changed_tables;
1355
CHANGED_TABLE_LIST *curr = transaction.changed_tables;
1357
for (; curr; prev_changed = &(curr->next), curr = curr->next)
1359
int cmp = (long)curr->key_length - (long)key_length;
1362
list_include(prev_changed, curr, changed_table_dup(key, key_length));
1364
("key_length: %ld %u", key_length,
1365
(*prev_changed)->key_length));
1370
cmp = memcmp(curr->key, key, curr->key_length);
1373
list_include(prev_changed, curr, changed_table_dup(key, key_length));
1375
("key_length: %ld %u", key_length,
1376
(*prev_changed)->key_length));
1381
DBUG_PRINT("info", ("already in list"));
1386
*prev_changed = changed_table_dup(key, key_length);
1387
DBUG_PRINT("info", ("key_length: %ld %u", key_length,
1388
(*prev_changed)->key_length));
1393
CHANGED_TABLE_LIST* THD::changed_table_dup(const char *key, long key_length)
1395
CHANGED_TABLE_LIST* new_table =
1396
(CHANGED_TABLE_LIST*) trans_alloc(ALIGN_SIZE(sizeof(CHANGED_TABLE_LIST))+
1400
my_error(EE_OUTOFMEMORY, MYF(ME_BELL),
1401
ALIGN_SIZE(sizeof(TABLE_LIST)) + key_length + 1);
1402
killed= KILL_CONNECTION;
1406
new_table->key= ((char*)new_table)+ ALIGN_SIZE(sizeof(CHANGED_TABLE_LIST));
1407
new_table->next = 0;
1408
new_table->key_length = key_length;
1409
::memcpy(new_table->key, key, key_length);
1414
int THD::send_explain_fields(select_result *result)
1416
List<Item> field_list;
1418
CHARSET_INFO *cs= system_charset_info;
1419
field_list.push_back(new Item_return_int("id",3, MYSQL_TYPE_LONGLONG));
1420
field_list.push_back(new Item_empty_string("select_type", 19, cs));
1421
field_list.push_back(item= new Item_empty_string("table", NAME_CHAR_LEN, cs));
1422
item->maybe_null= 1;
1423
if (lex->describe & DESCRIBE_PARTITIONS)
1425
/* Maximum length of string that make_used_partitions_str() can produce */
1426
item= new Item_empty_string("partitions", MAX_PARTITIONS * (1 + FN_LEN),
1428
field_list.push_back(item);
1429
item->maybe_null= 1;
1431
field_list.push_back(item= new Item_empty_string("type", 10, cs));
1432
item->maybe_null= 1;
1433
field_list.push_back(item=new Item_empty_string("possible_keys",
1434
NAME_CHAR_LEN*MAX_KEY, cs));
1436
field_list.push_back(item=new Item_empty_string("key", NAME_CHAR_LEN, cs));
1438
field_list.push_back(item=new Item_empty_string("key_len",
1439
NAME_CHAR_LEN*MAX_KEY));
1441
field_list.push_back(item=new Item_empty_string("ref",
1442
NAME_CHAR_LEN*MAX_REF_PARTS,
1445
field_list.push_back(item= new Item_return_int("rows", 10,
1446
MYSQL_TYPE_LONGLONG));
1447
if (lex->describe & DESCRIBE_EXTENDED)
1449
field_list.push_back(item= new Item_float("filtered", 0.1234, 2, 4));
1452
item->maybe_null= 1;
1453
field_list.push_back(new Item_empty_string("Extra", 255, cs));
1454
return (result->send_fields(field_list,
1455
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF));
1458
#ifdef SIGNAL_WITH_VIO_CLOSE
1459
void THD::close_active_vio()
1461
DBUG_ENTER("close_active_vio");
1462
safe_mutex_assert_owner(&LOCK_thd_data);
1463
#ifndef EMBEDDED_LIBRARY
1466
vio_close(active_vio);
1475
struct Item_change_record: public ilink
1479
/* Placement new was hidden by `new' in ilink (TODO: check): */
1480
static void *operator new(size_t size, void *mem) { return mem; }
1481
static void operator delete(void *ptr, size_t size) {}
1482
static void operator delete(void *ptr, void *mem) { /* never called */ }
1487
Register an item tree tree transformation, performed by the query
1488
optimizer. We need a pointer to runtime_memroot because it may be !=
1489
thd->mem_root (due to possible set_n_backup_active_arena called for thd).
1492
void THD::nocheck_register_item_tree_change(Item **place, Item *old_value,
1493
MEM_ROOT *runtime_memroot)
1495
Item_change_record *change;
1497
Now we use one node per change, which adds some memory overhead,
1498
but still is rather fast as we use alloc_root for allocations.
1499
A list of item tree changes of an average query should be short.
1501
void *change_mem= alloc_root(runtime_memroot, sizeof(*change));
1502
if (change_mem == 0)
1505
OOM, thd->fatal_error() is called by the error handler of the
1506
memroot. Just return.
1510
change= new (change_mem) Item_change_record;
1511
change->place= place;
1512
change->old_value= old_value;
1513
change_list.append(change);
1517
void THD::rollback_item_tree_changes()
1519
I_List_iterator<Item_change_record> it(change_list);
1520
Item_change_record *change;
1521
DBUG_ENTER("rollback_item_tree_changes");
1523
while ((change= it++))
1524
*change->place= change->old_value;
1525
/* We can forget about changes memory: it's allocated in runtime memroot */
1526
change_list.empty();
1531
/*****************************************************************************
1532
** Functions to provide a interface to select results
1533
*****************************************************************************/
1535
select_result::select_result()
1541
void select_result::send_error(uint errcode,const char *err)
1543
my_message(errcode, err, MYF(0));
1547
void select_result::cleanup()
1552
bool select_result::check_simple_select() const
1554
my_error(ER_SP_BAD_CURSOR_QUERY, MYF(0));
1559
static String default_line_term("\n",default_charset_info);
1560
static String default_escaped("\\",default_charset_info);
1561
static String default_field_term("\t",default_charset_info);
1563
sql_exchange::sql_exchange(char *name,bool flag)
1564
:file_name(name), opt_enclosed(0), dumpfile(flag), skip_lines(0)
1566
field_term= &default_field_term;
1567
enclosed= line_start= &my_empty_string;
1568
line_term= &default_line_term;
1569
escaped= &default_escaped;
1573
bool sql_exchange::escaped_given(void)
1575
return escaped != &default_escaped;
1579
bool select_send::send_fields(List<Item> &list, uint flags)
1582
if (!(res= thd->protocol->send_fields(&list, flags)))
1583
is_result_set_started= 1;
1587
void select_send::abort()
1589
DBUG_ENTER("select_send::abort");
1590
if (is_result_set_started && thd->spcont &&
1591
thd->spcont->find_handler(thd, thd->main_da.sql_errno(),
1592
MYSQL_ERROR::WARN_LEVEL_ERROR))
1595
We're executing a stored procedure, have an open result
1596
set, an SQL exception condition and a handler for it.
1597
In this situation we must abort the current statement,
1598
silence the error and start executing the continue/exit
1600
Before aborting the statement, let's end the open result set, as
1601
otherwise the client will hang due to the violation of the
1602
client/server protocol.
1604
thd->protocol->end_partial_result_set(thd);
1611
Cleanup an instance of this class for re-use
1612
at next execution of a prepared statement/
1613
stored procedure statement.
1616
void select_send::cleanup()
1618
is_result_set_started= FALSE;
1621
/* Send data to client. Returns 0 if ok */
1623
bool select_send::send_data(List<Item> &items)
1625
if (unit->offset_limit_cnt)
1626
{ // using limit offset,count
1627
unit->offset_limit_cnt--;
1632
We may be passing the control from mysqld to the client: release the
1633
InnoDB adaptive hash S-latch to avoid thread deadlocks if it was reserved
1636
ha_release_temporary_latches(thd);
1638
List_iterator_fast<Item> li(items);
1639
Protocol *protocol= thd->protocol;
1640
char buff[MAX_FIELD_WIDTH];
1641
String buffer(buff, sizeof(buff), &my_charset_bin);
1642
DBUG_ENTER("select_send::send_data");
1644
protocol->prepare_for_resend();
1648
if (item->send(protocol, &buffer))
1650
protocol->free(); // Free used buffer
1651
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
1655
Reset buffer to its original state, as it may have been altered in
1658
buffer.set(buff, sizeof(buff), &my_charset_bin);
1660
thd->sent_row_count++;
1661
if (thd->is_error())
1663
protocol->remove_last_row();
1667
DBUG_RETURN(protocol->write());
1671
bool select_send::send_eof()
1674
We may be passing the control from mysqld to the client: release the
1675
InnoDB adaptive hash S-latch to avoid thread deadlocks if it was reserved
1678
ha_release_temporary_latches(thd);
1680
/* Unlock tables before sending packet to gain some speed */
1683
mysql_unlock_tables(thd, thd->lock);
1687
Don't send EOF if we're in error condition (which implies we've already
1688
sent or are sending an error)
1690
if (thd->is_error())
1693
is_result_set_started= 0;
1698
/************************************************************************
1699
Handling writing to file
1700
************************************************************************/
1702
void select_to_file::send_error(uint errcode,const char *err)
1704
my_message(errcode, err, MYF(0));
1707
(void) end_io_cache(&cache);
1708
(void) my_close(file,MYF(0));
1709
(void) my_delete(path,MYF(0)); // Delete file on error
1715
bool select_to_file::send_eof()
1717
int error= test(end_io_cache(&cache));
1718
if (my_close(file,MYF(MY_WME)))
1723
In order to remember the value of affected rows for ROW_COUNT()
1724
function, SELECT INTO has to have an own SQLCOM.
1725
TODO: split from SQLCOM_SELECT
1727
::my_ok(thd,row_count);
1734
void select_to_file::cleanup()
1736
/* In case of error send_eof() may be not called: close the file here. */
1739
(void) end_io_cache(&cache);
1740
(void) my_close(file,MYF(0));
1748
select_to_file::~select_to_file()
1751
{ // This only happens in case of error
1752
(void) end_io_cache(&cache);
1753
(void) my_close(file,MYF(0));
1758
/***************************************************************************
1759
** Export of select to textfile
1760
***************************************************************************/
1762
select_export::~select_export()
1764
thd->sent_row_count=row_count;
1769
Create file with IO cache
1775
exchange Excange class
1784
static File create_file(THD *thd, char *path, sql_exchange *exchange,
1788
uint option= MY_UNPACK_FILENAME | MY_RELATIVE_PATH;
1790
#ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS
1791
option|= MY_REPLACE_DIR; // Force use of db directory
1794
if (!dirname_length(exchange->file_name))
1796
strxnmov(path, FN_REFLEN-1, mysql_real_data_home, thd->db ? thd->db : "",
1798
(void) fn_format(path, exchange->file_name, path, "", option);
1801
(void) fn_format(path, exchange->file_name, mysql_real_data_home, "", option);
1803
if (opt_secure_file_priv &&
1804
strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv)))
1806
/* Write only allowed to dir or subdir specified by secure_file_priv */
1807
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
1811
if (!access(path, F_OK))
1813
my_error(ER_FILE_EXISTS_ERROR, MYF(0), exchange->file_name);
1816
/* Create the file world readable */
1817
if ((file= my_create(path, 0666, O_WRONLY|O_EXCL, MYF(MY_WME))) < 0)
1820
(void) fchmod(file, 0666); // Because of umask()
1822
(void) chmod(path, 0666);
1824
if (init_io_cache(cache, file, 0L, WRITE_CACHE, 0L, 1, MYF(MY_WME)))
1826
my_close(file, MYF(0));
1827
my_delete(path, MYF(0)); // Delete file on error, it was just created
1835
select_export::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
1838
bool string_results= FALSE, non_string_results= FALSE;
1840
if ((uint) strlen(exchange->file_name) + NAME_LEN >= FN_REFLEN)
1841
strmake(path,exchange->file_name,FN_REFLEN-1);
1843
write_cs= exchange->cs ? exchange->cs : &my_charset_bin;
1845
if ((file= create_file(thd, path, exchange, &cache)) < 0)
1847
/* Check if there is any blobs in data */
1849
List_iterator_fast<Item> li(list);
1853
if (item->max_length >= MAX_BLOB_WIDTH)
1858
if (item->result_type() == STRING_RESULT)
1859
string_results= TRUE;
1861
non_string_results= TRUE;
1864
if (exchange->escaped->numchars() > 1 || exchange->enclosed->numchars() > 1)
1866
my_error(ER_WRONG_FIELD_TERMINATORS, MYF(0));
1869
if (exchange->escaped->length() > 1 || exchange->enclosed->length() > 1 ||
1870
!my_isascii(exchange->escaped->ptr()[0]) ||
1871
!my_isascii(exchange->enclosed->ptr()[0]) ||
1872
!exchange->field_term->is_ascii() || !exchange->line_term->is_ascii() ||
1873
!exchange->line_start->is_ascii())
1876
Current LOAD DATA INFILE recognizes field/line separators "as is" without
1877
converting from client charset to data file charset. So, it is supposed,
1878
that input file of LOAD DATA INFILE consists of data in one charset and
1879
separators in other charset. For the compatibility with that [buggy]
1880
behaviour SELECT INTO OUTFILE implementation has been saved "as is" too,
1881
but the new warning message has been added:
1883
Non-ASCII separator arguments are not fully supported
1885
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1886
WARN_NON_ASCII_SEPARATOR_NOT_IMPLEMENTED,
1887
ER(WARN_NON_ASCII_SEPARATOR_NOT_IMPLEMENTED));
1889
field_term_length=exchange->field_term->length();
1890
field_term_char= field_term_length ?
1891
(int) (uchar) (*exchange->field_term)[0] : INT_MAX;
1892
if (!exchange->line_term->length())
1893
exchange->line_term=exchange->field_term; // Use this if it exists
1894
field_sep_char= (exchange->enclosed->length() ?
1895
(int) (uchar) (*exchange->enclosed)[0] : field_term_char);
1896
if (exchange->escaped->length() && (exchange->escaped_given() ||
1897
!(thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES)))
1898
escape_char= (int) (uchar) (*exchange->escaped)[0];
1901
is_ambiguous_field_sep= test(strchr(ESCAPE_CHARS, field_sep_char));
1902
is_unsafe_field_sep= test(strchr(NUMERIC_CHARS, field_sep_char));
1903
line_sep_char= (exchange->line_term->length() ?
1904
(int) (uchar) (*exchange->line_term)[0] : INT_MAX);
1905
if (!field_term_length)
1906
exchange->opt_enclosed=0;
1907
if (!exchange->enclosed->length())
1908
exchange->opt_enclosed=1; // A little quicker loop
1909
fixed_row_size= (!field_term_length && !exchange->enclosed->length() &&
1911
if ((is_ambiguous_field_sep && exchange->enclosed->is_empty() &&
1912
(string_results || is_unsafe_field_sep)) ||
1913
(exchange->opt_enclosed && non_string_results &&
1914
field_term_length && strchr(NUMERIC_CHARS, field_term_char)))
1916
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1917
ER_AMBIGUOUS_FIELD_TERM, ER(ER_AMBIGUOUS_FIELD_TERM));
1918
is_ambiguous_field_term= TRUE;
1921
is_ambiguous_field_term= FALSE;
1927
#define NEED_ESCAPING(x) ((int) (uchar) (x) == escape_char || \
1928
(enclosed ? (int) (uchar) (x) == field_sep_char \
1929
: (int) (uchar) (x) == field_term_char) || \
1930
(int) (uchar) (x) == line_sep_char || \
1933
bool select_export::send_data(List<Item> &items)
1936
DBUG_ENTER("select_export::send_data");
1937
char buff[MAX_FIELD_WIDTH],null_buff[2],space[MAX_FIELD_WIDTH];
1938
char cvt_buff[MAX_FIELD_WIDTH];
1939
String cvt_str(cvt_buff, sizeof(cvt_buff), write_cs);
1940
bool space_inited=0;
1941
String tmp(buff,sizeof(buff),&my_charset_bin),*res;
1944
if (unit->offset_limit_cnt)
1945
{ // using limit offset,count
1946
unit->offset_limit_cnt--;
1951
uint used_length=0,items_left=items.elements;
1952
List_iterator_fast<Item> li(items);
1954
if (my_b_write(&cache,(uchar*) exchange->line_start->ptr(),
1955
exchange->line_start->length()))
1959
Item_result result_type=item->result_type();
1960
bool enclosed = (exchange->enclosed->length() &&
1961
(!exchange->opt_enclosed || result_type == STRING_RESULT));
1962
res=item->str_result(&tmp);
1963
if (res && !my_charset_same(write_cs, res->charset()) &&
1964
!my_charset_same(write_cs, &my_charset_bin))
1966
const char *well_formed_error_pos;
1967
const char *cannot_convert_error_pos;
1968
const char *from_end_pos;
1969
const char *error_pos;
1971
bytes= well_formed_copy_nchars(write_cs, cvt_buff, sizeof(cvt_buff),
1972
res->charset(), res->ptr(), res->length(),
1974
&well_formed_error_pos,
1975
&cannot_convert_error_pos,
1977
error_pos= well_formed_error_pos ? well_formed_error_pos
1978
: cannot_convert_error_pos;
1981
char printable_buff[32];
1982
convert_to_printable(printable_buff, sizeof(printable_buff),
1983
error_pos, res->ptr() + res->length() - error_pos,
1985
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1986
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
1987
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
1988
"string", printable_buff,
1989
item->name, row_count);
1991
cvt_str.length(bytes);
1994
if (res && enclosed)
1996
if (my_b_write(&cache,(uchar*) exchange->enclosed->ptr(),
1997
exchange->enclosed->length()))
2002
if (!fixed_row_size)
2004
if (escape_char != -1) // Use \N syntax
2006
null_buff[0]=escape_char;
2008
if (my_b_write(&cache,(uchar*) null_buff,2))
2011
else if (my_b_write(&cache,(uchar*) "NULL",4))
2016
used_length=0; // Fill with space
2022
used_length=min(res->length(),item->max_length);
2024
used_length=res->length();
2025
if ((result_type == STRING_RESULT || is_unsafe_field_sep) &&
2028
char *pos, *start, *end;
2029
CHARSET_INFO *res_charset= res->charset();
2030
CHARSET_INFO *character_set_client= thd->variables.
2031
character_set_client;
2032
bool check_second_byte= (res_charset == &my_charset_bin) &&
2033
character_set_client->
2034
escape_with_backslash_is_dangerous;
2035
DBUG_ASSERT(character_set_client->mbmaxlen == 2 ||
2036
!character_set_client->escape_with_backslash_is_dangerous);
2037
for (start=pos=(char*) res->ptr(),end=pos+used_length ;
2042
if (use_mb(res_charset))
2045
if ((l=my_ismbchar(res_charset, pos, end)))
2054
Special case when dumping BINARY/VARBINARY/BLOB values
2055
for the clients with character sets big5, cp932, gbk and sjis,
2056
which can have the escape character (0x5C "\" by default)
2057
as the second byte of a multi-byte sequence.
2060
- pos[0] is a valid multi-byte head (e.g 0xEE) and
2061
- pos[1] is 0x00, which will be escaped as "\0",
2063
then we'll get "0xEE + 0x5C + 0x30" in the output file.
2065
If this file is later loaded using this sequence of commands:
2067
mysql> create table t1 (a varchar(128)) character set big5;
2068
mysql> LOAD DATA INFILE 'dump.txt' INTO TABLE t1;
2070
then 0x5C will be misinterpreted as the second byte
2071
of a multi-byte character "0xEE + 0x5C", instead of
2072
escape character for 0x00.
2074
To avoid this confusion, we'll escape the multi-byte
2075
head character too, so the sequence "0xEE + 0x00" will be
2076
dumped as "0x5C + 0xEE + 0x5C + 0x30".
2078
Note, in the condition below we only check if
2079
mbcharlen is equal to 2, because there are no
2080
character sets with mbmaxlen longer than 2
2081
and with escape_with_backslash_is_dangerous set.
2082
DBUG_ASSERT before the loop makes that sure.
2085
if ((NEED_ESCAPING(*pos) ||
2086
(check_second_byte &&
2087
my_mbcharlen(character_set_client, (uchar) *pos) == 2 &&
2089
NEED_ESCAPING(pos[1]))) &&
2091
Don't escape field_term_char by doubling - doubling is only
2092
valid for ENCLOSED BY characters:
2094
(enclosed || !is_ambiguous_field_term ||
2095
(int) (uchar) *pos != field_term_char))
2098
tmp_buff[0]= ((int) (uchar) *pos == field_sep_char &&
2099
is_ambiguous_field_sep) ?
2100
field_sep_char : escape_char;
2101
tmp_buff[1]= *pos ? *pos : '0';
2102
if (my_b_write(&cache,(uchar*) start,(uint) (pos-start)) ||
2103
my_b_write(&cache,(uchar*) tmp_buff,2))
2108
if (my_b_write(&cache,(uchar*) start,(uint) (pos-start)))
2111
else if (my_b_write(&cache,(uchar*) res->ptr(),used_length))
2115
{ // Fill with space
2116
if (item->max_length > used_length)
2118
/* QQ: Fix by adding a my_b_fill() function */
2122
bfill(space,sizeof(space),' ');
2124
uint length=item->max_length-used_length;
2125
for (; length > sizeof(space) ; length-=sizeof(space))
2127
if (my_b_write(&cache,(uchar*) space,sizeof(space)))
2130
if (my_b_write(&cache,(uchar*) space,length))
2134
if (res && enclosed)
2136
if (my_b_write(&cache, (uchar*) exchange->enclosed->ptr(),
2137
exchange->enclosed->length()))
2142
if (my_b_write(&cache, (uchar*) exchange->field_term->ptr(),
2147
if (my_b_write(&cache,(uchar*) exchange->line_term->ptr(),
2148
exchange->line_term->length()))
2156
/***************************************************************************
2157
** Dump of select to a binary file
2158
***************************************************************************/
2162
select_dump::prepare(List<Item> &list __attribute__((unused)),
2166
return (int) ((file= create_file(thd, path, exchange, &cache)) < 0);
2170
bool select_dump::send_data(List<Item> &items)
2172
List_iterator_fast<Item> li(items);
2173
char buff[MAX_FIELD_WIDTH];
2174
String tmp(buff,sizeof(buff),&my_charset_bin),*res;
2177
DBUG_ENTER("select_dump::send_data");
2179
if (unit->offset_limit_cnt)
2180
{ // using limit offset,count
2181
unit->offset_limit_cnt--;
2184
if (row_count++ > 1)
2186
my_message(ER_TOO_MANY_ROWS, ER(ER_TOO_MANY_ROWS), MYF(0));
2191
res=item->str_result(&tmp);
2192
if (!res) // If NULL
2194
if (my_b_write(&cache,(uchar*) "",1))
2197
else if (my_b_write(&cache,(uchar*) res->ptr(),res->length()))
2199
my_error(ER_ERROR_ON_WRITE, MYF(0), path, my_errno);
2209
select_subselect::select_subselect(Item_subselect *item_arg)
2215
bool select_singlerow_subselect::send_data(List<Item> &items)
2217
DBUG_ENTER("select_singlerow_subselect::send_data");
2218
Item_singlerow_subselect *it= (Item_singlerow_subselect *)item;
2221
my_message(ER_SUBQUERY_NO_1_ROW, ER(ER_SUBQUERY_NO_1_ROW), MYF(0));
2224
if (unit->offset_limit_cnt)
2225
{ // Using limit offset,count
2226
unit->offset_limit_cnt--;
2229
List_iterator_fast<Item> li(items);
2231
for (uint i= 0; (val_item= li++); i++)
2232
it->store(i, val_item);
2238
void select_max_min_finder_subselect::cleanup()
2240
DBUG_ENTER("select_max_min_finder_subselect::cleanup");
2246
bool select_max_min_finder_subselect::send_data(List<Item> &items)
2248
DBUG_ENTER("select_max_min_finder_subselect::send_data");
2249
Item_maxmin_subselect *it= (Item_maxmin_subselect *)item;
2250
List_iterator_fast<Item> li(items);
2251
Item *val_item= li++;
2252
it->register_value();
2255
cache->store(val_item);
2257
it->store(0, cache);
2263
cache= Item_cache::get_cache(val_item);
2264
switch (val_item->result_type())
2267
op= &select_max_min_finder_subselect::cmp_real;
2270
op= &select_max_min_finder_subselect::cmp_int;
2273
op= &select_max_min_finder_subselect::cmp_str;
2275
case DECIMAL_RESULT:
2276
op= &select_max_min_finder_subselect::cmp_decimal;
2279
// This case should never be choosen
2284
cache->store(val_item);
2285
it->store(0, cache);
2291
bool select_max_min_finder_subselect::cmp_real()
2293
Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
2294
double val1= cache->val_real(), val2= maxmin->val_real();
2296
return (cache->null_value && !maxmin->null_value) ||
2297
(!cache->null_value && !maxmin->null_value &&
2299
return (maxmin->null_value && !cache->null_value) ||
2300
(!cache->null_value && !maxmin->null_value &&
2304
bool select_max_min_finder_subselect::cmp_int()
2306
Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
2307
longlong val1= cache->val_int(), val2= maxmin->val_int();
2309
return (cache->null_value && !maxmin->null_value) ||
2310
(!cache->null_value && !maxmin->null_value &&
2312
return (maxmin->null_value && !cache->null_value) ||
2313
(!cache->null_value && !maxmin->null_value &&
2317
bool select_max_min_finder_subselect::cmp_decimal()
2319
Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
2320
my_decimal cval, *cvalue= cache->val_decimal(&cval);
2321
my_decimal mval, *mvalue= maxmin->val_decimal(&mval);
2323
return (cache->null_value && !maxmin->null_value) ||
2324
(!cache->null_value && !maxmin->null_value &&
2325
my_decimal_cmp(cvalue, mvalue) > 0) ;
2326
return (maxmin->null_value && !cache->null_value) ||
2327
(!cache->null_value && !maxmin->null_value &&
2328
my_decimal_cmp(cvalue,mvalue) < 0);
2331
bool select_max_min_finder_subselect::cmp_str()
2333
String *val1, *val2, buf1, buf2;
2334
Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
2336
as far as both operand is Item_cache buf1 & buf2 will not be used,
2337
but added for safety
2339
val1= cache->val_str(&buf1);
2340
val2= maxmin->val_str(&buf1);
2342
return (cache->null_value && !maxmin->null_value) ||
2343
(!cache->null_value && !maxmin->null_value &&
2344
sortcmp(val1, val2, cache->collation.collation) > 0) ;
2345
return (maxmin->null_value && !cache->null_value) ||
2346
(!cache->null_value && !maxmin->null_value &&
2347
sortcmp(val1, val2, cache->collation.collation) < 0);
2350
bool select_exists_subselect::send_data(List<Item> &items)
2352
DBUG_ENTER("select_exists_subselect::send_data");
2353
Item_exists_subselect *it= (Item_exists_subselect *)item;
2354
if (unit->offset_limit_cnt)
2355
{ // Using limit offset,count
2356
unit->offset_limit_cnt--;
2365
/***************************************************************************
2366
Dump of select to variables
2367
***************************************************************************/
2369
int select_dumpvar::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
2373
if (var_list.elements != list.elements)
2375
my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT,
2376
ER(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT), MYF(0));
2383
bool select_dumpvar::check_simple_select() const
2385
my_error(ER_SP_BAD_CURSOR_SELECT, MYF(0));
2390
void select_dumpvar::cleanup()
2396
Query_arena::Type Query_arena::type() const
2398
DBUG_ASSERT(0); /* Should never be called */
2403
void Query_arena::free_items()
2406
DBUG_ENTER("Query_arena::free_items");
2407
/* This works because items are allocated with sql_alloc() */
2408
for (; free_list; free_list= next)
2410
next= free_list->next;
2411
free_list->delete_self();
2413
/* Postcondition: free_list is 0 */
2418
void Query_arena::set_query_arena(Query_arena *set)
2420
mem_root= set->mem_root;
2421
free_list= set->free_list;
2426
void Query_arena::cleanup_stmt()
2428
DBUG_ASSERT(! "Query_arena::cleanup_stmt() not implemented");
2435
Statement::Statement(LEX *lex_arg, MEM_ROOT *mem_root_arg,
2436
enum enum_state state_arg, ulong id_arg)
2437
:Query_arena(mem_root_arg, state_arg),
2439
mark_used_columns(MARK_COLUMNS_READ),
2445
query_string.length= 0;
2446
query_string.str= NULL;
2451
Query_arena::Type Statement::type() const
2457
void Statement::set_statement(Statement *stmt)
2460
mark_used_columns= stmt->mark_used_columns;
2462
query_string= stmt->query_string;
2463
cursor= stmt->cursor;
2468
Statement::set_n_backup_statement(Statement *stmt, Statement *backup)
2470
DBUG_ENTER("Statement::set_n_backup_statement");
2471
backup->set_statement(this);
2472
set_statement(stmt);
2477
void Statement::restore_backup_statement(Statement *stmt, Statement *backup)
2479
DBUG_ENTER("Statement::restore_backup_statement");
2480
stmt->set_statement(this);
2481
set_statement(backup);
2486
/** Assign a new value to thd->query. */
2488
void Statement::set_query_inner(char *query_arg, uint32 query_length_arg)
2490
query_string.str= query_arg;
2491
query_string.length= query_length_arg;
2495
void THD::end_statement()
2497
/* Cleanup SQL processing state to reuse this statement in next query. */
2501
/* Note that free_list is freed in cleanup_after_query() */
2504
Don't free mem_root, as mem_root is freed in the end of dispatch_command
2505
(once for any command).
2510
void THD::set_n_backup_active_arena(Query_arena *set, Query_arena *backup)
2512
DBUG_ENTER("THD::set_n_backup_active_arena");
2513
DBUG_ASSERT(backup->is_backup_arena == FALSE);
2515
backup->set_query_arena(this);
2516
set_query_arena(set);
2518
backup->is_backup_arena= TRUE;
2524
void THD::restore_active_arena(Query_arena *set, Query_arena *backup)
2526
DBUG_ENTER("THD::restore_active_arena");
2527
DBUG_ASSERT(backup->is_backup_arena);
2528
set->set_query_arena(this);
2529
set_query_arena(backup);
2531
backup->is_backup_arena= FALSE;
2536
Statement::~Statement()
2543
get_statement_id_as_hash_key(const uchar *record, size_t *key_length,
2544
my_bool not_used __attribute__((unused)))
2546
const Statement *statement= (const Statement *) record;
2547
*key_length= sizeof(statement->id);
2548
return (uchar *) &((const Statement *) statement)->id;
2551
static void delete_statement_as_hash_key(void *key)
2553
delete (Statement *) key;
2556
static uchar *get_stmt_name_hash_key(Statement *entry, size_t *length,
2557
my_bool not_used __attribute__((unused)))
2559
*length= entry->name.length;
2560
return (uchar*) entry->name.str;
2565
Statement_map::Statement_map() :
2566
last_found_statement(0)
2570
START_STMT_HASH_SIZE = 16,
2571
START_NAME_HASH_SIZE = 16
2573
hash_init(&st_hash, &my_charset_bin, START_STMT_HASH_SIZE, 0, 0,
2574
get_statement_id_as_hash_key,
2575
delete_statement_as_hash_key, MYF(0));
2576
hash_init(&names_hash, system_charset_info, START_NAME_HASH_SIZE, 0, 0,
2577
(hash_get_key) get_stmt_name_hash_key,
2583
Insert a new statement to the thread-local statement map.
2586
If there was an old statement with the same name, replace it with the
2587
new one. Otherwise, check if max_prepared_stmt_count is not reached yet,
2588
increase prepared_stmt_count, and insert the new statement. It's okay
2589
to delete an old statement and fail to insert the new one.
2592
All named prepared statements are also present in names_hash.
2593
Statement names in names_hash are unique.
2594
The statement is added only if prepared_stmt_count < max_prepard_stmt_count
2595
last_found_statement always points to a valid statement or is 0
2599
1 error: out of resources or max_prepared_stmt_count limit has been
2600
reached. An error is sent to the client, the statement is deleted.
2603
int Statement_map::insert(THD *thd, Statement *statement)
2605
if (my_hash_insert(&st_hash, (uchar*) statement))
2608
Delete is needed only in case of an insert failure. In all other
2609
cases hash_delete will also delete the statement.
2612
my_error(ER_OUT_OF_RESOURCES, MYF(0));
2615
if (statement->name.str && my_hash_insert(&names_hash, (uchar*) statement))
2617
my_error(ER_OUT_OF_RESOURCES, MYF(0));
2618
goto err_names_hash;
2620
pthread_mutex_lock(&LOCK_prepared_stmt_count);
2622
We don't check that prepared_stmt_count is <= max_prepared_stmt_count
2623
because we would like to allow to lower the total limit
2624
of prepared statements below the current count. In that case
2625
no new statements can be added until prepared_stmt_count drops below
2628
if (prepared_stmt_count >= max_prepared_stmt_count)
2630
pthread_mutex_unlock(&LOCK_prepared_stmt_count);
2631
my_error(ER_MAX_PREPARED_STMT_COUNT_REACHED, MYF(0),
2632
max_prepared_stmt_count);
2635
prepared_stmt_count++;
2636
pthread_mutex_unlock(&LOCK_prepared_stmt_count);
2638
last_found_statement= statement;
2642
if (statement->name.str)
2643
hash_delete(&names_hash, (uchar*) statement);
2645
hash_delete(&st_hash, (uchar*) statement);
2651
void Statement_map::close_transient_cursors()
2653
#ifdef TO_BE_IMPLEMENTED
2655
while ((stmt= transient_cursor_list.head()))
2656
stmt->close_cursor(); /* deletes itself from the list */
2661
void Statement_map::erase(Statement *statement)
2663
if (statement == last_found_statement)
2664
last_found_statement= 0;
2665
if (statement->name.str)
2666
hash_delete(&names_hash, (uchar *) statement);
2668
hash_delete(&st_hash, (uchar *) statement);
2669
pthread_mutex_lock(&LOCK_prepared_stmt_count);
2670
DBUG_ASSERT(prepared_stmt_count > 0);
2671
prepared_stmt_count--;
2672
pthread_mutex_unlock(&LOCK_prepared_stmt_count);
2676
void Statement_map::reset()
2678
/* Must be first, hash_free will reset st_hash.records */
2679
pthread_mutex_lock(&LOCK_prepared_stmt_count);
2680
DBUG_ASSERT(prepared_stmt_count >= st_hash.records);
2681
prepared_stmt_count-= st_hash.records;
2682
pthread_mutex_unlock(&LOCK_prepared_stmt_count);
2684
my_hash_reset(&names_hash);
2685
my_hash_reset(&st_hash);
2686
last_found_statement= 0;
2690
Statement_map::~Statement_map()
2692
/* Must go first, hash_free will reset st_hash.records */
2693
pthread_mutex_lock(&LOCK_prepared_stmt_count);
2694
DBUG_ASSERT(prepared_stmt_count >= st_hash.records);
2695
prepared_stmt_count-= st_hash.records;
2696
pthread_mutex_unlock(&LOCK_prepared_stmt_count);
2698
hash_free(&names_hash);
2699
hash_free(&st_hash);
2702
bool select_dumpvar::send_data(List<Item> &items)
2704
List_iterator_fast<my_var> var_li(var_list);
2705
List_iterator<Item> it(items);
2708
DBUG_ENTER("select_dumpvar::send_data");
2710
if (unit->offset_limit_cnt)
2711
{ // using limit offset,count
2712
unit->offset_limit_cnt--;
2717
my_message(ER_TOO_MANY_ROWS, ER(ER_TOO_MANY_ROWS), MYF(0));
2720
while ((mv= var_li++) && (item= it++))
2724
if (thd->spcont->set_variable(thd, mv->offset, &item))
2729
Item_func_set_user_var *suv= new Item_func_set_user_var(mv->s, item);
2730
if (suv->fix_fields(thd, 0))
2732
suv->save_item_result(item);
2737
DBUG_RETURN(thd->is_error());
2740
bool select_dumpvar::send_eof()
2743
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
2744
ER_SP_FETCH_NO_DATA, ER(ER_SP_FETCH_NO_DATA));
2746
In order to remember the value of affected rows for ROW_COUNT()
2747
function, SELECT INTO has to have an own SQLCOM.
2748
TODO: split from SQLCOM_SELECT
2750
::my_ok(thd,row_count);
2754
/****************************************************************************
2756
****************************************************************************/
2758
void TMP_TABLE_PARAM::init()
2760
DBUG_ENTER("TMP_TABLE_PARAM::init");
2761
DBUG_PRINT("enter", ("this: 0x%lx", (ulong)this));
2762
field_count= sum_func_count= func_count= hidden_field_count= 0;
2763
group_parts= group_length= group_null_parts= 0;
2766
precomputed_group_by= 0;
2771
void thd_increment_bytes_sent(ulong length)
2773
THD *thd=current_thd;
2774
if (likely(thd != 0))
2775
{ /* current_thd==0 when close_connection() calls net_send_error() */
2776
thd->status_var.bytes_sent+= length;
2781
void thd_increment_bytes_received(ulong length)
2783
current_thd->status_var.bytes_received+= length;
2787
void thd_increment_net_big_packet_count(ulong length)
2789
current_thd->status_var.net_big_packet_count+= length;
2793
void THD::set_status_var_init()
2795
bzero((char*) &status_var, sizeof(status_var));
2799
void Security_context::init()
2801
host= user= priv_user= ip= 0;
2802
host_or_ip= "connecting host";
2805
#ifndef NO_EMBEDDED_ACCESS_CHECKS
2806
db_access= NO_ACCESS;
2811
void Security_context::destroy()
2813
// If not pointer to constant
2814
if (host != my_localhost)
2816
if (user != delayed_user)
2822
void Security_context::skip_grants()
2824
/* privileges for the user are unknown everything is allowed */
2825
host_or_ip= (char *)"";
2826
master_access= ~NO_ACCESS;
2827
priv_user= (char *)"";
2832
bool Security_context::set_user(char *user_arg)
2835
user= my_strdup(user_arg, MYF(0));
2839
#ifndef NO_EMBEDDED_ACCESS_CHECKS
2841
Initialize this security context from the passed in credentials
2842
and activate it in the current thread.
2848
@param[out] backup Save a pointer to the current security context
2849
in the thread. In case of success it points to the
2850
saved old context, otherwise it points to NULL.
2853
During execution of a statement, multiple security contexts may
2855
- the security context of the authenticated user, used as the
2856
default security context for all top-level statements
2857
- in case of a view or a stored program, possibly the security
2858
context of the definer of the routine, if the object is
2859
defined with SQL SECURITY DEFINER option.
2861
The currently "active" security context is parameterized in THD
2862
member security_ctx. By default, after a connection is
2863
established, this member points at the "main" security context
2864
- the credentials of the authenticated user.
2866
Later, if we would like to execute some sub-statement or a part
2867
of a statement under credentials of a different user, e.g.
2868
definer of a procedure, we authenticate this user in a local
2869
instance of Security_context by means of this method (and
2870
ultimately by means of acl_getroot_no_password), and make the
2871
local instance active in the thread by re-setting
2872
thd->security_ctx pointer.
2874
Note, that the life cycle and memory management of the "main" and
2875
temporary security contexts are different.
2876
For the main security context, the memory for user/host/ip is
2877
allocated on system heap, and the THD class frees this memory in
2878
its destructor. The only case when contents of the main security
2879
context may change during its life time is when someone issued
2880
CHANGE USER command.
2881
Memory management of a "temporary" security context is
2882
responsibility of the module that creates it.
2884
@retval TRUE there is no user with the given credentials. The erro
2885
is reported in the thread.
2886
@retval FALSE success
2891
change_security_context(THD *thd,
2892
LEX_STRING *definer_user,
2893
LEX_STRING *definer_host,
2895
Security_context **backup)
2899
DBUG_ENTER("Security_context::change_security_context");
2901
DBUG_ASSERT(definer_user->str && definer_host->str);
2905
The current security context may have NULL members
2906
if we have just started the thread and not authenticated
2907
any user. This use case is currently in events worker thread.
2909
needs_change= (thd->security_ctx->priv_user == NULL ||
2910
strcmp(definer_user->str, thd->security_ctx->priv_user) ||
2911
thd->security_ctx->priv_host == NULL ||
2912
my_strcasecmp(system_charset_info, definer_host->str,
2913
thd->security_ctx->priv_host));
2916
if (acl_getroot_no_password(this, definer_user->str, definer_host->str,
2917
definer_host->str, db->str))
2919
my_error(ER_NO_SUCH_USER, MYF(0), definer_user->str,
2923
*backup= thd->security_ctx;
2924
thd->security_ctx= this;
2932
Security_context::restore_security_context(THD *thd,
2933
Security_context *backup)
2936
thd->security_ctx= backup;
2941
bool Security_context::user_matches(Security_context *them)
2943
return ((user != NULL) && (them->user != NULL) &&
2944
!strcmp(user, them->user));
2948
/****************************************************************************
2949
Handling of open and locked tables states.
2951
This is used when we want to open/lock (and then close) some tables when
2952
we already have a set of tables open and locked. We use these methods for
2953
access to mysql.proc table to find definitions of stored routines.
2954
****************************************************************************/
2956
void THD::reset_n_backup_open_tables_state(Open_tables_state *backup)
2958
DBUG_ENTER("reset_n_backup_open_tables_state");
2959
backup->set_open_tables_state(this);
2960
reset_open_tables_state();
2961
state_flags|= Open_tables_state::BACKUPS_AVAIL;
2966
void THD::restore_backup_open_tables_state(Open_tables_state *backup)
2968
DBUG_ENTER("restore_backup_open_tables_state");
2970
Before we will throw away current open tables state we want
2971
to be sure that it was properly cleaned up.
2973
DBUG_ASSERT(open_tables == 0 && temporary_tables == 0 &&
2974
handler_tables == 0 && derived_tables == 0 &&
2975
lock == 0 && locked_tables == 0 &&
2976
prelocked_mode == NON_PRELOCKED &&
2977
m_reprepare_observer == NULL);
2978
set_open_tables_state(backup);
2983
Check the killed state of a user thread
2984
@param thd user thread
2985
@retval 0 the user thread is active
2986
@retval 1 the user thread has been killed
2988
extern "C" int thd_killed(const MYSQL_THD thd)
2990
return(thd->killed);
2994
Return the thread id of a user thread
2995
@param thd user thread
2998
extern "C" unsigned long thd_get_thread_id(const MYSQL_THD thd)
3000
return((unsigned long)thd->thread_id);
3004
#ifdef INNODB_COMPATIBILITY_HOOKS
3005
extern "C" struct charset_info_st *thd_charset(MYSQL_THD thd)
3007
return(thd->charset());
3011
OBSOLETE : there's no way to ensure the string is null terminated.
3012
Use thd_query_string instead()
3014
extern "C" char **thd_query(MYSQL_THD thd)
3016
return(&thd->query_string.str);
3020
Get the current query string for the thread.
3022
@param The MySQL internal thread pointer
3023
@return query string and length. May be non-null-terminated.
3025
extern "C" LEX_STRING * thd_query_string (MYSQL_THD thd)
3027
return(&thd->query_string);
3030
extern "C" int thd_slave_thread(const MYSQL_THD thd)
3032
return(thd->slave_thread);
3035
extern "C" int thd_non_transactional_update(const MYSQL_THD thd)
3037
return(thd->transaction.all.modified_non_trans_table);
3040
extern "C" int thd_binlog_format(const MYSQL_THD thd)
3042
if (mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG))
3043
return (int) thd->variables.binlog_format;
3045
return BINLOG_FORMAT_UNSPEC;
3048
extern "C" void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all)
3050
mark_transaction_to_rollback(thd, all);
3053
extern "C" bool thd_binlog_filter_ok(const MYSQL_THD thd)
3055
return binlog_filter->db_ok(thd->db);
3057
#endif // INNODB_COMPATIBILITY_HOOKS */
3059
/****************************************************************************
3060
Handling of statement states in functions and triggers.
3062
This is used to ensure that the function/trigger gets a clean state
3063
to work with and does not cause any side effects of the calling statement.
3065
It also allows most stored functions and triggers to replicate even
3066
if they are used items that would normally be stored in the binary
3067
replication (like last_insert_id() etc...)
3069
The following things is done
3070
- Disable binary logging for the duration of the statement
3071
- Disable multi-result-sets for the duration of the statement
3072
- Value of last_insert_id() is saved and restored
3073
- Value set by 'SET INSERT_ID=#' is reset and restored
3074
- Value for found_rows() is reset and restored
3075
- examined_row_count is added to the total
3076
- cuted_fields is added to the total
3077
- new savepoint level is created and destroyed
3080
Seed for random() is saved for the first! usage of RAND()
3081
We reset examined_row_count and cuted_fields and add these to the
3082
result to ensure that if we have a bug that would reset these within
3083
a function, we are not loosing any rows from the main statement.
3085
We do not reset value of last_insert_id().
3086
****************************************************************************/
3088
void THD::reset_sub_statement_state(Sub_statement_state *backup,
3091
#ifndef EMBEDDED_LIBRARY
3092
/* BUG#33029, if we are replicating from a buggy master, reset
3093
auto_inc_intervals_forced to prevent substatement
3094
(triggers/functions) from using erroneous INSERT_ID value
3096
if (rpl_master_erroneous_autoinc(this))
3098
DBUG_ASSERT(backup->auto_inc_intervals_forced.nb_elements() == 0);
3099
auto_inc_intervals_forced.swap(&backup->auto_inc_intervals_forced);
3103
backup->options= options;
3104
backup->in_sub_stmt= in_sub_stmt;
3105
backup->enable_slow_log= enable_slow_log;
3106
backup->limit_found_rows= limit_found_rows;
3107
backup->examined_row_count= examined_row_count;
3108
backup->sent_row_count= sent_row_count;
3109
backup->cuted_fields= cuted_fields;
3110
backup->client_capabilities= client_capabilities;
3111
backup->savepoints= transaction.savepoints;
3112
backup->first_successful_insert_id_in_prev_stmt=
3113
first_successful_insert_id_in_prev_stmt;
3114
backup->first_successful_insert_id_in_cur_stmt=
3115
first_successful_insert_id_in_cur_stmt;
3117
if ((!lex->requires_prelocking() || is_update_query(lex->sql_command)) &&
3118
!current_stmt_binlog_row_based)
3120
options&= ~OPTION_BIN_LOG;
3123
if ((backup->options & OPTION_BIN_LOG) && is_update_query(lex->sql_command)&&
3124
!current_stmt_binlog_row_based)
3125
mysql_bin_log.start_union_events(this, this->query_id);
3127
/* Disable result sets */
3128
client_capabilities &= ~CLIENT_MULTI_RESULTS;
3129
in_sub_stmt|= new_state;
3130
examined_row_count= 0;
3133
transaction.savepoints= 0;
3134
first_successful_insert_id_in_cur_stmt= 0;
3138
void THD::restore_sub_statement_state(Sub_statement_state *backup)
3140
#ifndef EMBEDDED_LIBRARY
3141
/* BUG#33029, if we are replicating from a buggy master, restore
3142
auto_inc_intervals_forced so that the top statement can use the
3143
INSERT_ID value set before this statement.
3145
if (rpl_master_erroneous_autoinc(this))
3147
backup->auto_inc_intervals_forced.swap(&auto_inc_intervals_forced);
3148
DBUG_ASSERT(backup->auto_inc_intervals_forced.nb_elements() == 0);
3153
To save resources we want to release savepoints which were created
3154
during execution of function or trigger before leaving their savepoint
3155
level. It is enough to release first savepoint set on this level since
3156
all later savepoints will be released automatically.
3158
if (transaction.savepoints)
3161
for (sv= transaction.savepoints; sv->prev; sv= sv->prev)
3163
/* ha_release_savepoint() never returns error. */
3164
(void)ha_release_savepoint(this, sv);
3166
transaction.savepoints= backup->savepoints;
3167
options= backup->options;
3168
in_sub_stmt= backup->in_sub_stmt;
3169
enable_slow_log= backup->enable_slow_log;
3170
first_successful_insert_id_in_prev_stmt=
3171
backup->first_successful_insert_id_in_prev_stmt;
3172
first_successful_insert_id_in_cur_stmt=
3173
backup->first_successful_insert_id_in_cur_stmt;
3174
limit_found_rows= backup->limit_found_rows;
3175
sent_row_count= backup->sent_row_count;
3176
client_capabilities= backup->client_capabilities;
3178
If we've left sub-statement mode, reset the fatal error flag.
3179
Otherwise keep the current value, to propagate it up the sub-statement
3183
is_fatal_sub_stmt_error= FALSE;
3185
if ((options & OPTION_BIN_LOG) && is_update_query(lex->sql_command) &&
3186
!current_stmt_binlog_row_based)
3187
mysql_bin_log.stop_union_events(this);
3190
The following is added to the old values as we are interested in the
3191
total complexity of the query
3193
examined_row_count+= backup->examined_row_count;
3194
cuted_fields+= backup->cuted_fields;
3198
void THD::set_statement(Statement *stmt)
3200
pthread_mutex_lock(&LOCK_thd_data);
3201
Statement::set_statement(stmt);
3202
pthread_mutex_unlock(&LOCK_thd_data);
3206
/** Assign a new value to thd->query. */
3208
void THD::set_query(char *query_arg, uint32 query_length_arg)
3210
pthread_mutex_lock(&LOCK_thd_data);
3211
set_query_inner(query_arg, query_length_arg);
3212
pthread_mutex_unlock(&LOCK_thd_data);
3217
Mark transaction to rollback and mark error as fatal to a sub-statement.
3219
@param thd Thread handle
3220
@param all TRUE <=> rollback main transaction.
3223
void mark_transaction_to_rollback(THD *thd, bool all)
3227
thd->is_fatal_sub_stmt_error= TRUE;
3228
thd->transaction_rollback_request= all;
3230
Aborted transactions can not be IGNOREd.
3231
Switch off the IGNORE flag for the current
3232
SELECT_LEX. This should allow my_error()
3233
to report the error and abort the execution
3234
flow, even in presence
3237
if (thd->lex->current_select)
3238
thd->lex->current_select->no_error= FALSE;
3241
/***************************************************************************
3242
Handling of XA id cacheing
3243
***************************************************************************/
3245
pthread_mutex_t LOCK_xid_cache;
3248
extern "C" uchar *xid_get_hash_key(const uchar *, size_t *, my_bool);
3249
extern "C" void xid_free_hash(void *);
3251
uchar *xid_get_hash_key(const uchar *ptr, size_t *length,
3252
my_bool not_used __attribute__((unused)))
3254
*length=((XID_STATE*)ptr)->xid.key_length();
3255
return ((XID_STATE*)ptr)->xid.key();
3258
void xid_free_hash(void *ptr)
3260
if (!((XID_STATE*)ptr)->in_thd)
3261
my_free((uchar*)ptr, MYF(0));
3264
bool xid_cache_init()
3266
pthread_mutex_init(&LOCK_xid_cache, MY_MUTEX_INIT_FAST);
3267
return hash_init(&xid_cache, &my_charset_bin, 100, 0, 0,
3268
xid_get_hash_key, xid_free_hash, 0) != 0;
3271
void xid_cache_free()
3273
if (hash_inited(&xid_cache))
3275
hash_free(&xid_cache);
3276
pthread_mutex_destroy(&LOCK_xid_cache);
3280
XID_STATE *xid_cache_search(XID *xid)
3282
pthread_mutex_lock(&LOCK_xid_cache);
3283
XID_STATE *res=(XID_STATE *)hash_search(&xid_cache, xid->key(), xid->key_length());
3284
pthread_mutex_unlock(&LOCK_xid_cache);
3289
bool xid_cache_insert(XID *xid, enum xa_states xa_state)
3293
pthread_mutex_lock(&LOCK_xid_cache);
3294
if (hash_search(&xid_cache, xid->key(), xid->key_length()))
3296
else if (!(xs=(XID_STATE *)my_malloc(sizeof(*xs), MYF(MY_WME))))
3300
xs->xa_state=xa_state;
3303
res=my_hash_insert(&xid_cache, (uchar*)xs);
3305
pthread_mutex_unlock(&LOCK_xid_cache);
3310
bool xid_cache_insert(XID_STATE *xid_state)
3312
pthread_mutex_lock(&LOCK_xid_cache);
3313
DBUG_ASSERT(hash_search(&xid_cache, xid_state->xid.key(),
3314
xid_state->xid.key_length())==0);
3315
my_bool res=my_hash_insert(&xid_cache, (uchar*)xid_state);
3316
pthread_mutex_unlock(&LOCK_xid_cache);
3321
void xid_cache_delete(XID_STATE *xid_state)
3323
pthread_mutex_lock(&LOCK_xid_cache);
3324
hash_delete(&xid_cache, (uchar *)xid_state);
3325
pthread_mutex_unlock(&LOCK_xid_cache);
3329
Implementation of interface to write rows to the binary log through the
3330
thread. The thread is responsible for writing the rows it has
3331
inserted/updated/deleted.
3334
#ifndef MYSQL_CLIENT
3337
Template member function for ensuring that there is an rows log
3338
event of the apropriate type before proceeding.
3341
- Events of type 'RowEventT' have the type code 'type_code'.
3344
If a non-NULL pointer is returned, the pending event for thread 'thd' will
3345
be an event of type 'RowEventT' (which have the type code 'type_code')
3346
will either empty or have enough space to hold 'needed' bytes. In
3347
addition, the columns bitmap will be correct for the row, meaning that
3348
the pending event will be flushed if the columns in the event differ from
3349
the columns suppled to the function.
3352
If no error, a non-NULL pending event (either one which already existed or
3353
the newly created one).
3357
template <class RowsEventT> Rows_log_event*
3358
THD::binlog_prepare_pending_rows_event(TABLE* table, uint32 serv_id,
3359
MY_BITMAP const* cols,
3362
bool is_transactional,
3363
RowsEventT *hint __attribute__((unused)))
3365
DBUG_ENTER("binlog_prepare_pending_rows_event");
3366
/* Pre-conditions */
3367
DBUG_ASSERT(table->s->table_map_id != ~0UL);
3369
/* Fetch the type code for the RowsEventT template parameter */
3370
int const type_code= RowsEventT::TYPE_CODE;
3373
There is no good place to set up the transactional data, so we
3376
if (binlog_setup_trx_data())
3379
Rows_log_event* pending= binlog_get_pending_rows_event();
3381
if (unlikely(pending && !pending->is_valid()))
3385
Check if the current event is non-NULL and a write-rows
3386
event. Also check if the table provided is mapped: if it is not,
3387
then we have switched to writing to a new table.
3388
If there is no pending event, we need to create one. If there is a pending
3389
event, but it's not about the same table id, or not of the same type
3390
(between Write, Update and Delete), or not the same affected columns, or
3391
going to be too big, flush this event to disk and create a new pending
3395
pending->server_id != serv_id ||
3396
pending->get_table_id() != table->s->table_map_id ||
3397
pending->get_type_code() != type_code ||
3398
pending->get_data_size() + needed > opt_binlog_rows_event_max_size ||
3399
pending->get_width() != colcnt ||
3400
!bitmap_cmp(pending->get_cols(), cols))
3402
/* Create a new RowsEventT... */
3403
Rows_log_event* const
3404
ev= new RowsEventT(this, table, table->s->table_map_id, cols,
3408
ev->server_id= serv_id; // I don't like this, it's too easy to forget.
3410
flush the pending event and replace it with the newly created
3413
if (unlikely(mysql_bin_log.flush_and_set_pending_rows_event(this, ev)))
3419
DBUG_RETURN(ev); /* This is the new pending event */
3421
DBUG_RETURN(pending); /* This is the current pending event */
3424
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
3426
Instantiate the versions we need, we have -fno-implicit-template as
3429
template Rows_log_event*
3430
THD::binlog_prepare_pending_rows_event(TABLE*, uint32, MY_BITMAP const*,
3431
size_t, size_t, bool,
3432
Write_rows_log_event*);
3434
template Rows_log_event*
3435
THD::binlog_prepare_pending_rows_event(TABLE*, uint32, MY_BITMAP const*,
3436
size_t colcnt, size_t, bool,
3437
Delete_rows_log_event *);
3439
template Rows_log_event*
3440
THD::binlog_prepare_pending_rows_event(TABLE*, uint32, MY_BITMAP const*,
3441
size_t colcnt, size_t, bool,
3442
Update_rows_log_event *);
3447
field_type_name(enum_field_types type)
3450
case MYSQL_TYPE_DECIMAL:
3451
return "MYSQL_TYPE_DECIMAL";
3452
case MYSQL_TYPE_TINY:
3453
return "MYSQL_TYPE_TINY";
3454
case MYSQL_TYPE_SHORT:
3455
return "MYSQL_TYPE_SHORT";
3456
case MYSQL_TYPE_LONG:
3457
return "MYSQL_TYPE_LONG";
3458
case MYSQL_TYPE_FLOAT:
3459
return "MYSQL_TYPE_FLOAT";
3460
case MYSQL_TYPE_DOUBLE:
3461
return "MYSQL_TYPE_DOUBLE";
3462
case MYSQL_TYPE_NULL:
3463
return "MYSQL_TYPE_NULL";
3464
case MYSQL_TYPE_TIMESTAMP:
3465
return "MYSQL_TYPE_TIMESTAMP";
3466
case MYSQL_TYPE_LONGLONG:
3467
return "MYSQL_TYPE_LONGLONG";
3468
case MYSQL_TYPE_INT24:
3469
return "MYSQL_TYPE_INT24";
3470
case MYSQL_TYPE_DATE:
3471
return "MYSQL_TYPE_DATE";
3472
case MYSQL_TYPE_TIME:
3473
return "MYSQL_TYPE_TIME";
3474
case MYSQL_TYPE_DATETIME:
3475
return "MYSQL_TYPE_DATETIME";
3476
case MYSQL_TYPE_YEAR:
3477
return "MYSQL_TYPE_YEAR";
3478
case MYSQL_TYPE_NEWDATE:
3479
return "MYSQL_TYPE_NEWDATE";
3480
case MYSQL_TYPE_VARCHAR:
3481
return "MYSQL_TYPE_VARCHAR";
3482
case MYSQL_TYPE_BIT:
3483
return "MYSQL_TYPE_BIT";
3484
case MYSQL_TYPE_NEWDECIMAL:
3485
return "MYSQL_TYPE_NEWDECIMAL";
3486
case MYSQL_TYPE_ENUM:
3487
return "MYSQL_TYPE_ENUM";
3488
case MYSQL_TYPE_SET:
3489
return "MYSQL_TYPE_SET";
3490
case MYSQL_TYPE_TINY_BLOB:
3491
return "MYSQL_TYPE_TINY_BLOB";
3492
case MYSQL_TYPE_MEDIUM_BLOB:
3493
return "MYSQL_TYPE_MEDIUM_BLOB";
3494
case MYSQL_TYPE_LONG_BLOB:
3495
return "MYSQL_TYPE_LONG_BLOB";
3496
case MYSQL_TYPE_BLOB:
3497
return "MYSQL_TYPE_BLOB";
3498
case MYSQL_TYPE_VAR_STRING:
3499
return "MYSQL_TYPE_VAR_STRING";
3500
case MYSQL_TYPE_STRING:
3501
return "MYSQL_TYPE_STRING";
3502
case MYSQL_TYPE_GEOMETRY:
3503
return "MYSQL_TYPE_GEOMETRY";
3512
Class to handle temporary allocation of memory for row data.
3514
The responsibilities of the class is to provide memory for
3515
packing one or two rows of packed data (depending on what
3516
constructor is called).
3518
In order to make the allocation more efficient for "simple" rows,
3519
i.e., rows that do not contain any blobs, a pointer to the
3520
allocated memory is of memory is stored in the table structure
3521
for simple rows. If memory for a table containing a blob field
3522
is requested, only memory for that is allocated, and subsequently
3523
released when the object is destroyed.
3526
class Row_data_memory {
3529
Build an object to keep track of a block-local piece of memory
3530
for storing a row of data.
3533
Table where the pre-allocated memory is stored.
3536
Length of data that is needed, if the record contain blobs.
3538
Row_data_memory(TABLE *table, size_t const len1)
3542
m_alloc_checked= FALSE;
3544
allocate_memory(table, len1);
3545
m_ptr[0]= has_memory() ? m_memory : 0;
3549
Row_data_memory(TABLE *table, size_t const len1, size_t const len2)
3553
m_alloc_checked= FALSE;
3555
allocate_memory(table, len1 + len2);
3556
m_ptr[0]= has_memory() ? m_memory : 0;
3557
m_ptr[1]= has_memory() ? m_memory + len1 : 0;
3562
if (m_memory != 0 && m_release_memory_on_destruction)
3563
my_free((uchar*) m_memory, MYF(MY_WME));
3567
Is there memory allocated?
3569
@retval true There is memory allocated
3570
@retval false Memory allocation failed
3572
bool has_memory() const {
3574
m_alloc_checked= TRUE;
3576
return m_memory != 0;
3581
DBUG_ASSERT(s < sizeof(m_ptr)/sizeof(*m_ptr));
3582
DBUG_ASSERT(m_ptr[s] != 0);
3583
DBUG_ASSERT(m_alloc_checked == TRUE);
3588
void allocate_memory(TABLE *const table, size_t const total_length)
3590
if (table->s->blob_fields == 0)
3593
The maximum length of a packed record is less than this
3594
length. We use this value instead of the supplied length
3595
when allocating memory for records, since we don't know how
3596
the memory will be used in future allocations.
3598
Since table->s->reclength is for unpacked records, we have
3599
to add two bytes for each field, which can potentially be
3600
added to hold the length of a packed field.
3602
size_t const maxlen= table->s->reclength + 2 * table->s->fields;
3605
Allocate memory for two records if memory hasn't been
3606
allocated. We allocate memory for two records so that it can
3607
be used when processing update rows as well.
3609
if (table->write_row_record == 0)
3610
table->write_row_record=
3611
(uchar *) alloc_root(&table->mem_root, 2 * maxlen);
3612
m_memory= table->write_row_record;
3613
m_release_memory_on_destruction= FALSE;
3617
m_memory= (uchar *) my_malloc(total_length, MYF(MY_WME));
3618
m_release_memory_on_destruction= TRUE;
3623
mutable bool m_alloc_checked;
3625
bool m_release_memory_on_destruction;
3632
int THD::binlog_write_row(TABLE* table, bool is_trans,
3633
MY_BITMAP const* cols, size_t colcnt,
3634
uchar const *record)
3636
DBUG_ASSERT(current_stmt_binlog_row_based && mysql_bin_log.is_open());
3639
Pack records into format for transfer. We are allocating more
3640
memory than needed, but that doesn't matter.
3642
Row_data_memory memory(table, max_row_length(table, record));
3643
if (!memory.has_memory())
3644
return HA_ERR_OUT_OF_MEM;
3646
uchar *row_data= memory.slot(0);
3648
size_t const len= pack_row(table, cols, row_data, record);
3650
Rows_log_event* const ev=
3651
binlog_prepare_pending_rows_event(table, server_id, cols, colcnt,
3653
static_cast<Write_rows_log_event*>(0));
3655
if (unlikely(ev == 0))
3656
return HA_ERR_OUT_OF_MEM;
3658
return ev->add_row_data(row_data, len);
3661
int THD::binlog_update_row(TABLE* table, bool is_trans,
3662
MY_BITMAP const* cols, size_t colcnt,
3663
const uchar *before_record,
3664
const uchar *after_record)
3666
DBUG_ASSERT(current_stmt_binlog_row_based && mysql_bin_log.is_open());
3668
size_t const before_maxlen = max_row_length(table, before_record);
3669
size_t const after_maxlen = max_row_length(table, after_record);
3671
Row_data_memory row_data(table, before_maxlen, after_maxlen);
3672
if (!row_data.has_memory())
3673
return HA_ERR_OUT_OF_MEM;
3675
uchar *before_row= row_data.slot(0);
3676
uchar *after_row= row_data.slot(1);
3678
size_t const before_size= pack_row(table, cols, before_row,
3680
size_t const after_size= pack_row(table, cols, after_row,
3684
Don't print debug messages when running valgrind since they can
3685
trigger false warnings.
3688
DBUG_DUMP("before_record", before_record, table->s->reclength);
3689
DBUG_DUMP("after_record", after_record, table->s->reclength);
3690
DBUG_DUMP("before_row", before_row, before_size);
3691
DBUG_DUMP("after_row", after_row, after_size);
3694
Rows_log_event* const ev=
3695
binlog_prepare_pending_rows_event(table, server_id, cols, colcnt,
3696
before_size + after_size, is_trans,
3697
static_cast<Update_rows_log_event*>(0));
3699
if (unlikely(ev == 0))
3700
return HA_ERR_OUT_OF_MEM;
3703
ev->add_row_data(before_row, before_size) ||
3704
ev->add_row_data(after_row, after_size);
3707
int THD::binlog_delete_row(TABLE* table, bool is_trans,
3708
MY_BITMAP const* cols, size_t colcnt,
3709
uchar const *record)
3711
DBUG_ASSERT(current_stmt_binlog_row_based && mysql_bin_log.is_open());
3714
Pack records into format for transfer. We are allocating more
3715
memory than needed, but that doesn't matter.
3717
Row_data_memory memory(table, max_row_length(table, record));
3718
if (unlikely(!memory.has_memory()))
3719
return HA_ERR_OUT_OF_MEM;
3721
uchar *row_data= memory.slot(0);
3723
size_t const len= pack_row(table, cols, row_data, record);
3725
Rows_log_event* const ev=
3726
binlog_prepare_pending_rows_event(table, server_id, cols, colcnt,
3728
static_cast<Delete_rows_log_event*>(0));
3730
if (unlikely(ev == 0))
3731
return HA_ERR_OUT_OF_MEM;
3733
return ev->add_row_data(row_data, len);
3737
int THD::binlog_remove_pending_rows_event(bool clear_maps)
3739
DBUG_ENTER("THD::binlog_remove_pending_rows_event");
3741
if (!mysql_bin_log.is_open())
3744
mysql_bin_log.remove_pending_rows_event(this);
3747
binlog_table_maps= 0;
3752
int THD::binlog_flush_pending_rows_event(bool stmt_end)
3754
DBUG_ENTER("THD::binlog_flush_pending_rows_event");
3756
We shall flush the pending event even if we are not in row-based
3757
mode: it might be the case that we left row-based mode before
3758
flushing anything (e.g., if we have explicitly locked tables).
3760
if (!mysql_bin_log.is_open())
3764
Mark the event as the last event of a statement if the stmt_end
3768
if (Rows_log_event *pending= binlog_get_pending_rows_event())
3772
pending->set_flags(Rows_log_event::STMT_END_F);
3773
pending->flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F;
3774
binlog_table_maps= 0;
3777
error= mysql_bin_log.flush_and_set_pending_rows_event(this, 0);
3784
#if !defined(DBUG_OFF) && !defined(_lint)
3786
show_query_type(THD::enum_binlog_query_type qtype)
3789
case THD::ROW_QUERY_TYPE:
3791
case THD::STMT_QUERY_TYPE:
3793
case THD::MYSQL_QUERY_TYPE:
3795
case THD::QUERY_TYPE_COUNT:
3797
DBUG_ASSERT(0 <= qtype && qtype < THD::QUERY_TYPE_COUNT);
3799
static char buf[64];
3800
sprintf(buf, "UNKNOWN#%d", qtype);
3807
Member function that will log query, either row-based or
3808
statement-based depending on the value of the 'current_stmt_binlog_row_based'
3809
the value of the 'qtype' flag.
3811
This function should be called after the all calls to ha_*_row()
3812
functions have been issued, but before tables are unlocked and
3816
There shall be no writes to any system table after calling
3817
binlog_query(), so these writes has to be moved to before the call
3818
of binlog_query() for correct functioning.
3820
This is necessesary not only for RBR, but the master might crash
3821
after binlogging the query but before changing the system tables.
3822
This means that the slave and the master are not in the same state
3823
(after the master has restarted), so therefore we have to
3824
eliminate this problem.
3827
Error code, or 0 if no error.
3829
int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg,
3830
ulong query_len, bool is_trans, bool suppress_use,
3833
DBUG_ENTER("THD::binlog_query");
3834
DBUG_PRINT("enter", ("qtype: %s query: '%s'",
3835
show_query_type(qtype), query_arg));
3836
DBUG_ASSERT(query_arg && mysql_bin_log.is_open());
3839
If we are not in prelocked mode, mysql_unlock_tables() will be
3840
called after this binlog_query(), so we have to flush the pending
3841
rows event with the STMT_END_F set to unlock all tables at the
3844
If we are in prelocked mode, the flushing will be done inside the
3845
top-most close_thread_tables().
3847
if (this->prelocked_mode == NON_PRELOCKED)
3848
if (int error= binlog_flush_pending_rows_event(TRUE))
3852
If we are in statement mode and trying to log an unsafe statement,
3853
we should print a warning.
3855
if (sql_log_bin_toplevel && lex->is_stmt_unsafe() &&
3856
variables.binlog_format == BINLOG_FORMAT_STMT &&
3857
binlog_filter->db_ok(this->db))
3860
A warning can be elevated a error when STRICT sql mode.
3861
But we don't want to elevate binlog warning to error here.
3863
push_warning(this, MYSQL_ERROR::WARN_LEVEL_NOTE,
3864
ER_BINLOG_UNSAFE_STATEMENT,
3865
ER(ER_BINLOG_UNSAFE_STATEMENT));
3866
if (global_system_variables.log_warnings &&
3867
!(binlog_flags & BINLOG_FLAG_UNSAFE_STMT_PRINTED))
3869
sql_print_warning("%s Statement: %.*s",
3870
ER(ER_BINLOG_UNSAFE_STATEMENT),
3871
MYSQL_ERRMSG_SIZE, query_arg);
3872
binlog_flags|= BINLOG_FLAG_UNSAFE_STMT_PRINTED;
3877
case THD::ROW_QUERY_TYPE:
3879
("current_stmt_binlog_row_based: %d",
3880
current_stmt_binlog_row_based));
3881
if (current_stmt_binlog_row_based)
3883
/* Otherwise, we fall through */
3884
case THD::MYSQL_QUERY_TYPE:
3886
Using this query type is a conveniece hack, since we have been
3887
moving back and forth between using RBR for replication of
3888
system tables and not using it.
3890
Make sure to change in check_table_binlog_row_based() according
3891
to how you treat this.
3893
case THD::STMT_QUERY_TYPE:
3895
The MYSQL_LOG::write() function will set the STMT_END_F flag and
3896
flush the pending rows event if necessary.
3899
Query_log_event qinfo(this, query_arg, query_len, is_trans, suppress_use,
3901
qinfo.flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F;
3903
Binlog table maps will be irrelevant after a Query_log_event
3904
(they are just removed on the slave side) so after the query
3905
log event is written to the binary log, we pretend that no
3906
table maps were written.
3908
int error= mysql_bin_log.write(&qinfo);
3909
binlog_table_maps= 0;
3914
case THD::QUERY_TYPE_COUNT:
3916
DBUG_ASSERT(0 <= qtype && qtype < QUERY_TYPE_COUNT);
3921
bool Discrete_intervals_list::append(ulonglong start, ulonglong val,
3924
DBUG_ENTER("Discrete_intervals_list::append");
3925
/* first, see if this can be merged with previous */
3926
if ((head == NULL) || tail->merge_if_contiguous(start, val, incr))
3928
/* it cannot, so need to add a new interval */
3929
Discrete_interval *new_interval= new Discrete_interval(start, val, incr);
3930
DBUG_RETURN(append(new_interval));
3935
bool Discrete_intervals_list::append(Discrete_interval *new_interval)
3937
DBUG_ENTER("Discrete_intervals_list::append");
3938
if (unlikely(new_interval == NULL))
3940
DBUG_PRINT("info",("adding new auto_increment interval"));
3942
head= current= new_interval;
3944
tail->next= new_interval;
3950
#endif /* !defined(MYSQL_CLIENT) */