88
36
char internal_table_name[2]= "*";
89
37
char empty_c_string[1]= {0}; /* used for not defined db */
91
const char * const Session::DEFAULT_WHERE= "field list";
39
const char * const THD::DEFAULT_WHERE= "field list";
42
/*****************************************************************************
43
** Instansiate templates
44
*****************************************************************************/
46
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
48
template class List<Key>;
49
template class List_iterator<Key>;
50
template class List<Key_part_spec>;
51
template class List_iterator<Key_part_spec>;
52
template class List<Alter_drop>;
53
template class List_iterator<Alter_drop>;
54
template class List<Alter_column>;
55
template class List_iterator<Alter_column>;
58
/****************************************************************************
60
****************************************************************************/
62
extern "C" uchar *get_var_key(user_var_entry *entry, size_t *length,
63
bool not_used __attribute__((unused)))
65
*length= entry->name.length;
66
return (uchar*) entry->name.str;
69
extern "C" void free_user_var(user_var_entry *entry)
71
char *pos= (char*) entry+ALIGN_SIZE(sizeof(*entry));
72
if (entry->value && entry->value != pos)
73
my_free(entry->value, MYF(0));
74
my_free((char*) entry,MYF(0));
93
77
bool Key_part_spec::operator==(const Key_part_spec& other) const
95
79
return length == other.length &&
96
80
field_name.length == other.field_name.length &&
97
!my_strcasecmp(system_charset_info, field_name.str, other.field_name.str);
100
Open_tables_state::Open_tables_state(uint64_t version_arg) :
103
open_tables= temporary_tables= derived_tables= NULL;
104
extra_lock= lock= NULL;
81
!strcmp(field_name.str, other.field_name.str);
85
Construct an (almost) deep copy of this key. Only those
86
elements that are known to never change are not copied.
87
If out of memory, a partial copy is returned and an error is set
91
Key::Key(const Key &rhs, MEM_ROOT *mem_root)
93
key_create_info(rhs.key_create_info),
94
columns(rhs.columns, mem_root),
96
generated(rhs.generated)
98
list_copy_and_replace_each_value(columns, mem_root);
102
Construct an (almost) deep copy of this foreign key. Only those
103
elements that are known to never change are not copied.
104
If out of memory, a partial copy is returned and an error is set
108
Foreign_key::Foreign_key(const Foreign_key &rhs, MEM_ROOT *mem_root)
110
ref_table(rhs.ref_table),
111
ref_columns(rhs.ref_columns),
112
delete_opt(rhs.delete_opt),
113
update_opt(rhs.update_opt),
114
match_opt(rhs.match_opt)
116
list_copy_and_replace_each_value(ref_columns, mem_root);
120
Test if a foreign key (= generated key) is a prefix of the given key
121
(ignoring key name, key type and order of columns)
124
This is only used to test if an index for a FOREIGN KEY exists
127
We only compare field names
130
0 Generated key is a prefix of other key
134
bool foreign_key_prefix(Key *a, Key *b)
136
/* Ensure that 'a' is the generated key */
139
if (b->generated && a->columns.elements > b->columns.elements)
140
std::swap(a, b); // Put shorter key in 'a'
145
return true; // No foreign key
146
std::swap(a, b); // Put generated key in 'a'
149
/* Test if 'a' is a prefix of 'b' */
150
if (a->columns.elements > b->columns.elements)
151
return true; // Can't be prefix
153
List_iterator<Key_part_spec> col_it1(a->columns);
154
List_iterator<Key_part_spec> col_it2(b->columns);
155
const Key_part_spec *col1, *col2;
157
#ifdef ENABLE_WHEN_INNODB_CAN_HANDLE_SWAPED_FOREIGN_KEY_COLUMNS
158
while ((col1= col_it1++))
162
while ((col2= col_it2++))
171
return true; // Error
173
return false; // Is prefix
175
while ((col1= col_it1++))
178
if (!(*col1 == *col2))
181
return false; // Is prefix
186
/****************************************************************************
187
** Thread specific functions
188
****************************************************************************/
190
Open_tables_state::Open_tables_state(ulong version_arg)
191
:version(version_arg), state_flags(0U)
193
reset_open_tables_state();
108
197
The following functions form part of the C plugin API
110
int tmpfile(const char *prefix)
200
extern "C" int mysql_tmpfile(const char *prefix)
112
202
char filename[FN_REFLEN];
113
int fd = internal::create_temp_file(filename, drizzle_tmpdir.c_str(), prefix, MYF(MY_WME));
203
File fd = create_temp_file(filename, mysql_tmpdir, prefix,
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)
115
212
unlink(filename);
121
void **Session::getEngineData(const plugin::MonitoredInTransaction *monitored)
123
return static_cast<void **>(&ha_data[monitored->getId()].ha_ptr);
126
ResourceContext *Session::getResourceContext(const plugin::MonitoredInTransaction *monitored,
129
return &ha_data[monitored->getId()].resource_context[index];
132
int64_t session_test_options(const Session *session, int64_t test_options)
134
return session->options & test_options;
137
Session::Session(plugin::Client *client_arg, catalog::Instance::shared_ptr catalog_arg) :
138
Open_tables_state(refresh_version),
139
mem_root(&main_mem_root),
142
query(new std::string),
143
_schema(new std::string("")),
147
lock_id(&main_lock_id),
149
security_ctx(identifier::User::make_shared()),
150
_where(Session::DEFAULT_WHERE),
151
dbug_sentry(Session_SENTRY_MAGIC),
153
command(COM_CONNECT),
155
_epoch(boost::gregorian::date(1970,1,1)),
156
_connect_time(boost::posix_time::microsec_clock::universal_time()),
158
ha_data(plugin::num_trx_monitored_objects),
161
concurrent_execute_allowed(true),
162
arg_of_last_insert_id_function(false),
163
first_successful_insert_id_in_prev_stmt(0),
164
first_successful_insert_id_in_cur_stmt(0),
166
options(session_startup_options),
169
examined_row_count(0),
173
statement_id_counter(0),
177
_global_read_lock(NONE),
178
count_cuted_fields(CHECK_FIELD_ERROR_FOR_NULL),
180
some_tables_deleted(false),
183
is_fatal_error(false),
184
transaction_rollback_request(false),
185
is_fatal_sub_stmt_error(0),
186
tablespace_op(false),
187
derived_tables_processing(false),
190
transaction_message(NULL),
191
statement_message(NULL),
192
session_event_observers(NULL),
193
_catalog(catalog_arg),
196
client->setSession(this);
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)
275
Clear this diagnostics area.
277
Normally called at the end of a statement.
281
Diagnostics_area::reset_diagnostics_area()
283
can_overwrite_status= false;
284
/** Don't take chances in production */
290
m_total_warn_count= 0;
292
/** Tiny reset in debug mode to see garbage right away */
298
Set OK status -- ends commands that do not return a
299
result set, e.g. INSERT/UPDATE/DELETE.
303
Diagnostics_area::set_ok_status(THD *thd, ha_rows affected_rows_arg,
304
uint64_t last_insert_id_arg,
305
const char *message_arg)
309
In production, refuse to overwrite an error or a custom response
312
if (is_error() || is_disabled())
314
/** Only allowed to report success if has not yet reported an error */
316
m_server_status= thd->server_status;
317
m_total_warn_count= thd->total_warn_count;
318
m_affected_rows= affected_rows_arg;
319
m_last_insert_id= last_insert_id_arg;
321
strmake(m_message, message_arg, sizeof(m_message) - 1);
333
Diagnostics_area::set_eof_status(THD *thd)
335
/** Only allowed to report eof if has not yet reported an error */
339
In production, refuse to overwrite an error or a custom response
342
if (is_error() || is_disabled())
345
m_server_status= thd->server_status;
347
If inside a stored procedure, do not return the total
348
number of warnings, since they are not available to the client
351
m_total_warn_count= thd->total_warn_count;
361
Diagnostics_area::set_error_status(THD *thd __attribute__((unused)),
363
const char *message_arg)
366
Only allowed to report error if has not yet reported a success
367
The only exception is when we flush the message to the client,
368
an error can happen during the flush.
370
assert(! is_set() || can_overwrite_status);
372
In production, refuse to overwrite a custom response with an
378
m_sql_errno= sql_errno_arg;
379
strmake(m_message, message_arg, sizeof(m_message) - 1);
386
Mark the diagnostics area as 'DISABLED'.
388
This is used in rare cases when the COM_ command at hand sends a response
389
in a custom format. One example is the query cache, another is
394
Diagnostics_area::disable_status()
397
m_status= DA_DISABLED;
402
:Statement(&main_lex, &main_mem_root, CONVENTIONAL_EXECUTION,
403
/* statement id */ 0),
404
Open_tables_state(refresh_version), rli_fake(0),
405
lock_id(&main_lock_id),
406
user_time(0), in_sub_stmt(0),
407
binlog_table_maps(0), binlog_flags(0UL),
408
arg_of_last_insert_id_function(false),
409
first_successful_insert_id_in_prev_stmt(0),
410
first_successful_insert_id_in_prev_stmt_for_binlog(0),
411
first_successful_insert_id_in_cur_stmt(0),
412
stmt_depends_on_first_successful_insert_id_in_prev_stmt(false),
415
transaction_rollback_request(0),
416
is_fatal_sub_stmt_error(0),
421
derived_tables_processing(false),
199
427
Pass nominal parameters to init_alloc_root only to ensure that
200
428
the destructor works OK in case of an error. The main_mem_root
201
429
will be re-initialized in init_for_queries().
203
memory::init_sql_alloc(&main_mem_root, memory::ROOT_MIN_BLOCK_SIZE, 0);
431
init_sql_alloc(&main_mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0);
434
catalog= (char*)"std"; // the only catalog we have for now
435
main_security_ctx.init();
436
security_ctx= &main_security_ctx;
437
some_tables_deleted=no_errors=password= 0;
439
count_cuted_fields= CHECK_FIELD_IGNORE;
442
is_slave_error= thread_specific_used= false;
443
hash_clear(&handler_tables_hash);
204
446
cuted_fields= sent_row_count= row_count= 0L;
205
// Must be reset to handle error with Session's created for init of mysqld
449
statement_id_counter= 0UL;
450
// Must be reset to handle error with THD's created for init of mysqld
206
451
lex->current_select= 0;
452
start_time=(time_t) 0;
454
utime_after_lock= 0L;
207
457
memset(&variables, 0, sizeof(variables));
208
scoreboard_index= -1;
209
cleanup_done= abort_on_warning= no_warnings_for_error= false;
211
/* query_cache init */
463
db_charset= global_system_variables.collation_database;
464
memset(ha_data, 0, sizeof(ha_data));
466
binlog_evt_union.do_union= false;
468
dbug_sentry=THD_SENTRY_MAGIC;
470
client_capabilities= 0; // minimalistic client
471
system_thread= NON_SYSTEM_THREAD;
472
cleanup_done= abort_on_warning= no_warnings_for_error= 0;
473
peer_port= 0; // For SHOW PROCESSLIST
474
transaction.m_pending_rows_event= 0;
476
pthread_mutex_init(&LOCK_delete, MY_MUTEX_INIT_FAST);
215
478
/* Variables with default values */
216
479
proc_info="login";
218
plugin_sessionvar_init(this);
480
where= THD::DEFAULT_WHERE;
481
server_id = ::server_id;
487
/* Initialize sub structures */
488
init_sql_alloc(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE);
489
user_connect=(USER_CONN *)0;
490
hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
491
(hash_get_key) get_var_key,
492
(hash_free_key) free_user_var, 0);
494
/* For user vars replication*/
496
my_init_dynamic_array(&user_var_events,
497
sizeof(BINLOG_USER_VAR_EVENT *), 16, 16);
499
memset(&user_var_events, 0, sizeof(user_var_events));
502
protocol= &protocol_text; // Default protocol
503
protocol_text.init(this);
505
tablespace_op= false;
507
randominit(&rand, tmp + (ulong) &rand, tmp + (ulong) ::global_query_id);
508
substitute_null_with_insert_id = false;
509
thr_lock_info_init(&lock_info); /* safety: will be reset after start */
510
thr_lock_owner_init(&main_lock_id, &lock_info);
512
m_internal_handler= NULL;
516
void THD::push_internal_handler(Internal_error_handler *handler)
519
TODO: The current implementation is limited to 1 handler at a time only.
520
THD and sp_rcontext need to be modified to use a common handler stack.
522
assert(m_internal_handler == NULL);
523
m_internal_handler= handler;
527
bool THD::handle_error(uint sql_errno, const char *message,
528
DRIZZLE_ERROR::enum_warning_level level)
530
if (m_internal_handler)
532
return m_internal_handler->handle_error(sql_errno, message, level, this);
535
return false; // 'false', as per coding style
539
void THD::pop_internal_handler()
541
assert(m_internal_handler != NULL);
542
m_internal_handler= NULL;
546
void *thd_alloc(DRIZZLE_THD thd, unsigned int size)
548
return thd->alloc(size);
552
void *thd_calloc(DRIZZLE_THD thd, unsigned int size)
554
return thd->calloc(size);
558
char *thd_strdup(DRIZZLE_THD thd, const char *str)
560
return thd->strdup(str);
564
char *thd_strmake(DRIZZLE_THD thd, const char *str, unsigned int size)
566
return thd->strmake(str, size);
570
LEX_STRING *thd_make_lex_string(THD *thd, LEX_STRING *lex_str,
571
const char *str, unsigned int size,
572
int allocate_lex_string)
574
return thd->make_lex_string(lex_str, str, size,
575
(bool) allocate_lex_string);
579
void *thd_memdup(DRIZZLE_THD thd, const void* str, unsigned int size)
581
return thd->memdup(str, size);
585
void thd_get_xid(const DRIZZLE_THD thd, DRIZZLE_XID *xid)
587
*xid = *(DRIZZLE_XID *) &thd->transaction.xid_state.xid;
591
Init common variables that has to be reset on start and on change_user
596
pthread_mutex_lock(&LOCK_global_system_variables);
597
plugin_thdvar_init(this);
598
variables.time_format= date_time_format_copy((THD*) 0,
599
variables.time_format);
600
variables.date_format= date_time_format_copy((THD*) 0,
601
variables.date_format);
602
variables.datetime_format= date_time_format_copy((THD*) 0,
603
variables.datetime_format);
220
605
variables= global_system_variables above has reset
221
606
variables.pseudo_thread_id to 0. We need to correct it here to
222
607
avoid temporary tables replication failure.
224
609
variables.pseudo_thread_id= thread_id;
610
pthread_mutex_unlock(&LOCK_global_system_variables);
225
611
server_status= SERVER_STATUS_AUTOCOMMIT;
612
options= thd_startup_options;
227
614
if (variables.max_join_size == HA_POS_ERROR)
228
615
options |= OPTION_BIG_SELECTS;
230
617
options &= ~OPTION_BIG_SELECTS;
619
transaction.all.modified_non_trans_table= transaction.stmt.modified_non_trans_table= false;
232
620
open_options=ha_open_options;
233
update_lock_default= TL_WRITE;
621
update_lock_default= (variables.low_priority_updates ?
622
TL_WRITE_LOW_PRIORITY :
234
624
session_tx_isolation= (enum_tx_isolation) variables.tx_isolation;
235
625
warn_list.empty();
236
626
memset(warn_count, 0, sizeof(warn_count));
629
reset_current_stmt_binlog_row_based();
237
630
memset(&status_var, 0, sizeof(status_var));
239
/* Initialize sub structures */
240
memory::init_sql_alloc(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE);
242
substitute_null_with_insert_id = false;
243
lock_info.init(); /* safety: will be reset after start */
244
thr_lock_owner_init(&main_lock_id, &lock_info);
246
m_internal_handler= NULL;
248
plugin::EventObserver::registerSessionEvents(*this);
251
void Session::free_items()
254
/* This works because items are allocated with memory::sql_alloc() */
255
for (; free_list; free_list= next)
257
next= free_list->next;
258
free_list->delete_self();
262
void Session::push_internal_handler(Internal_error_handler *handler)
265
TODO: The current implementation is limited to 1 handler at a time only.
266
Session and sp_rcontext need to be modified to use a common handler stack.
268
assert(m_internal_handler == NULL);
269
m_internal_handler= handler;
272
bool Session::handle_error(drizzled::error_t sql_errno, const char *message,
273
DRIZZLE_ERROR::enum_warning_level level)
275
if (m_internal_handler)
277
return m_internal_handler->handle_error(sql_errno, message, level, this);
280
return false; // 'false', as per coding style
283
void Session::setAbort(bool arg)
285
mysys_var->abort= arg;
288
void Session::lockOnSys()
294
boost_unique_lock_t scopedLock(mysys_var->mutex);
295
if (mysys_var->current_cond)
297
mysys_var->current_mutex->lock();
298
mysys_var->current_cond->notify_all();
299
mysys_var->current_mutex->unlock();
303
void Session::pop_internal_handler()
305
assert(m_internal_handler != NULL);
306
m_internal_handler= NULL;
309
void Session::get_xid(DRIZZLE_XID *xid)
311
*xid = *(DRIZZLE_XID *) &transaction.xid_state.xid;
635
Init THD for query processing.
636
This has to be called once before we call mysql_parse.
637
See also comments in sql_class.h.
640
void THD::init_for_queries()
643
ha_enable_transaction(this,true);
645
reset_root_defaults(mem_root, variables.query_alloc_block_size,
646
variables.query_prealloc_size);
647
reset_root_defaults(&transaction.mem_root,
648
variables.trans_alloc_block_size,
649
variables.trans_prealloc_size);
650
transaction.xid_state.xid.null();
651
transaction.xid_state.in_thd=1;
314
655
/* Do operations that may take a long time */
316
void Session::cleanup(void)
657
void THD::cleanup(void)
318
assert(cleanup_done == false);
659
assert(cleanup_done == 0);
320
setKilled(KILL_CONNECTION);
661
killed= KILL_CONNECTION;
321
662
#ifdef ENABLE_WHEN_BINLOG_WILL_BE_ABLE_TO_PREPARE
322
663
if (transaction.xid_state.xa_state == XA_PREPARED)
460
839
assert(thread_stack);
462
currentSession().release();
463
currentSession().reset(this);
465
currentMemRoot().release();
466
currentMemRoot().reset(&mem_root);
841
if (my_pthread_setspecific_ptr(THR_THD, this) ||
842
my_pthread_setspecific_ptr(THR_MALLOC, &mem_root))
468
844
mysys_var=my_thread_var;
471
846
Let mysqld define the thread id (not mysys)
472
This allows us to move Session to different threads if needed.
847
This allows us to move THD to different threads if needed.
474
849
mysys_var->id= thread_id;
850
real_id= pthread_self(); // For debugging
477
We have to call thr_lock_info_init() again here as Session may have been
853
We have to call thr_lock_info_init() again here as THD may have been
478
854
created in another thread
486
Init Session for query processing.
487
This has to be called once before we call mysql_parse.
488
See also comments in session.h.
491
void Session::prepareForQueries()
493
if (variables.max_join_size == HA_POS_ERROR)
494
options |= OPTION_BIG_SELECTS;
496
version= refresh_version;
501
mem_root->reset_root_defaults(variables.query_alloc_block_size,
502
variables.query_prealloc_size);
503
transaction.xid_state.xid.null();
504
transaction.xid_state.in_session=1;
509
bool Session::initGlobals()
513
disconnect(ER_OUT_OF_RESOURCES);
514
status_var.aborted_connects++;
522
if (initGlobals() || authenticate())
530
while (not client->haveError() && getKilled() != KILL_CONNECTION)
532
if (not executeStatement())
539
bool Session::schedule(Session::shared_ptr &arg)
541
arg->scheduler= plugin::Scheduler::getScheduler();
542
assert(arg->scheduler);
546
long current_connections= connection_count;
548
if (current_connections > 0 and static_cast<uint64_t>(current_connections) > current_global_counters.max_used_connections)
550
current_global_counters.max_used_connections= static_cast<uint64_t>(connection_count);
553
current_global_counters.connections++;
554
arg->thread_id= arg->variables.pseudo_thread_id= global_thread_id++;
556
session::Cache::singleton().insert(arg);
558
if (unlikely(plugin::EventObserver::connectSession(*arg)))
560
// We should do something about an error...
563
if (plugin::Scheduler::getScheduler()->addSession(arg))
565
DRIZZLE_CONNECTION_START(arg->getSessionId());
566
char error_message_buff[DRIZZLE_ERRMSG_SIZE];
568
arg->setKilled(Session::KILL_CONNECTION);
570
arg->status_var.aborted_connects++;
572
/* Can't use my_error() since store_globals has not been called. */
573
/* TODO replace will better error message */
574
snprintf(error_message_buff, sizeof(error_message_buff),
575
ER(ER_CANT_CREATE_THREAD), 1);
576
arg->client->sendError(ER_CANT_CREATE_THREAD, error_message_buff);
586
Is this session viewable by the current user?
588
bool Session::isViewable(identifier::User::const_reference user_arg) const
590
return plugin::Authorization::isAuthorized(user_arg, this, false);
594
const char* Session::enter_cond(boost::condition_variable_any &cond, boost::mutex &mutex, const char* msg)
596
const char* old_msg = get_proc_info();
597
safe_mutex_assert_owner(mutex);
598
mysys_var->current_mutex = &mutex;
599
mysys_var->current_cond = &cond;
600
this->set_proc_info(msg);
604
void Session::exit_cond(const char* old_msg)
607
Putting the mutex unlock in exit_cond() ensures that
608
mysys_var->current_mutex is always unlocked _before_ mysys_var->mutex is
609
locked (if that would not be the case, you'll get a deadlock if someone
610
does a Session::awake() on you).
612
mysys_var->current_mutex->unlock();
613
boost_unique_lock_t scopedLock(mysys_var->mutex);
614
mysys_var->current_mutex = 0;
615
mysys_var->current_cond = 0;
616
this->set_proc_info(old_msg);
619
bool Session::authenticate()
621
if (client->authenticate())
624
status_var.aborted_connects++;
629
bool Session::checkUser(const std::string &passwd_str,
630
const std::string &in_db)
632
bool is_authenticated=
633
plugin::Authentication::isAuthenticated(user(), passwd_str);
635
if (is_authenticated != true)
637
status_var.access_denied++;
638
/* isAuthenticated has pushed the error message */
642
/* Change database if necessary */
643
if (not in_db.empty())
645
identifier::Schema identifier(in_db);
646
if (change_db(this, identifier))
648
/* change_db() has pushed the error message. */
653
password= not passwd_str.empty();
655
/* Ready to handle queries */
659
bool Session::executeStatement()
662
uint32_t packet_length;
664
enum enum_server_command l_command;
667
indicator of uninitialized lex => normal flow of errors handling
670
lex->current_select= 0;
672
main_da.reset_diagnostics_area();
674
if (client->readCommand(&l_packet, &packet_length) == false)
679
if (getKilled() == KILL_CONNECTION)
682
if (packet_length == 0)
685
l_command= static_cast<enum_server_command>(l_packet[0]);
687
if (command >= COM_END)
688
command= COM_END; // Wrong command
690
assert(packet_length);
691
return not dispatch_command(l_command, this, l_packet+1, (uint32_t) (packet_length-1));
694
bool Session::readAndStoreQuery(const char *in_packet, uint32_t in_packet_length)
696
/* Remove garbage at start and end of query */
697
while (in_packet_length > 0 && my_isspace(charset(), in_packet[0]))
702
const char *pos= in_packet + in_packet_length; /* Point at end null */
703
while (in_packet_length > 0 && (pos[-1] == ';' || my_isspace(charset() ,pos[-1])))
709
std::string *new_query= new std::string(in_packet, in_packet + in_packet_length);
710
// We can not be entirely sure _schema has a value
713
plugin::QueryRewriter::rewriteQuery(*_schema, *new_query);
715
query.reset(new_query);
716
_state.reset(new session::State(in_packet, in_packet_length));
721
bool Session::endTransaction(enum enum_mysql_completiontype completion)
725
TransactionServices &transaction_services= TransactionServices::singleton();
727
if (transaction.xid_state.xa_state != XA_NOTR)
729
my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[transaction.xid_state.xa_state]);
736
* We don't use endActiveTransaction() here to ensure that this works
737
* even if there is a problem with the OPTION_AUTO_COMMIT flag
738
* (Which of course should never happen...)
740
server_status&= ~SERVER_STATUS_IN_TRANS;
741
if (transaction_services.commitTransaction(*this, true))
743
options&= ~(OPTION_BEGIN);
746
do_release= 1; /* fall through */
747
case COMMIT_AND_CHAIN:
748
result= endActiveTransaction();
749
if (result == true && completion == COMMIT_AND_CHAIN)
750
result= startTransaction();
752
case ROLLBACK_RELEASE:
753
do_release= 1; /* fall through */
755
case ROLLBACK_AND_CHAIN:
757
server_status&= ~SERVER_STATUS_IN_TRANS;
758
if (transaction_services.rollbackTransaction(*this, true))
760
options&= ~(OPTION_BEGIN);
761
if (result == true && (completion == ROLLBACK_AND_CHAIN))
762
result= startTransaction();
766
my_error(ER_UNKNOWN_COM_ERROR, MYF(0));
772
my_error(static_cast<drizzled::error_t>(killed_errno()), MYF(0));
774
else if ((result == true) && do_release)
776
setKilled(Session::KILL_CONNECTION);
782
bool Session::endActiveTransaction()
785
TransactionServices &transaction_services= TransactionServices::singleton();
787
if (transaction.xid_state.xa_state != XA_NOTR)
789
my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[transaction.xid_state.xa_state]);
792
if (options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
794
server_status&= ~SERVER_STATUS_IN_TRANS;
795
if (transaction_services.commitTransaction(*this, true))
798
options&= ~(OPTION_BEGIN);
802
bool Session::startTransaction(start_transaction_option_t opt)
806
assert(! inTransaction());
808
options|= OPTION_BEGIN;
809
server_status|= SERVER_STATUS_IN_TRANS;
811
if (plugin::TransactionalStorageEngine::notifyStartTransaction(this, opt))
819
void Session::cleanup_after_query()
822
Reset rand_used so that detection of calls to rand() will save random
856
thr_lock_info_init(&lock_info);
865
THD::cleanup_after_query()
868
This function is used to reset thread data to its default state.
871
This function is not suitable for setting thread data to some
872
non-default values, as there is only one replication thread, so
873
different master threads may overwrite data of each other on
877
void THD::cleanup_after_query()
880
Reset rand_used so that detection of calls to rand() will save random
823
881
seeds if needed by the slave.
883
Do not reset rand_used if inside a stored function or trigger because
884
only the call to these operations is logged. Thus only the calling
885
statement needs to detect rand() calls made by its substatements. These
886
substatements must not set rand_used to 0 because it would remove the
887
detection of rand() by the calling statement.
889
if (!in_sub_stmt) /* stored functions and triggers are a special case */
826
891
/* Forget those values, for next binlogger: */
892
stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
827
893
auto_inc_intervals_in_cur_stmt_for_binlog.empty();
829
896
if (first_successful_insert_id_in_cur_stmt > 0)
831
898
/* set what LAST_INSERT_ID() will return */
832
first_successful_insert_id_in_prev_stmt= first_successful_insert_id_in_cur_stmt;
899
first_successful_insert_id_in_prev_stmt=
900
first_successful_insert_id_in_cur_stmt;
833
901
first_successful_insert_id_in_cur_stmt= 0;
834
902
substitute_null_with_insert_id= true;
837
arg_of_last_insert_id_function= false;
904
arg_of_last_insert_id_function= 0;
839
905
/* Free Items that were created during this execution */
843
_where= Session::DEFAULT_WHERE;
845
/* Reset the temporary shares we built */
846
for_each(temporary_shares.begin(),
847
temporary_shares.end(),
849
temporary_shares.clear();
908
where= THD::DEFAULT_WHERE;
853
913
Create a LEX_STRING in this connection.
1934
/***************************************************************************
1935
Dump of select to variables
1936
***************************************************************************/
1938
int select_dumpvar::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
1942
if (var_list.elements != list.elements)
1944
my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT,
1945
ER(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT), MYF(0));
1952
bool select_dumpvar::check_simple_select() const
1954
my_error(ER_SP_BAD_CURSOR_SELECT, MYF(0));
1959
void select_dumpvar::cleanup()
1965
void Query_arena::free_items()
1968
/* This works because items are allocated with sql_alloc() */
1969
for (; free_list; free_list= next)
1971
next= free_list->next;
1972
free_list->delete_self();
1974
/* Postcondition: free_list is 0 */
1979
void Query_arena::set_query_arena(Query_arena *set)
1981
mem_root= set->mem_root;
1982
free_list= set->free_list;
1987
void Query_arena::cleanup_stmt()
1989
assert("not implemented");
1527
Don't free mem_root, as mem_root is freed in the end of dispatch_command
1528
(once for any command).
1530
void Session::end_statement()
1996
Statement::Statement(LEX *lex_arg, MEM_ROOT *mem_root_arg,
1997
enum enum_state state_arg, ulong id_arg)
1998
:Query_arena(mem_root_arg, state_arg),
2000
mark_used_columns(MARK_COLUMNS_READ),
2011
void Statement::set_statement(Statement *stmt)
2014
mark_used_columns= stmt->mark_used_columns;
2017
query_length= stmt->query_length;
2022
Statement::set_n_backup_statement(Statement *stmt, Statement *backup)
2024
backup->set_statement(this);
2025
set_statement(stmt);
2030
void Statement::restore_backup_statement(Statement *stmt, Statement *backup)
2032
stmt->set_statement(this);
2033
set_statement(backup);
2038
void THD::end_statement()
1532
2040
/* Cleanup SQL processing state to reuse this statement in next query. */
1534
query_cache_key= ""; // reset the cache key
1535
resetResultsetMessage();
1538
bool Session::copy_db_to(char **p_db, size_t *p_db_length)
1541
if (_schema and _schema->empty())
1543
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1546
else if (not _schema)
1548
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1553
*p_db= strmake(_schema->c_str(), _schema->size());
1554
*p_db_length= _schema->size();
2044
/* Note that free_list is freed in cleanup_after_query() */
2047
Don't free mem_root, as mem_root is freed in the end of dispatch_command
2048
(once for any command).
2053
void THD::set_n_backup_active_arena(Query_arena *set, Query_arena *backup)
2055
assert(backup->is_backup_arena == false);
2057
backup->set_query_arena(this);
2058
set_query_arena(set);
2059
backup->is_backup_arena= true;
2064
void THD::restore_active_arena(Query_arena *set, Query_arena *backup)
2066
assert(backup->is_backup_arena);
2067
set->set_query_arena(this);
2068
set_query_arena(backup);
2069
backup->is_backup_arena= false;
2074
bool THD::copy_db_to(char **p_db, size_t *p_db_length)
2078
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
2081
*p_db= strmake(db, db_length);
2082
*p_db_length= db_length;
2087
bool select_dumpvar::send_data(List<Item> &items)
2089
List_iterator_fast<my_var> var_li(var_list);
2090
List_iterator<Item> it(items);
2094
if (unit->offset_limit_cnt)
2095
{ // using limit offset,count
2096
unit->offset_limit_cnt--;
2101
my_message(ER_TOO_MANY_ROWS, ER(ER_TOO_MANY_ROWS), MYF(0));
2104
while ((mv= var_li++) && (item= it++))
2108
Item_func_set_user_var *suv= new Item_func_set_user_var(mv->s, item);
2109
suv->fix_fields(thd, 0);
2114
return(thd->is_error());
2117
bool select_dumpvar::send_eof()
2120
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2121
ER_SP_FETCH_NO_DATA, ER(ER_SP_FETCH_NO_DATA));
2123
In order to remember the value of affected rows for ROW_COUNT()
2124
function, SELECT INTO has to have an own SQLCOM.
2125
TODO: split from SQLCOM_SELECT
2127
::my_ok(thd,row_count);
1559
2131
/****************************************************************************
1561
2133
****************************************************************************/
1563
void Tmp_Table_Param::init()
2135
void TMP_TABLE_PARAM::init()
1565
2137
field_count= sum_func_count= func_count= hidden_field_count= 0;
1566
2138
group_parts= group_length= group_null_parts= 0;
1567
2139
quick_group= 1;
1568
2140
table_charset= 0;
1569
2141
precomputed_group_by= 0;
2142
bit_fields_as_long= 0;
1572
void Tmp_Table_Param::cleanup(void)
2147
void thd_increment_bytes_sent(ulong length)
1574
/* Fix for Intel compiler */
1577
boost::checked_array_delete(copy_field);
1578
save_copy_field= save_copy_field_end= copy_field= copy_field_end= 0;
2149
THD *thd=current_thd;
2150
if (likely(thd != 0))
2151
{ /* current_thd==0 when close_connection() calls net_send_error() */
2152
thd->status_var.bytes_sent+= length;
1582
void Session::send_kill_message() const
1584
drizzled::error_t err= static_cast<drizzled::error_t>(killed_errno());
2157
void thd_increment_bytes_received(ulong length)
2159
current_thd->status_var.bytes_received+= length;
2163
void thd_increment_net_big_packet_count(ulong length)
2165
current_thd->status_var.net_big_packet_count+= length;
2168
void THD::send_kill_message() const
2170
int err= killed_errno();
1586
2172
my_message(err, ER(err), MYF(0));
1589
void Session::set_status_var_init()
2175
void THD::set_status_var_init()
1591
2177
memset(&status_var, 0, sizeof(status_var));
1595
void Session::set_db(const std::string &new_db)
1597
/* Do not reallocate memory if current chunk is big enough. */
1598
if (new_db.length())
1600
_schema.reset(new std::string(new_db));
1604
_schema.reset(new std::string(""));
2181
void Security_context::init()
2187
void Security_context::destroy()
2189
// If not pointer to constant
2195
void Security_context::skip_grants()
2197
/* privileges for the user are unknown everything is allowed */
2201
/****************************************************************************
2202
Handling of open and locked tables states.
2204
This is used when we want to open/lock (and then close) some tables when
2205
we already have a set of tables open and locked. We use these methods for
2206
access to mysql.proc table to find definitions of stored routines.
2207
****************************************************************************/
2209
void THD::reset_n_backup_open_tables_state(Open_tables_state *backup)
2211
backup->set_open_tables_state(this);
2212
reset_open_tables_state();
2213
state_flags|= Open_tables_state::BACKUPS_AVAIL;
2218
void THD::restore_backup_open_tables_state(Open_tables_state *backup)
2221
Before we will throw away current open tables state we want
2222
to be sure that it was properly cleaned up.
2224
assert(open_tables == 0 && temporary_tables == 0 &&
2225
handler_tables == 0 && derived_tables == 0 &&
2226
lock == 0 && locked_tables == 0);
2227
set_open_tables_state(backup);
2232
Check the killed state of a user thread
2233
@param thd user thread
2234
@retval 0 the user thread is active
2235
@retval 1 the user thread has been killed
2237
extern "C" int thd_killed(const DRIZZLE_THD thd)
2239
return(thd->killed);
2243
Return the thread id of a user thread
2244
@param thd user thread
2247
extern "C" unsigned long thd_get_thread_id(const DRIZZLE_THD thd)
2249
return((unsigned long)thd->thread_id);
2253
#ifdef INNODB_COMPATIBILITY_HOOKS
2254
extern "C" const struct charset_info_st *thd_charset(DRIZZLE_THD thd)
2256
return(thd->charset());
2259
extern "C" char **thd_query(DRIZZLE_THD thd)
2261
return(&thd->query);
2264
extern "C" int thd_slave_thread(const DRIZZLE_THD thd)
2266
return(thd->slave_thread);
2269
extern "C" int thd_non_transactional_update(const DRIZZLE_THD thd)
2271
return(thd->transaction.all.modified_non_trans_table);
2274
extern "C" int thd_binlog_format(const DRIZZLE_THD thd)
2276
return (int) thd->variables.binlog_format;
2279
extern "C" void thd_mark_transaction_to_rollback(DRIZZLE_THD thd, bool all)
2281
mark_transaction_to_rollback(thd, all);
2283
#endif // INNODB_COMPATIBILITY_HOOKS */
1610
2287
Mark transaction to rollback and mark error as fatal to a sub-statement.
1612
@param session Thread handle
2289
@param thd Thread handle
1613
2290
@param all true <=> rollback main transaction.
1615
void Session::markTransactionForRollback(bool all)
1617
is_fatal_sub_stmt_error= true;
1618
transaction_rollback_request= all;
1621
void Session::disconnect(enum error_t errcode)
1623
/* Allow any plugins to cleanup their session variables */
1624
plugin_sessionvar_cleanup(this);
1626
/* If necessary, log any aborted or unauthorized connections */
1627
if (getKilled() || client->wasAborted())
1629
status_var.aborted_threads++;
1632
if (client->wasAborted())
1634
if (not getKilled() && variables.log_warnings > 1)
1636
errmsg_printf(error::WARN, ER(ER_NEW_ABORTING_CONNECTION)
1638
, (_schema->empty() ? "unconnected" : _schema->c_str())
1639
, security_ctx->username().empty() == false ? security_ctx->username().c_str() : "unauthenticated"
1640
, security_ctx->address().c_str()
1641
, (main_da.is_error() ? main_da.message() : ER(ER_UNKNOWN_ERROR)));
1645
setKilled(Session::KILL_CONNECTION);
1647
if (client->isConnected())
1649
if (errcode != EE_OK)
1651
/*my_error(errcode, ER(errcode));*/
1652
client->sendError(errcode, ER(errcode));
1658
void Session::reset_for_next_command()
1663
Those two lines below are theoretically unneeded as
1664
Session::cleanup_after_query() should take care of this already.
1666
auto_inc_intervals_in_cur_stmt_for_binlog.empty();
1668
is_fatal_error= false;
1669
server_status&= ~ (SERVER_MORE_RESULTS_EXISTS |
1670
SERVER_QUERY_NO_INDEX_USED |
1671
SERVER_QUERY_NO_GOOD_INDEX_USED);
1674
main_da.reset_diagnostics_area();
1675
total_warn_count=0; // Warnings for this query
1676
sent_row_count= examined_row_count= 0;
1680
Close all temporary tables created by 'CREATE TEMPORARY TABLE' for thread
1683
void Open_tables_state::close_temporary_tables()
1688
if (not temporary_tables)
1691
for (table= temporary_tables; table; table= tmp_next)
1693
tmp_next= table->getNext();
1696
temporary_tables= NULL;
1700
unlink from session->temporary tables and close temporary table
1703
void Open_tables_state::close_temporary_table(Table *table)
1705
if (table->getPrev())
1707
table->getPrev()->setNext(table->getNext());
1708
if (table->getPrev()->getNext())
1710
table->getNext()->setPrev(table->getPrev());
1715
/* removing the item from the list */
1716
assert(table == temporary_tables);
1718
slave must reset its temporary list pointer to zero to exclude
1719
passing non-zero value to end_slave via rli->save_temporary_tables
1720
when no temp tables opened, see an invariant below.
1722
temporary_tables= table->getNext();
1723
if (temporary_tables)
1725
table->getNext()->setPrev(NULL);
1732
Close and drop a temporary table
1735
This dosn't unlink table from session->temporary
1736
If this is needed, use close_temporary_table()
1739
void Open_tables_state::nukeTable(Table *table)
1741
plugin::StorageEngine *table_type= table->getShare()->db_type();
1743
table->free_io_cache();
1744
table->delete_table();
1746
identifier::Table identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), table->getShare()->getPath());
1747
rm_temporary_table(table_type, identifier);
1749
boost::checked_delete(table->getMutableShare());
1751
boost::checked_delete(table);
1754
/** Clear most status variables. */
1755
extern time_t flush_status_time;
1757
void Session::refresh_status()
1759
/* Reset thread's status variables */
1760
memset(&status_var, 0, sizeof(status_var));
1762
flush_status_time= time((time_t*) 0);
1763
current_global_counters.max_used_connections= 1; /* We set it to one, because we know we exist */
1764
current_global_counters.connections= 0;
1767
user_var_entry *Session::getVariable(LEX_STRING &name, bool create_if_not_exists)
1769
return getVariable(std::string(name.str, name.length), create_if_not_exists);
1772
user_var_entry *Session::getVariable(const std::string &name, bool create_if_not_exists)
1777
UserVars::iterator iter= user_vars.find(name);
1778
if (iter != user_vars.end())
1779
return (*iter).second;
1781
if (not create_if_not_exists)
1784
user_var_entry *entry= NULL;
1785
entry= new (nothrow) user_var_entry(name.c_str(), query_id);
1790
std::pair<UserVars::iterator, bool> returnable= user_vars.insert(make_pair(name, entry));
1792
if (not returnable.second)
1794
boost::checked_delete(entry);
1800
void Session::setVariable(const std::string &name, const std::string &value)
1802
user_var_entry *updateable_var= getVariable(name.c_str(), true);
1805
updateable_var->update_hash(false,
1806
(void*)value.c_str(),
1807
static_cast<uint32_t>(value.length()), STRING_RESULT,
1809
DERIVATION_IMPLICIT, false);
1813
void Open_tables_state::mark_temp_tables_as_free_for_reuse()
1815
for (Table *table= temporary_tables ; table ; table= table->getNext())
1817
if (table->query_id == getQueryId())
1820
table->cursor->ha_reset();
1825
void Session::mark_used_tables_as_free_for_reuse(Table *table)
1827
for (; table ; table= table->getNext())
1829
if (table->query_id == getQueryId())
1832
table->cursor->ha_reset();
1838
Unlocks tables and frees derived tables.
1839
Put all normal tables used by thread in free list.
1841
It will only close/mark as free for reuse tables opened by this
1842
substatement, it will also check if we are closing tables after
1843
execution of complete query (i.e. we are on upper level) and will
1844
leave prelocked mode if needed.
1846
void Session::close_thread_tables()
1848
clearDerivedTables();
1851
Mark all temporary tables used by this statement as free for reuse.
1853
mark_temp_tables_as_free_for_reuse();
1855
Let us commit transaction for statement. Since in 5.0 we only have
1856
one statement transaction and don't allow several nested statement
1857
transactions this call will do nothing if we are inside of stored
1858
function or trigger (i.e. statement transaction is already active and
1859
does not belong to statement for which we do close_thread_tables()).
1860
TODO: This should be fixed in later releases.
1863
TransactionServices &transaction_services= TransactionServices::singleton();
1864
main_da.can_overwrite_status= true;
1865
transaction_services.autocommitOrRollback(*this, is_error());
1866
main_da.can_overwrite_status= false;
1867
transaction.stmt.reset();
1873
For RBR we flush the pending event just before we unlock all the
1874
tables. This means that we are at the end of a topmost
1875
statement, so we ensure that the STMT_END_F flag is set on the
1876
pending event. For statements that are *inside* stored
1877
functions, the pending event will not be flushed: that will be
1878
handled either before writing a query log event (inside
1879
binlog_query()) or when preparing a pending event.
1885
Note that we need to hold table::Cache::singleton().mutex() while changing the
1886
open_tables list. Another thread may work on it.
1887
(See: table::Cache::singleton().removeTable(), wait_completed_table())
1888
Closing a MERGE child before the parent would be fatal if the
1889
other thread tries to abort the MERGE lock in between.
1892
close_open_tables();
1895
void Session::close_tables_for_reopen(TableList **tables)
1898
If table list consists only from tables from prelocking set, table list
1899
for new attempt should be empty, so we have to update list's root pointer.
1901
if (lex->first_not_own_table() == *tables)
1903
lex->chop_off_not_own_tables();
1904
for (TableList *tmp= *tables; tmp; tmp= tmp->next_global)
1906
close_thread_tables();
1909
bool Session::openTablesLock(TableList *tables)
1916
if (open_tables_from_list(&tables, &counter))
1919
if (not lock_tables(tables, counter, &need_reopen))
1922
if (not need_reopen)
1925
close_tables_for_reopen(&tables);
1928
if ((handle_derived(lex, &derived_prepare) || (handle_derived(lex, &derived_filling))))
1935
@note "best_effort" is used in cases were if a failure occurred on this
1936
operation it would not be surprising because we are only removing because there
1937
might be an issue (lame engines).
1940
bool Open_tables_state::rm_temporary_table(const identifier::Table &identifier, bool best_effort)
1942
if (not plugin::StorageEngine::dropTable(*static_cast<Session *>(this), identifier))
1944
if (not best_effort)
1947
identifier.getSQLPath(path);
1948
errmsg_printf(error::WARN, _("Could not remove temporary table: '%s', error: %d"),
1949
path.c_str(), errno);
1958
bool Open_tables_state::rm_temporary_table(plugin::StorageEngine *base, const identifier::Table &identifier)
1960
drizzled::error_t error;
1963
if (not plugin::StorageEngine::dropTable(*static_cast<Session *>(this), *base, identifier, error))
1966
identifier.getSQLPath(path);
1967
errmsg_printf(error::WARN, _("Could not remove temporary table: '%s', error: %d"),
1968
path.c_str(), error);
1977
@note this will be removed, I am looking through Hudson to see if it is finding
1978
any tables that are missed during cleanup.
1980
void Open_tables_state::dumpTemporaryTableNames(const char *foo)
1984
if (not temporary_tables)
1987
cerr << "Begin Run: " << foo << "\n";
1988
for (table= temporary_tables; table; table= table->getNext())
1990
bool have_proto= false;
1992
message::Table *proto= table->getShare()->getTableMessage();
1993
if (table->getShare()->getTableMessage())
1996
const char *answer= have_proto ? "true" : "false";
2000
cerr << "\tTable Name " << table->getShare()->getSchemaName() << "." << table->getShare()->getTableName() << " : " << answer << "\n";
2001
cerr << "\t\t Proto " << proto->schema() << " " << proto->name() << "\n";
2005
cerr << "\tTabl;e Name " << table->getShare()->getSchemaName() << "." << table->getShare()->getTableName() << " : " << answer << "\n";
2010
table::Singular *Session::getInstanceTable()
2012
temporary_shares.push_back(new table::Singular()); // This will not go into the tableshare cache, so no key is used.
2014
table::Singular *tmp_share= temporary_shares.back();
2023
Create a reduced Table object with properly set up Field list from a
2024
list of field definitions.
2026
The created table doesn't have a table Cursor associated with
2027
it, has no keys, no group/distinct, no copy_funcs array.
2028
The sole purpose of this Table object is to use the power of Field
2029
class to read/write data to/from table->getInsertRecord(). Then one can store
2030
the record in any container (RB tree, hash, etc).
2031
The table is created in Session mem_root, so are the table's fields.
2032
Consequently, if you don't BLOB fields, you don't need to free it.
2034
@param session connection handle
2035
@param field_list list of column definitions
2038
0 if out of memory, Table object in case of success
2040
table::Singular *Session::getInstanceTable(List<CreateField> &field_list)
2042
temporary_shares.push_back(new table::Singular(this, field_list)); // This will not go into the tableshare cache, so no key is used.
2044
table::Singular *tmp_share= temporary_shares.back();
2053
static const std::string NONE= "NONE";
2054
static const std::string GOT_GLOBAL_READ_LOCK= "HAS GLOBAL READ LOCK";
2055
static const std::string MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT= "HAS GLOBAL READ LOCK WITH BLOCKING COMMIT";
2057
const std::string &type(drizzled::Session::global_read_lock_t type)
2063
case Session::GOT_GLOBAL_READ_LOCK:
2064
return GOT_GLOBAL_READ_LOCK;
2065
case Session::MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT:
2066
return MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT;
2070
size_t max_string_length(drizzled::Session::global_read_lock_t)
2072
return MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT.size();
2075
} /* namespace display */
2077
} /* namespace drizzled */
2293
void mark_transaction_to_rollback(THD *thd, bool all)
2297
thd->is_fatal_sub_stmt_error= true;
2298
thd->transaction_rollback_request= all;
2301
/***************************************************************************
2302
Handling of XA id cacheing
2303
***************************************************************************/
2305
pthread_mutex_t LOCK_xid_cache;
2308
extern "C" uchar *xid_get_hash_key(const uchar *, size_t *, bool);
2309
extern "C" void xid_free_hash(void *);
2311
uchar *xid_get_hash_key(const uchar *ptr, size_t *length,
2312
bool not_used __attribute__((unused)))
2314
*length=((XID_STATE*)ptr)->xid.key_length();
2315
return ((XID_STATE*)ptr)->xid.key();
2318
void xid_free_hash(void *ptr)
2320
if (!((XID_STATE*)ptr)->in_thd)
2321
my_free((uchar*)ptr, MYF(0));
2324
bool xid_cache_init()
2326
pthread_mutex_init(&LOCK_xid_cache, MY_MUTEX_INIT_FAST);
2327
return hash_init(&xid_cache, &my_charset_bin, 100, 0, 0,
2328
xid_get_hash_key, xid_free_hash, 0) != 0;
2331
void xid_cache_free()
2333
if (hash_inited(&xid_cache))
2335
hash_free(&xid_cache);
2336
pthread_mutex_destroy(&LOCK_xid_cache);
2340
XID_STATE *xid_cache_search(XID *xid)
2342
pthread_mutex_lock(&LOCK_xid_cache);
2343
XID_STATE *res=(XID_STATE *)hash_search(&xid_cache, xid->key(), xid->key_length());
2344
pthread_mutex_unlock(&LOCK_xid_cache);
2349
bool xid_cache_insert(XID *xid, enum xa_states xa_state)
2353
pthread_mutex_lock(&LOCK_xid_cache);
2354
if (hash_search(&xid_cache, xid->key(), xid->key_length()))
2356
else if (!(xs=(XID_STATE *)my_malloc(sizeof(*xs), MYF(MY_WME))))
2360
xs->xa_state=xa_state;
2363
res=my_hash_insert(&xid_cache, (uchar*)xs);
2365
pthread_mutex_unlock(&LOCK_xid_cache);
2370
bool xid_cache_insert(XID_STATE *xid_state)
2372
pthread_mutex_lock(&LOCK_xid_cache);
2373
assert(hash_search(&xid_cache, xid_state->xid.key(),
2374
xid_state->xid.key_length())==0);
2375
bool res=my_hash_insert(&xid_cache, (uchar*)xid_state);
2376
pthread_mutex_unlock(&LOCK_xid_cache);
2381
void xid_cache_delete(XID_STATE *xid_state)
2383
pthread_mutex_lock(&LOCK_xid_cache);
2384
hash_delete(&xid_cache, (uchar *)xid_state);
2385
pthread_mutex_unlock(&LOCK_xid_cache);
2389
Implementation of interface to write rows to the binary log through the
2390
thread. The thread is responsible for writing the rows it has
2391
inserted/updated/deleted.
2394
#ifndef DRIZZLE_CLIENT
2397
Template member function for ensuring that there is an rows log
2398
event of the apropriate type before proceeding.
2401
- Events of type 'RowEventT' have the type code 'type_code'.
2404
If a non-NULL pointer is returned, the pending event for thread 'thd' will
2405
be an event of type 'RowEventT' (which have the type code 'type_code')
2406
will either empty or have enough space to hold 'needed' bytes. In
2407
addition, the columns bitmap will be correct for the row, meaning that
2408
the pending event will be flushed if the columns in the event differ from
2409
the columns suppled to the function.
2412
If no error, a non-NULL pending event (either one which already existed or
2413
the newly created one).
2417
template <class RowsEventT> Rows_log_event*
2418
THD::binlog_prepare_pending_rows_event(Table* table, uint32_t serv_id,
2420
bool is_transactional,
2421
RowsEventT *hint __attribute__((unused)))
2423
/* Pre-conditions */
2424
assert(table->s->table_map_id != UINT32_MAX);
2426
/* Fetch the type code for the RowsEventT template parameter */
2427
int const type_code= RowsEventT::TYPE_CODE;
2430
There is no good place to set up the transactional data, so we
2433
if (binlog_setup_trx_data())
2436
Rows_log_event* pending= binlog_get_pending_rows_event();
2438
if (unlikely(pending && !pending->is_valid()))
2442
Check if the current event is non-NULL and a write-rows
2443
event. Also check if the table provided is mapped: if it is not,
2444
then we have switched to writing to a new table.
2445
If there is no pending event, we need to create one. If there is a pending
2446
event, but it's not about the same table id, or not of the same type
2447
(between Write, Update and Delete), or not the same affected columns, or
2448
going to be too big, flush this event to disk and create a new pending
2451
The last test is necessary for the Cluster injector to work
2452
correctly. The reason is that the Cluster can inject two write
2453
rows with different column bitmaps if there is an insert followed
2454
by an update in the same transaction, and these are grouped into a
2455
single epoch/transaction when fed to the injector.
2457
TODO: Fix the code so that the last test can be removed.
2460
pending->server_id != serv_id ||
2461
pending->get_table_id() != table->s->table_map_id ||
2462
pending->get_type_code() != type_code ||
2463
pending->get_data_size() + needed > opt_binlog_rows_event_max_size ||
2464
!bitmap_cmp(pending->get_cols(), table->write_set))
2466
/* Create a new RowsEventT... */
2467
Rows_log_event* const
2468
ev= new RowsEventT(this, table, table->s->table_map_id,
2472
ev->server_id= serv_id; // I don't like this, it's too easy to forget.
2474
flush the pending event and replace it with the newly created
2477
if (unlikely(mysql_bin_log.flush_and_set_pending_rows_event(this, ev)))
2483
return(ev); /* This is the new pending event */
2485
return(pending); /* This is the current pending event */
2488
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
2490
Instantiate the versions we need, we have -fno-implicit-template as
2493
template Rows_log_event*
2494
THD::binlog_prepare_pending_rows_event(Table*, uint32_t, size_t, bool,
2495
Write_rows_log_event*);
2497
template Rows_log_event*
2498
THD::binlog_prepare_pending_rows_event(Table*, uint32_t, size_t, bool,
2499
Delete_rows_log_event *);
2501
template Rows_log_event*
2502
THD::binlog_prepare_pending_rows_event(Table*, uint32_t, size_t, bool,
2503
Update_rows_log_event *);
2508
Class to handle temporary allocation of memory for row data.
2510
The responsibilities of the class is to provide memory for
2511
packing one or two rows of packed data (depending on what
2512
constructor is called).
2514
In order to make the allocation more efficient for "simple" rows,
2515
i.e., rows that do not contain any blobs, a pointer to the
2516
allocated memory is of memory is stored in the table structure
2517
for simple rows. If memory for a table containing a blob field
2518
is requested, only memory for that is allocated, and subsequently
2519
released when the object is destroyed.
2522
class Row_data_memory {
2525
Build an object to keep track of a block-local piece of memory
2526
for storing a row of data.
2529
Table where the pre-allocated memory is stored.
2532
Length of data that is needed, if the record contain blobs.
2534
Row_data_memory(Table *table, size_t const len1)
2537
m_alloc_checked= false;
2538
allocate_memory(table, len1);
2539
m_ptr[0]= has_memory() ? m_memory : 0;
2543
Row_data_memory(Table *table, size_t const len1, size_t const len2)
2546
m_alloc_checked= false;
2547
allocate_memory(table, len1 + len2);
2548
m_ptr[0]= has_memory() ? m_memory : 0;
2549
m_ptr[1]= has_memory() ? m_memory + len1 : 0;
2554
if (m_memory != 0 && m_release_memory_on_destruction)
2555
my_free((uchar*) m_memory, MYF(MY_WME));
2559
Is there memory allocated?
2561
@retval true There is memory allocated
2562
@retval false Memory allocation failed
2564
bool has_memory() const {
2565
m_alloc_checked= true;
2566
return m_memory != 0;
2571
assert(s < sizeof(m_ptr)/sizeof(*m_ptr));
2572
assert(m_ptr[s] != 0);
2573
assert(m_alloc_checked == true);
2578
void allocate_memory(Table *const table, size_t const total_length)
2580
if (table->s->blob_fields == 0)
2583
The maximum length of a packed record is less than this
2584
length. We use this value instead of the supplied length
2585
when allocating memory for records, since we don't know how
2586
the memory will be used in future allocations.
2588
Since table->s->reclength is for unpacked records, we have
2589
to add two bytes for each field, which can potentially be
2590
added to hold the length of a packed field.
2592
size_t const maxlen= table->s->reclength + 2 * table->s->fields;
2595
Allocate memory for two records if memory hasn't been
2596
allocated. We allocate memory for two records so that it can
2597
be used when processing update rows as well.
2599
if (table->write_row_record == 0)
2600
table->write_row_record=
2601
(uchar *) alloc_root(&table->mem_root, 2 * maxlen);
2602
m_memory= table->write_row_record;
2603
m_release_memory_on_destruction= false;
2607
m_memory= (uchar *) my_malloc(total_length, MYF(MY_WME));
2608
m_release_memory_on_destruction= true;
2612
mutable bool m_alloc_checked;
2613
bool m_release_memory_on_destruction;
2620
int THD::binlog_write_row(Table* table, bool is_trans,
2621
uchar const *record)
2623
assert(current_stmt_binlog_row_based && mysql_bin_log.is_open());
2626
Pack records into format for transfer. We are allocating more
2627
memory than needed, but that doesn't matter.
2629
Row_data_memory memory(table, table->max_row_length(record));
2630
if (!memory.has_memory())
2631
return HA_ERR_OUT_OF_MEM;
2633
uchar *row_data= memory.slot(0);
2635
size_t const len= pack_row(table, table->write_set, row_data, record);
2637
Rows_log_event* const ev=
2638
binlog_prepare_pending_rows_event(table, server_id, len, is_trans,
2639
static_cast<Write_rows_log_event*>(0));
2641
if (unlikely(ev == 0))
2642
return HA_ERR_OUT_OF_MEM;
2644
return ev->add_row_data(row_data, len);
2647
int THD::binlog_update_row(Table* table, bool is_trans,
2648
const uchar *before_record,
2649
const uchar *after_record)
2651
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);
2656
Row_data_memory row_data(table, before_maxlen, after_maxlen);
2657
if (!row_data.has_memory())
2658
return HA_ERR_OUT_OF_MEM;
2660
uchar *before_row= row_data.slot(0);
2661
uchar *after_row= row_data.slot(1);
2663
size_t const before_size= pack_row(table, table->read_set, before_row,
2665
size_t const after_size= pack_row(table, table->write_set, after_row,
2668
Rows_log_event* const ev=
2669
binlog_prepare_pending_rows_event(table, server_id,
2670
before_size + after_size, is_trans,
2671
static_cast<Update_rows_log_event*>(0));
2673
if (unlikely(ev == 0))
2674
return HA_ERR_OUT_OF_MEM;
2677
ev->add_row_data(before_row, before_size) ||
2678
ev->add_row_data(after_row, after_size);
2681
int THD::binlog_delete_row(Table* table, bool is_trans,
2682
uchar const *record)
2684
assert(current_stmt_binlog_row_based && mysql_bin_log.is_open());
2687
Pack records into format for transfer. We are allocating more
2688
memory than needed, but that doesn't matter.
2690
Row_data_memory memory(table, table->max_row_length(record));
2691
if (unlikely(!memory.has_memory()))
2692
return HA_ERR_OUT_OF_MEM;
2694
uchar *row_data= memory.slot(0);
2696
size_t const len= pack_row(table, table->read_set, row_data, record);
2698
Rows_log_event* const ev=
2699
binlog_prepare_pending_rows_event(table, server_id, len, is_trans,
2700
static_cast<Delete_rows_log_event*>(0));
2702
if (unlikely(ev == 0))
2703
return HA_ERR_OUT_OF_MEM;
2705
return ev->add_row_data(row_data, len);
2709
int THD::binlog_flush_pending_rows_event(bool stmt_end)
2712
We shall flush the pending event even if we are not in row-based
2713
mode: it might be the case that we left row-based mode before
2714
flushing anything (e.g., if we have explicitly locked tables).
2716
if (!mysql_bin_log.is_open())
2720
Mark the event as the last event of a statement if the stmt_end
2724
if (Rows_log_event *pending= binlog_get_pending_rows_event())
2728
pending->set_flags(Rows_log_event::STMT_END_F);
2729
pending->flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F;
2730
binlog_table_maps= 0;
2733
error= mysql_bin_log.flush_and_set_pending_rows_event(this, 0);
2741
Member function that will log query, either row-based or
2742
statement-based depending on the value of the 'current_stmt_binlog_row_based'
2743
the value of the 'qtype' flag.
2745
This function should be called after the all calls to ha_*_row()
2746
functions have been issued, but before tables are unlocked and
2750
There shall be no writes to any system table after calling
2751
binlog_query(), so these writes has to be moved to before the call
2752
of binlog_query() for correct functioning.
2754
This is necessesary not only for RBR, but the master might crash
2755
after binlogging the query but before changing the system tables.
2756
This means that the slave and the master are not in the same state
2757
(after the master has restarted), so therefore we have to
2758
eliminate this problem.
2761
Error code, or 0 if no error.
2763
int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg,
2764
ulong query_len, bool is_trans, bool suppress_use,
2765
THD::killed_state killed_status_arg)
2767
assert(query_arg && mysql_bin_log.is_open());
2769
if (int error= binlog_flush_pending_rows_event(true))
2773
If we are in statement mode and trying to log an unsafe statement,
2774
we should print a warning.
2776
if (lex->is_stmt_unsafe() &&
2777
variables.binlog_format == BINLOG_FORMAT_STMT)
2779
assert(this->query != NULL);
2780
push_warning(this, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2781
ER_BINLOG_UNSAFE_STATEMENT,
2782
ER(ER_BINLOG_UNSAFE_STATEMENT));
2783
if (!(binlog_flags & BINLOG_FLAG_UNSAFE_STMT_PRINTED))
2785
char warn_buf[DRIZZLE_ERRMSG_SIZE];
2786
snprintf(warn_buf, DRIZZLE_ERRMSG_SIZE, "%s Statement: %s",
2787
ER(ER_BINLOG_UNSAFE_STATEMENT), this->query);
2788
sql_print_warning(warn_buf);
2789
binlog_flags|= BINLOG_FLAG_UNSAFE_STMT_PRINTED;
2794
case THD::ROW_QUERY_TYPE:
2795
if (current_stmt_binlog_row_based)
2797
/* Otherwise, we fall through */
2798
case THD::DRIZZLE_QUERY_TYPE:
2800
Using this query type is a conveniece hack, since we have been
2801
moving back and forth between using RBR for replication of
2802
system tables and not using it.
2804
Make sure to change in check_table_binlog_row_based() according
2805
to how you treat this.
2807
case THD::STMT_QUERY_TYPE:
2809
The DRIZZLE_LOG::write() function will set the STMT_END_F flag and
2810
flush the pending rows event if necessary.
2813
Query_log_event qinfo(this, query_arg, query_len, is_trans, suppress_use,
2815
qinfo.flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F;
2817
Binlog table maps will be irrelevant after a Query_log_event
2818
(they are just removed on the slave side) so after the query
2819
log event is written to the binary log, we pretend that no
2820
table maps were written.
2822
int error= mysql_bin_log.write(&qinfo);
2823
binlog_table_maps= 0;
2828
case THD::QUERY_TYPE_COUNT:
2830
assert(0 <= qtype && qtype < QUERY_TYPE_COUNT);
2835
bool Discrete_intervals_list::append(uint64_t start, uint64_t val,
2838
/* first, see if this can be merged with previous */
2839
if ((head == NULL) || tail->merge_if_contiguous(start, val, incr))
2841
/* it cannot, so need to add a new interval */
2842
Discrete_interval *new_interval= new Discrete_interval(start, val, incr);
2843
return(append(new_interval));
2848
bool Discrete_intervals_list::append(Discrete_interval *new_interval)
2850
if (unlikely(new_interval == NULL))
2853
head= current= new_interval;
2855
tail->next= new_interval;
2861
#endif /* !defined(DRIZZLE_CLIENT) */