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>
36
#include <thr_alarm.h>
37
#include <mysys_err.h>
33
40
The following is used to initialise Table_ident with a internal
60
67
****************************************************************************/
62
extern "C" unsigned char *get_var_key(user_var_entry *entry, size_t *length,
63
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)))
65
72
*length= entry->name.length;
66
return (unsigned char*) entry->name.str;
73
return (uchar*) entry->name.str;
69
76
extern "C" void free_user_var(user_var_entry *entry)
71
78
char *pos= (char*) entry+ALIGN_SIZE(sizeof(*entry));
72
79
if (entry->value && entry->value != pos)
80
my_free(entry->value, MYF(0));
81
my_free((char*) entry,MYF(0));
77
84
bool Key_part_spec::operator==(const Key_part_spec& other) const
137
144
if (a->generated)
139
146
if (b->generated && a->columns.elements > b->columns.elements)
140
std::swap(a, b); // Put shorter key in 'a'
147
swap_variables(Key*, a, b); // Put shorter key in 'a'
144
151
if (!b->generated)
145
152
return true; // No foreign key
146
std::swap(a, b); // Put generated key in 'a'
153
swap_variables(Key*, a, b); // Put generated key in 'a'
149
156
/* Test if 'a' is a prefix of 'b' */
234
241
const char *set_thd_proc_info(THD *thd, const char *info,
235
const char *calling_function __attribute__((unused)),
236
const char *calling_file __attribute__((unused)),
237
const unsigned int calling_line __attribute__((unused)))
242
const char *calling_function __attribute__((__unused__)),
243
const char *calling_file __attribute__((__unused__)),
244
const unsigned int calling_line __attribute__((__unused__)))
239
const char *old_info= thd->get_proc_info();
240
thd->set_proc_info(info);
246
const char *old_info= thd->proc_info;
247
thd->proc_info= info;
271
278
thd->row_count++;
282
Dumps a text description of a thread, its security context
283
(user, host) and the current query.
286
thd_security_context()
287
thd current thread context
288
buffer pointer to preferred result buffer
289
length length of buffer
290
max_query_len how many chars of query to copy (0 for all)
296
char *thd_security_context(THD *thd, char *buffer, unsigned int length,
297
unsigned int max_query_len)
299
String str(buffer, length, &my_charset_latin1);
300
const Security_context *sctx= &thd->main_security_ctx;
304
len= snprintf(header, sizeof(header),
305
"MySQL thread id %lu, query id %lu",
306
thd->thread_id, (ulong) thd->query_id);
308
str.append(header, len);
313
str.append(sctx->host);
319
str.append(sctx->ip);
325
str.append(sctx->user);
331
str.append(thd->proc_info);
336
if (max_query_len < 1)
337
len= thd->query_length;
339
len= min(thd->query_length, max_query_len);
341
str.append(thd->query, len);
343
if (str.c_ptr_safe() == buffer)
345
return thd->strmake(str.ptr(), str.length());
275
349
Clear this diagnostics area.
402
:Statement(&main_lex, &main_mem_root,
476
:Statement(&main_lex, &main_mem_root, CONVENTIONAL_EXECUTION,
403
477
/* statement id */ 0),
404
478
Open_tables_state(refresh_version), rli_fake(0),
405
479
lock_id(&main_lock_id),
419
493
in_lock_tables(0),
421
495
derived_tables_processing(false),
498
@todo The following is a work around for online backup and the DDL blocker.
499
It should be removed when the generalized solution is in place.
500
This is needed to ensure the restore (which uses DDL) is not blocked
501
when the DDL blocker is engaged.
429
510
will be re-initialized in init_for_queries().
431
512
init_sql_alloc(&main_mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0);
433
515
catalog= (char*)"std"; // the only catalog we have for now
434
516
main_security_ctx.init();
453
535
utime_after_lock= 0L;
454
536
current_linfo = 0;
455
537
slave_thread = 0;
456
memset(&variables, 0, sizeof(variables));
538
bzero(&variables, sizeof(variables));
462
544
db_charset= global_system_variables.collation_database;
463
memset(ha_data, 0, sizeof(ha_data));
545
bzero(ha_data, sizeof(ha_data));
465
547
binlog_evt_union.do_union= false;
466
549
dbug_sentry=THD_SENTRY_MAGIC;
468
551
client_capabilities= 0; // minimalistic client
471
554
peer_port= 0; // For SHOW PROCESSLIST
472
555
transaction.m_pending_rows_event= 0;
473
556
transaction.on= 1;
557
#ifdef SIGNAL_WITH_VIO_CLOSE
474
560
pthread_mutex_init(&LOCK_delete, MY_MUTEX_INIT_FAST);
476
562
/* Variables with default values */
494
580
my_init_dynamic_array(&user_var_events,
495
581
sizeof(BINLOG_USER_VAR_EVENT *), 16, 16);
497
memset(&user_var_events, 0, sizeof(user_var_events));
583
bzero((char*) &user_var_events, sizeof(user_var_events));
500
586
protocol= &protocol_text; // Default protocol
501
587
protocol_text.init(this);
503
589
tablespace_op= false;
590
tmp= sql_rnd_with_mutex();
505
591
randominit(&rand, tmp + (ulong) &rand, tmp + (ulong) ::global_query_id);
506
592
substitute_null_with_insert_id = false;
507
593
thr_lock_info_init(&lock_info); /* safety: will be reset after start */
525
bool THD::handle_error(uint32_t sql_errno, const char *message,
526
DRIZZLE_ERROR::enum_warning_level level)
611
bool THD::handle_error(uint sql_errno, const char *message,
612
MYSQL_ERROR::enum_warning_level level)
528
614
if (m_internal_handler)
544
void *thd_alloc(DRIZZLE_THD thd, unsigned int size)
630
void *thd_alloc(MYSQL_THD thd, unsigned int size)
546
632
return thd->alloc(size);
550
void *thd_calloc(DRIZZLE_THD thd, unsigned int size)
636
void *thd_calloc(MYSQL_THD thd, unsigned int size)
552
638
return thd->calloc(size);
556
char *thd_strdup(DRIZZLE_THD thd, const char *str)
642
char *thd_strdup(MYSQL_THD thd, const char *str)
558
644
return thd->strdup(str);
562
char *thd_strmake(DRIZZLE_THD thd, const char *str, unsigned int size)
648
char *thd_strmake(MYSQL_THD thd, const char *str, unsigned int size)
564
650
return thd->strmake(str, size);
577
void *thd_memdup(DRIZZLE_THD thd, const void* str, unsigned int size)
663
void *thd_memdup(MYSQL_THD thd, const void* str, unsigned int size)
579
665
return thd->memdup(str, size);
583
void thd_get_xid(const DRIZZLE_THD thd, DRIZZLE_XID *xid)
669
void thd_get_xid(const MYSQL_THD thd, MYSQL_XID *xid)
585
*xid = *(DRIZZLE_XID *) &thd->transaction.xid_state.xid;
671
*xid = *(MYSQL_XID *) &thd->transaction.xid_state.xid;
622
708
session_tx_isolation= (enum_tx_isolation) variables.tx_isolation;
623
709
warn_list.empty();
624
memset(warn_count, 0, sizeof(warn_count));
710
bzero((char*) warn_count, sizeof(warn_count));
625
711
total_warn_count= 0;
626
712
update_charset();
627
713
reset_current_stmt_binlog_row_based();
628
memset(&status_var, 0, sizeof(status_var));
714
bzero((char *) &status_var, sizeof(status_var));
676
762
delete_dynamic(&user_var_events);
677
763
hash_free(&user_vars);
678
764
close_temporary_tables(this);
679
free((char*) variables.time_format);
680
free((char*) variables.date_format);
681
free((char*) variables.datetime_format);
765
my_free((char*) variables.time_format, MYF(MY_ALLOW_ZERO_PTR));
766
my_free((char*) variables.date_format, MYF(MY_ALLOW_ZERO_PTR));
767
my_free((char*) variables.datetime_format, MYF(MY_ALLOW_ZERO_PTR));
683
769
if (global_read_lock)
684
770
unlock_global_read_lock(this);
708
794
plugin_thdvar_cleanup(this);
710
796
main_security_ctx.destroy();
716
798
free_root(&warn_root,MYF(0));
717
799
free_root(&transaction.mem_root,MYF(0));
718
800
mysys_var=0; // Safety (shouldn't be needed)
746
828
void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var)
748
ulong *end= (ulong*) ((unsigned char*) to_var +
830
ulong *end= (ulong*) ((uchar*) to_var +
749
831
offsetof(STATUS_VAR, last_system_status_var) +
751
833
ulong *to= (ulong*) to_var, *from= (ulong*) from_var;
770
852
void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
771
853
STATUS_VAR *dec_var)
773
ulong *end= (ulong*) ((unsigned char*) to_var + offsetof(STATUS_VAR,
855
ulong *end= (ulong*) ((uchar*) to_var + offsetof(STATUS_VAR,
774
856
last_system_status_var) +
776
858
ulong *to= (ulong*) to_var, *from= (ulong*) from_var, *dec= (ulong*) dec_var;
791
873
thr_alarm_kill(thread_id);
792
874
if (!slave_thread)
793
875
thread_scheduler.post_kill_notification(this);
876
#ifdef SIGNAL_WITH_VIO_CLOSE
877
if (this != current_thd)
880
In addition to a signal, let's close the socket of the thread that
881
is being killed. This is to make sure it does not block if the
882
signal is lost. This needs to be done only on platforms where
883
signals are not a reliable interruption mechanism.
885
If we're killing ourselves, we know that we're not blocked, so this
922
1020
@return NULL on failure, or pointer to the LEX_STRING object
924
1022
LEX_STRING *THD::make_lex_string(LEX_STRING *lex_str,
925
const char* str, uint32_t length,
1023
const char* str, uint length,
926
1024
bool allocate_lex_string)
928
1026
if (allocate_lex_string)
955
1053
In this case to->str will point to 0 and to->length will be 0.
958
bool THD::convert_string(LEX_STRING *to, const CHARSET_INFO * const to_cs,
959
const char *from, uint32_t from_length,
960
const CHARSET_INFO * const from_cs)
1056
bool THD::convert_string(LEX_STRING *to, CHARSET_INFO *to_cs,
1057
const char *from, uint from_length,
1058
CHARSET_INFO *from_cs)
962
1060
size_t new_length= to_cs->mbmaxlen * from_length;
963
uint32_t dummy_errors;
964
1062
if (!(to->str= (char*) alloc(new_length+1)))
966
1064
to->length= 0; // Safety fix
988
1086
!0 out of memory
991
bool THD::convert_string(String *s, const CHARSET_INFO * const from_cs,
992
const CHARSET_INFO * const to_cs)
1089
bool THD::convert_string(String *s, CHARSET_INFO *from_cs, CHARSET_INFO *to_cs)
994
uint32_t dummy_errors;
995
1092
if (convert_buffer.copy(s->ptr(), s->length(), from_cs, to_cs, &dummy_errors))
997
1094
/* If convert_buffer >> s copying is more efficient long term */
1027
1124
/* routings to adding tables to list of changed in transaction tables */
1029
inline static void list_include(CHANGED_TableList** prev,
1030
CHANGED_TableList* curr,
1031
CHANGED_TableList* new_table)
1126
inline static void list_include(CHANGED_TABLE_LIST** prev,
1127
CHANGED_TABLE_LIST* curr,
1128
CHANGED_TABLE_LIST* new_table)
1040
1137
/* add table to list of changed in transaction tables */
1042
void THD::add_changed_table(Table *table)
1139
void THD::add_changed_table(TABLE *table)
1044
1141
assert((options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
1045
1142
table->file->has_transactions());
1052
1149
void THD::add_changed_table(const char *key, long key_length)
1054
CHANGED_TableList **prev_changed = &transaction.changed_tables;
1055
CHANGED_TableList *curr = transaction.changed_tables;
1151
CHANGED_TABLE_LIST **prev_changed = &transaction.changed_tables;
1152
CHANGED_TABLE_LIST *curr = transaction.changed_tables;
1057
1154
for (; curr; prev_changed = &(curr->next), curr = curr->next)
1084
CHANGED_TableList* THD::changed_table_dup(const char *key, long key_length)
1181
CHANGED_TABLE_LIST* THD::changed_table_dup(const char *key, long key_length)
1086
CHANGED_TableList* new_table =
1087
(CHANGED_TableList*) trans_alloc(ALIGN_SIZE(sizeof(CHANGED_TableList))+
1183
CHANGED_TABLE_LIST* new_table =
1184
(CHANGED_TABLE_LIST*) trans_alloc(ALIGN_SIZE(sizeof(CHANGED_TABLE_LIST))+
1088
1185
key_length + 1);
1089
1186
if (!new_table)
1091
1188
my_error(EE_OUTOFMEMORY, MYF(ME_BELL),
1092
ALIGN_SIZE(sizeof(TableList)) + key_length + 1);
1189
ALIGN_SIZE(sizeof(TABLE_LIST)) + key_length + 1);
1093
1190
killed= KILL_CONNECTION;
1097
new_table->key= ((char*)new_table)+ ALIGN_SIZE(sizeof(CHANGED_TableList));
1194
new_table->key= ((char*)new_table)+ ALIGN_SIZE(sizeof(CHANGED_TABLE_LIST));
1098
1195
new_table->next = 0;
1099
1196
new_table->key_length = key_length;
1100
1197
::memcpy(new_table->key, key, key_length);
1107
1204
List<Item> field_list;
1109
const CHARSET_INFO * const cs= system_charset_info;
1110
field_list.push_back(new Item_return_int("id",3, DRIZZLE_TYPE_LONGLONG));
1206
CHARSET_INFO *cs= system_charset_info;
1207
field_list.push_back(new Item_return_int("id",3, MYSQL_TYPE_LONGLONG));
1111
1208
field_list.push_back(new Item_empty_string("select_type", 19, cs));
1112
1209
field_list.push_back(item= new Item_empty_string("table", NAME_CHAR_LEN, cs));
1113
1210
item->maybe_null= 1;
1130
1227
item->maybe_null=1;
1131
1228
field_list.push_back(item= new Item_return_int("rows", 10,
1132
DRIZZLE_TYPE_LONGLONG));
1229
MYSQL_TYPE_LONGLONG));
1133
1230
if (lex->describe & DESCRIBE_EXTENDED)
1135
1232
field_list.push_back(item= new Item_float("filtered", 0.1234, 2, 4));
1141
1238
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF));
1241
#ifdef SIGNAL_WITH_VIO_CLOSE
1242
void THD::close_active_vio()
1244
safe_mutex_assert_owner(&LOCK_delete);
1247
vio_close(active_vio);
1145
1255
struct Item_change_record: public ilink
1148
1258
Item *old_value;
1149
1259
/* Placement new was hidden by `new' in ilink (TODO: check): */
1150
static void *operator new(size_t size __attribute__((unused)),
1260
static void *operator new(size_t size __attribute__((__unused__)),
1152
1262
{ return mem; }
1153
static void operator delete(void *ptr __attribute__((unused)),
1154
size_t size __attribute__((unused)))
1263
static void operator delete(void *ptr __attribute__((__unused__)),
1264
size_t size __attribute__((__unused__)))
1156
static void operator delete(void *ptr __attribute__((unused)),
1157
void *mem __attribute__((unused)))
1266
static void operator delete(void *ptr __attribute__((__unused__)),
1267
void *mem __attribute__((__unused__)))
1158
1268
{ /* never called */ }
1163
1273
Register an item tree tree transformation, performed by the query
1164
1274
optimizer. We need a pointer to runtime_memroot because it may be !=
1165
thd->mem_root (this may no longer be a true statement)
1275
thd->mem_root (due to possible set_n_backup_active_arena called for thd).
1168
1278
void THD::nocheck_register_item_tree_change(Item **place, Item *old_value,
1317
Check that the endpoint is still available.
1320
bool THD::vio_is_connected()
1324
/* End of input is signaled by poll if the socket is aborted. */
1325
if (vio_poll_read(net.vio, 0))
1328
/* Socket is aborted if signaled but no data is available. */
1329
if (vio_peek_read(net.vio, &bytes))
1332
return bytes ? true : false;
1206
1336
/*****************************************************************************
1207
1337
** Functions to provide a interface to select results
1208
1338
*****************************************************************************/
1212
1342
thd=current_thd;
1215
void select_result::send_error(uint32_t errcode,const char *err)
1345
void select_result::send_error(uint errcode,const char *err)
1217
1347
my_message(errcode, err, MYF(0));
1233
1363
static String default_line_term("\n",default_charset_info);
1234
1364
static String default_escaped("\\",default_charset_info);
1235
1365
static String default_field_term("\t",default_charset_info);
1366
static String default_xml_row_term("<row>", default_charset_info);
1237
1368
sql_exchange::sql_exchange(char *name, bool flag,
1238
1369
enum enum_filetype filetype_arg)
1241
1372
filetype= filetype_arg;
1242
1373
field_term= &default_field_term;
1243
1374
enclosed= line_start= &my_empty_string;
1244
line_term= &default_line_term;
1375
line_term= filetype == FILETYPE_CSV ?
1376
&default_line_term : &default_xml_row_term;
1245
1377
escaped= &default_escaped;
1249
bool select_send::send_fields(List<Item> &list, uint32_t flags)
1381
bool select_send::send_fields(List<Item> &list, uint flags)
1252
1384
if (!(res= thd->protocol->send_fields(&list, flags)))
1340
1472
Handling writing to file
1341
1473
************************************************************************/
1343
void select_to_file::send_error(uint32_t errcode,const char *err)
1475
void select_to_file::send_error(uint errcode,const char *err)
1345
1477
my_message(errcode, err, MYF(0));
1435
1567
if (!dirname_length(exchange->file_name))
1437
1569
strxnmov(path, FN_REFLEN-1, mysql_real_data_home, thd->db ? thd->db : "",
1439
1571
(void) fn_format(path, exchange->file_name, path, "", option);
1503
1635
field_term_length=exchange->field_term->length();
1504
1636
field_term_char= field_term_length ?
1505
(int) (unsigned char) (*exchange->field_term)[0] : INT_MAX;
1637
(int) (uchar) (*exchange->field_term)[0] : INT_MAX;
1506
1638
if (!exchange->line_term->length())
1507
1639
exchange->line_term=exchange->field_term; // Use this if it exists
1508
1640
field_sep_char= (exchange->enclosed->length() ?
1509
(int) (unsigned char) (*exchange->enclosed)[0] : field_term_char);
1641
(int) (uchar) (*exchange->enclosed)[0] : field_term_char);
1510
1642
escape_char= (exchange->escaped->length() ?
1511
(int) (unsigned char) (*exchange->escaped)[0] : -1);
1643
(int) (uchar) (*exchange->escaped)[0] : -1);
1512
1644
is_ambiguous_field_sep= test(strchr(ESCAPE_CHARS, field_sep_char));
1513
1645
is_unsafe_field_sep= test(strchr(NUMERIC_CHARS, field_sep_char));
1514
1646
line_sep_char= (exchange->line_term->length() ?
1515
(int) (unsigned char) (*exchange->line_term)[0] : INT_MAX);
1647
(int) (uchar) (*exchange->line_term)[0] : INT_MAX);
1516
1648
if (!field_term_length)
1517
1649
exchange->opt_enclosed=0;
1518
1650
if (!exchange->enclosed->length())
1524
1656
(exchange->opt_enclosed && non_string_results &&
1525
1657
field_term_length && strchr(NUMERIC_CHARS, field_term_char)))
1527
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1659
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1528
1660
ER_AMBIGUOUS_FIELD_TERM, ER(ER_AMBIGUOUS_FIELD_TERM));
1529
1661
is_ambiguous_field_term= true;
1538
#define NEED_ESCAPING(x) ((int) (unsigned char) (x) == escape_char || \
1539
(enclosed ? (int) (unsigned char) (x) == field_sep_char \
1540
: (int) (unsigned char) (x) == field_term_char) || \
1541
(int) (unsigned char) (x) == line_sep_char || \
1670
#define NEED_ESCAPING(x) ((int) (uchar) (x) == escape_char || \
1671
(enclosed ? (int) (uchar) (x) == field_sep_char \
1672
: (int) (uchar) (x) == field_term_char) || \
1673
(int) (uchar) (x) == line_sep_char || \
1544
1676
bool select_export::send_data(List<Item> &items)
1558
uint32_t used_length=0,items_left=items.elements;
1690
uint used_length=0,items_left=items.elements;
1559
1691
List_iterator_fast<Item> li(items);
1561
if (my_b_write(&cache,(unsigned char*) exchange->line_start->ptr(),
1693
if (my_b_write(&cache,(uchar*) exchange->line_start->ptr(),
1562
1694
exchange->line_start->length()))
1564
1696
while ((item=li++))
1569
1701
res=item->str_result(&tmp);
1570
1702
if (res && enclosed)
1572
if (my_b_write(&cache,(unsigned char*) exchange->enclosed->ptr(),
1704
if (my_b_write(&cache,(uchar*) exchange->enclosed->ptr(),
1573
1705
exchange->enclosed->length()))
1582
1714
null_buff[0]=escape_char;
1583
1715
null_buff[1]='N';
1584
if (my_b_write(&cache,(unsigned char*) null_buff,2))
1716
if (my_b_write(&cache,(uchar*) null_buff,2))
1587
else if (my_b_write(&cache,(unsigned char*) "NULL",4))
1719
else if (my_b_write(&cache,(uchar*) "NULL",4))
1597
1729
if (fixed_row_size)
1598
used_length=cmin(res->length(),item->max_length);
1730
used_length=min(res->length(),item->max_length);
1600
1732
used_length=res->length();
1601
1733
if ((result_type == STRING_RESULT || is_unsafe_field_sep) &&
1602
1734
escape_char != -1)
1604
1736
char *pos, *start, *end;
1605
const CHARSET_INFO * const res_charset= res->charset();
1606
const CHARSET_INFO * const character_set_client= thd->variables.
1607
character_set_client;
1737
CHARSET_INFO *res_charset= res->charset();
1738
CHARSET_INFO *character_set_client= thd->variables.
1739
character_set_client;
1608
1740
bool check_second_byte= (res_charset == &my_charset_bin) &&
1609
1741
character_set_client->
1610
1742
escape_with_backslash_is_dangerous;
1641
1773
If this file is later loaded using this sequence of commands:
1643
1775
mysql> create table t1 (a varchar(128)) character set big5;
1644
mysql> LOAD DATA INFILE 'dump.txt' INTO Table t1;
1776
mysql> LOAD DATA INFILE 'dump.txt' INTO TABLE t1;
1646
1778
then 0x5C will be misinterpreted as the second byte
1647
1779
of a multi-byte character "0xEE + 0x5C", instead of
1661
1793
if ((NEED_ESCAPING(*pos) ||
1662
1794
(check_second_byte &&
1663
my_mbcharlen(character_set_client, (unsigned char) *pos) == 2 &&
1795
my_mbcharlen(character_set_client, (uchar) *pos) == 2 &&
1664
1796
pos + 1 < end &&
1665
1797
NEED_ESCAPING(pos[1]))) &&
1668
1800
valid for ENCLOSED BY characters:
1670
1802
(enclosed || !is_ambiguous_field_term ||
1671
(int) (unsigned char) *pos != field_term_char))
1803
(int) (uchar) *pos != field_term_char))
1673
1805
char tmp_buff[2];
1674
tmp_buff[0]= ((int) (unsigned char) *pos == field_sep_char &&
1806
tmp_buff[0]= ((int) (uchar) *pos == field_sep_char &&
1675
1807
is_ambiguous_field_sep) ?
1676
1808
field_sep_char : escape_char;
1677
1809
tmp_buff[1]= *pos ? *pos : '0';
1678
if (my_b_write(&cache,(unsigned char*) start,(uint) (pos-start)) ||
1679
my_b_write(&cache,(unsigned char*) tmp_buff,2))
1810
if (my_b_write(&cache,(uchar*) start,(uint) (pos-start)) ||
1811
my_b_write(&cache,(uchar*) tmp_buff,2))
1684
if (my_b_write(&cache,(unsigned char*) start,(uint) (pos-start)))
1816
if (my_b_write(&cache,(uchar*) start,(uint) (pos-start)))
1687
else if (my_b_write(&cache,(unsigned char*) res->ptr(),used_length))
1819
else if (my_b_write(&cache,(uchar*) res->ptr(),used_length))
1690
1822
if (fixed_row_size)
1695
1827
if (!space_inited)
1697
1829
space_inited=1;
1698
memset(space, ' ', sizeof(space));
1830
bfill(space,sizeof(space),' ');
1700
uint32_t length=item->max_length-used_length;
1832
uint length=item->max_length-used_length;
1701
1833
for (; length > sizeof(space) ; length-=sizeof(space))
1703
if (my_b_write(&cache,(unsigned char*) space,sizeof(space)))
1835
if (my_b_write(&cache,(uchar*) space,sizeof(space)))
1706
if (my_b_write(&cache,(unsigned char*) space,length))
1838
if (my_b_write(&cache,(uchar*) space,length))
1710
1842
if (res && enclosed)
1712
if (my_b_write(&cache, (unsigned char*) exchange->enclosed->ptr(),
1844
if (my_b_write(&cache, (uchar*) exchange->enclosed->ptr(),
1713
1845
exchange->enclosed->length()))
1716
1848
if (--items_left)
1718
if (my_b_write(&cache, (unsigned char*) exchange->field_term->ptr(),
1850
if (my_b_write(&cache, (uchar*) exchange->field_term->ptr(),
1719
1851
field_term_length))
1723
if (my_b_write(&cache,(unsigned char*) exchange->line_term->ptr(),
1855
if (my_b_write(&cache,(uchar*) exchange->line_term->ptr(),
1724
1856
exchange->line_term->length()))
1766
1898
res=item->str_result(&tmp);
1767
1899
if (!res) // If NULL
1769
if (my_b_write(&cache,(unsigned char*) "",1))
1901
if (my_b_write(&cache,(uchar*) "",1))
1772
else if (my_b_write(&cache,(unsigned char*) res->ptr(),res->length()))
1904
else if (my_b_write(&cache,(uchar*) res->ptr(),res->length()))
1774
1906
my_error(ER_ERROR_ON_WRITE, MYF(0), path, my_errno);
1919
2051
sortcmp(val1, val2, cache->collation.collation) < 0);
1922
bool select_exists_subselect::send_data(List<Item> &items __attribute__((unused)))
2054
bool select_exists_subselect::send_data(List<Item> &items __attribute__((__unused__)))
1924
2056
Item_exists_subselect *it= (Item_exists_subselect *)item;
1925
2057
if (unit->offset_limit_cnt)
2113
void Query_arena::set_query_arena(Query_arena *set)
2115
mem_root= set->mem_root;
2116
free_list= set->free_list;
2121
void Query_arena::cleanup_stmt()
2123
assert("not implemented");
1982
2127
Statement functions
1985
Statement::Statement(LEX *lex_arg, MEM_ROOT *mem_root_arg, ulong id_arg)
1986
:Query_arena(mem_root_arg),
2130
Statement::Statement(LEX *lex_arg, MEM_ROOT *mem_root_arg,
2131
enum enum_state state_arg, ulong id_arg)
2132
:Query_arena(mem_root_arg, state_arg),
1988
2134
mark_used_columns(MARK_COLUMNS_READ),
1999
Don't free mem_root, as mem_root is freed in the end of dispatch_command
2000
(once for any command).
2145
void Statement::set_statement(Statement *stmt)
2148
mark_used_columns= stmt->mark_used_columns;
2151
query_length= stmt->query_length;
2156
Statement::set_n_backup_statement(Statement *stmt, Statement *backup)
2158
backup->set_statement(this);
2159
set_statement(stmt);
2164
void Statement::restore_backup_statement(Statement *stmt, Statement *backup)
2166
stmt->set_statement(this);
2167
set_statement(backup);
2002
2172
void THD::end_statement()
2004
2174
/* Cleanup SQL processing state to reuse this statement in next query. */
2009
bool THD::copy_db_to(char **p_db, size_t *p_db_length)
2013
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
2016
*p_db= strmake(db, db_length);
2017
*p_db_length= db_length;
2178
/* Note that free_list is freed in cleanup_after_query() */
2181
Don't free mem_root, as mem_root is freed in the end of dispatch_command
2182
(once for any command).
2187
void THD::set_n_backup_active_arena(Query_arena *set, Query_arena *backup)
2189
assert(backup->is_backup_arena == false);
2191
backup->set_query_arena(this);
2192
set_query_arena(set);
2193
backup->is_backup_arena= true;
2198
void THD::restore_active_arena(Query_arena *set, Query_arena *backup)
2200
assert(backup->is_backup_arena);
2201
set->set_query_arena(this);
2202
set_query_arena(backup);
2203
backup->is_backup_arena= false;
2022
2207
bool select_dumpvar::send_data(List<Item> &items)
2052
2237
bool select_dumpvar::send_eof()
2054
2239
if (! row_count)
2055
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2240
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
2056
2241
ER_SP_FETCH_NO_DATA, ER(ER_SP_FETCH_NO_DATA));
2058
2243
In order to remember the value of affected rows for ROW_COUNT()
2100
2285
current_thd->status_var.net_big_packet_count+= length;
2103
void THD::send_kill_message() const
2105
int err= killed_errno();
2107
my_message(err, ER(err), MYF(0));
2110
2289
void THD::set_status_var_init()
2112
memset(&status_var, 0, sizeof(status_var));
2291
bzero((char*) &status_var, sizeof(status_var));
2116
2295
void Security_context::init()
2297
host= user= priv_user= ip= 0;
2298
host_or_ip= "connecting host";
2122
2303
void Security_context::destroy()
2124
2305
// If not pointer to constant
2306
if (host != my_localhost)
2138
2313
void Security_context::skip_grants()
2140
2315
/* privileges for the user are unknown everything is allowed */
2316
host_or_ip= (char *)"";
2317
priv_user= (char *)"";
2187
2365
@param thd user thread
2188
2366
@return thread id
2190
extern "C" unsigned long thd_get_thread_id(const DRIZZLE_THD thd)
2368
extern "C" unsigned long thd_get_thread_id(const MYSQL_THD thd)
2192
2370
return((unsigned long)thd->thread_id);
2196
2374
#ifdef INNODB_COMPATIBILITY_HOOKS
2197
extern "C" const struct charset_info_st *thd_charset(DRIZZLE_THD thd)
2375
extern "C" struct charset_info_st *thd_charset(MYSQL_THD thd)
2199
2377
return(thd->charset());
2202
extern "C" char **thd_query(DRIZZLE_THD thd)
2380
extern "C" char **thd_query(MYSQL_THD thd)
2204
2382
return(&thd->query);
2207
extern "C" int thd_slave_thread(const DRIZZLE_THD thd)
2385
extern "C" int thd_slave_thread(const MYSQL_THD thd)
2209
2387
return(thd->slave_thread);
2212
extern "C" int thd_non_transactional_update(const DRIZZLE_THD thd)
2390
extern "C" int thd_non_transactional_update(const MYSQL_THD thd)
2214
2392
return(thd->transaction.all.modified_non_trans_table);
2217
extern "C" int thd_binlog_format(const DRIZZLE_THD thd)
2395
extern "C" int thd_binlog_format(const MYSQL_THD thd)
2219
2397
return (int) thd->variables.binlog_format;
2222
extern "C" void thd_mark_transaction_to_rollback(DRIZZLE_THD thd, bool all)
2400
extern "C" void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all)
2224
2402
mark_transaction_to_rollback(thd, all);
2248
2426
pthread_mutex_t LOCK_xid_cache;
2249
2427
HASH xid_cache;
2251
extern "C" unsigned char *xid_get_hash_key(const unsigned char *, size_t *, bool);
2429
extern "C" uchar *xid_get_hash_key(const uchar *, size_t *, my_bool);
2252
2430
extern "C" void xid_free_hash(void *);
2254
unsigned char *xid_get_hash_key(const unsigned char *ptr, size_t *length,
2432
uchar *xid_get_hash_key(const uchar *ptr, size_t *length,
2255
2433
bool not_used __attribute__((unused)))
2257
2435
*length=((XID_STATE*)ptr)->xid.key_length();
2261
2439
void xid_free_hash(void *ptr)
2263
2441
if (!((XID_STATE*)ptr)->in_thd)
2264
free((unsigned char*)ptr);
2442
my_free((uchar*)ptr, MYF(0));
2267
2445
bool xid_cache_init()
2292
2470
bool xid_cache_insert(XID *xid, enum xa_states xa_state)
2296
2474
pthread_mutex_lock(&LOCK_xid_cache);
2297
2475
if (hash_search(&xid_cache, xid->key(), xid->key_length()))
2315
2493
pthread_mutex_lock(&LOCK_xid_cache);
2316
2494
assert(hash_search(&xid_cache, xid_state->xid.key(),
2317
2495
xid_state->xid.key_length())==0);
2318
bool res=my_hash_insert(&xid_cache, (unsigned char*)xid_state);
2496
my_bool res=my_hash_insert(&xid_cache, (uchar*)xid_state);
2319
2497
pthread_mutex_unlock(&LOCK_xid_cache);
2324
2502
void xid_cache_delete(XID_STATE *xid_state)
2326
2504
pthread_mutex_lock(&LOCK_xid_cache);
2327
hash_delete(&xid_cache, (unsigned char *)xid_state);
2505
hash_delete(&xid_cache, (uchar *)xid_state);
2328
2506
pthread_mutex_unlock(&LOCK_xid_cache);
2359
2538
template <class RowsEventT> Rows_log_event*
2360
THD::binlog_prepare_pending_rows_event(Table* table, uint32_t serv_id,
2539
THD::binlog_prepare_pending_rows_event(TABLE* table, uint32 serv_id,
2362
2541
bool is_transactional,
2363
2542
RowsEventT *hint __attribute__((unused)))
2365
2544
/* Pre-conditions */
2366
assert(table->s->table_map_id != UINT32_MAX);
2545
assert(table->s->table_map_id != ~0UL);
2368
2547
/* Fetch the type code for the RowsEventT template parameter */
2369
2548
int const type_code= RowsEventT::TYPE_CODE;
2433
2612
compiling option.
2435
2614
template Rows_log_event*
2436
THD::binlog_prepare_pending_rows_event(Table*, uint32_t, size_t, bool,
2615
THD::binlog_prepare_pending_rows_event(TABLE*, uint32, size_t, bool,
2437
2616
Write_rows_log_event*);
2439
2618
template Rows_log_event*
2440
THD::binlog_prepare_pending_rows_event(Table*, uint32_t, size_t, bool,
2619
THD::binlog_prepare_pending_rows_event(TABLE*, uint32, size_t, bool,
2441
2620
Delete_rows_log_event *);
2443
2622
template Rows_log_event*
2444
THD::binlog_prepare_pending_rows_event(Table*, uint32_t, size_t, bool,
2623
THD::binlog_prepare_pending_rows_event(TABLE*, uint32, size_t, bool,
2445
2624
Update_rows_log_event *);
2474
2653
Length of data that is needed, if the record contain blobs.
2476
Row_data_memory(Table *table, size_t const len1)
2655
Row_data_memory(TABLE *table, size_t const len1)
2479
2658
m_alloc_checked= false;
2541
2720
if (table->write_row_record == 0)
2542
2721
table->write_row_record=
2543
(unsigned char *) alloc_root(&table->mem_root, 2 * maxlen);
2722
(uchar *) alloc_root(&table->mem_root, 2 * maxlen);
2544
2723
m_memory= table->write_row_record;
2545
2724
m_release_memory_on_destruction= false;
2549
m_memory= (unsigned char *) my_malloc(total_length, MYF(MY_WME));
2728
m_memory= (uchar *) my_malloc(total_length, MYF(MY_WME));
2550
2729
m_release_memory_on_destruction= true;
2554
2733
mutable bool m_alloc_checked;
2555
2734
bool m_release_memory_on_destruction;
2556
unsigned char *m_memory;
2557
unsigned char *m_ptr[2];
2562
int THD::binlog_write_row(Table* table, bool is_trans,
2563
unsigned char const *record)
2741
int THD::binlog_write_row(TABLE* table, bool is_trans,
2742
uchar const *record)
2565
2744
assert(current_stmt_binlog_row_based && mysql_bin_log.is_open());
2568
2747
Pack records into format for transfer. We are allocating more
2569
2748
memory than needed, but that doesn't matter.
2571
Row_data_memory memory(table, table->max_row_length(record));
2750
Row_data_memory memory(table, max_row_length(table, record));
2572
2751
if (!memory.has_memory())
2573
2752
return HA_ERR_OUT_OF_MEM;
2575
unsigned char *row_data= memory.slot(0);
2754
uchar *row_data= memory.slot(0);
2577
2756
size_t const len= pack_row(table, table->write_set, row_data, record);
2586
2765
return ev->add_row_data(row_data, len);
2589
int THD::binlog_update_row(Table* table, bool is_trans,
2590
const unsigned char *before_record,
2591
const unsigned char *after_record)
2768
int THD::binlog_update_row(TABLE* table, bool is_trans,
2769
const uchar *before_record,
2770
const uchar *after_record)
2593
2772
assert(current_stmt_binlog_row_based && mysql_bin_log.is_open());
2595
size_t const before_maxlen = table->max_row_length(before_record);
2596
size_t const after_maxlen = table->max_row_length(after_record);
2774
size_t const before_maxlen = max_row_length(table, before_record);
2775
size_t const after_maxlen = max_row_length(table, after_record);
2598
2777
Row_data_memory row_data(table, before_maxlen, after_maxlen);
2599
2778
if (!row_data.has_memory())
2600
2779
return HA_ERR_OUT_OF_MEM;
2602
unsigned char *before_row= row_data.slot(0);
2603
unsigned char *after_row= row_data.slot(1);
2781
uchar *before_row= row_data.slot(0);
2782
uchar *after_row= row_data.slot(1);
2605
2784
size_t const before_size= pack_row(table, table->read_set, before_row,
2606
2785
before_record);
2620
2799
ev->add_row_data(after_row, after_size);
2623
int THD::binlog_delete_row(Table* table, bool is_trans,
2624
unsigned char const *record)
2802
int THD::binlog_delete_row(TABLE* table, bool is_trans,
2803
uchar const *record)
2626
2805
assert(current_stmt_binlog_row_based && mysql_bin_log.is_open());
2629
2808
Pack records into format for transfer. We are allocating more
2630
2809
memory than needed, but that doesn't matter.
2632
Row_data_memory memory(table, table->max_row_length(record));
2811
Row_data_memory memory(table, max_row_length(table, record));
2633
2812
if (unlikely(!memory.has_memory()))
2634
2813
return HA_ERR_OUT_OF_MEM;
2636
unsigned char *row_data= memory.slot(0);
2815
uchar *row_data= memory.slot(0);
2638
2817
size_t const len= pack_row(table, table->read_set, row_data, record);
2719
2898
variables.binlog_format == BINLOG_FORMAT_STMT)
2721
2900
assert(this->query != NULL);
2722
push_warning(this, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2901
push_warning(this, MYSQL_ERROR::WARN_LEVEL_WARN,
2723
2902
ER_BINLOG_UNSAFE_STATEMENT,
2724
2903
ER(ER_BINLOG_UNSAFE_STATEMENT));
2725
2904
if (!(binlog_flags & BINLOG_FLAG_UNSAFE_STMT_PRINTED))
2727
char warn_buf[DRIZZLE_ERRMSG_SIZE];
2728
snprintf(warn_buf, DRIZZLE_ERRMSG_SIZE, "%s Statement: %s",
2906
char warn_buf[MYSQL_ERRMSG_SIZE];
2907
snprintf(warn_buf, MYSQL_ERRMSG_SIZE, "%s Statement: %s",
2729
2908
ER(ER_BINLOG_UNSAFE_STATEMENT), this->query);
2730
2909
sql_print_warning(warn_buf);
2731
2910
binlog_flags|= BINLOG_FLAG_UNSAFE_STMT_PRINTED;
2737
2916
if (current_stmt_binlog_row_based)
2739
2918
/* Otherwise, we fall through */
2740
case THD::DRIZZLE_QUERY_TYPE:
2919
case THD::MYSQL_QUERY_TYPE:
2742
2921
Using this query type is a conveniece hack, since we have been
2743
2922
moving back and forth between using RBR for replication of