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
/*****************************************************************************
23
** This file implements classes defined in session.h
19
** This file implements classes defined in sql_class.h
24
20
** Especially the classes to handle a result from a select
26
22
*****************************************************************************/
27
#include <drizzled/server_includes.h>
28
#include <drizzled/session.h>
29
#include <drizzled/replication/rli.h>
30
#include <drizzled/replication/record.h>
31
#include <drizzled/log_event.h>
24
#ifdef USE_PRAGMA_IMPLEMENTATION
25
#pragma implementation // gcc: Class implementation
28
#include "mysql_priv.h"
30
#include "rpl_record.h"
32
#include "log_event.h"
32
33
#include <sys/stat.h>
33
34
#include <mysys/thr_alarm.h>
34
35
#include <mysys/mysys_err.h>
35
#include <drizzled/error.h>
36
#include <drizzled/query_id.h>
37
#include <drizzled/data_home.h>
38
#include <drizzled/sql_base.h>
36
#include <drizzled/drizzled_error_messages.h>
40
extern scheduler_functions thread_scheduler;
42
39
The following is used to initialise Table_ident with a internal
69
66
****************************************************************************/
71
extern "C" unsigned char *get_var_key(user_var_entry *entry, size_t *length,
68
extern "C" uchar *get_var_key(user_var_entry *entry, size_t *length,
72
69
bool not_used __attribute__((unused)))
74
71
*length= entry->name.length;
75
return (unsigned char*) entry->name.str;
72
return (uchar*) entry->name.str;
78
75
extern "C" void free_user_var(user_var_entry *entry)
80
77
char *pos= (char*) entry+ALIGN_SIZE(sizeof(*entry));
81
78
if (entry->value && entry->value != pos)
79
my_free(entry->value, MYF(0));
80
my_free((char*) entry,MYF(0));
86
83
bool Key_part_spec::operator==(const Key_part_spec& other) const
196
Check if the foreign key options are compatible with columns
197
on which the FK is created.
203
bool Foreign_key::validate(List<Create_field> &table_fields)
205
Create_field *sql_field;
206
Key_part_spec *column;
207
List_iterator<Key_part_spec> cols(columns);
208
List_iterator<Create_field> it(table_fields);
209
while ((column= cols++))
212
while ((sql_field= it++) &&
213
my_strcasecmp(system_charset_info,
214
column->field_name.str,
215
sql_field->field_name)) {}
218
my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name.str);
221
if (type == Key::FOREIGN_KEY && sql_field->vcol_info)
223
if (delete_opt == FK_OPTION_SET_NULL)
225
my_error(ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN, MYF(0),
226
"ON DELETE SET NULL");
229
if (update_opt == FK_OPTION_SET_NULL)
231
my_error(ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN, MYF(0),
232
"ON UPDATE SET NULL");
235
if (update_opt == FK_OPTION_CASCADE)
237
my_error(ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN, MYF(0),
238
"ON UPDATE CASCADE");
247
192
/****************************************************************************
248
193
** Thread specific functions
249
194
****************************************************************************/
261
206
extern "C" int mysql_tmpfile(const char *prefix)
263
208
char filename[FN_REFLEN];
264
File fd = create_temp_file(filename, drizzle_tmpdir, prefix,
265
O_CREAT | O_EXCL | O_RDWR,
209
File fd = create_temp_file(filename, mysql_tmpdir, prefix,
210
O_CREAT | O_EXCL | O_RDWR | O_TEMPORARY,
214
This can be removed once the following bug is fixed:
215
Bug #28903 create_temp_file() doesn't honor O_TEMPORARY option
216
(file not removed) (Unix)
268
218
unlink(filename);
276
int session_in_lock_tables(const Session *session)
278
return test(session->in_lock_tables);
283
int session_tablespace_op(const Session *session)
285
return test(session->tablespace_op);
290
Set the process info field of the Session structure.
292
This function is used by plug-ins. Internally, the
293
Session::set_proc_info() function should be used.
295
@see Session::set_proc_info
298
set_session_proc_info(Session *session, const char *info)
300
session->set_proc_info(info);
304
const char *get_session_proc_info(Session *session)
306
return session->get_proc_info();
310
void **session_ha_data(const Session *session, const struct handlerton *hton)
312
return (void **) &session->ha_data[hton->slot].ha_ptr;
316
int64_t session_test_options(const Session *session, int64_t test_options)
318
return session->options & test_options;
322
int session_sql_command(const Session *session)
324
return (int) session->lex->sql_command;
328
int session_tx_isolation(const Session *session)
330
return (int) session->variables.tx_isolation;
334
void session_inc_row_count(Session *session)
336
session->row_count++;
226
int thd_in_lock_tables(const THD *thd)
228
return test(thd->in_lock_tables);
233
int thd_tablespace_op(const THD *thd)
235
return test(thd->tablespace_op);
240
const char *set_thd_proc_info(THD *thd, const char *info,
241
const char *calling_function __attribute__((unused)),
242
const char *calling_file __attribute__((unused)),
243
const unsigned int calling_line __attribute__((unused)))
245
const char *old_info= thd->proc_info;
246
thd->proc_info= info;
251
void **thd_ha_data(const THD *thd, const struct handlerton *hton)
253
return (void **) &thd->ha_data[hton->slot].ha_ptr;
257
int64_t thd_test_options(const THD *thd, int64_t test_options)
259
return thd->options & test_options;
263
int thd_sql_command(const THD *thd)
265
return (int) thd->lex->sql_command;
269
int thd_tx_isolation(const THD *thd)
271
return (int) thd->variables.tx_isolation;
275
void thd_inc_row_count(THD *thd)
281
Dumps a text description of a thread, its security context
282
(user, host) and the current query.
285
thd_security_context()
286
thd current thread context
287
buffer pointer to preferred result buffer
288
length length of buffer
289
max_query_len how many chars of query to copy (0 for all)
295
char *thd_security_context(THD *thd, char *buffer, unsigned int length,
296
unsigned int max_query_len)
298
String str(buffer, length, &my_charset_latin1);
299
const Security_context *sctx= &thd->main_security_ctx;
303
len= snprintf(header, sizeof(header),
304
"MySQL thread id %lu, query id %lu",
305
thd->thread_id, (ulong) thd->query_id);
307
str.append(header, len);
312
str.append(sctx->host);
318
str.append(sctx->ip);
324
str.append(sctx->user);
330
str.append(thd->proc_info);
335
if (max_query_len < 1)
336
len= thd->query_length;
338
len= min(thd->query_length, max_query_len);
340
str.append(thd->query, len);
342
if (str.c_ptr_safe() == buffer)
344
return thd->strmake(str.ptr(), str.length());
467
:Statement(&main_lex, &main_mem_root,
475
:Statement(&main_lex, &main_mem_root, CONVENTIONAL_EXECUTION,
468
476
/* statement id */ 0),
469
477
Open_tables_state(refresh_version), rli_fake(0),
470
478
lock_id(&main_lock_id),
479
user_time(0), in_sub_stmt(0),
472
480
binlog_table_maps(0), binlog_flags(0UL),
473
481
arg_of_last_insert_id_function(false),
474
482
first_successful_insert_id_in_prev_stmt(0),
483
first_successful_insert_id_in_prev_stmt_for_binlog(0),
475
484
first_successful_insert_id_in_cur_stmt(0),
476
485
stmt_depends_on_first_successful_insert_id_in_prev_stmt(false),
477
486
global_read_lock(0),
478
487
is_fatal_error(0),
479
488
transaction_rollback_request(0),
480
489
is_fatal_sub_stmt_error(0),
481
492
in_lock_tables(0),
482
494
derived_tables_processing(false),
560
578
protocol= &protocol_text; // Default protocol
561
579
protocol_text.init(this);
563
const Query_id& query_id= Query_id::get_query_id();
564
581
tablespace_op= false;
566
randominit(&rand, tmp + (ulong) &rand, tmp + query_id.value());
583
randominit(&rand, tmp + (ulong) &rand, tmp + (ulong) ::global_query_id);
567
584
substitute_null_with_insert_id = false;
568
585
thr_lock_info_init(&lock_info); /* safety: will be reset after start */
569
586
thr_lock_owner_init(&main_lock_id, &lock_info);
575
void Session::push_internal_handler(Internal_error_handler *handler)
592
void THD::push_internal_handler(Internal_error_handler *handler)
578
595
TODO: The current implementation is limited to 1 handler at a time only.
579
Session and sp_rcontext need to be modified to use a common handler stack.
596
THD and sp_rcontext need to be modified to use a common handler stack.
581
598
assert(m_internal_handler == NULL);
582
599
m_internal_handler= handler;
586
bool Session::handle_error(uint32_t sql_errno, const char *message,
587
DRIZZLE_ERROR::enum_warning_level level)
603
bool THD::handle_error(uint sql_errno, const char *message,
604
MYSQL_ERROR::enum_warning_level level)
589
606
if (m_internal_handler)
598
void Session::pop_internal_handler()
615
void THD::pop_internal_handler()
600
617
assert(m_internal_handler != NULL);
601
618
m_internal_handler= NULL;
604
#if defined(__cplusplus)
608
void *session_alloc(Session *session, unsigned int size)
610
return session->alloc(size);
613
void *session_calloc(Session *session, unsigned int size)
615
return session->calloc(size);
618
char *session_strdup(Session *session, const char *str)
620
return session->strdup(str);
623
char *session_strmake(Session *session, const char *str, unsigned int size)
625
return session->strmake(str, size);
628
void *session_memdup(Session *session, const void* str, unsigned int size)
630
return session->memdup(str, size);
633
void session_get_xid(const Session *session, DRIZZLE_XID *xid)
635
*xid = *(DRIZZLE_XID *) &session->transaction.xid_state.xid;
638
#if defined(__cplusplus)
622
void *thd_alloc(MYSQL_THD thd, unsigned int size)
624
return thd->alloc(size);
628
void *thd_calloc(MYSQL_THD thd, unsigned int size)
630
return thd->calloc(size);
634
char *thd_strdup(MYSQL_THD thd, const char *str)
636
return thd->strdup(str);
640
char *thd_strmake(MYSQL_THD thd, const char *str, unsigned int size)
642
return thd->strmake(str, size);
646
LEX_STRING *thd_make_lex_string(THD *thd, LEX_STRING *lex_str,
647
const char *str, unsigned int size,
648
int allocate_lex_string)
650
return thd->make_lex_string(lex_str, str, size,
651
(bool) allocate_lex_string);
655
void *thd_memdup(MYSQL_THD thd, const void* str, unsigned int size)
657
return thd->memdup(str, size);
661
void thd_get_xid(const MYSQL_THD thd, MYSQL_XID *xid)
663
*xid = *(MYSQL_XID *) &thd->transaction.xid_state.xid;
643
667
Init common variables that has to be reset on start and on change_user
646
void Session::init(void)
648
672
pthread_mutex_lock(&LOCK_global_system_variables);
649
plugin_sessionvar_init(this);
650
variables.time_format= date_time_format_copy((Session*) 0,
673
plugin_thdvar_init(this);
674
variables.time_format= date_time_format_copy((THD*) 0,
651
675
variables.time_format);
652
variables.date_format= date_time_format_copy((Session*) 0,
676
variables.date_format= date_time_format_copy((THD*) 0,
653
677
variables.date_format);
654
variables.datetime_format= date_time_format_copy((Session*) 0,
678
variables.datetime_format= date_time_format_copy((THD*) 0,
655
679
variables.datetime_format);
657
681
variables= global_system_variables above has reset
676
700
session_tx_isolation= (enum_tx_isolation) variables.tx_isolation;
677
701
warn_list.empty();
678
memset(warn_count, 0, sizeof(warn_count));
702
memset((char*) warn_count, 0, sizeof(warn_count));
679
703
total_warn_count= 0;
680
704
update_charset();
681
memset(&status_var, 0, sizeof(status_var));
705
reset_current_stmt_binlog_row_based();
706
memset((char *) &status_var, 0, sizeof(status_var));
686
Init Session for query processing.
711
Init THD for query processing.
687
712
This has to be called once before we call mysql_parse.
688
See also comments in session.h.
713
See also comments in sql_class.h.
691
void Session::init_for_queries()
716
void THD::init_for_queries()
694
719
ha_enable_transaction(this,true);
729
754
delete_dynamic(&user_var_events);
730
755
hash_free(&user_vars);
731
756
close_temporary_tables(this);
732
free((char*) variables.time_format);
733
free((char*) variables.date_format);
734
free((char*) variables.datetime_format);
757
my_free((char*) variables.time_format, MYF(MY_ALLOW_ZERO_PTR));
758
my_free((char*) variables.date_format, MYF(MY_ALLOW_ZERO_PTR));
759
my_free((char*) variables.datetime_format, MYF(MY_ALLOW_ZERO_PTR));
736
761
if (global_read_lock)
737
762
unlock_global_read_lock(this);
751
776
/* Close connection */
757
782
if (!cleanup_done)
760
785
ha_close_connection(this);
761
plugin_sessionvar_cleanup(this);
786
plugin_thdvar_cleanup(this);
763
788
main_security_ctx.destroy();
769
790
free_root(&warn_root,MYF(0));
770
791
free_root(&transaction.mem_root,MYF(0));
771
792
mysys_var=0; // Safety (shouldn't be needed)
772
793
pthread_mutex_destroy(&LOCK_delete);
773
dbug_sentry= Session_SENTRY_GONE;
794
dbug_sentry= THD_SENTRY_GONE;
836
void Session::awake(Session::killed_state state_to_set)
857
void THD::awake(THD::killed_state state_to_set)
838
Session_CHECK_SENTRY(this);
859
THD_CHECK_SENTRY(this);
839
860
safe_mutex_assert_owner(&LOCK_delete);
841
862
killed= state_to_set;
842
if (state_to_set != Session::KILL_QUERY)
863
if (state_to_set != THD::KILL_QUERY)
844
865
thr_alarm_kill(thread_id);
845
866
if (!slave_thread)
846
867
thread_scheduler.post_kill_notification(this);
868
#ifdef SIGNAL_WITH_VIO_CLOSE
869
if (this != current_thd)
872
In addition to a signal, let's close the socket of the thread that
873
is being killed. This is to make sure it does not block if the
874
signal is lost. This needs to be done only on platforms where
875
signals are not a reliable interruption mechanism.
877
If we're killing ourselves, we know that we're not blocked, so this
894
931
assert(thread_stack);
896
if (pthread_setspecific(THR_Session, this) ||
897
pthread_setspecific(THR_MALLOC, &mem_root))
933
if (my_pthread_setspecific_ptr(THR_THD, this) ||
934
my_pthread_setspecific_ptr(THR_MALLOC, &mem_root))
899
936
mysys_var=my_thread_var;
901
938
Let mysqld define the thread id (not mysys)
902
This allows us to move Session to different threads if needed.
939
This allows us to move THD to different threads if needed.
904
941
mysys_var->id= thread_id;
905
942
real_id= pthread_self(); // For debugging
908
We have to call thr_lock_info_init() again here as Session may have been
945
We have to call thr_lock_info_init() again here as THD may have been
909
946
created in another thread
911
948
thr_lock_info_init(&lock_info);
932
void Session::cleanup_after_query()
969
void THD::cleanup_after_query()
935
972
Reset rand_used so that detection of calls to rand() will save random
936
973
seeds if needed by the slave.
975
Do not reset rand_used if inside a stored function or trigger because
976
only the call to these operations is logged. Thus only the calling
977
statement needs to detect rand() calls made by its substatements. These
978
substatements must not set rand_used to 0 because it would remove the
979
detection of rand() by the calling statement.
981
if (!in_sub_stmt) /* stored functions and triggers are a special case */
939
983
/* Forget those values, for next binlogger: */
940
984
stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
941
985
auto_inc_intervals_in_cur_stmt_for_binlog.empty();
943
988
if (first_successful_insert_id_in_cur_stmt > 0)
1000
1045
In this case to->str will point to 0 and to->length will be 0.
1003
bool Session::convert_string(LEX_STRING *to, const CHARSET_INFO * const to_cs,
1004
const char *from, uint32_t from_length,
1005
const CHARSET_INFO * const from_cs)
1048
bool THD::convert_string(LEX_STRING *to, CHARSET_INFO *to_cs,
1049
const char *from, uint from_length,
1050
CHARSET_INFO *from_cs)
1007
1052
size_t new_length= to_cs->mbmaxlen * from_length;
1008
uint32_t dummy_errors;
1009
1054
if (!(to->str= (char*) alloc(new_length+1)))
1011
1056
to->length= 0; // Safety fix
1129
CHANGED_TableList* Session::changed_table_dup(const char *key, long key_length)
1173
CHANGED_TABLE_LIST* THD::changed_table_dup(const char *key, long key_length)
1131
CHANGED_TableList* new_table =
1132
(CHANGED_TableList*) trans_alloc(ALIGN_SIZE(sizeof(CHANGED_TableList))+
1175
CHANGED_TABLE_LIST* new_table =
1176
(CHANGED_TABLE_LIST*) trans_alloc(ALIGN_SIZE(sizeof(CHANGED_TABLE_LIST))+
1133
1177
key_length + 1);
1134
1178
if (!new_table)
1136
1180
my_error(EE_OUTOFMEMORY, MYF(ME_BELL),
1137
ALIGN_SIZE(sizeof(TableList)) + key_length + 1);
1181
ALIGN_SIZE(sizeof(TABLE_LIST)) + key_length + 1);
1138
1182
killed= KILL_CONNECTION;
1142
new_table->key= ((char*)new_table)+ ALIGN_SIZE(sizeof(CHANGED_TableList));
1186
new_table->key= ((char*)new_table)+ ALIGN_SIZE(sizeof(CHANGED_TABLE_LIST));
1143
1187
new_table->next = 0;
1144
1188
new_table->key_length = key_length;
1145
1189
::memcpy(new_table->key, key, key_length);
1208
1265
Register an item tree tree transformation, performed by the query
1209
1266
optimizer. We need a pointer to runtime_memroot because it may be !=
1210
session->mem_root (this may no longer be a true statement)
1267
thd->mem_root (due to possible set_n_backup_active_arena called for thd).
1213
void Session::nocheck_register_item_tree_change(Item **place, Item *old_value,
1270
void THD::nocheck_register_item_tree_change(Item **place, Item *old_value,
1214
1271
MEM_ROOT *runtime_memroot)
1216
1273
Item_change_record *change;
1309
Check that the endpoint is still available.
1312
bool THD::vio_is_connected()
1316
/* End of input is signaled by poll if the socket is aborted. */
1317
if (vio_poll_read(net.vio, 0))
1320
/* Socket is aborted if signaled but no data is available. */
1321
if (vio_peek_read(net.vio, &bytes))
1324
return bytes ? true : false;
1251
1328
/*****************************************************************************
1252
1329
** Functions to provide a interface to select results
1253
1330
*****************************************************************************/
1255
1332
select_result::select_result()
1257
session=current_session;
1260
void select_result::send_error(uint32_t errcode,const char *err)
1337
void select_result::send_error(uint errcode,const char *err)
1262
1339
my_message(errcode, err, MYF(0));
1286
1364
filetype= filetype_arg;
1287
1365
field_term= &default_field_term;
1288
1366
enclosed= line_start= &my_empty_string;
1289
line_term= &default_line_term;
1367
line_term= filetype == FILETYPE_CSV ?
1368
&default_line_term : &default_xml_row_term;
1290
1369
escaped= &default_escaped;
1294
bool select_send::send_fields(List<Item> &list, uint32_t flags)
1373
bool select_send::send_fields(List<Item> &list, uint flags)
1297
if (!(res= session->protocol->send_fields(&list, flags)))
1376
if (!(res= thd->protocol->send_fields(&list, flags)))
1298
1377
is_result_set_started= 1;
1480
1559
if (!dirname_length(exchange->file_name))
1482
strcpy(path, drizzle_real_data_home);
1484
strncat(path, session->db, FN_REFLEN-strlen(drizzle_real_data_home)-1);
1561
strxnmov(path, FN_REFLEN-1, mysql_real_data_home, thd->db ? thd->db : "",
1485
1563
(void) fn_format(path, exchange->file_name, path, "", option);
1488
(void) fn_format(path, exchange->file_name, drizzle_real_data_home, "", option);
1566
(void) fn_format(path, exchange->file_name, mysql_real_data_home, "", option);
1490
1568
if (opt_secure_file_priv &&
1491
1569
strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv)))
1549
1627
field_term_length=exchange->field_term->length();
1550
1628
field_term_char= field_term_length ?
1551
(int) (unsigned char) (*exchange->field_term)[0] : INT_MAX;
1629
(int) (uchar) (*exchange->field_term)[0] : INT_MAX;
1552
1630
if (!exchange->line_term->length())
1553
1631
exchange->line_term=exchange->field_term; // Use this if it exists
1554
1632
field_sep_char= (exchange->enclosed->length() ?
1555
(int) (unsigned char) (*exchange->enclosed)[0] : field_term_char);
1633
(int) (uchar) (*exchange->enclosed)[0] : field_term_char);
1556
1634
escape_char= (exchange->escaped->length() ?
1557
(int) (unsigned char) (*exchange->escaped)[0] : -1);
1635
(int) (uchar) (*exchange->escaped)[0] : -1);
1558
1636
is_ambiguous_field_sep= test(strchr(ESCAPE_CHARS, field_sep_char));
1559
1637
is_unsafe_field_sep= test(strchr(NUMERIC_CHARS, field_sep_char));
1560
1638
line_sep_char= (exchange->line_term->length() ?
1561
(int) (unsigned char) (*exchange->line_term)[0] : INT_MAX);
1639
(int) (uchar) (*exchange->line_term)[0] : INT_MAX);
1562
1640
if (!field_term_length)
1563
1641
exchange->opt_enclosed=0;
1564
1642
if (!exchange->enclosed->length())
1643
1721
if (fixed_row_size)
1644
used_length=cmin(res->length(),item->max_length);
1722
used_length=min(res->length(),item->max_length);
1646
1724
used_length=res->length();
1647
1725
if ((result_type == STRING_RESULT || is_unsafe_field_sep) &&
1648
1726
escape_char != -1)
1650
1728
char *pos, *start, *end;
1651
const CHARSET_INFO * const res_charset= res->charset();
1652
const CHARSET_INFO * const character_set_client= session->variables.
1653
character_set_client;
1729
CHARSET_INFO *res_charset= res->charset();
1730
CHARSET_INFO *character_set_client= thd->variables.
1731
character_set_client;
1654
1732
bool check_second_byte= (res_charset == &my_charset_bin) &&
1655
1733
character_set_client->
1656
1734
escape_with_backslash_is_dangerous;
1714
1792
valid for ENCLOSED BY characters:
1716
1794
(enclosed || !is_ambiguous_field_term ||
1717
(int) (unsigned char) *pos != field_term_char))
1795
(int) (uchar) *pos != field_term_char))
1719
1797
char tmp_buff[2];
1720
tmp_buff[0]= ((int) (unsigned char) *pos == field_sep_char &&
1798
tmp_buff[0]= ((int) (uchar) *pos == field_sep_char &&
1721
1799
is_ambiguous_field_sep) ?
1722
1800
field_sep_char : escape_char;
1723
1801
tmp_buff[1]= *pos ? *pos : '0';
1724
if (my_b_write(&cache,(unsigned char*) start,(uint) (pos-start)) ||
1725
my_b_write(&cache,(unsigned char*) tmp_buff,2))
1802
if (my_b_write(&cache,(uchar*) start,(uint) (pos-start)) ||
1803
my_b_write(&cache,(uchar*) tmp_buff,2))
1730
if (my_b_write(&cache,(unsigned char*) start,(uint) (pos-start)))
1808
if (my_b_write(&cache,(uchar*) start,(uint) (pos-start)))
1733
else if (my_b_write(&cache,(unsigned char*) res->ptr(),used_length))
1811
else if (my_b_write(&cache,(uchar*) res->ptr(),used_length))
1736
1814
if (fixed_row_size)
1743
1821
space_inited=1;
1744
1822
memset(space, ' ', sizeof(space));
1746
uint32_t length=item->max_length-used_length;
1824
uint length=item->max_length-used_length;
1747
1825
for (; length > sizeof(space) ; length-=sizeof(space))
1749
if (my_b_write(&cache,(unsigned char*) space,sizeof(space)))
1827
if (my_b_write(&cache,(uchar*) space,sizeof(space)))
1752
if (my_b_write(&cache,(unsigned char*) space,length))
1830
if (my_b_write(&cache,(uchar*) space,length))
1756
1834
if (res && enclosed)
1758
if (my_b_write(&cache, (unsigned char*) exchange->enclosed->ptr(),
1836
if (my_b_write(&cache, (uchar*) exchange->enclosed->ptr(),
1759
1837
exchange->enclosed->length()))
1762
1840
if (--items_left)
1764
if (my_b_write(&cache, (unsigned char*) exchange->field_term->ptr(),
1842
if (my_b_write(&cache, (uchar*) exchange->field_term->ptr(),
1765
1843
field_term_length))
1769
if (my_b_write(&cache,(unsigned char*) exchange->line_term->ptr(),
1847
if (my_b_write(&cache,(uchar*) exchange->line_term->ptr(),
1770
1848
exchange->line_term->length()))
1812
1890
res=item->str_result(&tmp);
1813
1891
if (!res) // If NULL
1815
if (my_b_write(&cache,(unsigned char*) "",1))
1893
if (my_b_write(&cache,(uchar*) "",1))
1818
else if (my_b_write(&cache,(unsigned char*) res->ptr(),res->length()))
1896
else if (my_b_write(&cache,(uchar*) res->ptr(),res->length()))
1820
1898
my_error(ER_ERROR_ON_WRITE, MYF(0), path, my_errno);
2105
void Query_arena::set_query_arena(Query_arena *set)
2107
mem_root= set->mem_root;
2108
free_list= set->free_list;
2113
void Query_arena::cleanup_stmt()
2115
assert("not implemented");
2028
2119
Statement functions
2031
Statement::Statement(LEX *lex_arg, MEM_ROOT *mem_root_arg, ulong id_arg)
2032
:Query_arena(mem_root_arg),
2122
Statement::Statement(LEX *lex_arg, MEM_ROOT *mem_root_arg,
2123
enum enum_state state_arg, ulong id_arg)
2124
:Query_arena(mem_root_arg, state_arg),
2034
2126
mark_used_columns(MARK_COLUMNS_READ),
2045
Don't free mem_root, as mem_root is freed in the end of dispatch_command
2046
(once for any command).
2048
void Session::end_statement()
2137
void Statement::set_statement(Statement *stmt)
2140
mark_used_columns= stmt->mark_used_columns;
2143
query_length= stmt->query_length;
2148
Statement::set_n_backup_statement(Statement *stmt, Statement *backup)
2150
backup->set_statement(this);
2151
set_statement(stmt);
2156
void Statement::restore_backup_statement(Statement *stmt, Statement *backup)
2158
stmt->set_statement(this);
2159
set_statement(backup);
2164
void THD::end_statement()
2050
2166
/* Cleanup SQL processing state to reuse this statement in next query. */
2055
bool Session::copy_db_to(char **p_db, size_t *p_db_length)
2170
/* Note that free_list is freed in cleanup_after_query() */
2173
Don't free mem_root, as mem_root is freed in the end of dispatch_command
2174
(once for any command).
2179
void THD::set_n_backup_active_arena(Query_arena *set, Query_arena *backup)
2181
assert(backup->is_backup_arena == false);
2183
backup->set_query_arena(this);
2184
set_query_arena(set);
2185
backup->is_backup_arena= true;
2190
void THD::restore_active_arena(Query_arena *set, Query_arena *backup)
2192
assert(backup->is_backup_arena);
2193
set->set_query_arena(this);
2194
set_query_arena(backup);
2195
backup->is_backup_arena= false;
2200
bool THD::copy_db_to(char **p_db, size_t *p_db_length)
2057
2202
if (db == NULL)
2087
2232
if (mv->local == 0)
2089
2234
Item_func_set_user_var *suv= new Item_func_set_user_var(mv->s, item);
2090
suv->fix_fields(session, 0);
2235
suv->fix_fields(thd, 0);
2095
return(session->is_error());
2240
return(thd->is_error());
2098
2243
bool select_dumpvar::send_eof()
2100
2245
if (! row_count)
2101
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2246
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
2102
2247
ER_SP_FETCH_NO_DATA, ER(ER_SP_FETCH_NO_DATA));
2104
2249
In order to remember the value of affected rows for ROW_COUNT()
2105
2250
function, SELECT INTO has to have an own SQLCOM.
2106
2251
TODO: split from SQLCOM_SELECT
2108
::my_ok(session,row_count);
2253
::my_ok(thd,row_count);
2127
void TMP_TABLE_PARAM::cleanup(void)
2129
/* Fix for Intel compiler */
2132
delete [] copy_field;
2133
save_copy_field= copy_field= 0;
2138
void session_increment_bytes_sent(ulong length)
2140
Session *session=current_session;
2141
if (likely(session != 0))
2142
{ /* current_session==0 when close_connection() calls net_send_error() */
2143
session->status_var.bytes_sent+= length;
2148
void session_increment_bytes_received(ulong length)
2150
current_session->status_var.bytes_received+= length;
2154
void session_increment_net_big_packet_count(ulong length)
2156
current_session->status_var.net_big_packet_count+= length;
2159
void Session::send_kill_message() const
2273
void thd_increment_bytes_sent(ulong length)
2275
THD *thd=current_thd;
2276
if (likely(thd != 0))
2277
{ /* current_thd==0 when close_connection() calls net_send_error() */
2278
thd->status_var.bytes_sent+= length;
2283
void thd_increment_bytes_received(ulong length)
2285
current_thd->status_var.bytes_received+= length;
2289
void thd_increment_net_big_packet_count(ulong length)
2291
current_thd->status_var.net_big_packet_count+= length;
2294
void THD::send_kill_message() const
2161
2296
int err= killed_errno();
2163
2298
my_message(err, ER(err), MYF(0));
2166
void Session::set_status_var_init()
2301
void THD::set_status_var_init()
2168
memset(&status_var, 0, sizeof(status_var));
2303
memset((char*) &status_var, 0, sizeof(status_var));
2172
2307
void Security_context::init()
2309
host= user= priv_user= ip= 0;
2310
host_or_ip= "connecting host";
2178
2315
void Security_context::destroy()
2180
2317
// If not pointer to constant
2318
if (host != my_localhost)
2194
2325
void Security_context::skip_grants()
2196
2327
/* privileges for the user are unknown everything is allowed */
2328
host_or_ip= (char *)"";
2329
priv_user= (char *)"";
2231
2365
Check the killed state of a user thread
2232
@param session user thread
2366
@param thd user thread
2233
2367
@retval 0 the user thread is active
2234
2368
@retval 1 the user thread has been killed
2236
extern "C" int session_killed(const Session *session)
2370
extern "C" int thd_killed(const MYSQL_THD thd)
2238
return(session->killed);
2372
return(thd->killed);
2242
2376
Return the thread id of a user thread
2243
@param session user thread
2377
@param thd user thread
2244
2378
@return thread id
2246
extern "C" unsigned long session_get_thread_id(const Session *session)
2248
return((unsigned long)session->thread_id);
2253
LEX_STRING *session_make_lex_string(Session *session, LEX_STRING *lex_str,
2254
const char *str, unsigned int size,
2255
int allocate_lex_string)
2257
return session->make_lex_string(lex_str, str, size,
2258
(bool) allocate_lex_string);
2261
extern "C" const struct charset_info_st *session_charset(Session *session)
2263
return(session->charset());
2266
extern "C" char **session_query(Session *session)
2268
return(&session->query);
2271
extern "C" int session_slave_thread(const Session *session)
2273
return(session->slave_thread);
2276
extern "C" int session_non_transactional_update(const Session *session)
2278
return(session->transaction.all.modified_non_trans_table);
2281
extern "C" void session_mark_transaction_to_rollback(Session *session, bool all)
2283
mark_transaction_to_rollback(session, all);
2380
extern "C" unsigned long thd_get_thread_id(const MYSQL_THD thd)
2382
return((unsigned long)thd->thread_id);
2386
#ifdef INNODB_COMPATIBILITY_HOOKS
2387
extern "C" struct charset_info_st *thd_charset(MYSQL_THD thd)
2389
return(thd->charset());
2392
extern "C" char **thd_query(MYSQL_THD thd)
2394
return(&thd->query);
2397
extern "C" int thd_slave_thread(const MYSQL_THD thd)
2399
return(thd->slave_thread);
2402
extern "C" int thd_non_transactional_update(const MYSQL_THD thd)
2404
return(thd->transaction.all.modified_non_trans_table);
2407
extern "C" int thd_binlog_format(const MYSQL_THD thd)
2409
return (int) thd->variables.binlog_format;
2412
extern "C" void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all)
2414
mark_transaction_to_rollback(thd, all);
2416
#endif // INNODB_COMPATIBILITY_HOOKS */
2288
2420
Mark transaction to rollback and mark error as fatal to a sub-statement.
2290
@param session Thread handle
2422
@param thd Thread handle
2291
2423
@param all true <=> rollback main transaction.
2294
void mark_transaction_to_rollback(Session *session, bool all)
2426
void mark_transaction_to_rollback(THD *thd, bool all)
2298
session->is_fatal_sub_stmt_error= true;
2299
session->transaction_rollback_request= all;
2430
thd->is_fatal_sub_stmt_error= true;
2431
thd->transaction_rollback_request= all;
2302
2434
/***************************************************************************
2306
2438
pthread_mutex_t LOCK_xid_cache;
2307
2439
HASH xid_cache;
2309
extern "C" unsigned char *xid_get_hash_key(const unsigned char *, size_t *, bool);
2441
extern "C" uchar *xid_get_hash_key(const uchar *, size_t *, bool);
2310
2442
extern "C" void xid_free_hash(void *);
2312
unsigned char *xid_get_hash_key(const unsigned char *ptr, size_t *length,
2444
uchar *xid_get_hash_key(const uchar *ptr, size_t *length,
2313
2445
bool not_used __attribute__((unused)))
2315
2447
*length=((XID_STATE*)ptr)->xid.key_length();
2491
2624
compiling option.
2493
2626
template Rows_log_event*
2494
Session::binlog_prepare_pending_rows_event(Table*, uint32_t, size_t, bool,
2627
THD::binlog_prepare_pending_rows_event(TABLE*, uint32_t, size_t, bool,
2495
2628
Write_rows_log_event*);
2497
2630
template Rows_log_event*
2498
Session::binlog_prepare_pending_rows_event(Table*, uint32_t, size_t, bool,
2631
THD::binlog_prepare_pending_rows_event(TABLE*, uint32_t, size_t, bool,
2499
2632
Delete_rows_log_event *);
2501
2634
template Rows_log_event*
2502
Session::binlog_prepare_pending_rows_event(Table*, uint32_t, size_t, bool,
2635
THD::binlog_prepare_pending_rows_event(TABLE*, uint32_t, size_t, bool,
2503
2636
Update_rows_log_event *);
2599
2732
if (table->write_row_record == 0)
2600
2733
table->write_row_record=
2601
(unsigned char *) alloc_root(&table->mem_root, 2 * maxlen);
2734
(uchar *) alloc_root(&table->mem_root, 2 * maxlen);
2602
2735
m_memory= table->write_row_record;
2603
2736
m_release_memory_on_destruction= false;
2607
m_memory= (unsigned char *) my_malloc(total_length, MYF(MY_WME));
2740
m_memory= (uchar *) my_malloc(total_length, MYF(MY_WME));
2608
2741
m_release_memory_on_destruction= true;
2612
2745
mutable bool m_alloc_checked;
2613
2746
bool m_release_memory_on_destruction;
2614
unsigned char *m_memory;
2615
unsigned char *m_ptr[2];
2620
int Session::binlog_write_row(Table* table, bool is_trans,
2621
unsigned char const *record)
2753
int THD::binlog_write_row(TABLE* table, bool is_trans,
2754
uchar const *record)
2623
assert(drizzle_bin_log.is_open());
2756
assert(current_stmt_binlog_row_based && mysql_bin_log.is_open());
2626
2759
Pack records into format for transfer. We are allocating more
2627
2760
memory than needed, but that doesn't matter.
2629
Row_data_memory memory(table, table->max_row_length(record));
2762
Row_data_memory memory(table, max_row_length(table, record));
2630
2763
if (!memory.has_memory())
2631
2764
return HA_ERR_OUT_OF_MEM;
2633
unsigned char *row_data= memory.slot(0);
2766
uchar *row_data= memory.slot(0);
2635
2768
size_t const len= pack_row(table, table->write_set, row_data, record);
2644
2777
return ev->add_row_data(row_data, len);
2647
int Session::binlog_update_row(Table* table, bool is_trans,
2648
const unsigned char *before_record,
2649
const unsigned char *after_record)
2780
int THD::binlog_update_row(TABLE* table, bool is_trans,
2781
const uchar *before_record,
2782
const uchar *after_record)
2651
assert(drizzle_bin_log.is_open());
2784
assert(current_stmt_binlog_row_based && mysql_bin_log.is_open());
2653
size_t const before_maxlen = table->max_row_length(before_record);
2654
size_t const after_maxlen = table->max_row_length(after_record);
2786
size_t const before_maxlen = max_row_length(table, before_record);
2787
size_t const after_maxlen = max_row_length(table, after_record);
2656
2789
Row_data_memory row_data(table, before_maxlen, after_maxlen);
2657
2790
if (!row_data.has_memory())
2658
2791
return HA_ERR_OUT_OF_MEM;
2660
unsigned char *before_row= row_data.slot(0);
2661
unsigned char *after_row= row_data.slot(1);
2793
uchar *before_row= row_data.slot(0);
2794
uchar *after_row= row_data.slot(1);
2663
2796
size_t const before_size= pack_row(table, table->read_set, before_row,
2664
2797
before_record);
2678
2811
ev->add_row_data(after_row, after_size);
2681
int Session::binlog_delete_row(Table* table, bool is_trans,
2682
unsigned char const *record)
2814
int THD::binlog_delete_row(TABLE* table, bool is_trans,
2815
uchar const *record)
2684
assert(drizzle_bin_log.is_open());
2817
assert(current_stmt_binlog_row_based && mysql_bin_log.is_open());
2687
2820
Pack records into format for transfer. We are allocating more
2688
2821
memory than needed, but that doesn't matter.
2690
Row_data_memory memory(table, table->max_row_length(record));
2823
Row_data_memory memory(table, max_row_length(table, record));
2691
2824
if (unlikely(!memory.has_memory()))
2692
2825
return HA_ERR_OUT_OF_MEM;
2694
unsigned char *row_data= memory.slot(0);
2827
uchar *row_data= memory.slot(0);
2696
2829
size_t const len= pack_row(table, table->read_set, row_data, record);
2761
2894
Error code, or 0 if no error.
2763
int Session::binlog_query(Session::enum_binlog_query_type qtype, char const *query_arg,
2896
int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg,
2764
2897
ulong query_len, bool is_trans, bool suppress_use,
2765
Session::killed_state killed_status_arg)
2898
THD::killed_state killed_status_arg)
2767
assert(query_arg && drizzle_bin_log.is_open());
2900
assert(query_arg && mysql_bin_log.is_open());
2769
2902
if (int error= binlog_flush_pending_rows_event(true))
2906
If we are in statement mode and trying to log an unsafe statement,
2907
we should print a warning.
2909
if (lex->is_stmt_unsafe() &&
2910
variables.binlog_format == BINLOG_FORMAT_STMT)
2912
assert(this->query != NULL);
2913
push_warning(this, MYSQL_ERROR::WARN_LEVEL_WARN,
2914
ER_BINLOG_UNSAFE_STATEMENT,
2915
ER(ER_BINLOG_UNSAFE_STATEMENT));
2916
if (!(binlog_flags & BINLOG_FLAG_UNSAFE_STMT_PRINTED))
2918
char warn_buf[MYSQL_ERRMSG_SIZE];
2919
snprintf(warn_buf, MYSQL_ERRMSG_SIZE, "%s Statement: %s",
2920
ER(ER_BINLOG_UNSAFE_STATEMENT), this->query);
2921
sql_print_warning(warn_buf);
2922
binlog_flags|= BINLOG_FLAG_UNSAFE_STMT_PRINTED;
2772
2926
switch (qtype) {
2773
case Session::ROW_QUERY_TYPE:
2775
case Session::DRIZZLE_QUERY_TYPE:
2927
case THD::ROW_QUERY_TYPE:
2928
if (current_stmt_binlog_row_based)
2930
/* Otherwise, we fall through */
2931
case THD::MYSQL_QUERY_TYPE:
2777
2933
Using this query type is a conveniece hack, since we have been
2778
2934
moving back and forth between using RBR for replication of
2841
@param session Thread handle
2842
@param errcode Error code to print to console
2843
@param lock 1 if we have have to lock LOCK_thread_count
2846
For the connection that is doing shutdown, this is called twice
2848
void close_connection(Session *session, uint32_t errcode, bool lock)
2852
(void) pthread_mutex_lock(&LOCK_thread_count);
2853
session->killed= Session::KILL_CONNECTION;
2854
if ((vio= session->net.vio) != 0)
2857
net_send_error(session, errcode, ER(errcode)); /* purecov: inspected */
2858
net_close(&(session->net)); /* vio is freed in delete session */
2861
(void) pthread_mutex_unlock(&LOCK_thread_count);
2994
#endif /* !defined(MYSQL_CLIENT) */