1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; version 2 of the License.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1
/* Copyright (C) 2000-2006 MySQL AB
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 */
21
17
/*****************************************************************************
26
22
*****************************************************************************/
27
23
#include <drizzled/server_includes.h>
28
#include <drizzled/rpl_rli.h>
29
#include <drizzled/rpl_record.h>
30
#include <drizzled/log_event.h>
25
#include "rpl_record.h"
26
#include "log_event.h"
31
27
#include <sys/stat.h>
32
28
#include <mysys/thr_alarm.h>
33
29
#include <mysys/mysys_err.h>
34
#include <drizzled/error.h>
35
#include <drizzled/query_id.h>
36
#include <drizzled/data_home.h>
30
#include <drizzled/drizzled_error_messages.h>
38
extern scheduler_functions thread_scheduler;
40
33
The following is used to initialise Table_ident with a internal
67
60
****************************************************************************/
69
extern "C" unsigned char *get_var_key(user_var_entry *entry, size_t *length,
62
extern "C" uchar *get_var_key(user_var_entry *entry, size_t *length,
70
63
bool not_used __attribute__((unused)))
72
65
*length= entry->name.length;
73
return (unsigned char*) entry->name.str;
66
return (uchar*) entry->name.str;
76
69
extern "C" void free_user_var(user_var_entry *entry)
78
71
char *pos= (char*) entry+ALIGN_SIZE(sizeof(*entry));
79
72
if (entry->value && entry->value != pos)
73
my_free(entry->value, MYF(0));
74
my_free((char*) entry,MYF(0));
84
77
bool Key_part_spec::operator==(const Key_part_spec& other) const
194
Check if the foreign key options are compatible with columns
195
on which the FK is created.
201
bool Foreign_key::validate(List<Create_field> &table_fields)
203
Create_field *sql_field;
204
Key_part_spec *column;
205
List_iterator<Key_part_spec> cols(columns);
206
List_iterator<Create_field> it(table_fields);
207
while ((column= cols++))
210
while ((sql_field= it++) &&
211
my_strcasecmp(system_charset_info,
212
column->field_name.str,
213
sql_field->field_name)) {}
216
my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name.str);
219
if (type == Key::FOREIGN_KEY && sql_field->vcol_info)
221
if (delete_opt == FK_OPTION_SET_NULL)
223
my_error(ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN, MYF(0),
224
"ON DELETE SET NULL");
227
if (update_opt == FK_OPTION_SET_NULL)
229
my_error(ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN, MYF(0),
230
"ON UPDATE SET NULL");
233
if (update_opt == FK_OPTION_CASCADE)
235
my_error(ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN, MYF(0),
236
"ON UPDATE CASCADE");
245
186
/****************************************************************************
246
187
** Thread specific functions
247
188
****************************************************************************/
261
202
char filename[FN_REFLEN];
262
203
File fd = create_temp_file(filename, mysql_tmpdir, prefix,
263
O_CREAT | O_EXCL | O_RDWR,
204
O_CREAT | O_EXCL | O_RDWR | O_TEMPORARY,
208
This can be removed once the following bug is fixed:
209
Bug #28903 create_temp_file() doesn't honor O_TEMPORARY option
210
(file not removed) (Unix)
266
212
unlink(filename);
274
int session_in_lock_tables(const Session *session)
276
return test(session->in_lock_tables);
281
int session_tablespace_op(const Session *session)
283
return test(session->tablespace_op);
288
Set the process info field of the Session structure.
290
This function is used by plug-ins. Internally, the
291
Session::set_proc_info() function should be used.
293
@see Session::set_proc_info
296
set_session_proc_info(Session *session, const char *info)
298
session->set_proc_info(info);
302
const char *get_session_proc_info(Session *session)
304
return session->get_proc_info();
308
void **session_ha_data(const Session *session, const struct handlerton *hton)
310
return (void **) &session->ha_data[hton->slot].ha_ptr;
314
int64_t session_test_options(const Session *session, int64_t test_options)
316
return session->options & test_options;
320
int session_sql_command(const Session *session)
322
return (int) session->lex->sql_command;
326
int session_tx_isolation(const Session *session)
328
return (int) session->variables.tx_isolation;
332
void session_inc_row_count(Session *session)
334
session->row_count++;
220
int thd_in_lock_tables(const THD *thd)
222
return test(thd->in_lock_tables);
227
int thd_tablespace_op(const THD *thd)
229
return test(thd->tablespace_op);
234
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)))
239
const char *old_info= thd->get_proc_info();
240
thd->set_proc_info(info);
245
void **thd_ha_data(const THD *thd, const struct handlerton *hton)
247
return (void **) &thd->ha_data[hton->slot].ha_ptr;
251
int64_t thd_test_options(const THD *thd, int64_t test_options)
253
return thd->options & test_options;
257
int thd_sql_command(const THD *thd)
259
return (int) thd->lex->sql_command;
263
int thd_tx_isolation(const THD *thd)
265
return (int) thd->variables.tx_isolation;
269
void thd_inc_row_count(THD *thd)
465
:Statement(&main_lex, &main_mem_root,
402
:Statement(&main_lex, &main_mem_root, CONVENTIONAL_EXECUTION,
466
403
/* statement id */ 0),
467
404
Open_tables_state(refresh_version), rli_fake(0),
468
405
lock_id(&main_lock_id),
406
user_time(0), in_sub_stmt(0),
470
407
binlog_table_maps(0), binlog_flags(0UL),
471
408
arg_of_last_insert_id_function(false),
472
409
first_successful_insert_id_in_prev_stmt(0),
562
505
protocol= &protocol_text; // Default protocol
563
506
protocol_text.init(this);
565
const Query_id& query_id= Query_id::get_query_id();
566
508
tablespace_op= false;
568
randominit(&rand, tmp + (ulong) &rand, tmp + query_id.value());
510
randominit(&rand, tmp + (ulong) &rand, tmp + (ulong) ::global_query_id);
569
511
substitute_null_with_insert_id = false;
570
512
thr_lock_info_init(&lock_info); /* safety: will be reset after start */
571
513
thr_lock_owner_init(&main_lock_id, &lock_info);
577
void Session::push_internal_handler(Internal_error_handler *handler)
519
void THD::push_internal_handler(Internal_error_handler *handler)
580
522
TODO: The current implementation is limited to 1 handler at a time only.
581
Session and sp_rcontext need to be modified to use a common handler stack.
523
THD and sp_rcontext need to be modified to use a common handler stack.
583
525
assert(m_internal_handler == NULL);
584
526
m_internal_handler= handler;
588
bool Session::handle_error(uint32_t sql_errno, const char *message,
530
bool THD::handle_error(uint sql_errno, const char *message,
589
531
DRIZZLE_ERROR::enum_warning_level level)
591
533
if (m_internal_handler)
600
void Session::pop_internal_handler()
542
void THD::pop_internal_handler()
602
544
assert(m_internal_handler != NULL);
603
545
m_internal_handler= NULL;
606
#if defined(__cplusplus)
610
void *session_alloc(Session *session, unsigned int size)
612
return session->alloc(size);
615
void *session_calloc(Session *session, unsigned int size)
617
return session->calloc(size);
620
char *session_strdup(Session *session, const char *str)
622
return session->strdup(str);
625
char *session_strmake(Session *session, const char *str, unsigned int size)
627
return session->strmake(str, size);
630
void *session_memdup(Session *session, const void* str, unsigned int size)
632
return session->memdup(str, size);
635
void session_get_xid(const Session *session, DRIZZLE_XID *xid)
637
*xid = *(DRIZZLE_XID *) &session->transaction.xid_state.xid;
640
#if defined(__cplusplus)
549
void *thd_alloc(DRIZZLE_THD thd, unsigned int size)
551
return thd->alloc(size);
555
void *thd_calloc(DRIZZLE_THD thd, unsigned int size)
557
return thd->calloc(size);
561
char *thd_strdup(DRIZZLE_THD thd, const char *str)
563
return thd->strdup(str);
567
char *thd_strmake(DRIZZLE_THD thd, const char *str, unsigned int size)
569
return thd->strmake(str, size);
573
LEX_STRING *thd_make_lex_string(THD *thd, LEX_STRING *lex_str,
574
const char *str, unsigned int size,
575
int allocate_lex_string)
577
return thd->make_lex_string(lex_str, str, size,
578
(bool) allocate_lex_string);
582
void *thd_memdup(DRIZZLE_THD thd, const void* str, unsigned int size)
584
return thd->memdup(str, size);
588
void thd_get_xid(const DRIZZLE_THD thd, DRIZZLE_XID *xid)
590
*xid = *(DRIZZLE_XID *) &thd->transaction.xid_state.xid;
645
594
Init common variables that has to be reset on start and on change_user
648
void Session::init(void)
650
599
pthread_mutex_lock(&LOCK_global_system_variables);
651
plugin_sessionvar_init(this);
652
variables.time_format= date_time_format_copy((Session*) 0,
600
plugin_thdvar_init(this);
601
variables.time_format= date_time_format_copy((THD*) 0,
653
602
variables.time_format);
654
variables.date_format= date_time_format_copy((Session*) 0,
603
variables.date_format= date_time_format_copy((THD*) 0,
655
604
variables.date_format);
656
variables.datetime_format= date_time_format_copy((Session*) 0,
605
variables.datetime_format= date_time_format_copy((THD*) 0,
657
606
variables.datetime_format);
659
608
variables= global_system_variables above has reset
702
651
variables.trans_alloc_block_size,
703
652
variables.trans_prealloc_size);
704
653
transaction.xid_state.xid.null();
705
transaction.xid_state.in_session=1;
654
transaction.xid_state.in_thd=1;
709
658
/* Do operations that may take a long time */
711
void Session::cleanup(void)
660
void THD::cleanup(void)
713
662
assert(cleanup_done == 0);
732
681
delete_dynamic(&user_var_events);
733
682
hash_free(&user_vars);
734
683
close_temporary_tables(this);
735
free((char*) variables.time_format);
736
free((char*) variables.date_format);
737
free((char*) variables.datetime_format);
684
my_free((char*) variables.time_format, MYF(MY_ALLOW_ZERO_PTR));
685
my_free((char*) variables.date_format, MYF(MY_ALLOW_ZERO_PTR));
686
my_free((char*) variables.datetime_format, MYF(MY_ALLOW_ZERO_PTR));
739
688
if (global_read_lock)
740
689
unlock_global_read_lock(this);
754
703
/* Close connection */
760
709
if (!cleanup_done)
763
712
ha_close_connection(this);
764
plugin_sessionvar_cleanup(this);
713
plugin_thdvar_cleanup(this);
766
715
main_security_ctx.destroy();
772
717
free_root(&warn_root,MYF(0));
773
718
free_root(&transaction.mem_root,MYF(0));
774
719
mysys_var=0; // Safety (shouldn't be needed)
775
720
pthread_mutex_destroy(&LOCK_delete);
776
dbug_sentry= Session_SENTRY_GONE;
721
dbug_sentry= THD_SENTRY_GONE;
839
void Session::awake(Session::killed_state state_to_set)
784
void THD::awake(THD::killed_state state_to_set)
841
Session_CHECK_SENTRY(this);
786
THD_CHECK_SENTRY(this);
842
787
safe_mutex_assert_owner(&LOCK_delete);
844
789
killed= state_to_set;
845
if (state_to_set != Session::KILL_QUERY)
790
if (state_to_set != THD::KILL_QUERY)
847
792
thr_alarm_kill(thread_id);
848
793
if (!slave_thread)
849
794
thread_scheduler.post_kill_notification(this);
795
#ifdef SIGNAL_WITH_VIO_CLOSE
796
if (this != current_thd)
799
In addition to a signal, let's close the socket of the thread that
800
is being killed. This is to make sure it does not block if the
801
signal is lost. This needs to be done only on platforms where
802
signals are not a reliable interruption mechanism.
804
If we're killing ourselves, we know that we're not blocked, so this
897
858
assert(thread_stack);
899
if (pthread_setspecific(THR_Session, this) ||
900
pthread_setspecific(THR_MALLOC, &mem_root))
860
if (my_pthread_setspecific_ptr(THR_THD, this) ||
861
my_pthread_setspecific_ptr(THR_MALLOC, &mem_root))
902
863
mysys_var=my_thread_var;
904
865
Let mysqld define the thread id (not mysys)
905
This allows us to move Session to different threads if needed.
866
This allows us to move THD to different threads if needed.
907
868
mysys_var->id= thread_id;
908
869
real_id= pthread_self(); // For debugging
911
We have to call thr_lock_info_init() again here as Session may have been
872
We have to call thr_lock_info_init() again here as THD may have been
912
873
created in another thread
914
875
thr_lock_info_init(&lock_info);
935
void Session::cleanup_after_query()
896
void THD::cleanup_after_query()
938
899
Reset rand_used so that detection of calls to rand() will save random
939
900
seeds if needed by the slave.
902
Do not reset rand_used if inside a stored function or trigger because
903
only the call to these operations is logged. Thus only the calling
904
statement needs to detect rand() calls made by its substatements. These
905
substatements must not set rand_used to 0 because it would remove the
906
detection of rand() by the calling statement.
908
if (!in_sub_stmt) /* stored functions and triggers are a special case */
942
910
/* Forget those values, for next binlogger: */
943
911
stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
970
938
instead of using lex_str value
971
939
@return NULL on failure, or pointer to the LEX_STRING object
973
LEX_STRING *Session::make_lex_string(LEX_STRING *lex_str,
974
const char* str, uint32_t length,
941
LEX_STRING *THD::make_lex_string(LEX_STRING *lex_str,
942
const char* str, uint length,
975
943
bool allocate_lex_string)
977
945
if (allocate_lex_string)
1004
972
In this case to->str will point to 0 and to->length will be 0.
1007
bool Session::convert_string(LEX_STRING *to, const CHARSET_INFO * const to_cs,
1008
const char *from, uint32_t from_length,
975
bool THD::convert_string(LEX_STRING *to, const CHARSET_INFO * const to_cs,
976
const char *from, uint from_length,
1009
977
const CHARSET_INFO * const from_cs)
1011
979
size_t new_length= to_cs->mbmaxlen * from_length;
1012
uint32_t dummy_errors;
1013
981
if (!(to->str= (char*) alloc(new_length+1)))
1015
983
to->length= 0; // Safety fix
1037
1005
!0 out of memory
1040
bool Session::convert_string(String *s, const CHARSET_INFO * const from_cs,
1008
bool THD::convert_string(String *s, const CHARSET_INFO * const from_cs,
1041
1009
const CHARSET_INFO * const to_cs)
1043
uint32_t dummy_errors;
1044
1012
if (convert_buffer.copy(s->ptr(), s->length(), from_cs, to_cs, &dummy_errors))
1046
1014
/* If convert_buffer >> s copying is more efficient long term */
1212
1193
Register an item tree tree transformation, performed by the query
1213
1194
optimizer. We need a pointer to runtime_memroot because it may be !=
1214
session->mem_root (this may no longer be a true statement)
1195
thd->mem_root (due to possible set_n_backup_active_arena called for thd).
1217
void Session::nocheck_register_item_tree_change(Item **place, Item *old_value,
1198
void THD::nocheck_register_item_tree_change(Item **place, Item *old_value,
1218
1199
MEM_ROOT *runtime_memroot)
1220
1201
Item_change_record *change;
1237
Check that the endpoint is still available.
1240
bool THD::vio_is_connected()
1244
/* End of input is signaled by poll if the socket is aborted. */
1245
if (vio_poll_read(net.vio, 0))
1248
/* Socket is aborted if signaled but no data is available. */
1249
if (vio_peek_read(net.vio, &bytes))
1252
return bytes ? true : false;
1255
1256
/*****************************************************************************
1256
1257
** Functions to provide a interface to select results
1257
1258
*****************************************************************************/
1259
1260
select_result::select_result()
1261
session=current_session;
1264
void select_result::send_error(uint32_t errcode,const char *err)
1265
void select_result::send_error(uint errcode,const char *err)
1266
1267
my_message(errcode, err, MYF(0));
1334
1335
We may be passing the control from mysqld to the client: release the
1335
1336
InnoDB adaptive hash S-latch to avoid thread deadlocks if it was reserved
1338
ha_release_temporary_latches(session);
1339
ha_release_temporary_latches(thd);
1340
1341
List_iterator_fast<Item> li(items);
1341
Protocol *protocol= session->protocol;
1342
Protocol *protocol= thd->protocol;
1342
1343
char buff[MAX_FIELD_WIDTH];
1343
1344
String buffer(buff, sizeof(buff), &my_charset_bin);
1370
1371
We may be passing the control from mysqld to the client: release the
1371
1372
InnoDB adaptive hash S-latch to avoid thread deadlocks if it was reserved
1374
ha_release_temporary_latches(session);
1375
ha_release_temporary_latches(thd);
1376
1377
/* Unlock tables before sending packet to gain some speed */
1379
mysql_unlock_tables(session, session->lock);
1380
mysql_unlock_tables(thd, thd->lock);
1383
1384
is_result_set_started= 0;
1474
static File create_file(Session *session, char *path, sql_exchange *exchange,
1475
static File create_file(THD *thd, char *path, sql_exchange *exchange,
1475
1476
IO_CACHE *cache)
1478
uint32_t option= MY_UNPACK_FILENAME | MY_RELATIVE_PATH;
1479
uint option= MY_UNPACK_FILENAME | MY_RELATIVE_PATH;
1480
1481
#ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS
1481
1482
option|= MY_REPLACE_DIR; // Force use of db directory
1484
1485
if (!dirname_length(exchange->file_name))
1486
strcpy(path, mysql_real_data_home);
1488
strncat(path, session->db, FN_REFLEN-strlen(mysql_real_data_home)-1);
1487
strxnmov(path, FN_REFLEN-1, mysql_real_data_home, thd->db ? thd->db : "",
1489
1489
(void) fn_format(path, exchange->file_name, path, "", option);
1531
1531
if ((uint) strlen(exchange->file_name) + NAME_LEN >= FN_REFLEN)
1532
1532
strmake(path,exchange->file_name,FN_REFLEN-1);
1534
if ((file= create_file(session, path, exchange, &cache)) < 0)
1534
if ((file= create_file(thd, path, exchange, &cache)) < 0)
1536
1536
/* Check if there is any blobs in data */
1553
1553
field_term_length=exchange->field_term->length();
1554
1554
field_term_char= field_term_length ?
1555
(int) (unsigned char) (*exchange->field_term)[0] : INT_MAX;
1555
(int) (uchar) (*exchange->field_term)[0] : INT_MAX;
1556
1556
if (!exchange->line_term->length())
1557
1557
exchange->line_term=exchange->field_term; // Use this if it exists
1558
1558
field_sep_char= (exchange->enclosed->length() ?
1559
(int) (unsigned char) (*exchange->enclosed)[0] : field_term_char);
1559
(int) (uchar) (*exchange->enclosed)[0] : field_term_char);
1560
1560
escape_char= (exchange->escaped->length() ?
1561
(int) (unsigned char) (*exchange->escaped)[0] : -1);
1561
(int) (uchar) (*exchange->escaped)[0] : -1);
1562
1562
is_ambiguous_field_sep= test(strchr(ESCAPE_CHARS, field_sep_char));
1563
1563
is_unsafe_field_sep= test(strchr(NUMERIC_CHARS, field_sep_char));
1564
1564
line_sep_char= (exchange->line_term->length() ?
1565
(int) (unsigned char) (*exchange->line_term)[0] : INT_MAX);
1565
(int) (uchar) (*exchange->line_term)[0] : INT_MAX);
1566
1566
if (!field_term_length)
1567
1567
exchange->opt_enclosed=0;
1568
1568
if (!exchange->enclosed->length())
1574
1574
(exchange->opt_enclosed && non_string_results &&
1575
1575
field_term_length && strchr(NUMERIC_CHARS, field_term_char)))
1577
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1577
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1578
1578
ER_AMBIGUOUS_FIELD_TERM, ER(ER_AMBIGUOUS_FIELD_TERM));
1579
1579
is_ambiguous_field_term= true;
1588
#define NEED_ESCAPING(x) ((int) (unsigned char) (x) == escape_char || \
1589
(enclosed ? (int) (unsigned char) (x) == field_sep_char \
1590
: (int) (unsigned char) (x) == field_term_char) || \
1591
(int) (unsigned char) (x) == line_sep_char || \
1588
#define NEED_ESCAPING(x) ((int) (uchar) (x) == escape_char || \
1589
(enclosed ? (int) (uchar) (x) == field_sep_char \
1590
: (int) (uchar) (x) == field_term_char) || \
1591
(int) (uchar) (x) == line_sep_char || \
1594
1594
bool select_export::send_data(List<Item> &items)
1608
uint32_t used_length=0,items_left=items.elements;
1608
uint used_length=0,items_left=items.elements;
1609
1609
List_iterator_fast<Item> li(items);
1611
if (my_b_write(&cache,(unsigned char*) exchange->line_start->ptr(),
1611
if (my_b_write(&cache,(uchar*) exchange->line_start->ptr(),
1612
1612
exchange->line_start->length()))
1614
1614
while ((item=li++))
1632
1632
null_buff[0]=escape_char;
1633
1633
null_buff[1]='N';
1634
if (my_b_write(&cache,(unsigned char*) null_buff,2))
1634
if (my_b_write(&cache,(uchar*) null_buff,2))
1637
else if (my_b_write(&cache,(unsigned char*) "NULL",4))
1637
else if (my_b_write(&cache,(uchar*) "NULL",4))
1718
1718
valid for ENCLOSED BY characters:
1720
1720
(enclosed || !is_ambiguous_field_term ||
1721
(int) (unsigned char) *pos != field_term_char))
1721
(int) (uchar) *pos != field_term_char))
1723
1723
char tmp_buff[2];
1724
tmp_buff[0]= ((int) (unsigned char) *pos == field_sep_char &&
1724
tmp_buff[0]= ((int) (uchar) *pos == field_sep_char &&
1725
1725
is_ambiguous_field_sep) ?
1726
1726
field_sep_char : escape_char;
1727
1727
tmp_buff[1]= *pos ? *pos : '0';
1728
if (my_b_write(&cache,(unsigned char*) start,(uint) (pos-start)) ||
1729
my_b_write(&cache,(unsigned char*) tmp_buff,2))
1728
if (my_b_write(&cache,(uchar*) start,(uint) (pos-start)) ||
1729
my_b_write(&cache,(uchar*) tmp_buff,2))
1734
if (my_b_write(&cache,(unsigned char*) start,(uint) (pos-start)))
1734
if (my_b_write(&cache,(uchar*) start,(uint) (pos-start)))
1737
else if (my_b_write(&cache,(unsigned char*) res->ptr(),used_length))
1737
else if (my_b_write(&cache,(uchar*) res->ptr(),used_length))
1740
1740
if (fixed_row_size)
1747
1747
space_inited=1;
1748
1748
memset(space, ' ', sizeof(space));
1750
uint32_t length=item->max_length-used_length;
1750
uint length=item->max_length-used_length;
1751
1751
for (; length > sizeof(space) ; length-=sizeof(space))
1753
if (my_b_write(&cache,(unsigned char*) space,sizeof(space)))
1753
if (my_b_write(&cache,(uchar*) space,sizeof(space)))
1756
if (my_b_write(&cache,(unsigned char*) space,length))
1756
if (my_b_write(&cache,(uchar*) space,length))
1760
1760
if (res && enclosed)
1762
if (my_b_write(&cache, (unsigned char*) exchange->enclosed->ptr(),
1762
if (my_b_write(&cache, (uchar*) exchange->enclosed->ptr(),
1763
1763
exchange->enclosed->length()))
1766
1766
if (--items_left)
1768
if (my_b_write(&cache, (unsigned char*) exchange->field_term->ptr(),
1768
if (my_b_write(&cache, (uchar*) exchange->field_term->ptr(),
1769
1769
field_term_length))
1773
if (my_b_write(&cache,(unsigned char*) exchange->line_term->ptr(),
1773
if (my_b_write(&cache,(uchar*) exchange->line_term->ptr(),
1774
1774
exchange->line_term->length()))
1816
1816
res=item->str_result(&tmp);
1817
1817
if (!res) // If NULL
1819
if (my_b_write(&cache,(unsigned char*) "",1))
1819
if (my_b_write(&cache,(uchar*) "",1))
1822
else if (my_b_write(&cache,(unsigned char*) res->ptr(),res->length()))
1822
else if (my_b_write(&cache,(uchar*) res->ptr(),res->length()))
1824
1824
my_error(ER_ERROR_ON_WRITE, MYF(0), path, my_errno);
2031
void Query_arena::set_query_arena(Query_arena *set)
2033
mem_root= set->mem_root;
2034
free_list= set->free_list;
2039
void Query_arena::cleanup_stmt()
2041
assert("not implemented");
2032
2045
Statement functions
2035
Statement::Statement(LEX *lex_arg, MEM_ROOT *mem_root_arg, ulong id_arg)
2036
:Query_arena(mem_root_arg),
2048
Statement::Statement(LEX *lex_arg, MEM_ROOT *mem_root_arg,
2049
enum enum_state state_arg, ulong id_arg)
2050
:Query_arena(mem_root_arg, state_arg),
2038
2052
mark_used_columns(MARK_COLUMNS_READ),
2049
Don't free mem_root, as mem_root is freed in the end of dispatch_command
2050
(once for any command).
2052
void Session::end_statement()
2063
void Statement::set_statement(Statement *stmt)
2066
mark_used_columns= stmt->mark_used_columns;
2069
query_length= stmt->query_length;
2074
Statement::set_n_backup_statement(Statement *stmt, Statement *backup)
2076
backup->set_statement(this);
2077
set_statement(stmt);
2082
void Statement::restore_backup_statement(Statement *stmt, Statement *backup)
2084
stmt->set_statement(this);
2085
set_statement(backup);
2090
void THD::end_statement()
2054
2092
/* Cleanup SQL processing state to reuse this statement in next query. */
2059
bool Session::copy_db_to(char **p_db, size_t *p_db_length)
2096
/* Note that free_list is freed in cleanup_after_query() */
2099
Don't free mem_root, as mem_root is freed in the end of dispatch_command
2100
(once for any command).
2105
void THD::set_n_backup_active_arena(Query_arena *set, Query_arena *backup)
2107
assert(backup->is_backup_arena == false);
2109
backup->set_query_arena(this);
2110
set_query_arena(set);
2111
backup->is_backup_arena= true;
2116
void THD::restore_active_arena(Query_arena *set, Query_arena *backup)
2118
assert(backup->is_backup_arena);
2119
set->set_query_arena(this);
2120
set_query_arena(backup);
2121
backup->is_backup_arena= false;
2126
bool THD::copy_db_to(char **p_db, size_t *p_db_length)
2061
2128
if (db == NULL)
2091
2158
if (mv->local == 0)
2093
2160
Item_func_set_user_var *suv= new Item_func_set_user_var(mv->s, item);
2094
suv->fix_fields(session, 0);
2161
suv->fix_fields(thd, 0);
2099
return(session->is_error());
2166
return(thd->is_error());
2102
2169
bool select_dumpvar::send_eof()
2104
2171
if (! row_count)
2105
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2172
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2106
2173
ER_SP_FETCH_NO_DATA, ER(ER_SP_FETCH_NO_DATA));
2108
2175
In order to remember the value of affected rows for ROW_COUNT()
2109
2176
function, SELECT INTO has to have an own SQLCOM.
2110
2177
TODO: split from SQLCOM_SELECT
2112
::my_ok(session,row_count);
2179
::my_ok(thd,row_count);
2132
void session_increment_bytes_sent(ulong length)
2199
void thd_increment_bytes_sent(ulong length)
2134
Session *session=current_session;
2135
if (likely(session != 0))
2136
{ /* current_session==0 when close_connection() calls net_send_error() */
2137
session->status_var.bytes_sent+= length;
2201
THD *thd=current_thd;
2202
if (likely(thd != 0))
2203
{ /* current_thd==0 when close_connection() calls net_send_error() */
2204
thd->status_var.bytes_sent+= length;
2142
void session_increment_bytes_received(ulong length)
2144
current_session->status_var.bytes_received+= length;
2148
void session_increment_net_big_packet_count(ulong length)
2150
current_session->status_var.net_big_packet_count+= length;
2153
void Session::send_kill_message() const
2209
void thd_increment_bytes_received(ulong length)
2211
current_thd->status_var.bytes_received+= length;
2215
void thd_increment_net_big_packet_count(ulong length)
2217
current_thd->status_var.net_big_packet_count+= length;
2220
void THD::send_kill_message() const
2155
2222
int err= killed_errno();
2157
2224
my_message(err, ER(err), MYF(0));
2160
void Session::set_status_var_init()
2227
void THD::set_status_var_init()
2162
2229
memset(&status_var, 0, sizeof(status_var));
2225
2284
Check the killed state of a user thread
2226
@param session user thread
2285
@param thd user thread
2227
2286
@retval 0 the user thread is active
2228
2287
@retval 1 the user thread has been killed
2230
extern "C" int session_killed(const Session *session)
2289
extern "C" int thd_killed(const DRIZZLE_THD thd)
2232
return(session->killed);
2291
return(thd->killed);
2236
2295
Return the thread id of a user thread
2237
@param session user thread
2296
@param thd user thread
2238
2297
@return thread id
2240
extern "C" unsigned long session_get_thread_id(const Session *session)
2242
return((unsigned long)session->thread_id);
2247
LEX_STRING *session_make_lex_string(Session *session, LEX_STRING *lex_str,
2248
const char *str, unsigned int size,
2249
int allocate_lex_string)
2251
return session->make_lex_string(lex_str, str, size,
2252
(bool) allocate_lex_string);
2255
extern "C" const struct charset_info_st *session_charset(Session *session)
2257
return(session->charset());
2260
extern "C" char **session_query(Session *session)
2262
return(&session->query);
2265
extern "C" int session_slave_thread(const Session *session)
2267
return(session->slave_thread);
2270
extern "C" int session_non_transactional_update(const Session *session)
2272
return(session->transaction.all.modified_non_trans_table);
2275
extern "C" int session_binlog_format(const Session *session)
2277
return (int) session->variables.binlog_format;
2280
extern "C" void session_mark_transaction_to_rollback(Session *session, bool all)
2282
mark_transaction_to_rollback(session, all);
2299
extern "C" unsigned long thd_get_thread_id(const DRIZZLE_THD thd)
2301
return((unsigned long)thd->thread_id);
2305
#ifdef INNODB_COMPATIBILITY_HOOKS
2306
extern "C" const struct charset_info_st *thd_charset(DRIZZLE_THD thd)
2308
return(thd->charset());
2311
extern "C" char **thd_query(DRIZZLE_THD thd)
2313
return(&thd->query);
2316
extern "C" int thd_slave_thread(const DRIZZLE_THD thd)
2318
return(thd->slave_thread);
2321
extern "C" int thd_non_transactional_update(const DRIZZLE_THD thd)
2323
return(thd->transaction.all.modified_non_trans_table);
2326
extern "C" int thd_binlog_format(const DRIZZLE_THD thd)
2328
return (int) thd->variables.binlog_format;
2331
extern "C" void thd_mark_transaction_to_rollback(DRIZZLE_THD thd, bool all)
2333
mark_transaction_to_rollback(thd, all);
2335
#endif // INNODB_COMPATIBILITY_HOOKS */
2287
2339
Mark transaction to rollback and mark error as fatal to a sub-statement.
2289
@param session Thread handle
2341
@param thd Thread handle
2290
2342
@param all true <=> rollback main transaction.
2293
void mark_transaction_to_rollback(Session *session, bool all)
2345
void mark_transaction_to_rollback(THD *thd, bool all)
2297
session->is_fatal_sub_stmt_error= true;
2298
session->transaction_rollback_request= all;
2349
thd->is_fatal_sub_stmt_error= true;
2350
thd->transaction_rollback_request= all;
2301
2353
/***************************************************************************
2305
2357
pthread_mutex_t LOCK_xid_cache;
2306
2358
HASH xid_cache;
2308
extern "C" unsigned char *xid_get_hash_key(const unsigned char *, size_t *, bool);
2360
extern "C" uchar *xid_get_hash_key(const uchar *, size_t *, bool);
2309
2361
extern "C" void xid_free_hash(void *);
2311
unsigned char *xid_get_hash_key(const unsigned char *ptr, size_t *length,
2363
uchar *xid_get_hash_key(const uchar *ptr, size_t *length,
2312
2364
bool not_used __attribute__((unused)))
2314
2366
*length=((XID_STATE*)ptr)->xid.key_length();
2400
2453
- Events of type 'RowEventT' have the type code 'type_code'.
2402
2455
POST CONDITION:
2403
If a non-NULL pointer is returned, the pending event for thread 'session' will
2456
If a non-NULL pointer is returned, the pending event for thread 'thd' will
2404
2457
be an event of type 'RowEventT' (which have the type code 'type_code')
2405
2458
will either empty or have enough space to hold 'needed' bytes. In
2406
2459
addition, the columns bitmap will be correct for the row, meaning that
2490
2543
compiling option.
2492
2545
template Rows_log_event*
2493
Session::binlog_prepare_pending_rows_event(Table*, uint32_t, size_t, bool,
2546
THD::binlog_prepare_pending_rows_event(Table*, uint32_t, size_t, bool,
2494
2547
Write_rows_log_event*);
2496
2549
template Rows_log_event*
2497
Session::binlog_prepare_pending_rows_event(Table*, uint32_t, size_t, bool,
2550
THD::binlog_prepare_pending_rows_event(Table*, uint32_t, size_t, bool,
2498
2551
Delete_rows_log_event *);
2500
2553
template Rows_log_event*
2501
Session::binlog_prepare_pending_rows_event(Table*, uint32_t, size_t, bool,
2554
THD::binlog_prepare_pending_rows_event(Table*, uint32_t, size_t, bool,
2502
2555
Update_rows_log_event *);
2598
2651
if (table->write_row_record == 0)
2599
2652
table->write_row_record=
2600
(unsigned char *) alloc_root(&table->mem_root, 2 * maxlen);
2653
(uchar *) alloc_root(&table->mem_root, 2 * maxlen);
2601
2654
m_memory= table->write_row_record;
2602
2655
m_release_memory_on_destruction= false;
2606
m_memory= (unsigned char *) my_malloc(total_length, MYF(MY_WME));
2659
m_memory= (uchar *) my_malloc(total_length, MYF(MY_WME));
2607
2660
m_release_memory_on_destruction= true;
2611
2664
mutable bool m_alloc_checked;
2612
2665
bool m_release_memory_on_destruction;
2613
unsigned char *m_memory;
2614
unsigned char *m_ptr[2];
2619
int Session::binlog_write_row(Table* table, bool is_trans,
2620
unsigned char const *record)
2672
int THD::binlog_write_row(Table* table, bool is_trans,
2673
uchar const *record)
2622
2675
assert(current_stmt_binlog_row_based && mysql_bin_log.is_open());
2643
2696
return ev->add_row_data(row_data, len);
2646
int Session::binlog_update_row(Table* table, bool is_trans,
2647
const unsigned char *before_record,
2648
const unsigned char *after_record)
2699
int THD::binlog_update_row(Table* table, bool is_trans,
2700
const uchar *before_record,
2701
const uchar *after_record)
2650
2703
assert(current_stmt_binlog_row_based && mysql_bin_log.is_open());
2656
2709
if (!row_data.has_memory())
2657
2710
return HA_ERR_OUT_OF_MEM;
2659
unsigned char *before_row= row_data.slot(0);
2660
unsigned char *after_row= row_data.slot(1);
2712
uchar *before_row= row_data.slot(0);
2713
uchar *after_row= row_data.slot(1);
2662
2715
size_t const before_size= pack_row(table, table->read_set, before_row,
2663
2716
before_record);
2760
2813
Error code, or 0 if no error.
2762
int Session::binlog_query(Session::enum_binlog_query_type qtype, char const *query_arg,
2815
int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg,
2763
2816
ulong query_len, bool is_trans, bool suppress_use,
2764
Session::killed_state killed_status_arg)
2817
THD::killed_state killed_status_arg)
2766
2819
assert(query_arg && mysql_bin_log.is_open());
2784
2837
char warn_buf[DRIZZLE_ERRMSG_SIZE];
2785
2838
snprintf(warn_buf, DRIZZLE_ERRMSG_SIZE, "%s Statement: %s",
2786
2839
ER(ER_BINLOG_UNSAFE_STATEMENT), this->query);
2787
sql_print_warning("%s",warn_buf);
2840
sql_print_warning(warn_buf);
2788
2841
binlog_flags|= BINLOG_FLAG_UNSAFE_STMT_PRINTED;
2792
2845
switch (qtype) {
2793
case Session::ROW_QUERY_TYPE:
2846
case THD::ROW_QUERY_TYPE:
2794
2847
if (current_stmt_binlog_row_based)
2796
2849
/* Otherwise, we fall through */
2797
case Session::DRIZZLE_QUERY_TYPE:
2850
case THD::DRIZZLE_QUERY_TYPE:
2799
2852
Using this query type is a conveniece hack, since we have been
2800
2853
moving back and forth between using RBR for replication of