20
20
** Especially the classes to handle a result from a select
22
22
*****************************************************************************/
23
#include <drizzled/server_includes.h>
24
#ifdef USE_PRAGMA_IMPLEMENTATION
25
#pragma implementation // gcc: Class implementation
28
#include "mysql_priv.h"
24
29
#include "rpl_rli.h"
25
30
#include "rpl_record.h"
32
#include <my_bitmap.h>
26
33
#include "log_event.h"
27
35
#include <sys/stat.h>
28
#include <mysys/thr_alarm.h>
29
#include <mysys/mysys_err.h>
30
#include <drizzled/drizzled_error_messages.h>
31
#include <drizzled/innodb_plugin_extras.h>
36
#include <thr_alarm.h>
37
#include <mysys_err.h>
34
40
The following is used to initialise Table_ident with a internal
61
67
****************************************************************************/
63
extern "C" unsigned char *get_var_key(user_var_entry *entry, size_t *length,
64
bool not_used __attribute__((unused)))
69
extern "C" uchar *get_var_key(user_var_entry *entry, size_t *length,
70
my_bool not_used __attribute__((unused)))
66
72
*length= entry->name.length;
67
return (unsigned char*) entry->name.str;
73
return (uchar*) entry->name.str;
70
76
extern "C" void free_user_var(user_var_entry *entry)
72
78
char *pos= (char*) entry+ALIGN_SIZE(sizeof(*entry));
73
79
if (entry->value && entry->value != pos)
80
my_free(entry->value, MYF(0));
81
my_free((char*) entry,MYF(0));
78
84
bool Key_part_spec::operator==(const Key_part_spec& other) const
138
144
if (a->generated)
140
146
if (b->generated && a->columns.elements > b->columns.elements)
141
std::swap(a, b); // Put shorter key in 'a'
147
swap_variables(Key*, a, b); // Put shorter key in 'a'
145
151
if (!b->generated)
146
return true; // No foreign key
147
std::swap(a, b); // Put generated key in 'a'
152
return TRUE; // No foreign key
153
swap_variables(Key*, a, b); // Put generated key in 'a'
150
156
/* Test if 'a' is a prefix of 'b' */
151
157
if (a->columns.elements > b->columns.elements)
152
return true; // Can't be prefix
158
return TRUE; // Can't be prefix
154
160
List_iterator<Key_part_spec> col_it1(a->columns);
155
161
List_iterator<Key_part_spec> col_it2(b->columns);
165
171
if (*col1 == *col2)
172
return true; // Error
178
return TRUE; // Error
174
return false; // Is prefix
180
return FALSE; // Is prefix
176
182
while ((col1= col_it1++))
179
185
if (!(*col1 == *col2))
182
return false; // Is prefix
188
return FALSE; // Is prefix
188
Check if the foreign key options are compatible with columns
189
on which the FK is created.
195
bool Foreign_key::validate(List<Create_field> &table_fields)
197
Create_field *sql_field;
198
Key_part_spec *column;
199
List_iterator<Key_part_spec> cols(columns);
200
List_iterator<Create_field> it(table_fields);
201
while ((column= cols++))
204
while ((sql_field= it++) &&
205
my_strcasecmp(system_charset_info,
206
column->field_name.str,
207
sql_field->field_name)) {}
210
my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name.str);
213
if (type == Key::FOREIGN_KEY && sql_field->vcol_info)
215
if (delete_opt == FK_OPTION_SET_NULL)
217
my_error(ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN, MYF(0),
218
"ON DELETE SET NULL");
221
if (update_opt == FK_OPTION_SET_NULL)
223
my_error(ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN, MYF(0),
224
"ON UPDATE SET NULL");
227
if (update_opt == FK_OPTION_CASCADE)
229
my_error(ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN, MYF(0),
230
"ON UPDATE CASCADE");
239
193
/****************************************************************************
240
194
** Thread specific functions
241
195
****************************************************************************/
255
209
char filename[FN_REFLEN];
256
210
File fd = create_temp_file(filename, mysql_tmpdir, prefix,
257
O_CREAT | O_EXCL | O_RDWR,
211
O_CREAT | O_EXCL | O_RDWR | O_TEMPORARY,
215
This can be removed once the following bug is fixed:
216
Bug #28903 create_temp_file() doesn't honor O_TEMPORARY option
217
(file not removed) (Unix)
260
219
unlink(filename);
282
Set the process info field of the THD structure.
284
This function is used by plug-ins. Internally, the
285
THD::set_proc_info() function should be used.
287
@see THD::set_proc_info
290
set_thd_proc_info(THD *thd, const char *info)
292
thd->set_proc_info(info);
296
const char *get_thd_proc_info(THD *thd)
241
const char *set_thd_proc_info(THD *thd, const char *info,
242
const char *calling_function,
243
const char *calling_file,
244
const unsigned int calling_line)
298
return thd->get_proc_info();
246
const char *old_info= thd->proc_info;
247
DBUG_PRINT("proc_info", ("%s:%d %s", calling_file, calling_line,
248
(info != NULL) ? info : "(null)"));
249
thd->proc_info= info;
328
280
thd->row_count++;
284
Dumps a text description of a thread, its security context
285
(user, host) and the current query.
288
thd_security_context()
289
thd current thread context
290
buffer pointer to preferred result buffer
291
length length of buffer
292
max_query_len how many chars of query to copy (0 for all)
298
char *thd_security_context(THD *thd, char *buffer, unsigned int length,
299
unsigned int max_query_len)
301
String str(buffer, length, &my_charset_latin1);
302
const Security_context *sctx= &thd->main_security_ctx;
306
len= my_snprintf(header, sizeof(header),
307
"MySQL thread id %lu, query id %lu",
308
thd->thread_id, (ulong) thd->query_id);
310
str.append(header, len);
315
str.append(sctx->host);
321
str.append(sctx->ip);
327
str.append(sctx->user);
333
str.append(thd->proc_info);
338
if (max_query_len < 1)
339
len= thd->query_length;
341
len= min(thd->query_length, max_query_len);
343
str.append(thd->query, len);
345
if (str.c_ptr_safe() == buffer)
347
return thd->strmake(str.ptr(), str.length());
332
351
Clear this diagnostics area.
360
381
Diagnostics_area::set_ok_status(THD *thd, ha_rows affected_rows_arg,
361
uint64_t last_insert_id_arg,
382
ulonglong last_insert_id_arg,
362
383
const char *message_arg)
385
DBUG_ASSERT(! is_set());
366
388
In production, refuse to overwrite an error or a custom response
367
389
with an OK packet.
369
391
if (is_error() || is_disabled())
371
394
/** Only allowed to report success if has not yet reported an error */
373
396
m_server_status= thd->server_status;
424
448
The only exception is when we flush the message to the client,
425
449
an error can happen during the flush.
427
assert(! is_set() || can_overwrite_status);
451
DBUG_ASSERT(! is_set() || can_overwrite_status);
429
454
In production, refuse to overwrite a custom response with an
432
457
if (is_disabled())
435
461
m_sql_errno= sql_errno_arg;
436
462
strmake(m_message, message_arg, sizeof(m_message) - 1);
451
477
Diagnostics_area::disable_status()
479
DBUG_ASSERT(! is_set());
454
480
m_status= DA_DISABLED;
459
:Statement(&main_lex, &main_mem_root,
485
:Statement(&main_lex, &main_mem_root, CONVENTIONAL_EXECUTION,
460
486
/* statement id */ 0),
461
487
Open_tables_state(refresh_version), rli_fake(0),
462
488
lock_id(&main_lock_id),
489
user_time(0), in_sub_stmt(0),
464
490
binlog_table_maps(0), binlog_flags(0UL),
465
arg_of_last_insert_id_function(false),
491
arg_of_last_insert_id_function(FALSE),
466
492
first_successful_insert_id_in_prev_stmt(0),
467
493
first_successful_insert_id_in_prev_stmt_for_binlog(0),
468
494
first_successful_insert_id_in_cur_stmt(0),
469
stmt_depends_on_first_successful_insert_id_in_prev_stmt(false),
495
stmt_depends_on_first_successful_insert_id_in_prev_stmt(FALSE),
470
496
global_read_lock(0),
471
497
is_fatal_error(0),
472
498
transaction_rollback_request(0),
475
501
time_zone_used(0),
476
502
in_lock_tables(0),
477
derived_tables_processing(false),
504
derived_tables_processing(FALSE),
507
@todo The following is a work around for online backup and the DDL blocker.
508
It should be removed when the generalized solution is in place.
509
This is needed to ensure the restore (which uses DDL) is not blocked
510
when the DDL blocker is engaged.
509
544
utime_after_lock= 0L;
510
545
current_linfo = 0;
511
546
slave_thread = 0;
512
memset(&variables, 0, sizeof(variables));
547
bzero(&variables, sizeof(variables));
518
553
db_charset= global_system_variables.collation_database;
519
memset(ha_data, 0, sizeof(ha_data));
554
bzero(ha_data, sizeof(ha_data));
521
binlog_evt_union.do_union= false;
556
binlog_evt_union.do_union= FALSE;
522
559
dbug_sentry=THD_SENTRY_MAGIC;
524
562
client_capabilities= 0; // minimalistic client
525
563
system_thread= NON_SYSTEM_THREAD;
527
565
peer_port= 0; // For SHOW PROCESSLIST
528
566
transaction.m_pending_rows_event= 0;
529
567
transaction.on= 1;
568
#ifdef SIGNAL_WITH_VIO_CLOSE
530
571
pthread_mutex_init(&LOCK_delete, MY_MUTEX_INIT_FAST);
532
573
/* Variables with default values */
550
591
my_init_dynamic_array(&user_var_events,
551
592
sizeof(BINLOG_USER_VAR_EVENT *), 16, 16);
553
memset(&user_var_events, 0, sizeof(user_var_events));
594
bzero((char*) &user_var_events, sizeof(user_var_events));
556
597
protocol= &protocol_text; // Default protocol
557
598
protocol_text.init(this);
559
tablespace_op= false;
601
tmp= sql_rnd_with_mutex();
561
602
randominit(&rand, tmp + (ulong) &rand, tmp + (ulong) ::global_query_id);
562
substitute_null_with_insert_id = false;
603
substitute_null_with_insert_id = FALSE;
563
604
thr_lock_info_init(&lock_info); /* safety: will be reset after start */
564
605
thr_lock_owner_init(&main_lock_id, &lock_info);
573
614
TODO: The current implementation is limited to 1 handler at a time only.
574
615
THD and sp_rcontext need to be modified to use a common handler stack.
576
assert(m_internal_handler == NULL);
617
DBUG_ASSERT(m_internal_handler == NULL);
577
618
m_internal_handler= handler;
581
bool THD::handle_error(uint32_t sql_errno, const char *message,
582
DRIZZLE_ERROR::enum_warning_level level)
622
bool THD::handle_error(uint sql_errno, const char *message,
623
MYSQL_ERROR::enum_warning_level level)
584
625
if (m_internal_handler)
586
627
return m_internal_handler->handle_error(sql_errno, message, level, this);
589
return false; // 'false', as per coding style
630
return FALSE; // 'FALSE', as per coding style
593
634
void THD::pop_internal_handler()
595
assert(m_internal_handler != NULL);
636
DBUG_ASSERT(m_internal_handler != NULL);
596
637
m_internal_handler= NULL;
600
void *thd_alloc(DRIZZLE_THD thd, unsigned int size)
641
void *thd_alloc(MYSQL_THD thd, unsigned int size)
602
643
return thd->alloc(size);
606
void *thd_calloc(DRIZZLE_THD thd, unsigned int size)
647
void *thd_calloc(MYSQL_THD thd, unsigned int size)
608
649
return thd->calloc(size);
612
char *thd_strdup(DRIZZLE_THD thd, const char *str)
653
char *thd_strdup(MYSQL_THD thd, const char *str)
614
655
return thd->strdup(str);
618
char *thd_strmake(DRIZZLE_THD thd, const char *str, unsigned int size)
659
char *thd_strmake(MYSQL_THD thd, const char *str, unsigned int size)
620
661
return thd->strmake(str, size);
633
void *thd_memdup(DRIZZLE_THD thd, const void* str, unsigned int size)
674
void *thd_memdup(MYSQL_THD thd, const void* str, unsigned int size)
635
676
return thd->memdup(str, size);
639
void thd_get_xid(const DRIZZLE_THD thd, DRIZZLE_XID *xid)
680
void thd_get_xid(const MYSQL_THD thd, MYSQL_XID *xid)
641
*xid = *(DRIZZLE_XID *) &thd->transaction.xid_state.xid;
682
*xid = *(MYSQL_XID *) &thd->transaction.xid_state.xid;
671
712
options &= ~OPTION_BIG_SELECTS;
673
transaction.all.modified_non_trans_table= transaction.stmt.modified_non_trans_table= false;
714
transaction.all.modified_non_trans_table= transaction.stmt.modified_non_trans_table= FALSE;
674
715
open_options=ha_open_options;
675
716
update_lock_default= (variables.low_priority_updates ?
676
717
TL_WRITE_LOW_PRIORITY :
678
719
session_tx_isolation= (enum_tx_isolation) variables.tx_isolation;
679
720
warn_list.empty();
680
memset(warn_count, 0, sizeof(warn_count));
721
bzero((char*) warn_count, sizeof(warn_count));
681
722
total_warn_count= 0;
682
723
update_charset();
683
724
reset_current_stmt_binlog_row_based();
684
memset(&status_var, 0, sizeof(status_var));
725
bzero((char *) &status_var, sizeof(status_var));
694
735
void THD::init_for_queries()
697
ha_enable_transaction(this,true);
738
ha_enable_transaction(this,TRUE);
699
740
reset_root_defaults(mem_root, variables.query_alloc_block_size,
700
741
variables.query_prealloc_size);
732
774
delete_dynamic(&user_var_events);
733
775
hash_free(&user_vars);
734
776
close_temporary_tables(this);
735
free((char*) variables.time_format);
736
free((char*) variables.date_format);
737
free((char*) variables.datetime_format);
777
my_free((char*) variables.time_format, MYF(MY_ALLOW_ZERO_PTR));
778
my_free((char*) variables.date_format, MYF(MY_ALLOW_ZERO_PTR));
779
my_free((char*) variables.datetime_format, MYF(MY_ALLOW_ZERO_PTR));
739
781
if (global_read_lock)
740
782
unlock_global_read_lock(this);
790
Set the proc_info field.
791
Do not use this method directly, use THD_SET_PROC_INFO instead.
794
void THD::set_proc_info(const char* file, int line, const char* info)
798
file and line correspond to the __FILE__ and __LINE__ where
799
THD_SET_PROC_INFO was called.
800
These two parameters are provided to help instrumenting the code.
803
DBUG_PRINT("info", ("THD::set_proc_info(%s, %d, %s)",
804
file, line, (info ? info : NullS)));
748
813
THD_CHECK_SENTRY(this);
814
DBUG_ENTER("~THD()");
749
815
/* Ensure that no one is using THD */
750
816
pthread_mutex_lock(&LOCK_delete);
751
817
pthread_mutex_unlock(&LOCK_delete);
763
829
ha_close_connection(this);
764
830
plugin_thdvar_cleanup(this);
832
DBUG_PRINT("info", ("freeing security context"));
766
833
main_security_ctx.destroy();
772
835
free_root(&warn_root,MYF(0));
773
836
free_root(&transaction.mem_root,MYF(0));
774
837
mysys_var=0; // Safety (shouldn't be needed)
775
838
pthread_mutex_destroy(&LOCK_delete);
776
840
dbug_sentry= THD_SENTRY_GONE;
802
867
void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var)
804
ulong *end= (ulong*) ((unsigned char*) to_var +
869
ulong *end= (ulong*) ((uchar*) to_var +
805
870
offsetof(STATUS_VAR, last_system_status_var) +
807
872
ulong *to= (ulong*) to_var, *from= (ulong*) from_var;
826
891
void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
827
892
STATUS_VAR *dec_var)
829
ulong *end= (ulong*) ((unsigned char*) to_var + offsetof(STATUS_VAR,
894
ulong *end= (ulong*) ((uchar*) to_var + offsetof(STATUS_VAR,
830
895
last_system_status_var) +
832
897
ulong *to= (ulong*) to_var, *from= (ulong*) from_var, *dec= (ulong*) dec_var;
847
914
thr_alarm_kill(thread_id);
848
915
if (!slave_thread)
849
916
thread_scheduler.post_kill_notification(this);
917
#ifdef SIGNAL_WITH_VIO_CLOSE
918
if (this != current_thd)
921
In addition to a signal, let's close the socket of the thread that
922
is being killed. This is to make sure it does not block if the
923
signal is lost. This needs to be done only on platforms where
924
signals are not a reliable interruption mechanism.
926
If we're killing ourselves, we know that we're not blocked, so this
938
1021
Reset rand_used so that detection of calls to rand() will save random
939
1022
seeds if needed by the slave.
1024
Do not reset rand_used if inside a stored function or trigger because
1025
only the call to these operations is logged. Thus only the calling
1026
statement needs to detect rand() calls made by its substatements. These
1027
substatements must not set rand_used to 0 because it would remove the
1028
detection of rand() by the calling statement.
1030
if (!in_sub_stmt) /* stored functions and triggers are a special case */
942
1032
/* Forget those values, for next binlogger: */
943
1033
stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
950
1040
first_successful_insert_id_in_prev_stmt=
951
1041
first_successful_insert_id_in_cur_stmt;
952
1042
first_successful_insert_id_in_cur_stmt= 0;
953
substitute_null_with_insert_id= true;
1043
substitute_null_with_insert_id= TRUE;
955
1045
arg_of_last_insert_id_function= 0;
956
1046
/* Free Items that were created during this execution */
966
1056
@param lex_str pointer to LEX_STRING object to be initialized
967
1057
@param str initializer to be copied into lex_str
968
1058
@param length length of str, in bytes
969
@param allocate_lex_string if true, allocate new LEX_STRING object,
1059
@param allocate_lex_string if TRUE, allocate new LEX_STRING object,
970
1060
instead of using lex_str value
971
1061
@return NULL on failure, or pointer to the LEX_STRING object
973
1063
LEX_STRING *THD::make_lex_string(LEX_STRING *lex_str,
974
const char* str, uint32_t length,
1064
const char* str, uint length,
975
1065
bool allocate_lex_string)
977
1067
if (allocate_lex_string)
1004
1094
In this case to->str will point to 0 and to->length will be 0.
1007
bool THD::convert_string(LEX_STRING *to, const CHARSET_INFO * const to_cs,
1008
const char *from, uint32_t from_length,
1009
const CHARSET_INFO * const from_cs)
1097
bool THD::convert_string(LEX_STRING *to, CHARSET_INFO *to_cs,
1098
const char *from, uint from_length,
1099
CHARSET_INFO *from_cs)
1101
DBUG_ENTER("convert_string");
1011
1102
size_t new_length= to_cs->mbmaxlen * from_length;
1012
uint32_t dummy_errors;
1013
1104
if (!(to->str= (char*) alloc(new_length+1)))
1015
1106
to->length= 0; // Safety fix
1107
DBUG_RETURN(1); // EOM
1018
1109
to->length= copy_and_convert((char*) to->str, new_length, to_cs,
1019
1110
from, from_length, from_cs, &dummy_errors);
1020
1111
to->str[to->length]=0; // Safety
1037
1128
!0 out of memory
1040
bool THD::convert_string(String *s, const CHARSET_INFO * const from_cs,
1041
const CHARSET_INFO * const to_cs)
1131
bool THD::convert_string(String *s, CHARSET_INFO *from_cs, CHARSET_INFO *to_cs)
1043
uint32_t dummy_errors;
1044
1134
if (convert_buffer.copy(s->ptr(), s->length(), from_cs, to_cs, &dummy_errors))
1046
1136
/* If convert_buffer >> s copying is more efficient long term */
1047
1137
if (convert_buffer.alloced_length() >= convert_buffer.length() * 2 ||
1048
1138
!s->is_alloced())
1076
1166
/* routings to adding tables to list of changed in transaction tables */
1078
inline static void list_include(CHANGED_TableList** prev,
1079
CHANGED_TableList* curr,
1080
CHANGED_TableList* new_table)
1168
inline static void list_include(CHANGED_TABLE_LIST** prev,
1169
CHANGED_TABLE_LIST* curr,
1170
CHANGED_TABLE_LIST* new_table)
1089
1179
/* add table to list of changed in transaction tables */
1091
void THD::add_changed_table(Table *table)
1181
void THD::add_changed_table(TABLE *table)
1093
assert((options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
1183
DBUG_ENTER("THD::add_changed_table(table)");
1185
DBUG_ASSERT((options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
1094
1186
table->file->has_transactions());
1095
1187
add_changed_table(table->s->table_cache_key.str,
1096
1188
(long) table->s->table_cache_key.length);
1101
1193
void THD::add_changed_table(const char *key, long key_length)
1103
CHANGED_TableList **prev_changed = &transaction.changed_tables;
1104
CHANGED_TableList *curr = transaction.changed_tables;
1195
DBUG_ENTER("THD::add_changed_table(key)");
1196
CHANGED_TABLE_LIST **prev_changed = &transaction.changed_tables;
1197
CHANGED_TABLE_LIST *curr = transaction.changed_tables;
1106
1199
for (; curr; prev_changed = &(curr->next), curr = curr->next)
1119
1215
list_include(prev_changed, curr, changed_table_dup(key, key_length));
1217
("key_length: %ld %u", key_length,
1218
(*prev_changed)->key_length));
1122
1221
else if (cmp == 0)
1223
DBUG_PRINT("info", ("already in list"));
1128
1228
*prev_changed = changed_table_dup(key, key_length);
1229
DBUG_PRINT("info", ("key_length: %ld %u", key_length,
1230
(*prev_changed)->key_length));
1133
CHANGED_TableList* THD::changed_table_dup(const char *key, long key_length)
1235
CHANGED_TABLE_LIST* THD::changed_table_dup(const char *key, long key_length)
1135
CHANGED_TableList* new_table =
1136
(CHANGED_TableList*) trans_alloc(ALIGN_SIZE(sizeof(CHANGED_TableList))+
1237
CHANGED_TABLE_LIST* new_table =
1238
(CHANGED_TABLE_LIST*) trans_alloc(ALIGN_SIZE(sizeof(CHANGED_TABLE_LIST))+
1137
1239
key_length + 1);
1138
1240
if (!new_table)
1140
1242
my_error(EE_OUTOFMEMORY, MYF(ME_BELL),
1141
ALIGN_SIZE(sizeof(TableList)) + key_length + 1);
1243
ALIGN_SIZE(sizeof(TABLE_LIST)) + key_length + 1);
1142
1244
killed= KILL_CONNECTION;
1146
new_table->key= ((char*)new_table)+ ALIGN_SIZE(sizeof(CHANGED_TableList));
1248
new_table->key= ((char*)new_table)+ ALIGN_SIZE(sizeof(CHANGED_TABLE_LIST));
1147
1249
new_table->next = 0;
1148
1250
new_table->key_length = key_length;
1149
1251
::memcpy(new_table->key, key, key_length);
1156
1258
List<Item> field_list;
1158
const CHARSET_INFO * const cs= system_charset_info;
1159
field_list.push_back(new Item_return_int("id",3, DRIZZLE_TYPE_LONGLONG));
1260
CHARSET_INFO *cs= system_charset_info;
1261
field_list.push_back(new Item_return_int("id",3, MYSQL_TYPE_LONGLONG));
1160
1262
field_list.push_back(new Item_empty_string("select_type", 19, cs));
1161
1263
field_list.push_back(item= new Item_empty_string("table", NAME_CHAR_LEN, cs));
1162
1264
item->maybe_null= 1;
1190
1292
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF));
1295
#ifdef SIGNAL_WITH_VIO_CLOSE
1296
void THD::close_active_vio()
1298
DBUG_ENTER("close_active_vio");
1299
safe_mutex_assert_owner(&LOCK_delete);
1302
vio_close(active_vio);
1194
1310
struct Item_change_record: public ilink
1197
1313
Item *old_value;
1198
1314
/* Placement new was hidden by `new' in ilink (TODO: check): */
1199
static void *operator new(size_t size __attribute__((unused)),
1202
static void operator delete(void *ptr __attribute__((unused)),
1203
size_t size __attribute__((unused)))
1205
static void operator delete(void *ptr __attribute__((unused)),
1206
void *mem __attribute__((unused)))
1207
{ /* never called */ }
1315
static void *operator new(size_t size, void *mem) { return mem; }
1316
static void operator delete(void *ptr, size_t size) {}
1317
static void operator delete(void *ptr, void *mem) { /* never called */ }
1212
1322
Register an item tree tree transformation, performed by the query
1213
1323
optimizer. We need a pointer to runtime_memroot because it may be !=
1214
thd->mem_root (this may no longer be a true statement)
1324
thd->mem_root (due to possible set_n_backup_active_arena called for thd).
1217
1327
void THD::nocheck_register_item_tree_change(Item **place, Item *old_value,
1244
1354
I_List_iterator<Item_change_record> it(change_list);
1245
1355
Item_change_record *change;
1356
DBUG_ENTER("rollback_item_tree_changes");
1247
1358
while ((change= it++))
1248
1359
*change->place= change->old_value;
1249
1360
/* We can forget about changes memory: it's allocated in runtime memroot */
1250
1361
change_list.empty();
1367
Check that the endpoint is still available.
1370
bool THD::vio_is_connected()
1374
/* End of input is signaled by poll if the socket is aborted. */
1375
if (vio_poll_read(net.vio, 0))
1378
/* Socket is aborted if signaled but no data is available. */
1379
if (vio_peek_read(net.vio, &bytes))
1382
return bytes ? TRUE : FALSE;
1275
1406
bool select_result::check_simple_select() const
1277
1408
my_error(ER_SP_BAD_CURSOR_QUERY, MYF(0));
1282
1413
static String default_line_term("\n",default_charset_info);
1283
1414
static String default_escaped("\\",default_charset_info);
1284
1415
static String default_field_term("\t",default_charset_info);
1416
static String default_xml_row_term("<row>", default_charset_info);
1286
1418
sql_exchange::sql_exchange(char *name, bool flag,
1287
1419
enum enum_filetype filetype_arg)
1290
1422
filetype= filetype_arg;
1291
1423
field_term= &default_field_term;
1292
1424
enclosed= line_start= &my_empty_string;
1293
line_term= &default_line_term;
1425
line_term= filetype == FILETYPE_CSV ?
1426
&default_line_term : &default_xml_row_term;
1294
1427
escaped= &default_escaped;
1298
bool select_send::send_fields(List<Item> &list, uint32_t flags)
1431
bool select_send::send_fields(List<Item> &list, uint flags)
1301
1434
if (!(res= thd->protocol->send_fields(&list, flags)))
1341
1475
Protocol *protocol= thd->protocol;
1342
1476
char buff[MAX_FIELD_WIDTH];
1343
1477
String buffer(buff, sizeof(buff), &my_charset_bin);
1478
DBUG_ENTER("select_send::send_data");
1345
1480
protocol->prepare_for_resend();
1389
1524
Handling writing to file
1390
1525
************************************************************************/
1392
void select_to_file::send_error(uint32_t errcode,const char *err)
1527
void select_to_file::send_error(uint errcode,const char *err)
1394
1529
my_message(errcode, err, MYF(0));
1484
1619
if (!dirname_length(exchange->file_name))
1486
1621
strxnmov(path, FN_REFLEN-1, mysql_real_data_home, thd->db ? thd->db : "",
1488
1623
(void) fn_format(path, exchange->file_name, path, "", option);
1525
1660
select_export::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
1527
1662
bool blob_flag=0;
1528
bool string_results= false, non_string_results= false;
1663
bool string_results= FALSE, non_string_results= FALSE;
1530
1665
if ((uint) strlen(exchange->file_name) + NAME_LEN >= FN_REFLEN)
1531
1666
strmake(path,exchange->file_name,FN_REFLEN-1);
1546
1681
if (item->result_type() == STRING_RESULT)
1547
string_results= true;
1682
string_results= TRUE;
1549
non_string_results= true;
1684
non_string_results= TRUE;
1552
1687
field_term_length=exchange->field_term->length();
1553
1688
field_term_char= field_term_length ?
1554
(int) (unsigned char) (*exchange->field_term)[0] : INT_MAX;
1689
(int) (uchar) (*exchange->field_term)[0] : INT_MAX;
1555
1690
if (!exchange->line_term->length())
1556
1691
exchange->line_term=exchange->field_term; // Use this if it exists
1557
1692
field_sep_char= (exchange->enclosed->length() ?
1558
(int) (unsigned char) (*exchange->enclosed)[0] : field_term_char);
1693
(int) (uchar) (*exchange->enclosed)[0] : field_term_char);
1559
1694
escape_char= (exchange->escaped->length() ?
1560
(int) (unsigned char) (*exchange->escaped)[0] : -1);
1695
(int) (uchar) (*exchange->escaped)[0] : -1);
1561
1696
is_ambiguous_field_sep= test(strchr(ESCAPE_CHARS, field_sep_char));
1562
1697
is_unsafe_field_sep= test(strchr(NUMERIC_CHARS, field_sep_char));
1563
1698
line_sep_char= (exchange->line_term->length() ?
1564
(int) (unsigned char) (*exchange->line_term)[0] : INT_MAX);
1699
(int) (uchar) (*exchange->line_term)[0] : INT_MAX);
1565
1700
if (!field_term_length)
1566
1701
exchange->opt_enclosed=0;
1567
1702
if (!exchange->enclosed->length())
1573
1708
(exchange->opt_enclosed && non_string_results &&
1574
1709
field_term_length && strchr(NUMERIC_CHARS, field_term_char)))
1576
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1711
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1577
1712
ER_AMBIGUOUS_FIELD_TERM, ER(ER_AMBIGUOUS_FIELD_TERM));
1578
is_ambiguous_field_term= true;
1713
is_ambiguous_field_term= TRUE;
1581
is_ambiguous_field_term= false;
1716
is_ambiguous_field_term= FALSE;
1587
#define NEED_ESCAPING(x) ((int) (unsigned char) (x) == escape_char || \
1588
(enclosed ? (int) (unsigned char) (x) == field_sep_char \
1589
: (int) (unsigned char) (x) == field_term_char) || \
1590
(int) (unsigned char) (x) == line_sep_char || \
1722
#define NEED_ESCAPING(x) ((int) (uchar) (x) == escape_char || \
1723
(enclosed ? (int) (uchar) (x) == field_sep_char \
1724
: (int) (uchar) (x) == field_term_char) || \
1725
(int) (uchar) (x) == line_sep_char || \
1593
1728
bool select_export::send_data(List<Item> &items)
1731
DBUG_ENTER("select_export::send_data");
1595
1732
char buff[MAX_FIELD_WIDTH],null_buff[2],space[MAX_FIELD_WIDTH];
1596
1733
bool space_inited=0;
1597
1734
String tmp(buff,sizeof(buff),&my_charset_bin),*res;
1600
1737
if (unit->offset_limit_cnt)
1601
1738
{ // using limit offset,count
1602
1739
unit->offset_limit_cnt--;
1607
uint32_t used_length=0,items_left=items.elements;
1744
uint used_length=0,items_left=items.elements;
1608
1745
List_iterator_fast<Item> li(items);
1610
if (my_b_write(&cache,(unsigned char*) exchange->line_start->ptr(),
1747
if (my_b_write(&cache,(uchar*) exchange->line_start->ptr(),
1611
1748
exchange->line_start->length()))
1613
1750
while ((item=li++))
1618
1755
res=item->str_result(&tmp);
1619
1756
if (res && enclosed)
1621
if (my_b_write(&cache,(unsigned char*) exchange->enclosed->ptr(),
1758
if (my_b_write(&cache,(uchar*) exchange->enclosed->ptr(),
1622
1759
exchange->enclosed->length()))
1631
1768
null_buff[0]=escape_char;
1632
1769
null_buff[1]='N';
1633
if (my_b_write(&cache,(unsigned char*) null_buff,2))
1770
if (my_b_write(&cache,(uchar*) null_buff,2))
1636
else if (my_b_write(&cache,(unsigned char*) "NULL",4))
1773
else if (my_b_write(&cache,(uchar*) "NULL",4))
1646
1783
if (fixed_row_size)
1647
used_length=cmin(res->length(),item->max_length);
1784
used_length=min(res->length(),item->max_length);
1649
1786
used_length=res->length();
1650
1787
if ((result_type == STRING_RESULT || is_unsafe_field_sep) &&
1651
1788
escape_char != -1)
1653
1790
char *pos, *start, *end;
1654
const CHARSET_INFO * const res_charset= res->charset();
1655
const CHARSET_INFO * const character_set_client= thd->variables.
1656
character_set_client;
1791
CHARSET_INFO *res_charset= res->charset();
1792
CHARSET_INFO *character_set_client= thd->variables.
1793
character_set_client;
1657
1794
bool check_second_byte= (res_charset == &my_charset_bin) &&
1658
1795
character_set_client->
1659
1796
escape_with_backslash_is_dangerous;
1660
assert(character_set_client->mbmaxlen == 2 ||
1797
DBUG_ASSERT(character_set_client->mbmaxlen == 2 ||
1661
1798
!character_set_client->escape_with_backslash_is_dangerous);
1662
1799
for (start=pos=(char*) res->ptr(),end=pos+used_length ;
1690
1827
If this file is later loaded using this sequence of commands:
1692
1829
mysql> create table t1 (a varchar(128)) character set big5;
1693
mysql> LOAD DATA INFILE 'dump.txt' INTO Table t1;
1830
mysql> LOAD DATA INFILE 'dump.txt' INTO TABLE t1;
1695
1832
then 0x5C will be misinterpreted as the second byte
1696
1833
of a multi-byte character "0xEE + 0x5C", instead of
1704
1841
mbcharlen is equal to 2, because there are no
1705
1842
character sets with mbmaxlen longer than 2
1706
1843
and with escape_with_backslash_is_dangerous set.
1707
assert before the loop makes that sure.
1844
DBUG_ASSERT before the loop makes that sure.
1710
1847
if ((NEED_ESCAPING(*pos) ||
1711
1848
(check_second_byte &&
1712
my_mbcharlen(character_set_client, (unsigned char) *pos) == 2 &&
1849
my_mbcharlen(character_set_client, (uchar) *pos) == 2 &&
1713
1850
pos + 1 < end &&
1714
1851
NEED_ESCAPING(pos[1]))) &&
1717
1854
valid for ENCLOSED BY characters:
1719
1856
(enclosed || !is_ambiguous_field_term ||
1720
(int) (unsigned char) *pos != field_term_char))
1857
(int) (uchar) *pos != field_term_char))
1722
1859
char tmp_buff[2];
1723
tmp_buff[0]= ((int) (unsigned char) *pos == field_sep_char &&
1860
tmp_buff[0]= ((int) (uchar) *pos == field_sep_char &&
1724
1861
is_ambiguous_field_sep) ?
1725
1862
field_sep_char : escape_char;
1726
1863
tmp_buff[1]= *pos ? *pos : '0';
1727
if (my_b_write(&cache,(unsigned char*) start,(uint) (pos-start)) ||
1728
my_b_write(&cache,(unsigned char*) tmp_buff,2))
1864
if (my_b_write(&cache,(uchar*) start,(uint) (pos-start)) ||
1865
my_b_write(&cache,(uchar*) tmp_buff,2))
1733
if (my_b_write(&cache,(unsigned char*) start,(uint) (pos-start)))
1870
if (my_b_write(&cache,(uchar*) start,(uint) (pos-start)))
1736
else if (my_b_write(&cache,(unsigned char*) res->ptr(),used_length))
1873
else if (my_b_write(&cache,(uchar*) res->ptr(),used_length))
1739
1876
if (fixed_row_size)
1744
1881
if (!space_inited)
1746
1883
space_inited=1;
1747
memset(space, ' ', sizeof(space));
1884
bfill(space,sizeof(space),' ');
1749
uint32_t length=item->max_length-used_length;
1886
uint length=item->max_length-used_length;
1750
1887
for (; length > sizeof(space) ; length-=sizeof(space))
1752
if (my_b_write(&cache,(unsigned char*) space,sizeof(space)))
1889
if (my_b_write(&cache,(uchar*) space,sizeof(space)))
1755
if (my_b_write(&cache,(unsigned char*) space,length))
1892
if (my_b_write(&cache,(uchar*) space,length))
1759
1896
if (res && enclosed)
1761
if (my_b_write(&cache, (unsigned char*) exchange->enclosed->ptr(),
1898
if (my_b_write(&cache, (uchar*) exchange->enclosed->ptr(),
1762
1899
exchange->enclosed->length()))
1765
1902
if (--items_left)
1767
if (my_b_write(&cache, (unsigned char*) exchange->field_term->ptr(),
1904
if (my_b_write(&cache, (uchar*) exchange->field_term->ptr(),
1768
1905
field_term_length))
1772
if (my_b_write(&cache,(unsigned char*) exchange->line_term->ptr(),
1909
if (my_b_write(&cache,(uchar*) exchange->line_term->ptr(),
1773
1910
exchange->line_term->length()))
1799
1936
String tmp(buff,sizeof(buff),&my_charset_bin),*res;
1939
DBUG_ENTER("select_dump::send_data");
1803
1941
if (unit->offset_limit_cnt)
1804
1942
{ // using limit offset,count
1805
1943
unit->offset_limit_cnt--;
1808
1946
if (row_count++ > 1)
1815
1953
res=item->str_result(&tmp);
1816
1954
if (!res) // If NULL
1818
if (my_b_write(&cache,(unsigned char*) "",1))
1956
if (my_b_write(&cache,(uchar*) "",1))
1821
else if (my_b_write(&cache,(unsigned char*) res->ptr(),res->length()))
1959
else if (my_b_write(&cache,(uchar*) res->ptr(),res->length()))
1823
1961
my_error(ER_ERROR_ON_WRITE, MYF(0), path, my_errno);
1839
1977
bool select_singlerow_subselect::send_data(List<Item> &items)
1979
DBUG_ENTER("select_singlerow_subselect::send_data");
1841
1980
Item_singlerow_subselect *it= (Item_singlerow_subselect *)item;
1842
1981
if (it->assigned())
1844
1983
my_message(ER_SUBQUERY_NO_1_ROW, ER(ER_SUBQUERY_NO_1_ROW), MYF(0));
1847
1986
if (unit->offset_limit_cnt)
1848
1987
{ // Using limit offset,count
1849
1988
unit->offset_limit_cnt--;
1852
1991
List_iterator_fast<Item> li(items);
1853
1992
Item *val_item;
1854
for (uint32_t i= 0; (val_item= li++); i++)
1993
for (uint i= 0; (val_item= li++); i++)
1855
1994
it->store(i, val_item);
1856
1995
it->assigned(1);
1861
2000
void select_max_min_finder_subselect::cleanup()
2002
DBUG_ENTER("select_max_min_finder_subselect::cleanup");
1868
2008
bool select_max_min_finder_subselect::send_data(List<Item> &items)
2010
DBUG_ENTER("select_max_min_finder_subselect::send_data");
1870
2011
Item_maxmin_subselect *it= (Item_maxmin_subselect *)item;
1871
2012
List_iterator_fast<Item> li(items);
1872
2013
Item *val_item= li++;
1925
2066
bool select_max_min_finder_subselect::cmp_int()
1927
2068
Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
1928
int64_t val1= cache->val_int(), val2= maxmin->val_int();
2069
longlong val1= cache->val_int(), val2= maxmin->val_int();
1930
2071
return (cache->null_value && !maxmin->null_value) ||
1931
2072
(!cache->null_value && !maxmin->null_value &&
1968
2109
sortcmp(val1, val2, cache->collation.collation) < 0);
1971
bool select_exists_subselect::send_data(List<Item> &items __attribute__((unused)))
2112
bool select_exists_subselect::send_data(List<Item> &items)
2114
DBUG_ENTER("select_exists_subselect::send_data");
1973
2115
Item_exists_subselect *it= (Item_exists_subselect *)item;
1974
2116
if (unit->offset_limit_cnt)
1975
{ // Using limit offset,count
2117
{ // Using limit offset,count
1976
2118
unit->offset_limit_cnt--;
1980
2122
it->assigned(1);
2023
2166
free_list->delete_self();
2025
2168
/* Postcondition: free_list is 0 */
2173
void Query_arena::set_query_arena(Query_arena *set)
2175
mem_root= set->mem_root;
2176
free_list= set->free_list;
2181
void Query_arena::cleanup_stmt()
2183
DBUG_ASSERT("Query_arena::cleanup_stmt()" == "not implemented");
2031
2187
Statement functions
2034
Statement::Statement(LEX *lex_arg, MEM_ROOT *mem_root_arg, ulong id_arg)
2035
:Query_arena(mem_root_arg),
2190
Statement::Statement(LEX *lex_arg, MEM_ROOT *mem_root_arg,
2191
enum enum_state state_arg, ulong id_arg)
2192
:Query_arena(mem_root_arg, state_arg),
2037
2194
mark_used_columns(MARK_COLUMNS_READ),
2048
Don't free mem_root, as mem_root is freed in the end of dispatch_command
2049
(once for any command).
2205
void Statement::set_statement(Statement *stmt)
2208
mark_used_columns= stmt->mark_used_columns;
2211
query_length= stmt->query_length;
2216
Statement::set_n_backup_statement(Statement *stmt, Statement *backup)
2218
DBUG_ENTER("Statement::set_n_backup_statement");
2219
backup->set_statement(this);
2220
set_statement(stmt);
2225
void Statement::restore_backup_statement(Statement *stmt, Statement *backup)
2227
DBUG_ENTER("Statement::restore_backup_statement");
2228
stmt->set_statement(this);
2229
set_statement(backup);
2051
2234
void THD::end_statement()
2053
2236
/* Cleanup SQL processing state to reuse this statement in next query. */
2058
bool THD::copy_db_to(char **p_db, size_t *p_db_length)
2062
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
2065
*p_db= strmake(db, db_length);
2066
*p_db_length= db_length;
2240
/* Note that free_list is freed in cleanup_after_query() */
2243
Don't free mem_root, as mem_root is freed in the end of dispatch_command
2244
(once for any command).
2249
void THD::set_n_backup_active_arena(Query_arena *set, Query_arena *backup)
2251
DBUG_ENTER("THD::set_n_backup_active_arena");
2252
DBUG_ASSERT(backup->is_backup_arena == FALSE);
2254
backup->set_query_arena(this);
2255
set_query_arena(set);
2257
backup->is_backup_arena= TRUE;
2263
void THD::restore_active_arena(Query_arena *set, Query_arena *backup)
2265
DBUG_ENTER("THD::restore_active_arena");
2266
DBUG_ASSERT(backup->is_backup_arena);
2267
set->set_query_arena(this);
2268
set_query_arena(backup);
2270
backup->is_backup_arena= FALSE;
2071
2275
bool select_dumpvar::send_data(List<Item> &items)
2074
2278
List_iterator<Item> it(items);
2281
DBUG_ENTER("select_dumpvar::send_data");
2078
2283
if (unit->offset_limit_cnt)
2079
2284
{ // using limit offset,count
2080
2285
unit->offset_limit_cnt--;
2083
2288
if (row_count++)
2085
2290
my_message(ER_TOO_MANY_ROWS, ER(ER_TOO_MANY_ROWS), MYF(0));
2088
2293
while ((mv= var_li++) && (item= it++))
2098
return(thd->is_error());
2303
DBUG_RETURN(thd->is_error());
2101
2306
bool select_dumpvar::send_eof()
2103
2308
if (! row_count)
2104
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2309
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
2105
2310
ER_SP_FETCH_NO_DATA, ER(ER_SP_FETCH_NO_DATA));
2107
2312
In order to remember the value of affected rows for ROW_COUNT()
2119
2324
void TMP_TABLE_PARAM::init()
2326
DBUG_ENTER("TMP_TABLE_PARAM::init");
2327
DBUG_PRINT("enter", ("this: 0x%lx", (ulong)this));
2121
2328
field_count= sum_func_count= func_count= hidden_field_count= 0;
2122
2329
group_parts= group_length= group_null_parts= 0;
2123
2330
quick_group= 1;
2124
2331
table_charset= 0;
2125
2332
precomputed_group_by= 0;
2126
2333
bit_fields_as_long= 0;
2149
2356
current_thd->status_var.net_big_packet_count+= length;
2152
void THD::send_kill_message() const
2154
int err= killed_errno();
2156
my_message(err, ER(err), MYF(0));
2159
2360
void THD::set_status_var_init()
2161
memset(&status_var, 0, sizeof(status_var));
2362
bzero((char*) &status_var, sizeof(status_var));
2165
2366
void Security_context::init()
2368
host= user= priv_user= ip= 0;
2369
host_or_ip= "connecting host";
2171
2374
void Security_context::destroy()
2173
2376
// If not pointer to constant
2377
if (host != my_localhost)
2187
2384
void Security_context::skip_grants()
2189
2386
/* privileges for the user are unknown everything is allowed */
2387
host_or_ip= (char *)"";
2388
priv_user= (char *)"";
2201
2401
void THD::reset_n_backup_open_tables_state(Open_tables_state *backup)
2403
DBUG_ENTER("reset_n_backup_open_tables_state");
2203
2404
backup->set_open_tables_state(this);
2204
2405
reset_open_tables_state();
2205
2406
state_flags|= Open_tables_state::BACKUPS_AVAIL;
2210
2411
void THD::restore_backup_open_tables_state(Open_tables_state *backup)
2413
DBUG_ENTER("restore_backup_open_tables_state");
2213
2415
Before we will throw away current open tables state we want
2214
2416
to be sure that it was properly cleaned up.
2216
assert(open_tables == 0 && temporary_tables == 0 &&
2418
DBUG_ASSERT(open_tables == 0 && temporary_tables == 0 &&
2217
2419
handler_tables == 0 && derived_tables == 0 &&
2218
2420
lock == 0 && locked_tables == 0);
2219
2421
set_open_tables_state(backup);
2236
2438
@param thd user thread
2237
2439
@return thread id
2239
extern "C" unsigned long thd_get_thread_id(const DRIZZLE_THD thd)
2441
extern "C" unsigned long thd_get_thread_id(const MYSQL_THD thd)
2241
2443
return((unsigned long)thd->thread_id);
2245
2447
#ifdef INNODB_COMPATIBILITY_HOOKS
2246
extern "C" const struct charset_info_st *thd_charset(DRIZZLE_THD thd)
2448
extern "C" struct charset_info_st *thd_charset(MYSQL_THD thd)
2248
2450
return(thd->charset());
2251
extern "C" char **thd_query(DRIZZLE_THD thd)
2453
extern "C" char **thd_query(MYSQL_THD thd)
2253
2455
return(&thd->query);
2256
extern "C" int thd_slave_thread(const DRIZZLE_THD thd)
2458
extern "C" int thd_slave_thread(const MYSQL_THD thd)
2258
2460
return(thd->slave_thread);
2261
extern "C" int thd_non_transactional_update(const DRIZZLE_THD thd)
2463
extern "C" int thd_non_transactional_update(const MYSQL_THD thd)
2263
2465
return(thd->transaction.all.modified_non_trans_table);
2266
extern "C" int thd_binlog_format(const DRIZZLE_THD thd)
2468
extern "C" int thd_binlog_format(const MYSQL_THD thd)
2268
2470
return (int) thd->variables.binlog_format;
2271
extern "C" void thd_mark_transaction_to_rollback(DRIZZLE_THD thd, bool all)
2473
extern "C" void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all)
2273
2475
mark_transaction_to_rollback(thd, all);
2279
2481
Mark transaction to rollback and mark error as fatal to a sub-statement.
2281
2483
@param thd Thread handle
2282
@param all true <=> rollback main transaction.
2484
@param all TRUE <=> rollback main transaction.
2285
2487
void mark_transaction_to_rollback(THD *thd, bool all)
2289
thd->is_fatal_sub_stmt_error= true;
2491
thd->is_fatal_sub_stmt_error= TRUE;
2290
2492
thd->transaction_rollback_request= all;
2297
2499
pthread_mutex_t LOCK_xid_cache;
2298
2500
HASH xid_cache;
2300
extern "C" unsigned char *xid_get_hash_key(const unsigned char *, size_t *, bool);
2502
extern "C" uchar *xid_get_hash_key(const uchar *, size_t *, my_bool);
2301
2503
extern "C" void xid_free_hash(void *);
2303
unsigned char *xid_get_hash_key(const unsigned char *ptr, size_t *length,
2304
bool not_used __attribute__((unused)))
2505
uchar *xid_get_hash_key(const uchar *ptr, size_t *length,
2506
my_bool not_used __attribute__((unused)))
2306
2508
*length=((XID_STATE*)ptr)->xid.key_length();
2307
2509
return ((XID_STATE*)ptr)->xid.key();
2362
2564
bool xid_cache_insert(XID_STATE *xid_state)
2364
2566
pthread_mutex_lock(&LOCK_xid_cache);
2365
assert(hash_search(&xid_cache, xid_state->xid.key(),
2567
DBUG_ASSERT(hash_search(&xid_cache, xid_state->xid.key(),
2366
2568
xid_state->xid.key_length())==0);
2367
bool res=my_hash_insert(&xid_cache, (unsigned char*)xid_state);
2569
my_bool res=my_hash_insert(&xid_cache, (uchar*)xid_state);
2368
2570
pthread_mutex_unlock(&LOCK_xid_cache);
2373
2575
void xid_cache_delete(XID_STATE *xid_state)
2375
2577
pthread_mutex_lock(&LOCK_xid_cache);
2376
hash_delete(&xid_cache, (unsigned char *)xid_state);
2578
hash_delete(&xid_cache, (uchar *)xid_state);
2377
2579
pthread_mutex_unlock(&LOCK_xid_cache);
2408
2611
template <class RowsEventT> Rows_log_event*
2409
THD::binlog_prepare_pending_rows_event(Table* table, uint32_t serv_id,
2612
THD::binlog_prepare_pending_rows_event(TABLE* table, uint32 serv_id,
2411
2614
bool is_transactional,
2412
2615
RowsEventT *hint __attribute__((unused)))
2617
DBUG_ENTER("binlog_prepare_pending_rows_event");
2414
2618
/* Pre-conditions */
2415
assert(table->s->table_map_id != UINT32_MAX);
2619
DBUG_ASSERT(table->s->table_map_id != ~0UL);
2417
2621
/* Fetch the type code for the RowsEventT template parameter */
2418
2622
int const type_code= RowsEventT::TYPE_CODE;
2468
2672
if (unlikely(mysql_bin_log.flush_and_set_pending_rows_event(this, ev)))
2474
return(ev); /* This is the new pending event */
2678
DBUG_RETURN(ev); /* This is the new pending event */
2476
return(pending); /* This is the current pending event */
2680
DBUG_RETURN(pending); /* This is the current pending event */
2479
2683
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
2482
2686
compiling option.
2484
2688
template Rows_log_event*
2485
THD::binlog_prepare_pending_rows_event(Table*, uint32_t, size_t, bool,
2689
THD::binlog_prepare_pending_rows_event(TABLE*, uint32, size_t, bool,
2486
2690
Write_rows_log_event*);
2488
2692
template Rows_log_event*
2489
THD::binlog_prepare_pending_rows_event(Table*, uint32_t, size_t, bool,
2693
THD::binlog_prepare_pending_rows_event(TABLE*, uint32, size_t, bool,
2490
2694
Delete_rows_log_event *);
2492
2696
template Rows_log_event*
2493
THD::binlog_prepare_pending_rows_event(Table*, uint32_t, size_t, bool,
2697
THD::binlog_prepare_pending_rows_event(TABLE*, uint32, size_t, bool,
2494
2698
Update_rows_log_event *);
2523
2727
Length of data that is needed, if the record contain blobs.
2525
Row_data_memory(Table *table, size_t const len1)
2729
Row_data_memory(TABLE *table, size_t const len1)
2528
m_alloc_checked= false;
2733
m_alloc_checked= FALSE;
2529
2735
allocate_memory(table, len1);
2530
2736
m_ptr[0]= has_memory() ? m_memory : 0;
2534
Row_data_memory(Table *table, size_t const len1, size_t const len2)
2740
Row_data_memory(TABLE *table, size_t const len1, size_t const len2)
2537
m_alloc_checked= false;
2744
m_alloc_checked= FALSE;
2538
2746
allocate_memory(table, len1 + len2);
2539
2747
m_ptr[0]= has_memory() ? m_memory : 0;
2540
2748
m_ptr[1]= has_memory() ? m_memory + len1 : 0;
2553
2761
@retval false Memory allocation failed
2555
2763
bool has_memory() const {
2556
m_alloc_checked= true;
2765
m_alloc_checked= TRUE;
2557
2767
return m_memory != 0;
2560
unsigned char *slot(uint32_t s)
2562
assert(s < sizeof(m_ptr)/sizeof(*m_ptr));
2563
assert(m_ptr[s] != 0);
2564
assert(m_alloc_checked == true);
2772
DBUG_ASSERT(s < sizeof(m_ptr)/sizeof(*m_ptr));
2773
DBUG_ASSERT(m_ptr[s] != 0);
2774
DBUG_ASSERT(m_alloc_checked == TRUE);
2565
2775
return m_ptr[s];
2569
void allocate_memory(Table *const table, size_t const total_length)
2779
void allocate_memory(TABLE *const table, size_t const total_length)
2571
2781
if (table->s->blob_fields == 0)
2590
2800
if (table->write_row_record == 0)
2591
2801
table->write_row_record=
2592
(unsigned char *) alloc_root(&table->mem_root, 2 * maxlen);
2802
(uchar *) alloc_root(&table->mem_root, 2 * maxlen);
2593
2803
m_memory= table->write_row_record;
2594
m_release_memory_on_destruction= false;
2804
m_release_memory_on_destruction= FALSE;
2598
m_memory= (unsigned char *) my_malloc(total_length, MYF(MY_WME));
2599
m_release_memory_on_destruction= true;
2808
m_memory= (uchar *) my_malloc(total_length, MYF(MY_WME));
2809
m_release_memory_on_destruction= TRUE;
2603
2814
mutable bool m_alloc_checked;
2604
2816
bool m_release_memory_on_destruction;
2605
unsigned char *m_memory;
2606
unsigned char *m_ptr[2];
2611
int THD::binlog_write_row(Table* table, bool is_trans,
2612
unsigned char const *record)
2823
int THD::binlog_write_row(TABLE* table, bool is_trans,
2824
uchar const *record)
2614
assert(current_stmt_binlog_row_based && mysql_bin_log.is_open());
2826
DBUG_ASSERT(current_stmt_binlog_row_based && mysql_bin_log.is_open());
2617
2829
Pack records into format for transfer. We are allocating more
2618
2830
memory than needed, but that doesn't matter.
2620
Row_data_memory memory(table, table->max_row_length(record));
2832
Row_data_memory memory(table, max_row_length(table, record));
2621
2833
if (!memory.has_memory())
2622
2834
return HA_ERR_OUT_OF_MEM;
2624
unsigned char *row_data= memory.slot(0);
2836
uchar *row_data= memory.slot(0);
2626
2838
size_t const len= pack_row(table, table->write_set, row_data, record);
2635
2847
return ev->add_row_data(row_data, len);
2638
int THD::binlog_update_row(Table* table, bool is_trans,
2639
const unsigned char *before_record,
2640
const unsigned char *after_record)
2850
int THD::binlog_update_row(TABLE* table, bool is_trans,
2851
const uchar *before_record,
2852
const uchar *after_record)
2642
assert(current_stmt_binlog_row_based && mysql_bin_log.is_open());
2854
DBUG_ASSERT(current_stmt_binlog_row_based && mysql_bin_log.is_open());
2644
size_t const before_maxlen = table->max_row_length(before_record);
2645
size_t const after_maxlen = table->max_row_length(after_record);
2856
size_t const before_maxlen = max_row_length(table, before_record);
2857
size_t const after_maxlen = max_row_length(table, after_record);
2647
2859
Row_data_memory row_data(table, before_maxlen, after_maxlen);
2648
2860
if (!row_data.has_memory())
2649
2861
return HA_ERR_OUT_OF_MEM;
2651
unsigned char *before_row= row_data.slot(0);
2652
unsigned char *after_row= row_data.slot(1);
2863
uchar *before_row= row_data.slot(0);
2864
uchar *after_row= row_data.slot(1);
2654
2866
size_t const before_size= pack_row(table, table->read_set, before_row,
2655
2867
before_record);
2656
2868
size_t const after_size= pack_row(table, table->write_set, after_row,
2872
Don't print debug messages when running valgrind since they can
2873
trigger false warnings.
2876
DBUG_DUMP("before_record", before_record, table->s->reclength);
2877
DBUG_DUMP("after_record", after_record, table->s->reclength);
2878
DBUG_DUMP("before_row", before_row, before_size);
2879
DBUG_DUMP("after_row", after_row, after_size);
2659
2882
Rows_log_event* const ev=
2660
2883
binlog_prepare_pending_rows_event(table, server_id,
2661
2884
before_size + after_size, is_trans,
2669
2892
ev->add_row_data(after_row, after_size);
2672
int THD::binlog_delete_row(Table* table, bool is_trans,
2673
unsigned char const *record)
2895
int THD::binlog_delete_row(TABLE* table, bool is_trans,
2896
uchar const *record)
2675
assert(current_stmt_binlog_row_based && mysql_bin_log.is_open());
2898
DBUG_ASSERT(current_stmt_binlog_row_based && mysql_bin_log.is_open());
2678
2901
Pack records into format for transfer. We are allocating more
2679
2902
memory than needed, but that doesn't matter.
2681
Row_data_memory memory(table, table->max_row_length(record));
2904
Row_data_memory memory(table, max_row_length(table, record));
2682
2905
if (unlikely(!memory.has_memory()))
2683
2906
return HA_ERR_OUT_OF_MEM;
2685
unsigned char *row_data= memory.slot(0);
2908
uchar *row_data= memory.slot(0);
2910
DBUG_DUMP("table->read_set", (uchar*) table->read_set->bitmap, (table->s->fields + 7) / 8);
2687
2911
size_t const len= pack_row(table, table->read_set, row_data, record);
2689
2913
Rows_log_event* const ev=
2700
2924
int THD::binlog_flush_pending_rows_event(bool stmt_end)
2926
DBUG_ENTER("THD::binlog_flush_pending_rows_event");
2703
2928
We shall flush the pending event even if we are not in row-based
2704
2929
mode: it might be the case that we left row-based mode before
2705
2930
flushing anything (e.g., if we have explicitly locked tables).
2707
2932
if (!mysql_bin_log.is_open())
2711
2936
Mark the event as the last event of a statement if the stmt_end
2755
2980
ulong query_len, bool is_trans, bool suppress_use,
2756
2981
THD::killed_state killed_status_arg)
2758
assert(query_arg && mysql_bin_log.is_open());
2983
DBUG_ENTER("THD::binlog_query");
2984
DBUG_PRINT("enter", ("qtype: %d query: '%s'", qtype, query_arg));
2985
DBUG_ASSERT(query_arg && mysql_bin_log.is_open());
2760
if (int error= binlog_flush_pending_rows_event(true))
2987
if (int error= binlog_flush_pending_rows_event(TRUE))
2764
2991
If we are in statement mode and trying to log an unsafe statement,
2767
2994
if (lex->is_stmt_unsafe() &&
2768
2995
variables.binlog_format == BINLOG_FORMAT_STMT)
2770
assert(this->query != NULL);
2771
push_warning(this, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2997
DBUG_ASSERT(this->query != NULL);
2998
push_warning(this, MYSQL_ERROR::WARN_LEVEL_WARN,
2772
2999
ER_BINLOG_UNSAFE_STATEMENT,
2773
3000
ER(ER_BINLOG_UNSAFE_STATEMENT));
2774
3001
if (!(binlog_flags & BINLOG_FLAG_UNSAFE_STMT_PRINTED))
2776
char warn_buf[DRIZZLE_ERRMSG_SIZE];
2777
snprintf(warn_buf, DRIZZLE_ERRMSG_SIZE, "%s Statement: %s",
2778
ER(ER_BINLOG_UNSAFE_STATEMENT), this->query);
3003
char warn_buf[MYSQL_ERRMSG_SIZE];
3004
my_snprintf(warn_buf, MYSQL_ERRMSG_SIZE, "%s Statement: %s",
3005
ER(ER_BINLOG_UNSAFE_STATEMENT), this->query);
2779
3006
sql_print_warning(warn_buf);
2780
3007
binlog_flags|= BINLOG_FLAG_UNSAFE_STMT_PRINTED;
2784
3011
switch (qtype) {
2785
3012
case THD::ROW_QUERY_TYPE:
2786
3013
if (current_stmt_binlog_row_based)
2788
3015
/* Otherwise, we fall through */
2789
case THD::DRIZZLE_QUERY_TYPE:
3016
case THD::MYSQL_QUERY_TYPE:
2791
3018
Using this query type is a conveniece hack, since we have been
2792
3019
moving back and forth between using RBR for replication of
2813
3040
int error= mysql_bin_log.write(&qinfo);
2814
3041
binlog_table_maps= 0;
2819
3046
case THD::QUERY_TYPE_COUNT:
2821
assert(0 <= qtype && qtype < QUERY_TYPE_COUNT);
3048
DBUG_ASSERT(0 <= qtype && qtype < QUERY_TYPE_COUNT);
2826
bool Discrete_intervals_list::append(uint64_t start, uint64_t val,
3053
bool Discrete_intervals_list::append(ulonglong start, ulonglong val,
3056
DBUG_ENTER("Discrete_intervals_list::append");
2829
3057
/* first, see if this can be merged with previous */
2830
3058
if ((head == NULL) || tail->merge_if_contiguous(start, val, incr))
2832
3060
/* it cannot, so need to add a new interval */
2833
3061
Discrete_interval *new_interval= new Discrete_interval(start, val, incr);
2834
return(append(new_interval));
3062
DBUG_RETURN(append(new_interval));
2839
3067
bool Discrete_intervals_list::append(Discrete_interval *new_interval)
3069
DBUG_ENTER("Discrete_intervals_list::append");
2841
3070
if (unlikely(new_interval == NULL))
3072
DBUG_PRINT("info",("adding new auto_increment interval"));
2843
3073
if (head == NULL)
2844
3074
head= current= new_interval;
2846
3076
tail->next= new_interval;
2847
3077
tail= new_interval;
3082
#endif /* !defined(MYSQL_CLIENT) */