99
96
!strcmp(field_name.str, other.field_name.str);
102
Open_tables_state::Open_tables_state(uint64_t version_arg)
103
:version(version_arg), backups_available(false)
100
Construct an (almost) deep copy of this key. Only those
101
elements that are known to never change are not copied.
102
If out of memory, a partial copy is returned and an error is set
106
Key::Key(const Key &rhs, MEM_ROOT *mem_root)
108
key_create_info(rhs.key_create_info),
109
columns(rhs.columns, mem_root),
111
generated(rhs.generated)
113
list_copy_and_replace_each_value(columns, mem_root);
117
Construct an (almost) deep copy of this foreign key. Only those
118
elements that are known to never change are not copied.
119
If out of memory, a partial copy is returned and an error is set
123
Foreign_key::Foreign_key(const Foreign_key &rhs, MEM_ROOT *mem_root)
125
ref_table(rhs.ref_table),
126
ref_columns(rhs.ref_columns),
127
delete_opt(rhs.delete_opt),
128
update_opt(rhs.update_opt),
129
match_opt(rhs.match_opt)
131
list_copy_and_replace_each_value(ref_columns, mem_root);
135
Test if a foreign key (= generated key) is a prefix of the given key
136
(ignoring key name, key type and order of columns)
139
This is only used to test if an index for a FOREIGN KEY exists
142
We only compare field names
145
0 Generated key is a prefix of other key
149
bool foreign_key_prefix(Key *a, Key *b)
151
/* Ensure that 'a' is the generated key */
154
if (b->generated && a->columns.elements > b->columns.elements)
155
std::swap(a, b); // Put shorter key in 'a'
160
return true; // No foreign key
161
std::swap(a, b); // Put generated key in 'a'
164
/* Test if 'a' is a prefix of 'b' */
165
if (a->columns.elements > b->columns.elements)
166
return true; // Can't be prefix
168
List_iterator<Key_part_spec> col_it1(a->columns);
169
List_iterator<Key_part_spec> col_it2(b->columns);
170
const Key_part_spec *col1, *col2;
172
#ifdef ENABLE_WHEN_INNODB_CAN_HANDLE_SWAPED_FOREIGN_KEY_COLUMNS
173
while ((col1= col_it1++))
177
while ((col2= col_it2++))
186
return true; // Error
188
return false; // Is prefix
190
while ((col1= col_it1++))
193
if (!(*col1 == *col2))
196
return false; // Is prefix
202
Check if the foreign key options are compatible with columns
203
on which the FK is created.
209
bool Foreign_key::validate(List<Create_field> &table_fields)
211
Create_field *sql_field;
212
Key_part_spec *column;
213
List_iterator<Key_part_spec> cols(columns);
214
List_iterator<Create_field> it(table_fields);
215
while ((column= cols++))
218
while ((sql_field= it++) &&
219
my_strcasecmp(system_charset_info,
220
column->field_name.str,
221
sql_field->field_name)) {}
224
my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name.str);
227
if (type == Key::FOREIGN_KEY && sql_field->vcol_info)
229
if (delete_opt == FK_OPTION_SET_NULL)
231
my_error(ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN, MYF(0),
232
"ON DELETE SET NULL");
235
if (update_opt == FK_OPTION_SET_NULL)
237
my_error(ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN, MYF(0),
238
"ON UPDATE SET NULL");
241
if (update_opt == FK_OPTION_CASCADE)
243
my_error(ER_WRONG_FK_OPTION_FOR_VIRTUAL_COLUMN, MYF(0),
244
"ON UPDATE CASCADE");
253
/****************************************************************************
254
** Thread specific functions
255
****************************************************************************/
257
Open_tables_state::Open_tables_state(ulong version_arg)
258
:version(version_arg), state_flags(0U)
105
260
reset_open_tables_state();
174
336
return (int) session->variables.tx_isolation;
177
Session::Session(plugin::Client *client_arg)
179
Open_tables_state(refresh_version),
180
mem_root(&main_mem_root),
186
lock_id(&main_lock_id),
188
ha_data(plugin::num_trx_monitored_objects),
189
arg_of_last_insert_id_function(false),
190
first_successful_insert_id_in_prev_stmt(0),
191
first_successful_insert_id_in_cur_stmt(0),
194
some_tables_deleted(false),
197
is_fatal_error(false),
198
transaction_rollback_request(false),
199
is_fatal_sub_stmt_error(0),
200
derived_tables_processing(false),
201
tablespace_op(false),
204
transaction_message(NULL),
205
statement_message(NULL)
207
memset(process_list_info, 0, PROCESS_LIST_WIDTH);
208
client->setSession(this);
340
void session_inc_row_count(Session *session)
342
session->row_count++;
346
Clear this diagnostics area.
348
Normally called at the end of a statement.
352
Diagnostics_area::reset_diagnostics_area()
354
can_overwrite_status= false;
355
/** Don't take chances in production */
361
m_total_warn_count= 0;
363
/** Tiny reset in debug mode to see garbage right away */
369
Set OK status -- ends commands that do not return a
370
result set, e.g. INSERT/UPDATE/DELETE.
374
Diagnostics_area::set_ok_status(Session *session, ha_rows affected_rows_arg,
375
uint64_t last_insert_id_arg,
376
const char *message_arg)
380
In production, refuse to overwrite an error or a custom response
383
if (is_error() || is_disabled())
385
/** Only allowed to report success if has not yet reported an error */
387
m_server_status= session->server_status;
388
m_total_warn_count= session->total_warn_count;
389
m_affected_rows= affected_rows_arg;
390
m_last_insert_id= last_insert_id_arg;
392
strncpy(m_message, message_arg, sizeof(m_message) - 1);
404
Diagnostics_area::set_eof_status(Session *session)
406
/** Only allowed to report eof if has not yet reported an error */
410
In production, refuse to overwrite an error or a custom response
413
if (is_error() || is_disabled())
416
m_server_status= session->server_status;
418
If inside a stored procedure, do not return the total
419
number of warnings, since they are not available to the client
422
m_total_warn_count= session->total_warn_count;
432
Diagnostics_area::set_error_status(Session *session __attribute__((unused)),
433
uint32_t sql_errno_arg,
434
const char *message_arg)
437
Only allowed to report error if has not yet reported a success
438
The only exception is when we flush the message to the client,
439
an error can happen during the flush.
441
assert(! is_set() || can_overwrite_status);
443
In production, refuse to overwrite a custom response with an
449
m_sql_errno= sql_errno_arg;
450
strncpy(m_message, message_arg, sizeof(m_message) - 1);
457
Mark the diagnostics area as 'DISABLED'.
459
This is used in rare cases when the COM_ command at hand sends a response
460
in a custom format. One example is the query cache, another is
465
Diagnostics_area::disable_status()
468
m_status= DA_DISABLED;
473
:Statement(&main_lex, &main_mem_root,
474
/* statement id */ 0),
475
Open_tables_state(refresh_version),
476
lock_id(&main_lock_id),
478
arg_of_last_insert_id_function(false),
479
first_successful_insert_id_in_prev_stmt(0),
480
first_successful_insert_id_in_cur_stmt(0),
483
transaction_rollback_request(0),
484
is_fatal_sub_stmt_error(0),
486
derived_tables_processing(false),
211
493
Pass nominal parameters to init_alloc_root only to ensure that
212
494
the destructor works OK in case of an error. The main_mem_root
213
495
will be re-initialized in init_for_queries().
215
memory::init_sql_alloc(&main_mem_root, memory::ROOT_MIN_BLOCK_SIZE, 0);
497
init_sql_alloc(&main_mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0);
499
catalog= (char*)"std"; // the only catalog we have for now
500
some_tables_deleted=no_errors=password= 0;
217
501
count_cuted_fields= CHECK_FIELD_IGNORE;
218
502
killed= NOT_KILLED;
504
is_slave_error= thread_specific_used= false;
505
hash_clear(&handler_tables_hash);
222
508
cuted_fields= sent_row_count= row_count= 0L;
223
510
row_count_func= -1;
224
511
statement_id_counter= 0UL;
225
512
// Must be reset to handle error with Session's created for init of mysqld
227
514
start_time=(time_t) 0;
229
516
utime_after_lock= 0L;
230
518
memset(&variables, 0, sizeof(variables));
523
db_charset= global_system_variables.collation_database;
524
memset(ha_data, 0, sizeof(ha_data));
527
binlog_evt_union.do_union= false;
236
528
dbug_sentry=Session_SENTRY_MAGIC;
237
cleanup_done= abort_on_warning= no_warnings_for_error= false;
530
client_capabilities= 0; // minimalistic client
531
system_thread= NON_SYSTEM_THREAD;
532
cleanup_done= abort_on_warning= no_warnings_for_error= 0;
533
peer_port= 0; // For SHOW PROCESSLIST
238
535
pthread_mutex_init(&LOCK_delete, MY_MUTEX_INIT_FAST);
240
537
/* Variables with default values */
241
538
proc_info="login";
242
539
where= Session::DEFAULT_WHERE;
243
command= COM_CONNECT;
245
plugin_sessionvar_init(this);
247
variables= global_system_variables above has reset
248
variables.pseudo_thread_id to 0. We need to correct it here to
249
avoid temporary tables replication failure.
251
variables.pseudo_thread_id= thread_id;
252
server_status= SERVER_STATUS_AUTOCOMMIT;
253
options= session_startup_options;
255
if (variables.max_join_size == HA_POS_ERROR)
256
options |= OPTION_BIG_SELECTS;
258
options &= ~OPTION_BIG_SELECTS;
260
open_options=ha_open_options;
261
update_lock_default= TL_WRITE;
262
session_tx_isolation= (enum_tx_isolation) variables.tx_isolation;
264
memset(warn_count, 0, sizeof(warn_count));
266
memset(&status_var, 0, sizeof(status_var));
540
server_id = ::server_id;
268
545
/* Initialize sub structures */
269
memory::init_sql_alloc(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE);
546
init_sql_alloc(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE);
547
user_connect=(USER_CONN *)0;
270
548
hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
271
549
(hash_get_key) get_var_key,
272
550
(hash_free_key) free_user_var, 0);
552
/* For user vars replication*/
554
my_init_dynamic_array(&user_var_events,
555
sizeof(BINLOG_USER_VAR_EVENT *), 16, 16);
557
memset(&user_var_events, 0, sizeof(user_var_events));
560
protocol= &protocol_text; // Default protocol
561
protocol_text.init(this);
563
const Query_id& query_id= Query_id::get_query_id();
564
tablespace_op= false;
566
randominit(&rand, tmp + (ulong) &rand, tmp + query_id.value());
274
567
substitute_null_with_insert_id = false;
275
568
thr_lock_info_init(&lock_info); /* safety: will be reset after start */
276
569
thr_lock_owner_init(&main_lock_id, &lock_info);
643
Init common variables that has to be reset on start and on change_user
646
void Session::init(void)
648
pthread_mutex_lock(&LOCK_global_system_variables);
649
plugin_sessionvar_init(this);
650
variables.time_format= date_time_format_copy((Session*) 0,
651
variables.time_format);
652
variables.date_format= date_time_format_copy((Session*) 0,
653
variables.date_format);
654
variables.datetime_format= date_time_format_copy((Session*) 0,
655
variables.datetime_format);
657
variables= global_system_variables above has reset
658
variables.pseudo_thread_id to 0. We need to correct it here to
659
avoid temporary tables replication failure.
661
variables.pseudo_thread_id= thread_id;
662
pthread_mutex_unlock(&LOCK_global_system_variables);
663
server_status= SERVER_STATUS_AUTOCOMMIT;
664
options= session_startup_options;
666
if (variables.max_join_size == HA_POS_ERROR)
667
options |= OPTION_BIG_SELECTS;
669
options &= ~OPTION_BIG_SELECTS;
671
transaction.all.modified_non_trans_table= transaction.stmt.modified_non_trans_table= false;
672
open_options=ha_open_options;
673
update_lock_default= TL_WRITE;
674
session_tx_isolation= (enum_tx_isolation) variables.tx_isolation;
676
memset(warn_count, 0, sizeof(warn_count));
679
memset(&status_var, 0, sizeof(status_var));
684
Init Session for query processing.
685
This has to be called once before we call mysql_parse.
686
See also comments in session.h.
689
void Session::init_for_queries()
692
ha_enable_transaction(this,true);
694
reset_root_defaults(mem_root, variables.query_alloc_block_size,
695
variables.query_prealloc_size);
696
reset_root_defaults(&transaction.mem_root,
697
variables.trans_alloc_block_size,
698
variables.trans_prealloc_size);
699
transaction.xid_state.xid.null();
700
transaction.xid_state.in_session=1;
357
704
/* Do operations that may take a long time */
359
706
void Session::cleanup(void)
361
assert(cleanup_done == false);
708
assert(cleanup_done == 0);
363
710
killed= KILL_CONNECTION;
364
711
#ifdef ENABLE_WHEN_BINLOG_WILL_BE_ABLE_TO_PREPARE
371
TransactionServices &transaction_services= TransactionServices::singleton();
372
transaction_services.ha_rollback_trans(this, true);
373
719
xid_cache_delete(&transaction.xid_state);
723
lock=locked_tables; locked_tables=0;
724
close_thread_tables(this);
726
mysql_ha_cleanup(this);
727
delete_dynamic(&user_var_events);
375
728
hash_free(&user_vars);
376
729
close_temporary_tables();
730
free((char*) variables.time_format);
731
free((char*) variables.date_format);
732
free((char*) variables.datetime_format);
378
734
if (global_read_lock)
379
735
unlock_global_read_lock(this);
384
741
Session::~Session()
743
Session_CHECK_SENTRY(this);
744
/* Ensure that no one is using Session */
745
pthread_mutex_lock(&LOCK_delete);
746
pthread_mutex_unlock(&LOCK_delete);
387
747
add_to_status(&global_status_var, &status_var);
389
if (client->isConnected())
391
if (global_system_variables.log_warnings)
392
errmsg_printf(ERRMSG_LVL_WARN, ER(ER_FORCING_CLOSE),internal::my_progname,
394
(getSecurityContext().getUser().c_str() ?
395
getSecurityContext().getUser().c_str() : ""));
396
disconnect(0, false);
399
749
/* Close connection */
403
if (cleanup_done == false)
406
plugin::StorageEngine::closeConnection(this);
758
ha_close_connection(this);
407
759
plugin_sessionvar_cleanup(this);
409
766
free_root(&warn_root,MYF(0));
767
free_root(&transaction.mem_root,MYF(0));
410
768
mysys_var=0; // Safety (shouldn't be needed)
769
pthread_mutex_destroy(&LOCK_delete);
411
770
dbug_sentry= Session_SENTRY_GONE;
413
772
free_root(&main_mem_root, MYF(0));
414
773
pthread_setspecific(THR_Session, 0);
416
plugin::Logging::postEndDo(this);
418
/* Ensure that no one is using Session */
419
pthread_mutex_unlock(&LOCK_delete);
420
pthread_mutex_destroy(&LOCK_delete);
424
779
Add all status variables to another status variable array
541
902
created in another thread
543
904
thr_lock_info_init(&lock_info);
548
Init Session for query processing.
549
This has to be called once before we call mysql_parse.
550
See also comments in session.h.
913
Session::cleanup_after_query()
916
This function is used to reset thread data to its default state.
919
This function is not suitable for setting thread data to some
920
non-default values, as there is only one replication thread, so
921
different master threads may overwrite data of each other on
553
void Session::prepareForQueries()
555
if (variables.max_join_size == HA_POS_ERROR)
556
options |= OPTION_BIG_SELECTS;
558
version= refresh_version;
563
reset_root_defaults(mem_root, variables.query_alloc_block_size,
564
variables.query_prealloc_size);
565
transaction.xid_state.xid.null();
566
transaction.xid_state.in_session=1;
569
bool Session::initGlobals()
573
disconnect(ER_OUT_OF_RESOURCES, true);
574
statistic_increment(aborted_connects, &LOCK_status);
582
if (initGlobals() || authenticate())
590
while (! client->haveError() && killed != KILL_CONNECTION)
592
if (! executeStatement())
599
bool Session::schedule()
601
scheduler= plugin::Scheduler::getScheduler();
604
connection_count.increment();
606
if (connection_count > max_used_connections)
607
max_used_connections= connection_count;
609
thread_id= variables.pseudo_thread_id= global_thread_id++;
611
pthread_mutex_lock(&LOCK_thread_count);
612
getSessionList().push_back(this);
613
pthread_mutex_unlock(&LOCK_thread_count);
615
if (scheduler->addSession(this))
617
DRIZZLE_CONNECTION_START(thread_id);
618
char error_message_buff[DRIZZLE_ERRMSG_SIZE];
620
killed= Session::KILL_CONNECTION;
622
statistic_increment(aborted_connects, &LOCK_status);
624
/* Can't use my_error() since store_globals has not been called. */
625
/* TODO replace will better error message */
626
snprintf(error_message_buff, sizeof(error_message_buff),
627
ER(ER_CANT_CREATE_THREAD), 1);
628
client->sendError(ER_CANT_CREATE_THREAD, error_message_buff);
636
const char* Session::enter_cond(pthread_cond_t *cond,
637
pthread_mutex_t* mutex,
640
const char* old_msg = get_proc_info();
641
safe_mutex_assert_owner(mutex);
642
mysys_var->current_mutex = mutex;
643
mysys_var->current_cond = cond;
644
this->set_proc_info(msg);
648
void Session::exit_cond(const char* old_msg)
651
Putting the mutex unlock in exit_cond() ensures that
652
mysys_var->current_mutex is always unlocked _before_ mysys_var->mutex is
653
locked (if that would not be the case, you'll get a deadlock if someone
654
does a Session::awake() on you).
656
pthread_mutex_unlock(mysys_var->current_mutex);
657
pthread_mutex_lock(&mysys_var->mutex);
658
mysys_var->current_mutex = 0;
659
mysys_var->current_cond = 0;
660
this->set_proc_info(old_msg);
661
pthread_mutex_unlock(&mysys_var->mutex);
664
bool Session::authenticate()
667
if (client->authenticate())
670
statistic_increment(aborted_connects, &LOCK_status);
674
bool Session::checkUser(const char *passwd, uint32_t passwd_len, const char *in_db)
676
const string passwd_str(passwd, passwd_len);
677
bool is_authenticated=
678
plugin::Authentication::isAuthenticated(getSecurityContext(),
681
if (is_authenticated != true)
683
/* isAuthenticated has pushed the error message */
687
/* Change database if necessary */
688
if (in_db && in_db[0])
690
SchemaIdentifier identifier(in_db);
691
if (mysql_change_db(this, identifier))
693
/* mysql_change_db() has pushed the error message. */
698
password= test(passwd_len); // remember for error messages
700
/* Ready to handle queries */
704
bool Session::executeStatement()
707
uint32_t packet_length;
709
enum enum_server_command l_command;
712
indicator of uninitialized lex => normal flow of errors handling
715
lex->current_select= 0;
717
main_da.reset_diagnostics_area();
719
if (client->readCommand(&l_packet, &packet_length) == false)
722
if (packet_length == 0)
725
l_command= (enum enum_server_command) (unsigned char) l_packet[0];
727
if (command >= COM_END)
728
command= COM_END; // Wrong command
730
assert(packet_length);
731
return ! dispatch_command(l_command, this, l_packet+1, (uint32_t) (packet_length-1));
734
bool Session::readAndStoreQuery(const char *in_packet, uint32_t in_packet_length)
736
/* Remove garbage at start and end of query */
737
while (in_packet_length > 0 && my_isspace(charset(), in_packet[0]))
742
const char *pos= in_packet + in_packet_length; /* Point at end null */
743
while (in_packet_length > 0 &&
744
(pos[-1] == ';' || my_isspace(charset() ,pos[-1])))
750
query.assign(in_packet, in_packet + in_packet_length);
755
bool Session::endTransaction(enum enum_mysql_completiontype completion)
759
TransactionServices &transaction_services= TransactionServices::singleton();
761
if (transaction.xid_state.xa_state != XA_NOTR)
763
my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[transaction.xid_state.xa_state]);
770
* We don't use endActiveTransaction() here to ensure that this works
771
* even if there is a problem with the OPTION_AUTO_COMMIT flag
772
* (Which of course should never happen...)
774
server_status&= ~SERVER_STATUS_IN_TRANS;
775
if (transaction_services.ha_commit_trans(this, true))
777
options&= ~(OPTION_BEGIN);
780
do_release= 1; /* fall through */
781
case COMMIT_AND_CHAIN:
782
result= endActiveTransaction();
783
if (result == true && completion == COMMIT_AND_CHAIN)
784
result= startTransaction();
786
case ROLLBACK_RELEASE:
787
do_release= 1; /* fall through */
789
case ROLLBACK_AND_CHAIN:
791
server_status&= ~SERVER_STATUS_IN_TRANS;
792
if (transaction_services.ha_rollback_trans(this, true))
794
options&= ~(OPTION_BEGIN);
795
if (result == true && (completion == ROLLBACK_AND_CHAIN))
796
result= startTransaction();
800
my_error(ER_UNKNOWN_COM_ERROR, MYF(0));
805
my_error(killed_errno(), MYF(0));
806
else if ((result == true) && do_release)
807
killed= Session::KILL_CONNECTION;
812
bool Session::endActiveTransaction()
815
TransactionServices &transaction_services= TransactionServices::singleton();
817
if (transaction.xid_state.xa_state != XA_NOTR)
819
my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[transaction.xid_state.xa_state]);
822
if (options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
824
server_status&= ~SERVER_STATUS_IN_TRANS;
825
if (transaction_services.ha_commit_trans(this, true))
828
options&= ~(OPTION_BEGIN);
832
bool Session::startTransaction(start_transaction_option_t opt)
836
if (! endActiveTransaction())
842
options|= OPTION_BEGIN;
843
server_status|= SERVER_STATUS_IN_TRANS;
845
if (plugin::TransactionalStorageEngine::notifyStartTransaction(this, opt))
854
925
void Session::cleanup_after_query()
976
Convert a string to another character set
980
to Store new allocated string here
981
to_cs New character set for allocated string
982
from String to convert
983
from_length Length of string to convert
984
from_cs Original character set
987
to will be 0-terminated to make it easy to pass to system funcs
992
In this case to->str will point to 0 and to->length will be 0.
995
bool Session::convert_string(LEX_STRING *to, const CHARSET_INFO * const to_cs,
996
const char *from, uint32_t from_length,
997
const CHARSET_INFO * const from_cs)
999
size_t new_length= to_cs->mbmaxlen * from_length;
1000
uint32_t dummy_errors;
1001
if (!(to->str= (char*) alloc(new_length+1)))
1003
to->length= 0; // Safety fix
1006
to->length= copy_and_convert((char*) to->str, new_length, to_cs,
1007
from, from_length, from_cs, &dummy_errors);
1008
to->str[to->length]=0; // Safety
1014
Convert string from source character set to target character set inplace.
1017
Session::convert_string
1020
Convert string using convert_buffer - buffer for character set
1021
conversion shared between all protocols.
1028
bool Session::convert_string(String *s, const CHARSET_INFO * const from_cs,
1029
const CHARSET_INFO * const to_cs)
1031
uint32_t dummy_errors;
1032
if (convert_buffer.copy(s->ptr(), s->length(), from_cs, to_cs, &dummy_errors))
1034
/* If convert_buffer >> s copying is more efficient long term */
1035
if (convert_buffer.alloced_length() >= convert_buffer.length() * 2 ||
1038
return s->copy(convert_buffer);
1040
s->swap(convert_buffer);
1046
Update some cache variables when character set changes
1049
void Session::update_charset()
1052
charset_is_system_charset= !String::needs_conversion(0,charset(),
1053
system_charset_info,
1055
charset_is_collation_connection=
1056
!String::needs_conversion(0,charset(),variables.getCollation(),
1058
charset_is_character_set_filesystem=
1059
!String::needs_conversion(0, charset(),
1060
variables.character_set_filesystem, ¬_used);
1064
/* routings to adding tables to list of changed in transaction tables */
1066
inline static void list_include(CHANGED_TableList** prev,
1067
CHANGED_TableList* curr,
1068
CHANGED_TableList* new_table)
1073
(*prev)->next = curr;
1077
/* add table to list of changed in transaction tables */
1079
void Session::add_changed_table(Table *table)
1081
assert((options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
1082
table->file->has_transactions());
1083
add_changed_table(table->s->table_cache_key.str,
1084
(long) table->s->table_cache_key.length);
1089
void Session::add_changed_table(const char *key, long key_length)
1091
CHANGED_TableList **prev_changed = &transaction.changed_tables;
1092
CHANGED_TableList *curr = transaction.changed_tables;
1094
for (; curr; prev_changed = &(curr->next), curr = curr->next)
1096
int cmp = (long)curr->key_length - (long)key_length;
1099
list_include(prev_changed, curr, changed_table_dup(key, key_length));
1104
cmp = memcmp(curr->key, key, curr->key_length);
1107
list_include(prev_changed, curr, changed_table_dup(key, key_length));
1116
*prev_changed = changed_table_dup(key, key_length);
1121
CHANGED_TableList* Session::changed_table_dup(const char *key, long key_length)
1123
CHANGED_TableList* new_table =
1124
(CHANGED_TableList*) trans_alloc(ALIGN_SIZE(sizeof(CHANGED_TableList))+
1128
my_error(EE_OUTOFMEMORY, MYF(ME_BELL),
1129
ALIGN_SIZE(sizeof(TableList)) + key_length + 1);
1130
killed= KILL_CONNECTION;
1134
new_table->key= ((char*)new_table)+ ALIGN_SIZE(sizeof(CHANGED_TableList));
1135
new_table->next = 0;
1136
new_table->key_length = key_length;
1137
::memcpy(new_table->key, key, key_length);
908
1142
int Session::send_explain_fields(select_result *result)
910
1144
List<Item> field_list;
941
1175
item->maybe_null= 1;
942
1176
field_list.push_back(new Item_empty_string("Extra", 255, cs));
943
return (result->send_fields(field_list));
946
void select_result::send_error(uint32_t errcode, const char *err)
1177
return (result->send_fields(field_list,
1178
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF));
1182
struct Item_change_record: public ilink
1186
/* Placement new was hidden by `new' in ilink (TODO: check): */
1187
static void *operator new(size_t size __attribute__((unused)),
1190
static void operator delete(void *ptr __attribute__((unused)),
1191
size_t size __attribute__((unused)))
1193
static void operator delete(void *ptr __attribute__((unused)),
1194
void *mem __attribute__((unused)))
1195
{ /* never called */ }
1200
Register an item tree tree transformation, performed by the query
1201
optimizer. We need a pointer to runtime_memroot because it may be !=
1202
session->mem_root (this may no longer be a true statement)
1205
void Session::nocheck_register_item_tree_change(Item **place, Item *old_value,
1206
MEM_ROOT *runtime_memroot)
1208
Item_change_record *change;
1210
Now we use one node per change, which adds some memory overhead,
1211
but still is rather fast as we use alloc_root for allocations.
1212
A list of item tree changes of an average query should be short.
1214
void *change_mem= alloc_root(runtime_memroot, sizeof(*change));
1215
if (change_mem == 0)
1218
OOM, session->fatal_error() is called by the error handler of the
1219
memroot. Just return.
1223
change= new (change_mem) Item_change_record;
1224
change->place= place;
1225
change->old_value= old_value;
1226
change_list.append(change);
1230
void Session::rollback_item_tree_changes()
1232
I_List_iterator<Item_change_record> it(change_list);
1233
Item_change_record *change;
1235
while ((change= it++))
1236
*change->place= change->old_value;
1237
/* We can forget about changes memory: it's allocated in runtime memroot */
1238
change_list.empty();
1243
/*****************************************************************************
1244
** Functions to provide a interface to select results
1245
*****************************************************************************/
1247
select_result::select_result()
1249
session=current_session;
1252
void select_result::send_error(uint32_t errcode,const char *err)
948
1254
my_message(errcode, err, MYF(0));
1258
void select_result::cleanup()
1263
static String default_line_term("\n",default_charset_info);
1264
static String default_escaped("\\",default_charset_info);
1265
static String default_field_term("\t",default_charset_info);
1267
sql_exchange::sql_exchange(char *name, bool flag,
1268
enum enum_filetype filetype_arg)
1269
:file_name(name), opt_enclosed(0), dumpfile(flag), skip_lines(0)
1271
filetype= filetype_arg;
1272
field_term= &default_field_term;
1273
enclosed= line_start= &my_empty_string;
1274
line_term= &default_line_term;
1275
escaped= &default_escaped;
1279
bool select_send::send_fields(List<Item> &list, uint32_t flags)
1282
if (!(res= session->protocol->send_fields(&list, flags)))
1283
is_result_set_started= 1;
1287
void select_send::abort()
1294
Cleanup an instance of this class for re-use
1295
at next execution of a prepared statement/
1296
stored procedure statement.
1299
void select_send::cleanup()
1301
is_result_set_started= false;
1304
/* Send data to client. Returns 0 if ok */
1306
bool select_send::send_data(List<Item> &items)
1308
if (unit->offset_limit_cnt)
1309
{ // using limit offset,count
1310
unit->offset_limit_cnt--;
1315
We may be passing the control from mysqld to the client: release the
1316
InnoDB adaptive hash S-latch to avoid thread deadlocks if it was reserved
1319
ha_release_temporary_latches(session);
1321
List_iterator_fast<Item> li(items);
1322
Protocol *protocol= session->protocol;
1323
char buff[MAX_FIELD_WIDTH];
1324
String buffer(buff, sizeof(buff), &my_charset_bin);
1326
protocol->prepare_for_resend();
1330
if (item->send(protocol, &buffer))
1332
protocol->free(); // Free used buffer
1333
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
1337
session->sent_row_count++;
1338
if (session->is_error())
1340
protocol->remove_last_row();
1343
if (session->vio_ok())
1344
return(protocol->write());
1348
bool select_send::send_eof()
1351
We may be passing the control from mysqld to the client: release the
1352
InnoDB adaptive hash S-latch to avoid thread deadlocks if it was reserved
1355
ha_release_temporary_latches(session);
1357
/* Unlock tables before sending packet to gain some speed */
1360
mysql_unlock_tables(session, session->lock);
1364
is_result_set_started= 0;
951
1369
/************************************************************************
952
1370
Handling writing to file
953
1371
************************************************************************/
1171
1598
res=item->str_result(&tmp);
1172
1599
if (res && enclosed)
1174
if (my_b_write(cache,(unsigned char*) exchange->enclosed->ptr(),
1175
exchange->enclosed->length()))
1601
if (my_b_write(&cache,(unsigned char*) exchange->enclosed->ptr(),
1602
exchange->enclosed->length()))
1180
1607
if (!fixed_row_size)
1182
if (escape_char != -1) // Use \N syntax
1184
null_buff[0]=escape_char;
1186
if (my_b_write(cache,(unsigned char*) null_buff,2))
1189
else if (my_b_write(cache,(unsigned char*) "NULL",4))
1609
if (escape_char != -1) // Use \N syntax
1611
null_buff[0]=escape_char;
1613
if (my_b_write(&cache,(unsigned char*) null_buff,2))
1616
else if (my_b_write(&cache,(unsigned char*) "NULL",4))
1194
used_length=0; // Fill with space
1621
used_length=0; // Fill with space
1199
1626
if (fixed_row_size)
1200
used_length= min(res->length(),item->max_length);
1627
used_length=cmin(res->length(),item->max_length);
1202
used_length= res->length();
1629
used_length=res->length();
1204
1630
if ((result_type == STRING_RESULT || is_unsafe_field_sep) &&
1207
1633
char *pos, *start, *end;
1208
1634
const CHARSET_INFO * const res_charset= res->charset();
1209
1635
const CHARSET_INFO * const character_set_client= default_charset_info;
1211
1637
bool check_second_byte= (res_charset == &my_charset_bin) &&
1212
character_set_client->
1213
escape_with_backslash_is_dangerous;
1638
character_set_client->
1639
escape_with_backslash_is_dangerous;
1214
1640
assert(character_set_client->mbmaxlen == 2 ||
1215
1641
!character_set_client->escape_with_backslash_is_dangerous);
1216
for (start=pos=(char*) res->ptr(),end=pos+used_length ;
1220
if (use_mb(res_charset))
1223
if ((l=my_ismbchar(res_charset, pos, end)))
1642
for (start=pos=(char*) res->ptr(),end=pos+used_length ;
1647
if (use_mb(res_charset))
1650
if ((l=my_ismbchar(res_charset, pos, end)))
1231
1659
Special case when dumping BINARY/VARBINARY/BLOB values
1259
1687
assert before the loop makes that sure.
1262
if ((needs_escaping(*pos, enclosed) ||
1690
if ((NEED_ESCAPING(*pos) ||
1263
1691
(check_second_byte &&
1264
1692
my_mbcharlen(character_set_client, (unsigned char) *pos) == 2 &&
1265
1693
pos + 1 < end &&
1266
needs_escaping(pos[1], enclosed))) &&
1694
NEED_ESCAPING(pos[1]))) &&
1268
Don't escape field_term_char by doubling - doubling is only
1269
valid for ENCLOSED BY characters:
1696
Don't escape field_term_char by doubling - doubling is only
1697
valid for ENCLOSED BY characters:
1271
1699
(enclosed || !is_ambiguous_field_term ||
1272
1700
(int) (unsigned char) *pos != field_term_char))
1275
1703
tmp_buff[0]= ((int) (unsigned char) *pos == field_sep_char &&
1276
1704
is_ambiguous_field_sep) ?
1277
field_sep_char : escape_char;
1278
tmp_buff[1]= *pos ? *pos : '0';
1279
if (my_b_write(cache,(unsigned char*) start,(uint32_t) (pos-start)) ||
1280
my_b_write(cache,(unsigned char*) tmp_buff,2))
1285
if (my_b_write(cache,(unsigned char*) start,(uint32_t) (pos-start)))
1705
field_sep_char : escape_char;
1706
tmp_buff[1]= *pos ? *pos : '0';
1707
if (my_b_write(&cache,(unsigned char*) start,(uint) (pos-start)) ||
1708
my_b_write(&cache,(unsigned char*) tmp_buff,2))
1713
if (my_b_write(&cache,(unsigned char*) start,(uint) (pos-start)))
1288
else if (my_b_write(cache,(unsigned char*) res->ptr(),used_length))
1716
else if (my_b_write(&cache,(unsigned char*) res->ptr(),used_length))
1291
1719
if (fixed_row_size)
1292
1720
{ // Fill with space
1293
1721
if (item->max_length > used_length)
1295
/* QQ: Fix by adding a my_b_fill() function */
1299
memset(space, ' ', sizeof(space));
1301
uint32_t length=item->max_length-used_length;
1302
for (; length > sizeof(space) ; length-=sizeof(space))
1304
if (my_b_write(cache,(unsigned char*) space,sizeof(space)))
1307
if (my_b_write(cache,(unsigned char*) space,length))
1723
/* QQ: Fix by adding a my_b_fill() function */
1727
memset(space, ' ', sizeof(space));
1729
uint32_t length=item->max_length-used_length;
1730
for (; length > sizeof(space) ; length-=sizeof(space))
1732
if (my_b_write(&cache,(unsigned char*) space,sizeof(space)))
1735
if (my_b_write(&cache,(unsigned char*) space,length))
1311
1739
if (res && enclosed)
1313
if (my_b_write(cache, (unsigned char*) exchange->enclosed->ptr(),
1741
if (my_b_write(&cache, (unsigned char*) exchange->enclosed->ptr(),
1314
1742
exchange->enclosed->length()))
1317
1745
if (--items_left)
1319
if (my_b_write(cache, (unsigned char*) exchange->field_term->ptr(),
1747
if (my_b_write(&cache, (unsigned char*) exchange->field_term->ptr(),
1320
1748
field_term_length))
1324
if (my_b_write(cache,(unsigned char*) exchange->line_term->ptr(),
1325
exchange->line_term->length()))
1752
if (my_b_write(&cache,(unsigned char*) exchange->line_term->ptr(),
1753
exchange->line_term->length()))
1544
2031
bool Session::copy_db_to(char **p_db, size_t *p_db_length)
1548
2035
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1551
*p_db= strmake(db.c_str(), db.length());
1552
*p_db_length= db.length();
2038
*p_db= strmake(db, db_length);
2039
*p_db_length= db_length;
2044
bool select_dumpvar::send_data(List<Item> &items)
2046
List_iterator_fast<my_var> var_li(var_list);
2047
List_iterator<Item> it(items);
2051
if (unit->offset_limit_cnt)
2052
{ // using limit offset,count
2053
unit->offset_limit_cnt--;
2058
my_message(ER_TOO_MANY_ROWS, ER(ER_TOO_MANY_ROWS), MYF(0));
2061
while ((mv= var_li++) && (item= it++))
2065
Item_func_set_user_var *suv= new Item_func_set_user_var(mv->s, item);
2066
suv->fix_fields(session, 0);
2071
return(session->is_error());
2074
bool select_dumpvar::send_eof()
2077
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2078
ER_SP_FETCH_NO_DATA, ER(ER_SP_FETCH_NO_DATA));
2080
In order to remember the value of affected rows for ROW_COUNT()
2081
function, SELECT INTO has to have an own SQLCOM.
2082
TODO: split from SQLCOM_SELECT
2084
::my_ok(session,row_count);
1556
2088
/****************************************************************************
1558
2090
****************************************************************************/
1560
void Tmp_Table_Param::init()
2092
void TMP_TABLE_PARAM::init()
1562
2094
field_count= sum_func_count= func_count= hidden_field_count= 0;
1563
2095
group_parts= group_length= group_null_parts= 0;
1564
2096
quick_group= 1;
1565
2097
table_charset= 0;
1566
2098
precomputed_group_by= 0;
2099
bit_fields_as_long= 0;
1569
void Tmp_Table_Param::cleanup(void)
2103
void TMP_TABLE_PARAM::cleanup(void)
1571
2105
/* Fix for Intel compiler */
1572
2106
if (copy_field)
1682
2279
session->transaction_rollback_request= all;
1686
void Session::disconnect(uint32_t errcode, bool should_lock)
1688
/* Allow any plugins to cleanup their session variables */
1689
plugin_sessionvar_cleanup(this);
1691
/* If necessary, log any aborted or unauthorized connections */
1692
if (killed || client->wasAborted())
1693
statistic_increment(aborted_threads, &LOCK_status);
1695
if (client->wasAborted())
1697
if (! killed && variables.log_warnings > 1)
1699
SecurityContext *sctx= &security_ctx;
1701
errmsg_printf(ERRMSG_LVL_WARN, ER(ER_NEW_ABORTING_CONNECTION)
1703
, (db.empty() ? "unconnected" : db.c_str())
1704
, sctx->getUser().empty() == false ? sctx->getUser().c_str() : "unauthenticated"
1705
, sctx->getIp().c_str()
1706
, (main_da.is_error() ? main_da.message() : ER(ER_UNKNOWN_ERROR)));
1710
/* Close out our connection to the client */
2282
/***************************************************************************
2283
Handling of XA id cacheing
2284
***************************************************************************/
2286
pthread_mutex_t LOCK_xid_cache;
2289
extern "C" unsigned char *xid_get_hash_key(const unsigned char *, size_t *, bool);
2290
extern "C" void xid_free_hash(void *);
2292
unsigned char *xid_get_hash_key(const unsigned char *ptr, size_t *length,
2293
bool not_used __attribute__((unused)))
2295
*length=((XID_STATE*)ptr)->xid.key_length();
2296
return ((XID_STATE*)ptr)->xid.key();
2299
void xid_free_hash(void *ptr)
2301
if (!((XID_STATE*)ptr)->in_session)
2302
free((unsigned char*)ptr);
2305
bool xid_cache_init()
2307
pthread_mutex_init(&LOCK_xid_cache, MY_MUTEX_INIT_FAST);
2308
return hash_init(&xid_cache, &my_charset_bin, 100, 0, 0,
2309
xid_get_hash_key, xid_free_hash, 0) != 0;
2312
void xid_cache_free()
2314
if (hash_inited(&xid_cache))
2316
hash_free(&xid_cache);
2317
pthread_mutex_destroy(&LOCK_xid_cache);
2321
XID_STATE *xid_cache_search(XID *xid)
2323
pthread_mutex_lock(&LOCK_xid_cache);
2324
XID_STATE *res=(XID_STATE *)hash_search(&xid_cache, xid->key(), xid->key_length());
2325
pthread_mutex_unlock(&LOCK_xid_cache);
2330
bool xid_cache_insert(XID *xid, enum xa_states xa_state)
2334
pthread_mutex_lock(&LOCK_xid_cache);
2335
if (hash_search(&xid_cache, xid->key(), xid->key_length()))
2337
else if (!(xs=(XID_STATE *)malloc(sizeof(*xs))))
2341
xs->xa_state=xa_state;
2344
res=my_hash_insert(&xid_cache, (unsigned char*)xs);
2346
pthread_mutex_unlock(&LOCK_xid_cache);
2351
bool xid_cache_insert(XID_STATE *xid_state)
2353
pthread_mutex_lock(&LOCK_xid_cache);
2354
assert(hash_search(&xid_cache, xid_state->xid.key(),
2355
xid_state->xid.key_length())==0);
2356
bool res=my_hash_insert(&xid_cache, (unsigned char*)xid_state);
2357
pthread_mutex_unlock(&LOCK_xid_cache);
2362
void xid_cache_delete(XID_STATE *xid_state)
2364
pthread_mutex_lock(&LOCK_xid_cache);
2365
hash_delete(&xid_cache, (unsigned char *)xid_state);
2366
pthread_mutex_unlock(&LOCK_xid_cache);
2371
Class to handle temporary allocation of memory for row data.
2373
The responsibilities of the class is to provide memory for
2374
packing one or two rows of packed data (depending on what
2375
constructor is called).
2377
In order to make the allocation more efficient for "simple" rows,
2378
i.e., rows that do not contain any blobs, a pointer to the
2379
allocated memory is of memory is stored in the table structure
2380
for simple rows. If memory for a table containing a blob field
2381
is requested, only memory for that is allocated, and subsequently
2382
released when the object is destroyed.
2385
class Row_data_memory {
2388
Build an object to keep track of a block-local piece of memory
2389
for storing a row of data.
2392
Table where the pre-allocated memory is stored.
2395
Length of data that is needed, if the record contain blobs.
2397
Row_data_memory(Table *table, size_t const len1)
2400
m_alloc_checked= false;
2401
allocate_memory(table, len1);
2402
m_ptr[0]= has_memory() ? m_memory : 0;
2406
Row_data_memory(Table *table, size_t const len1, size_t const len2)
2409
m_alloc_checked= false;
2410
allocate_memory(table, len1 + len2);
2411
m_ptr[0]= has_memory() ? m_memory : 0;
2412
m_ptr[1]= has_memory() ? m_memory + len1 : 0;
2417
if (m_memory != 0 && m_release_memory_on_destruction)
2418
free((unsigned char*) m_memory);
2422
Is there memory allocated?
2424
@retval true There is memory allocated
2425
@retval false Memory allocation failed
2427
bool has_memory() const {
2428
m_alloc_checked= true;
2429
return m_memory != 0;
2432
unsigned char *slot(uint32_t s)
2434
assert(s < sizeof(m_ptr)/sizeof(*m_ptr));
2435
assert(m_ptr[s] != 0);
2436
assert(m_alloc_checked == true);
2441
void allocate_memory(Table *const table, size_t const total_length)
2443
if (table->s->blob_fields == 0)
2446
The maximum length of a packed record is less than this
2447
length. We use this value instead of the supplied length
2448
when allocating memory for records, since we don't know how
2449
the memory will be used in future allocations.
2451
Since table->s->reclength is for unpacked records, we have
2452
to add two bytes for each field, which can potentially be
2453
added to hold the length of a packed field.
2455
size_t const maxlen= table->s->reclength + 2 * table->s->fields;
2458
Allocate memory for two records if memory hasn't been
2459
allocated. We allocate memory for two records so that it can
2460
be used when processing update rows as well.
2462
if (table->write_row_record == 0)
2463
table->write_row_record=
2464
(unsigned char *) alloc_root(&table->mem_root, 2 * maxlen);
2465
m_memory= table->write_row_record;
2466
m_release_memory_on_destruction= false;
2470
m_memory= (unsigned char *) malloc(total_length);
2471
m_release_memory_on_destruction= true;
2475
mutable bool m_alloc_checked;
2476
bool m_release_memory_on_destruction;
2477
unsigned char *m_memory;
2478
unsigned char *m_ptr[2];
2482
bool Discrete_intervals_list::append(uint64_t start, uint64_t val,
2485
/* first, see if this can be merged with previous */
2486
if ((head == NULL) || tail->merge_if_contiguous(start, val, incr))
2488
/* it cannot, so need to add a new interval */
2489
Discrete_interval *new_interval= new Discrete_interval(start, val, incr);
2490
return(append(new_interval));
2495
bool Discrete_intervals_list::append(Discrete_interval *new_interval)
2497
if (unlikely(new_interval == NULL))
2500
head= current= new_interval;
2502
tail->next= new_interval;
2511
@param session Thread handle
2512
@param errcode Error code to print to console
2513
@param lock 1 if we have have to lock LOCK_thread_count
2516
For the connection that is doing shutdown, this is called twice
2518
void Session::close_connection(uint32_t errcode, bool lock)
1712
2522
(void) pthread_mutex_lock(&LOCK_thread_count);
1713
2523
killed= Session::KILL_CONNECTION;
1714
if (client->isConnected())
2524
if ((vio= net.vio) != 0)
1718
/*my_error(errcode, ER(errcode));*/
1719
client->sendError(errcode, ER(errcode));
2527
net_send_error(this, errcode, ER(errcode)); /* purecov: inspected */
2528
net_close(&net); /* vio is freed in delete session */
1724
2531
(void) pthread_mutex_unlock(&LOCK_thread_count);
2537
Reset Session part responsible for command processing state.
2539
This needs to be called before execution of every statement
2540
(prepared or conventional).
2541
It is not called by substatements of routines.
2544
Make it a method of Session and align its name with the rest of
2545
reset/end/start/init methods.
2547
Call it after we use Session for queries, not before.
1727
2550
void Session::reset_for_next_command()
1755
2607
Table *tmp_next;
1757
if (not temporary_tables)
2609
if (!temporary_tables)
1760
2612
for (table= temporary_tables; table; table= tmp_next)
1762
2614
tmp_next= table->next;
1765
temporary_tables= NULL;
1769
unlink from session->temporary tables and close temporary table
1772
void Session::close_temporary_table(Table *table)
1776
table->prev->next= table->next;
1777
if (table->prev->next)
1778
table->next->prev= table->prev;
1782
/* removing the item from the list */
1783
assert(table == temporary_tables);
1785
slave must reset its temporary list pointer to zero to exclude
1786
passing non-zero value to end_slave via rli->save_temporary_tables
1787
when no temp tables opened, see an invariant below.
1789
temporary_tables= table->next;
1790
if (temporary_tables)
1791
table->next->prev= NULL;
1797
Close and drop a temporary table
1800
This dosn't unlink table from session->temporary
1801
If this is needed, use close_temporary_table()
1804
void Session::nukeTable(Table *table)
1806
plugin::StorageEngine *table_type= table->s->db_type();
1808
table->free_io_cache();
1809
table->closefrm(false);
1811
TableIdentifier identifier(table->s->getSchemaName(), table->s->table_name.str, table->s->path.str);
1812
rm_temporary_table(table_type, identifier);
1814
table->s->free_table_share();
1816
/* This makes me sad, but we're allocating it via malloc */
1820
/** Clear most status variables. */
1821
extern time_t flush_status_time;
1822
extern uint32_t max_used_connections;
1824
void Session::refresh_status()
1826
pthread_mutex_lock(&LOCK_status);
1828
/* Add thread's status variabes to global status */
1829
add_to_status(&global_status_var, &status_var);
1831
/* Reset thread's status variables */
1832
memset(&status_var, 0, sizeof(status_var));
1834
/* Reset some global variables */
1835
reset_status_vars();
1837
/* Reset the counters of all key caches (default and named). */
1838
reset_key_cache_counters();
1839
flush_status_time= time((time_t*) 0);
1840
max_used_connections= 1; /* We set it to one, because we know we exist */
1841
pthread_mutex_unlock(&LOCK_status);
1844
user_var_entry *Session::getVariable(LEX_STRING &name, bool create_if_not_exists)
1846
user_var_entry *entry= NULL;
1848
entry= (user_var_entry*) hash_search(&user_vars, (unsigned char*) name.str, name.length);
1850
if ((entry == NULL) && create_if_not_exists)
1852
if (!hash_inited(&user_vars))
1854
entry= new (nothrow) user_var_entry(name.str, query_id);
1859
if (my_hash_insert(&user_vars, (unsigned char*) entry))
1862
free((char*) entry);
1871
void Session::mark_temp_tables_as_free_for_reuse()
1873
for (Table *table= temporary_tables ; table ; table= table->next)
1875
if (table->query_id == query_id)
1878
table->cursor->ha_reset();
1883
void Session::mark_used_tables_as_free_for_reuse(Table *table)
1885
for (; table ; table= table->next)
1887
if (table->query_id == query_id)
1890
table->cursor->ha_reset();
1896
Unlocks tables and frees derived tables.
1897
Put all normal tables used by thread in free list.
1899
It will only close/mark as free for reuse tables opened by this
1900
substatement, it will also check if we are closing tables after
1901
execution of complete query (i.e. we are on upper level) and will
1902
leave prelocked mode if needed.
1904
void Session::close_thread_tables()
1909
We are assuming here that session->derived_tables contains ONLY derived
1910
tables for this substatement. i.e. instead of approach which uses
1911
query_id matching for determining which of the derived tables belong
1912
to this substatement we rely on the ability of substatements to
1913
save/restore session->derived_tables during their execution.
1915
TODO: Probably even better approach is to simply associate list of
1916
derived tables with (sub-)statement instead of thread and destroy
1917
them at the end of its execution.
1923
Close all derived tables generated in queries like
1924
SELECT * FROM (SELECT * FROM t1)
1926
for (table= derived_tables ; table ; table= next)
1929
table->free_tmp_table(this);
1935
Mark all temporary tables used by this statement as free for reuse.
1937
mark_temp_tables_as_free_for_reuse();
1939
Let us commit transaction for statement. Since in 5.0 we only have
1940
one statement transaction and don't allow several nested statement
1941
transactions this call will do nothing if we are inside of stored
1942
function or trigger (i.e. statement transaction is already active and
1943
does not belong to statement for which we do close_thread_tables()).
1944
TODO: This should be fixed in later releases.
1946
if (backups_available == false)
1948
TransactionServices &transaction_services= TransactionServices::singleton();
1949
main_da.can_overwrite_status= true;
1950
transaction_services.ha_autocommit_or_rollback(this, is_error());
1951
main_da.can_overwrite_status= false;
1952
transaction.stmt.reset();
1958
For RBR we flush the pending event just before we unlock all the
1959
tables. This means that we are at the end of a topmost
1960
statement, so we ensure that the STMT_END_F flag is set on the
1961
pending event. For statements that are *inside* stored
1962
functions, the pending event will not be flushed: that will be
1963
handled either before writing a query log event (inside
1964
binlog_query()) or when preparing a pending event.
1966
mysql_unlock_tables(this, lock);
1970
Note that we need to hold LOCK_open while changing the
1971
open_tables list. Another thread may work on it.
1972
(See: remove_table_from_cache(), mysql_wait_completed_table())
1973
Closing a MERGE child before the parent would be fatal if the
1974
other thread tries to abort the MERGE lock in between.
1977
close_open_tables();
1980
void Session::close_tables_for_reopen(TableList **tables)
1983
If table list consists only from tables from prelocking set, table list
1984
for new attempt should be empty, so we have to update list's root pointer.
1986
if (lex->first_not_own_table() == *tables)
1988
lex->chop_off_not_own_tables();
1989
for (TableList *tmp= *tables; tmp; tmp= tmp->next_global)
1991
close_thread_tables();
1994
bool Session::openTablesLock(TableList *tables)
2001
if (open_tables_from_list(&tables, &counter))
2004
if (not lock_tables(tables, counter, &need_reopen))
2006
if (not need_reopen)
2008
close_tables_for_reopen(&tables);
2010
if ((mysql_handle_derived(lex, &mysql_derived_prepare) ||
2011
(fill_derived_tables() &&
2012
mysql_handle_derived(lex, &mysql_derived_filling))))
2018
bool Session::openTables(TableList *tables, uint32_t flags)
2021
bool ret= fill_derived_tables();
2022
assert(ret == false);
2023
if (open_tables_from_list(&tables, &counter, flags) ||
2024
mysql_handle_derived(lex, &mysql_derived_prepare))
2029
bool Session::rm_temporary_table(TableIdentifier &identifier)
2031
if (plugin::StorageEngine::dropTable(*this, identifier))
2033
errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
2034
identifier.getSQLPath().c_str(), errno);
2035
dumpTemporaryTableNames("rm_temporary_table()");
2043
bool Session::rm_temporary_table(plugin::StorageEngine *base, TableIdentifier &identifier)
2047
if (plugin::StorageEngine::dropTable(*this, *base, identifier))
2049
errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
2050
identifier.getSQLPath().c_str(), errno);
2051
dumpTemporaryTableNames("rm_temporary_table()");
2060
@note this will be removed, I am looking through Hudson to see if it is finding
2061
any tables that are missed during cleanup.
2063
void Session::dumpTemporaryTableNames(const char *foo)
2067
if (not temporary_tables)
2070
cerr << "Begin Run: " << foo << "\n";
2071
for (table= temporary_tables; table; table= table->next)
2073
bool have_proto= false;
2075
message::Table *proto= table->s->getTableProto();
2076
if (table->s->getTableProto())
2079
const char *answer= have_proto ? "true" : "false";
2083
cerr << "\tTable Name " << table->s->getSchemaName() << "." << table->s->table_name.str << " : " << answer << "\n";
2084
cerr << "\t\t Proto " << proto->schema() << " " << proto->name() << "\n";
2087
cerr << "\tTabl;e Name " << table->s->getSchemaName() << "." << table->s->table_name.str << " : " << answer << "\n";
2091
bool Session::storeTableMessage(TableIdentifier &identifier, message::Table &table_message)
2093
table_message_cache.insert(make_pair(identifier.getPath(), table_message));
2098
bool Session::removeTableMessage(TableIdentifier &identifier)
2100
TableMessageCache::iterator iter;
2102
iter= table_message_cache.find(identifier.getPath());
2104
if (iter == table_message_cache.end())
2107
table_message_cache.erase(iter);
2112
bool Session::getTableMessage(TableIdentifier &identifier, message::Table &table_message)
2114
TableMessageCache::iterator iter;
2116
iter= table_message_cache.find(identifier.getPath());
2118
if (iter == table_message_cache.end())
2121
table_message.CopyFrom(((*iter).second));
2126
bool Session::doesTableMessageExist(TableIdentifier &identifier)
2128
TableMessageCache::iterator iter;
2130
iter= table_message_cache.find(identifier.getPath());
2132
if (iter == table_message_cache.end())
2140
bool Session::renameTableMessage(TableIdentifier &from, TableIdentifier &to)
2142
TableMessageCache::iterator iter;
2144
table_message_cache[to.getPath()]= table_message_cache[from.getPath()];
2146
iter= table_message_cache.find(to.getPath());
2148
if (iter == table_message_cache.end())
2153
(*iter).second.set_schema(to.getSchemaName());
2154
(*iter).second.set_name(to.getTableName());
2159
} /* namespace drizzled */
2615
close_temporary(table, 1, 1);
2617
temporary_tables= 0;