53
53
static pthread_mutex_t LOCK_table_share;
54
54
static bool table_def_inited= 0;
56
static int open_unireg_entry(Session *thd, Table *entry, TableList *table_list,
56
static int open_unireg_entry(Session *session, Table *entry, TableList *table_list,
58
58
char *cache_key, uint32_t cache_key_length);
59
59
static void free_cache_entry(Table *entry);
60
static void close_old_data_files(Session *thd, Table *table, bool morph_locks,
60
static void close_old_data_files(Session *session, Table *table, bool morph_locks,
61
61
bool send_refresh);
121
uint32_t create_table_def_key(Session *thd, char *key, TableList *table_list,
121
uint32_t create_table_def_key(Session *session, char *key, TableList *table_list,
124
124
uint32_t key_length= (uint) (my_stpcpy(my_stpcpy(key, table_list->db)+1,
125
125
table_list->table_name)-key)+1;
128
int4store(key + key_length, thd->server_id);
129
int4store(key + key_length + 4, thd->variables.pseudo_thread_id);
128
int4store(key + key_length, session->server_id);
129
int4store(key + key_length + 4, session->variables.pseudo_thread_id);
130
130
key_length+= TMP_TABLE_KEY_EXTRA;
132
132
return key_length;
323
323
static TABLE_SHARE
324
*get_table_share_with_create(Session *thd, TableList *table_list,
324
*get_table_share_with_create(Session *session, TableList *table_list,
325
325
char *key, uint32_t key_length,
326
326
uint32_t db_flags, int *error)
328
328
TABLE_SHARE *share;
331
share= get_table_share(thd, table_list, key, key_length, db_flags, error);
331
share= get_table_share(session, table_list, key, key_length, db_flags, error);
333
333
If share is not NULL, we found an existing share.
349
349
@todo Rework alternative ways to deal with ER_NO_SUCH Table.
351
if (share || (thd->is_error() && (thd->main_da.sql_errno() != ER_NO_SUCH_TABLE)))
351
if (share || (session->is_error() && (session->main_da.sql_errno() != ER_NO_SUCH_TABLE)))
355
355
/* Table didn't exist. Check if some engine can provide it */
356
if ((tmp= ha_create_table_from_engine(thd, table_list->db,
356
if ((tmp= ha_create_table_from_engine(session, table_list->db,
357
357
table_list->table_name)) < 0)
362
362
/* Give right error message */
363
session->clear_error();
364
364
my_printf_error(ER_UNKNOWN_ERROR,
365
365
"Failed to open '%-.64s', error while "
366
366
"unpacking from engine",
370
370
/* Table existed in engine. Let's open it */
371
drizzle_reset_errors(thd, 1); // Clear warnings
372
thd->clear_error(); // Clear error message
373
return(get_table_share(thd, table_list, key, key_length,
371
drizzle_reset_errors(session, 1); // Clear warnings
372
session->clear_error(); // Clear error message
373
return(get_table_share(session, table_list, key, key_length,
374
374
db_flags, error));
663
663
and tables must be NULL.
666
bool close_cached_tables(Session *thd, TableList *tables, bool have_lock,
666
bool close_cached_tables(Session *session, TableList *tables, bool have_lock,
667
667
bool wait_for_refresh, bool wait_for_placeholders)
670
assert(thd || (!wait_for_refresh && !tables));
670
assert(session || (!wait_for_refresh && !tables));
673
673
pthread_mutex_lock(&LOCK_open);
755
755
If there is any table that has a lower refresh_version, wait until
756
756
this is closed (or this thread is killed) before returning
758
thd->mysys_var->current_mutex= &LOCK_open;
759
thd->mysys_var->current_cond= &COND_refresh;
760
thd->set_proc_info("Flushing tables");
758
session->mysys_var->current_mutex= &LOCK_open;
759
session->mysys_var->current_cond= &COND_refresh;
760
session->set_proc_info("Flushing tables");
762
close_old_data_files(thd,thd->open_tables,1,1);
762
close_old_data_files(session,session->open_tables,1,1);
763
mysql_ha_flush(session);
766
766
/* Wait until all threads has closed all the tables we had locked */
767
while (found && ! thd->killed)
767
while (found && ! session->killed)
770
770
for (uint32_t idx=0 ; idx < open_cache.records ; idx++)
772
772
Table *table=(Table*) hash_element(&open_cache,idx);
773
773
/* Avoid a self-deadlock. */
774
if (table->in_use == thd)
774
if (table->in_use == session)
777
777
Note that we wait here only for tables which are actually open, and
801
801
old locks. This should always succeed (unless some external process
802
802
has removed the tables)
804
thd->in_lock_tables=1;
805
result=reopen_tables(thd,1,1);
806
thd->in_lock_tables=0;
804
session->in_lock_tables=1;
805
result=reopen_tables(session,1,1);
806
session->in_lock_tables=0;
807
807
/* Set version for table */
808
for (Table *table=thd->open_tables; table ; table= table->next)
808
for (Table *table=session->open_tables; table ; table= table->next)
811
811
Preserve the version (0) of write locked tables so that a impending
819
819
pthread_mutex_unlock(&LOCK_open);
820
820
if (wait_for_refresh)
822
pthread_mutex_lock(&thd->mysys_var->mutex);
823
thd->mysys_var->current_mutex= 0;
824
thd->mysys_var->current_cond= 0;
825
thd->set_proc_info(0);
826
pthread_mutex_unlock(&thd->mysys_var->mutex);
822
pthread_mutex_lock(&session->mysys_var->mutex);
823
session->mysys_var->current_mutex= 0;
824
session->mysys_var->current_cond= 0;
825
session->set_proc_info(0);
826
pthread_mutex_unlock(&session->mysys_var->mutex);
834
834
if specified string is NULL, then any table with a connection string.
837
bool close_cached_connection_tables(Session *thd, bool if_wait_for_refresh,
837
bool close_cached_connection_tables(Session *session, bool if_wait_for_refresh,
838
838
LEX_STRING *connection, bool have_lock)
841
841
TableList tmp, *tables= NULL;
842
842
bool result= false;
845
845
memset(&tmp, 0, sizeof(TableList));
870
870
tmp.table_name= share->table_name.str;
871
871
tmp.next_local= tables;
873
tables= (TableList *) memdup_root(thd->mem_root, (char*)&tmp,
873
tables= (TableList *) memdup_root(session->mem_root, (char*)&tmp,
874
874
sizeof(TableList));
878
result= close_cached_tables(thd, tables, true, false, false);
878
result= close_cached_tables(session, tables, true, false, false);
881
881
pthread_mutex_unlock(&LOCK_open);
883
883
if (if_wait_for_refresh)
885
pthread_mutex_lock(&thd->mysys_var->mutex);
886
thd->mysys_var->current_mutex= 0;
887
thd->mysys_var->current_cond= 0;
888
thd->set_proc_info(0);
889
pthread_mutex_unlock(&thd->mysys_var->mutex);
885
pthread_mutex_lock(&session->mysys_var->mutex);
886
session->mysys_var->current_mutex= 0;
887
session->mysys_var->current_cond= 0;
888
session->set_proc_info(0);
889
pthread_mutex_unlock(&session->mysys_var->mutex);
897
897
Mark all temporary tables which were used by the current statement or
898
898
substatement as free for reuse, but only if the query_id can be cleared.
900
@param thd thread context
900
@param session thread context
902
902
@remark For temp tables associated with a open SQL HANDLER the query_id
903
903
is not reset until the HANDLER is closed.
906
static void mark_temp_tables_as_free_for_reuse(Session *thd)
906
static void mark_temp_tables_as_free_for_reuse(Session *session)
908
for (Table *table= thd->temporary_tables ; table ; table= table->next)
908
for (Table *table= session->temporary_tables ; table ; table= table->next)
910
if ((table->query_id == thd->query_id) && ! table->open_by_handler)
910
if ((table->query_id == session->query_id) && ! table->open_by_handler)
912
912
table->query_id= 0;
913
913
table->file->ha_reset();
969
969
pthread_mutex_lock(&LOCK_open);
971
while (thd->open_tables)
972
found_old_table|= close_thread_table(thd, &thd->open_tables);
973
thd->some_tables_deleted= 0;
971
while (session->open_tables)
972
found_old_table|= close_thread_table(session, &session->open_tables);
973
session->some_tables_deleted= 0;
975
975
/* Free tables to hold down open files */
976
976
while (open_cache.records > table_cache_size && unused_tables)
1003
1003
leave prelocked mode if needed.
1006
void close_thread_tables(Session *thd)
1006
void close_thread_tables(Session *session)
1011
We are assuming here that thd->derived_tables contains ONLY derived
1011
We are assuming here that session->derived_tables contains ONLY derived
1012
1012
tables for this substatement. i.e. instead of approach which uses
1013
1013
query_id matching for determining which of the derived tables belong
1014
1014
to this substatement we rely on the ability of substatements to
1015
save/restore thd->derived_tables during their execution.
1015
save/restore session->derived_tables during their execution.
1017
1017
TODO: Probably even better approach is to simply associate list of
1018
1018
derived tables with (sub-)statement instead of thread and destroy
1019
1019
them at the end of its execution.
1021
if (thd->derived_tables)
1021
if (session->derived_tables)
1025
1025
Close all derived tables generated in queries like
1026
1026
SELECT * FROM (SELECT * FROM t1)
1028
for (table= thd->derived_tables ; table ; table= next)
1028
for (table= session->derived_tables ; table ; table= next)
1030
1030
next= table->next;
1031
table->free_tmp_table(thd);
1031
table->free_tmp_table(session);
1033
thd->derived_tables= 0;
1033
session->derived_tables= 0;
1037
1037
Mark all temporary tables used by this statement as free for reuse.
1039
mark_temp_tables_as_free_for_reuse(thd);
1039
mark_temp_tables_as_free_for_reuse(session);
1041
1041
Let us commit transaction for statement. Since in 5.0 we only have
1042
1042
one statement transaction and don't allow several nested statement
1045
1045
does not belong to statement for which we do close_thread_tables()).
1046
1046
TODO: This should be fixed in later releases.
1048
if (!(thd->state_flags & Open_tables_state::BACKUPS_AVAIL))
1048
if (!(session->state_flags & Open_tables_state::BACKUPS_AVAIL))
1050
thd->main_da.can_overwrite_status= true;
1051
ha_autocommit_or_rollback(thd, thd->is_error());
1052
thd->main_da.can_overwrite_status= false;
1053
thd->transaction.stmt.reset();
1050
session->main_da.can_overwrite_status= true;
1051
ha_autocommit_or_rollback(session, session->is_error());
1052
session->main_da.can_overwrite_status= false;
1053
session->transaction.stmt.reset();
1056
if (thd->locked_tables)
1056
if (session->locked_tables)
1059
1059
/* Ensure we are calling ha_reset() for all used tables */
1060
mark_used_tables_as_free_for_reuse(thd, thd->open_tables);
1060
mark_used_tables_as_free_for_reuse(session, session->open_tables);
1063
1063
We are under simple LOCK TABLES so should not do anything else.
1076
1076
handled either before writing a query log event (inside
1077
1077
binlog_query()) or when preparing a pending event.
1079
thd->binlog_flush_pending_rows_event(true);
1080
mysql_unlock_tables(thd, thd->lock);
1079
session->binlog_flush_pending_rows_event(true);
1080
mysql_unlock_tables(session, session->lock);
1084
1084
Note that we need to hold LOCK_open while changing the
1150
1150
creates one DROP TEMPORARY Table binlog event for each pseudo-thread
1153
void close_temporary_tables(Session *thd)
1153
void close_temporary_tables(Session *session)
1156
1156
Table *next= NULL;
1157
1157
Table *prev_table;
1158
/* Assume thd->options has OPTION_QUOTE_SHOW_CREATE */
1158
/* Assume session->options has OPTION_QUOTE_SHOW_CREATE */
1159
1159
bool was_quote_show= true;
1161
if (!thd->temporary_tables)
1161
if (!session->temporary_tables)
1164
if (!mysql_bin_log.is_open() || thd->current_stmt_binlog_row_based)
1164
if (!mysql_bin_log.is_open() || session->current_stmt_binlog_row_based)
1166
1166
Table *tmp_next;
1167
for (table= thd->temporary_tables; table; table= tmp_next)
1167
for (table= session->temporary_tables; table; table= tmp_next)
1169
1169
tmp_next= table->next;
1170
1170
close_temporary(table, 1, 1);
1172
thd->temporary_tables= 0;
1172
session->temporary_tables= 0;
1197
1197
if (!found_user_tables)
1198
1198
found_user_tables= true;
1199
for (prev_sorted= NULL, sorted= thd->temporary_tables; sorted != table;
1199
for (prev_sorted= NULL, sorted= session->temporary_tables; sorted != table;
1200
1200
prev_sorted= sorted, sorted= sorted->next)
1202
1202
if (!is_user_table(sorted) ||
1203
tmpkeyval(thd, sorted) > tmpkeyval(thd, table))
1203
tmpkeyval(session, sorted) > tmpkeyval(session, table))
1205
1205
/* move into the sorted part of the list from the unsorted */
1206
1206
prev_table->next= table->next;
1223
1223
/* We always quote db,table names though it is slight overkill */
1224
1224
if (found_user_tables &&
1225
!(was_quote_show= test(thd->options & OPTION_QUOTE_SHOW_CREATE)))
1225
!(was_quote_show= test(session->options & OPTION_QUOTE_SHOW_CREATE)))
1227
thd->options |= OPTION_QUOTE_SHOW_CREATE;
1227
session->options |= OPTION_QUOTE_SHOW_CREATE;
1230
1230
/* scan sorted tmps to generate sequence of DROP */
1231
for (table= thd->temporary_tables; table; table= next)
1231
for (table= session->temporary_tables; table; table= next)
1233
1233
if (is_user_table(table))
1235
my_thread_id save_pseudo_thread_id= thd->variables.pseudo_thread_id;
1235
my_thread_id save_pseudo_thread_id= session->variables.pseudo_thread_id;
1236
1236
/* Set pseudo_thread_id to be that of the processed table */
1237
thd->variables.pseudo_thread_id= tmpkeyval(thd, table);
1237
session->variables.pseudo_thread_id= tmpkeyval(session, table);
1239
1239
Loop forward through all tables within the sublist of
1240
1240
common pseudo_thread_id to create single DROP query.
1242
1242
for (s_query.length(stub_len);
1243
1243
table && is_user_table(table) &&
1244
tmpkeyval(thd, table) == thd->variables.pseudo_thread_id;
1244
tmpkeyval(session, table) == session->variables.pseudo_thread_id;
1248
1248
We are going to add 4 ` around the db/table names and possible more
1249
1249
due to special characters in the names
1251
append_identifier(thd, &s_query, table->s->db.str, strlen(table->s->db.str));
1251
append_identifier(session, &s_query, table->s->db.str, strlen(table->s->db.str));
1252
1252
s_query.append('.');
1253
append_identifier(thd, &s_query, table->s->table_name.str,
1253
append_identifier(session, &s_query, table->s->table_name.str,
1254
1254
strlen(table->s->table_name.str));
1255
1255
s_query.append(',');
1256
1256
next= table->next;
1257
1257
close_temporary(table, 1, 1);
1260
const CHARSET_INFO * const cs_save= thd->variables.character_set_client;
1261
thd->variables.character_set_client= system_charset_info;
1262
Query_log_event qinfo(thd, s_query.ptr(),
1259
session->clear_error();
1260
const CHARSET_INFO * const cs_save= session->variables.character_set_client;
1261
session->variables.character_set_client= system_charset_info;
1262
Query_log_event qinfo(session, s_query.ptr(),
1263
1263
s_query.length() - 1 /* to remove trailing ',' */,
1265
thd->variables.character_set_client= cs_save;
1265
session->variables.character_set_client= cs_save;
1267
1267
Imagine the thread had created a temp table, then was doing a
1268
1268
SELECT, and the SELECT was killed. Then it's not clever to
1396
1396
if (((! (res= find_table_in_global_list(table_list, d_name, t_name))) &&
1397
(! (res= mysql_lock_have_duplicate(thd, table, table_list)))) ||
1397
(! (res= mysql_lock_have_duplicate(session, table, table_list)))) ||
1398
1398
((!res->table || res->table != table->table) &&
1399
1399
(!check_alias || !(lower_case_table_names ?
1400
1400
my_strcasecmp(files_charset_info, t_alias, res->alias) :
1437
Table *find_temporary_table(Session *thd, const char *db, const char *table_name)
1437
Table *find_temporary_table(Session *session, const char *db, const char *table_name)
1439
1439
TableList table_list;
1441
1441
table_list.db= (char*) db;
1442
1442
table_list.table_name= (char*) table_name;
1443
return find_temporary_table(thd, &table_list);
1443
return find_temporary_table(session, &table_list);
1447
Table *find_temporary_table(Session *thd, TableList *table_list)
1447
Table *find_temporary_table(Session *session, TableList *table_list)
1449
1449
char key[MAX_DBKEY_LENGTH];
1450
1450
uint key_length;
1453
key_length= create_table_def_key(thd, key, table_list, 1);
1454
for (table=thd->temporary_tables ; table ; table= table->next)
1453
key_length= create_table_def_key(session, key, table_list, 1);
1454
for (table=session->temporary_tables ; table ; table= table->next)
1456
1456
if (table->s->table_cache_key.length == key_length &&
1457
1457
!memcmp(table->s->table_cache_key.str, key, key_length))
1465
1465
Drop a temporary table.
1467
Try to locate the table in the list of thd->temporary_tables.
1467
Try to locate the table in the list of session->temporary_tables.
1468
1468
If the table is found:
1469
1469
- if the table is being used by some outer statement, fail.
1470
- if the table is in thd->locked_tables, unlock it and
1470
- if the table is in session->locked_tables, unlock it and
1471
1471
remove it from the list of locked tables. Currently only transactional
1472
1472
temporary tables are present in the locked_tables list.
1473
1473
- Close the temporary table, remove its .FRM
1478
1478
or ALTER Table. Even though part of the work done by this function
1479
1479
is redundant when the table is internal, as long as we
1480
1480
link both internal and user temporary tables into the same
1481
thd->temporary_tables list, it's impossible to tell here whether
1481
session->temporary_tables list, it's impossible to tell here whether
1482
1482
we're dealing with an internal or a user temporary table.
1484
1484
@retval 0 the table was found and dropped successfully.
1487
1487
@retval -1 the table is in use by a outer query
1490
int drop_temporary_table(Session *thd, TableList *table_list)
1490
int drop_temporary_table(Session *session, TableList *table_list)
1494
if (!(table= find_temporary_table(thd, table_list)))
1494
if (!(table= find_temporary_table(session, table_list)))
1497
1497
/* Table might be in use by some outer statement. */
1498
if (table->query_id && table->query_id != thd->query_id)
1498
if (table->query_id && table->query_id != session->query_id)
1500
1500
my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
1505
1505
If LOCK TABLES list is not empty and contains this table,
1506
1506
unlock the table and remove the table from this list.
1508
mysql_lock_remove(thd, thd->locked_tables, table, false);
1509
close_temporary_table(thd, table, 1, 1);
1508
mysql_lock_remove(session, session->locked_tables, table, false);
1509
close_temporary_table(session, table, 1, 1);
1514
unlink from thd->temporary tables and close temporary table
1514
unlink from session->temporary tables and close temporary table
1517
void close_temporary_table(Session *thd, Table *table,
1517
void close_temporary_table(Session *session, Table *table,
1518
1518
bool free_share, bool delete_table)
1520
1520
if (table->prev)
1528
1528
/* removing the item from the list */
1529
assert(table == thd->temporary_tables);
1529
assert(table == session->temporary_tables);
1531
1531
slave must reset its temporary list pointer to zero to exclude
1532
1532
passing non-zero value to end_slave via rli->save_temporary_tables
1533
1533
when no temp tables opened, see an invariant below.
1535
thd->temporary_tables= table->next;
1536
if (thd->temporary_tables)
1535
session->temporary_tables= table->next;
1536
if (session->temporary_tables)
1537
1537
table->next->prev= 0;
1539
if (thd->slave_thread)
1539
if (session->slave_thread)
1541
1541
/* natural invariant of temporary_tables */
1542
assert(slave_open_temp_tables || !thd->temporary_tables);
1542
assert(slave_open_temp_tables || !session->temporary_tables);
1543
1543
slave_open_temp_tables--;
1545
1545
close_temporary(table, free_share, delete_table);
1582
1582
only if the ALTER contained a RENAME clause (otherwise, table_name is the old
1584
1584
Prepares a table cache key, which is the concatenation of db, table_name and
1585
thd->slave_proxy_id, separated by '\0'.
1585
session->slave_proxy_id, separated by '\0'.
1588
bool rename_temporary_table(Session* thd, Table *table, const char *db,
1588
bool rename_temporary_table(Session* session, Table *table, const char *db,
1589
1589
const char *table_name)
1599
1599
table_list.db= (char*) db;
1600
1600
table_list.table_name= (char*) table_name;
1601
key_length= create_table_def_key(thd, key, &table_list, 1);
1601
key_length= create_table_def_key(session, key, &table_list, 1);
1602
1602
share->set_table_cache_key(key, key_length);
1652
1652
Closing a MERGE child before the parent would be fatal if the
1653
1653
other thread tries to abort the MERGE lock in between.
1655
for (prev= &thd->open_tables; *prev; )
1655
for (prev= &session->open_tables; *prev; )
1659
1659
if (list->s->table_cache_key.length == key_length &&
1660
1660
!memcmp(list->s->table_cache_key.str, key, key_length))
1662
if (unlock && thd->locked_tables)
1663
mysql_lock_remove(thd, thd->locked_tables, list, true);
1662
if (unlock && session->locked_tables)
1663
mysql_lock_remove(session, session->locked_tables, list, true);
1665
1665
/* Remove table from open_tables list. */
1666
1666
*prev= list->next;
1699
1699
table that was locked with LOCK TABLES.
1702
void drop_open_table(Session *thd, Table *table, const char *db_name,
1702
void drop_open_table(Session *session, Table *table, const char *db_name,
1703
1703
const char *table_name)
1705
1705
if (table->s->tmp_table)
1706
close_temporary_table(thd, table, 1, 1);
1706
close_temporary_table(session, table, 1, 1);
1709
1709
handlerton *table_type= table->s->db_type();
1712
1712
unlink_open_table() also tells threads waiting for refresh or close
1713
1713
that something has happened.
1715
unlink_open_table(thd, table, false);
1715
unlink_open_table(session, table, false);
1716
1716
quick_rm_table(table_type, db_name, table_name, 0);
1717
1717
pthread_mutex_unlock(&LOCK_open);
1726
1726
wait_for_condition()
1727
session Thread handler
1728
1728
mutex mutex that is currently hold that is associated with condition
1729
1729
Will be unlocked on return
1730
1730
cond Condition to wait for
1733
void wait_for_condition(Session *thd, pthread_mutex_t *mutex, pthread_cond_t *cond)
1733
void wait_for_condition(Session *session, pthread_mutex_t *mutex, pthread_cond_t *cond)
1735
1735
/* Wait until the current table is up to date */
1736
1736
const char *proc_info;
1737
thd->mysys_var->current_mutex= mutex;
1738
thd->mysys_var->current_cond= cond;
1739
proc_info=thd->get_proc_info();
1740
thd->set_proc_info("Waiting for table");
1737
session->mysys_var->current_mutex= mutex;
1738
session->mysys_var->current_cond= cond;
1739
proc_info=session->get_proc_info();
1740
session->set_proc_info("Waiting for table");
1741
if (!session->killed)
1742
1742
(void) pthread_cond_wait(cond, mutex);
1755
1755
pthread_mutex_unlock(mutex);
1756
pthread_mutex_lock(&thd->mysys_var->mutex);
1757
thd->mysys_var->current_mutex= 0;
1758
thd->mysys_var->current_cond= 0;
1759
thd->set_proc_info(proc_info);
1760
pthread_mutex_unlock(&thd->mysys_var->mutex);
1756
pthread_mutex_lock(&session->mysys_var->mutex);
1757
session->mysys_var->current_mutex= 0;
1758
session->mysys_var->current_cond= 0;
1759
session->set_proc_info(proc_info);
1760
pthread_mutex_unlock(&session->mysys_var->mutex);
1766
1766
Exclusively name-lock a table that is already write-locked by the
1767
1767
current thread.
1769
@param thd current thread context
1769
@param session current thread context
1770
1770
@param tables table list containing one table to open.
1772
1772
@return false on success, true otherwise.
1775
bool name_lock_locked_table(Session *thd, TableList *tables)
1775
bool name_lock_locked_table(Session *session, TableList *tables)
1777
1777
/* Under LOCK TABLES we must only accept write locked tables. */
1778
tables->table= find_locked_table(thd, tables->db, tables->table_name);
1778
tables->table= find_locked_table(session, tables->db, tables->table_name);
1780
1780
if (!tables->table)
1781
1781
my_error(ER_TABLE_NOT_LOCKED, MYF(0), tables->alias);
1828
1828
safe_mutex_assert_owner(&LOCK_open);
1830
if (thd->killed || !table)
1830
if (session->killed || !table)
1833
1833
orig_table= *table;
1835
if (open_unireg_entry(thd, table, table_list, table_name,
1835
if (open_unireg_entry(session, table, table_list, table_name,
1836
1836
table->s->table_cache_key.str,
1837
1837
table->s->table_cache_key.length))
1956
1956
@retval false Success. 'table' parameter set according to above rules.
1959
bool lock_table_name_if_not_cached(Session *thd, const char *db,
1959
bool lock_table_name_if_not_cached(Session *session, const char *db,
1960
1960
const char *table_name, Table **table)
1962
1962
char key[MAX_DBKEY_LENGTH];
1974
if (!(*table= table_cache_insert_placeholder(thd, key, key_length)))
1974
if (!(*table= table_cache_insert_placeholder(session, key, key_length)))
1976
1976
pthread_mutex_unlock(&LOCK_open);
1979
1979
(*table)->open_placeholder= 1;
1980
(*table)->next= thd->open_tables;
1981
thd->open_tables= *table;
1980
(*table)->next= session->open_tables;
1981
session->open_tables= *table;
1982
1982
pthread_mutex_unlock(&LOCK_open);
1988
1988
Check that table exists in table definition cache, on disk
1989
1989
or in some storage engine.
1991
@param thd Thread context
1991
@param session Thread context
1992
1992
@param table Table list element
1993
1993
@param[out] exists Out parameter which is set to true if table
1994
1994
exists and to false otherwise.
2088
2088
char *alias= table_list->alias;
2089
2089
HASH_SEARCH_STATE state;
2091
/* Parsing of partitioning information from .frm needs thd->lex set up. */
2092
assert(thd->lex->is_lex_started);
2091
/* Parsing of partitioning information from .frm needs session->lex set up. */
2092
assert(session->lex->is_lex_started);
2094
2094
/* find a unused table in the open table cache */
2098
2098
/* an open table operation needs a lot of the stack space */
2099
if (check_stack_overrun(thd, STACK_MIN_SIZE_FOR_OPEN, (unsigned char *)&alias))
2105
key_length= (create_table_def_key(thd, key, table_list, 1) -
2099
if (check_stack_overrun(session, STACK_MIN_SIZE_FOR_OPEN, (unsigned char *)&alias))
2102
if (session->killed)
2105
key_length= (create_table_def_key(session, key, table_list, 1) -
2106
2106
TMP_TABLE_KEY_EXTRA);
2151
2151
open not pre-opened tables in pre-locked/LOCK TABLES mode.
2152
2152
TODO: move this block into a separate function.
2154
if (thd->locked_tables)
2154
if (session->locked_tables)
2155
2155
{ // Using table locks
2156
2156
Table *best_table= 0;
2157
2157
int best_distance= INT_MIN;
2158
2158
bool check_if_used= false;
2159
for (table=thd->open_tables; table ; table=table->next)
2159
for (table=session->open_tables; table ; table=table->next)
2161
2161
if (table->s->table_cache_key.length == key_length &&
2162
2162
!memcmp(table->s->table_cache_key.str, key, key_length))
2164
2164
if (check_if_used && table->query_id &&
2165
table->query_id != thd->query_id)
2165
table->query_id != session->query_id)
2168
2168
If we are in stored function or trigger we should ensure that
2256
2256
and try to reopen them.
2257
2257
Note: refresh_version is currently changed only during FLUSH TABLES.
2259
if (!thd->open_tables)
2260
thd->version=refresh_version;
2261
else if ((thd->version != refresh_version) &&
2259
if (!session->open_tables)
2260
session->version=refresh_version;
2261
else if ((session->version != refresh_version) &&
2262
2262
! (flags & DRIZZLE_LOCK_IGNORE_FLUSH))
2264
2264
/* Someone did a refresh while thread was opening tables */
2317
2317
if (flags & DRIZZLE_LOCK_IGNORE_FLUSH)
2319
2319
/* Force close at once after usage */
2320
thd->version= table->s->version;
2320
session->version= table->s->version;
2324
2324
/* Avoid self-deadlocks by detecting self-dependencies. */
2325
if (table->open_placeholder && table->in_use == thd)
2325
if (table->open_placeholder && table->in_use == session)
2327
2327
pthread_mutex_unlock(&LOCK_open);
2328
2328
my_error(ER_UPDATE_TABLE_USED, MYF(0), table->s->table_name.str);
2342
2342
the earlier call to mysql_ha_flush() in this same critical
2345
close_old_data_files(thd,thd->open_tables,0,0);
2345
close_old_data_files(session,session->open_tables,0,0);
2347
2347
Back-off part 2: try to avoid "busy waiting" on the table:
2348
2348
if the table is in use by some other thread, we suspend
2358
2358
after we open first instance but before we open second
2361
if (table->in_use != thd)
2361
if (table->in_use != session)
2363
2363
/* wait_for_conditionwill unlock LOCK_open for us */
2364
wait_for_condition(thd, &LOCK_open, &COND_refresh);
2364
wait_for_condition(session, &LOCK_open, &COND_refresh);
2441
error= open_unireg_entry(thd, table, table_list, alias, key, key_length);
2441
error= open_unireg_entry(session, table, table_list, alias, key, key_length);
2442
2442
/* Combine the follow two */
2458
2458
pthread_mutex_unlock(&LOCK_open);
2461
table->next=thd->open_tables; /* Link into simple list */
2462
thd->open_tables=table;
2461
table->next=session->open_tables; /* Link into simple list */
2462
session->open_tables=table;
2464
2464
table->reginfo.lock_type=TL_READ; /* Assume read */
2467
2467
assert(table->s->ref_count > 0 || table->s->tmp_table != NO_TMP_TABLE);
2469
if (thd->lex->need_correct_ident())
2469
if (session->lex->need_correct_ident())
2470
2470
table->alias_name_used= my_strcasecmp(table_alias_charset,
2471
2471
table->s->table_name.str, alias);
2472
2472
/* Fix alias if table name changes */
2501
Table *find_locked_table(Session *thd, const char *db,const char *table_name)
2501
Table *find_locked_table(Session *session, const char *db,const char *table_name)
2503
2503
char key[MAX_DBKEY_LENGTH];
2504
2504
uint32_t key_length=(uint) (my_stpcpy(my_stpcpy(key,db)+1,table_name)-key)+1;
2506
for (Table *table=thd->open_tables; table ; table=table->next)
2506
for (Table *table=session->open_tables; table ; table=table->next)
2508
2508
if (table->s->table_cache_key.length == key_length &&
2509
2509
!memcmp(table->s->table_cache_key.str, key, key_length))
2551
2551
table_list.table_name= table->s->table_name.str;
2552
2552
table_list.table= table;
2554
if (wait_for_locked_table_names(thd, &table_list))
2554
if (wait_for_locked_table_names(session, &table_list))
2555
2555
return(1); // Thread was killed
2557
if (open_unireg_entry(thd, &tmp, &table_list,
2557
if (open_unireg_entry(session, &tmp, &table_list,
2559
2559
table->s->table_cache_key.str,
2560
2560
table->s->table_cache_key.length))
2627
2627
the strings are used in a loop even after the share may be freed.
2630
void close_data_files_and_morph_locks(Session *thd, const char *db,
2630
void close_data_files_and_morph_locks(Session *session, const char *db,
2631
2631
const char *table_name)
2635
2635
safe_mutex_assert_owner(&LOCK_open);
2640
2640
If we are not under LOCK TABLES we should have only one table
2641
2641
open and locked so it makes sense to remove the lock at once.
2643
mysql_unlock_tables(thd, thd->lock);
2643
mysql_unlock_tables(session, session->lock);
2649
2649
for target table name if we process ALTER Table ... RENAME.
2650
2650
So loop below makes sense even if we are not under LOCK TABLES.
2652
for (table=thd->open_tables; table ; table=table->next)
2652
for (table=session->open_tables; table ; table=table->next)
2654
2654
if (!strcmp(table->s->table_name.str, table_name) &&
2655
2655
!strcmp(table->s->db.str, db))
2657
if (thd->locked_tables)
2657
if (session->locked_tables)
2659
mysql_lock_remove(thd, thd->locked_tables, table, true);
2659
mysql_lock_remove(session, session->locked_tables, table, true);
2661
2661
table->open_placeholder= 1;
2662
2662
close_handle_and_leave_table_as_lock(table);
2686
2686
@return false in case of success, true - otherwise.
2689
bool reopen_tables(Session *thd, bool get_locks, bool mark_share_as_old)
2689
bool reopen_tables(Session *session, bool get_locks, bool mark_share_as_old)
2691
2691
Table *table,*next,**prev;
2692
2692
Table **tables,**tables_ptr; // For locks
2706
2706
Do not handle locks of MERGE children.
2708
2708
uint32_t opens=0;
2709
for (table= thd->open_tables; table ; table=table->next)
2709
for (table= session->open_tables; table ; table=table->next)
2711
2711
tables= (Table**) my_alloca(sizeof(Table*)*opens);
2714
tables= &thd->open_tables;
2714
tables= &session->open_tables;
2715
2715
tables_ptr =tables;
2717
prev= &thd->open_tables;
2718
for (table=thd->open_tables; table ; table=next)
2717
prev= &session->open_tables;
2718
for (table=session->open_tables; table ; table=next)
2720
2720
uint32_t db_stat=table->db_stat;
2721
2721
next=table->next;
2748
2748
wait_for_tables() as it tries to acquire LOCK_open, which is
2749
2749
already locked.
2751
thd->some_tables_deleted=0;
2752
if ((lock= mysql_lock_tables(thd, tables, (uint) (tables_ptr - tables),
2751
session->some_tables_deleted=0;
2752
if ((lock= mysql_lock_tables(session, tables, (uint) (tables_ptr - tables),
2753
2753
flags, ¬_used)))
2755
thd->locked_tables=mysql_lock_merge(thd->locked_tables,lock);
2755
session->locked_tables=mysql_lock_merge(session->locked_tables,lock);
2778
2778
Close handlers for tables in list, but leave the Table structure
2779
2779
intact so that we can re-open these quickly.
2781
@param thd Thread context
2781
@param session Thread context
2782
2782
@param table Head of the list of Table objects
2783
2783
@param morph_locks true - remove locks which we have on tables being closed
2784
2784
but ensure that no DML or DDL will sneak in before
2814
2814
lock on it. This will also give them a chance to close their
2815
2815
instances of this table.
2817
mysql_lock_abort(thd, ulcktbl, true);
2818
mysql_lock_remove(thd, thd->locked_tables, ulcktbl, true);
2817
mysql_lock_abort(session, ulcktbl, true);
2818
mysql_lock_remove(session, session->locked_tables, ulcktbl, true);
2819
2819
ulcktbl->lock_count= 0;
2821
2821
if ((ulcktbl != table) && ulcktbl->db_stat)
2901
2901
/* Wait until all used tables are refreshed */
2903
bool wait_for_tables(Session *thd)
2903
bool wait_for_tables(Session *session)
2907
thd->set_proc_info("Waiting for tables");
2907
session->set_proc_info("Waiting for tables");
2908
2908
pthread_mutex_lock(&LOCK_open);
2909
while (!thd->killed)
2909
while (!session->killed)
2911
thd->some_tables_deleted=0;
2912
close_old_data_files(thd,thd->open_tables,0,dropping_tables != 0);
2913
mysql_ha_flush(thd);
2914
if (!table_is_used(thd->open_tables,1))
2911
session->some_tables_deleted=0;
2912
close_old_data_files(session,session->open_tables,0,dropping_tables != 0);
2913
mysql_ha_flush(session);
2914
if (!table_is_used(session->open_tables,1))
2916
2916
(void) pthread_cond_wait(&COND_refresh,&LOCK_open);
2918
if (session->killed)
2919
2919
result= 1; // aborted
2922
2922
/* Now we can open all tables without any interference */
2923
thd->set_proc_info("Reopen tables");
2924
thd->version= refresh_version;
2925
result=reopen_tables(thd,0,0);
2923
session->set_proc_info("Reopen tables");
2924
session->version= refresh_version;
2925
result=reopen_tables(session,0,0);
2927
2927
pthread_mutex_unlock(&LOCK_open);
2928
thd->set_proc_info(0);
2928
session->set_proc_info(0);
2929
2929
return(result);
2957
Table *drop_locked_tables(Session *thd,const char *db, const char *table_name)
2957
Table *drop_locked_tables(Session *session,const char *db, const char *table_name)
2959
2959
Table *table,*next,**prev, *found= 0;
2960
prev= &thd->open_tables;
2960
prev= &session->open_tables;
2963
2963
Note that we need to hold LOCK_open while changing the
2966
2966
Closing a MERGE child before the parent would be fatal if the
2967
2967
other thread tries to abort the MERGE lock in between.
2969
for (table= thd->open_tables; table ; table=next)
2969
for (table= session->open_tables; table ; table=next)
2971
2971
next=table->next;
2972
2972
if (!strcmp(table->s->table_name.str, table_name) &&
2973
2973
!strcmp(table->s->db.str, db))
2975
mysql_lock_remove(thd, thd->locked_tables, table, true);
2975
mysql_lock_remove(session, session->locked_tables, table, true);
3014
3014
other threads trying to get the lock.
3017
void abort_locked_tables(Session *thd,const char *db, const char *table_name)
3017
void abort_locked_tables(Session *session,const char *db, const char *table_name)
3020
for (table= thd->open_tables; table ; table= table->next)
3020
for (table= session->open_tables; table ; table= table->next)
3022
3022
if (!strcmp(table->s->table_name.str, table_name) &&
3023
3023
!strcmp(table->s->db.str, db))
3025
3025
/* If MERGE child, forward lock handling to parent. */
3026
mysql_lock_abort(thd, table, true);
3026
mysql_lock_abort(session, table, true);
3114
3114
safe_mutex_assert_owner(&LOCK_open);
3116
if (!(share= get_table_share_with_create(thd, table_list, cache_key,
3116
if (!(share= get_table_share_with_create(session, table_list, cache_key,
3117
3117
cache_key_length,
3118
3118
table_list->i_s_requested_object,
3122
while ((error= open_table_from_share(thd, share, alias,
3122
while ((error= open_table_from_share(session, share, alias,
3123
3123
(uint) (HA_OPEN_KEYFILE |
3124
3124
HA_OPEN_RNDFILE |
3126
3126
HA_TRY_READ_ONLY),
3127
3127
(EXTRA_RECORD),
3128
thd->open_options, entry, OTM_OPEN)))
3128
session->open_options, entry, OTM_OPEN)))
3130
3130
if (error == 7) // Table def changed
3159
3159
/* Free share and wait until it's released by all threads */
3160
3160
release_table_share(share, RELEASE_WAIT_FOR_DROP);
3161
if (!session->killed)
3163
drizzle_reset_errors(thd, 1); // Clear warnings
3164
thd->clear_error(); // Clear error message
3163
drizzle_reset_errors(session, 1); // Clear warnings
3164
session->clear_error(); // Clear error message
3169
3169
if (!entry->s || !entry->s->crashed)
3171
3171
// Code below is for repairing a crashed file
3172
if ((error= lock_table_name(thd, table_list, true)))
3172
if ((error= lock_table_name(session, table_list, true)))
3176
if (wait_for_locked_table_names(thd, table_list))
3176
if (wait_for_locked_table_names(session, table_list))
3178
unlock_table_name(thd, table_list);
3178
unlock_table_name(session, table_list);
3182
3182
pthread_mutex_unlock(&LOCK_open);
3183
thd->clear_error(); // Clear error message
3183
session->clear_error(); // Clear error message
3185
if (open_table_from_share(thd, share, alias,
3185
if (open_table_from_share(session, share, alias,
3186
3186
(uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
3188
3188
HA_TRY_READ_ONLY),
3190
3190
ha_open_options | HA_OPEN_FOR_REPAIR,
3191
3191
entry, OTM_OPEN) || ! entry->file ||
3192
(entry->file->is_crashed() && entry->file->ha_check_and_repair(thd)))
3192
(entry->file->is_crashed() && entry->file->ha_check_and_repair(session)))
3194
3194
/* Give right error message */
3195
session->clear_error();
3196
3196
my_error(ER_NOT_KEYFILE, MYF(0), share->table_name.str, my_errno);
3197
3197
sql_print_error(_("Couldn't repair table: %s.%s"), share->db.str,
3198
3198
share->table_name.str);
3226
3226
/* this DELETE FROM is needed even with row-based binlogging */
3227
3227
end = strxmov(my_stpcpy(query, "DELETE FROM `"),
3228
3228
share->db.str,"`.`",share->table_name.str,"`", NULL);
3229
thd->binlog_query(Session::STMT_QUERY_TYPE,
3229
session->binlog_query(Session::STMT_QUERY_TYPE,
3230
3230
query, (ulong)(end-query), false, false);
3370
3370
result= -1; // Fatal error
3373
if (tables->lock_type != TL_UNLOCK && ! thd->locked_tables)
3373
if (tables->lock_type != TL_UNLOCK && ! session->locked_tables)
3375
3375
if (tables->lock_type == TL_WRITE_DEFAULT)
3376
tables->table->reginfo.lock_type= thd->update_lock_default;
3376
tables->table->reginfo.lock_type= session->update_lock_default;
3377
3377
else if (tables->table->s->tmp_table == NO_TMP_TABLE)
3378
3378
tables->table->reginfo.lock_type= tables->lock_type;
3382
thd->set_proc_info(0);
3382
session->set_proc_info(0);
3383
3383
free_root(&new_frm_mem, MYF(0)); // Free pre-alloced block
3385
3385
if (result && tables)
3388
3388
Some functions determine success as (tables->table != NULL).
3389
tables->table is in thd->open_tables.
3389
tables->table is in session->open_tables.
3391
3391
tables->table= NULL;
3506
3506
table_list->table table
3509
Table *open_ltable(Session *thd, TableList *table_list, thr_lock_type lock_type,
3509
Table *open_ltable(Session *session, TableList *table_list, thr_lock_type lock_type,
3510
3510
uint32_t lock_flags)
3515
thd->set_proc_info("Opening table");
3516
thd->current_tablenr= 0;
3517
while (!(table= open_table(thd, table_list, &refresh, 0)) &&
3515
session->set_proc_info("Opening table");
3516
session->current_tablenr= 0;
3517
while (!(table= open_table(session, table_list, &refresh, 0)) &&
3523
3523
table_list->lock_type= lock_type;
3524
3524
table_list->table= table;
3525
if (thd->locked_tables)
3525
if (session->locked_tables)
3527
if (check_lock_and_start_stmt(thd, table, lock_type))
3527
if (check_lock_and_start_stmt(session, table, lock_type))
3532
assert(thd->lock == 0); // You must lock everything at once
3532
assert(session->lock == 0); // You must lock everything at once
3533
3533
if ((table->reginfo.lock_type= lock_type) != TL_UNLOCK)
3534
if (! (thd->lock= mysql_lock_tables(thd, &table_list->table, 1,
3534
if (! (session->lock= mysql_lock_tables(session, &table_list->table, 1,
3535
3535
lock_flags, &refresh)))
3540
thd->set_proc_info(0);
3540
session->set_proc_info(0);
3562
3562
There are two convenience functions:
3563
- simple_open_n_lock_tables(thd, tables) without derived handling
3564
- open_and_lock_tables(thd, tables) with derived handling
3563
- simple_open_n_lock_tables(session, tables) without derived handling
3564
- open_and_lock_tables(session, tables) with derived handling
3565
3565
Both inline functions call open_and_lock_tables_derived() with
3566
3566
the third argument set appropriately.
3569
int open_and_lock_tables_derived(Session *thd, TableList *tables, bool derived)
3569
int open_and_lock_tables_derived(Session *session, TableList *tables, bool derived)
3571
3571
uint32_t counter;
3572
3572
bool need_reopen;
3576
if (open_tables(thd, &tables, &counter, 0))
3576
if (open_tables(session, &tables, &counter, 0))
3579
if (!lock_tables(thd, tables, counter, &need_reopen))
3579
if (!lock_tables(session, tables, counter, &need_reopen))
3581
3581
if (!need_reopen)
3583
close_tables_for_reopen(thd, &tables);
3583
close_tables_for_reopen(session, &tables);
3586
(mysql_handle_derived(thd->lex, &mysql_derived_prepare) ||
3587
(thd->fill_derived_tables() &&
3588
mysql_handle_derived(thd->lex, &mysql_derived_filling))))
3586
(mysql_handle_derived(session->lex, &mysql_derived_prepare) ||
3587
(session->fill_derived_tables() &&
3588
mysql_handle_derived(session->lex, &mysql_derived_filling))))
3589
3589
return(true); /* purecov: inspected */
3611
3611
data from the tables.
3614
bool open_normal_and_derived_tables(Session *thd, TableList *tables, uint32_t flags)
3614
bool open_normal_and_derived_tables(Session *session, TableList *tables, uint32_t flags)
3616
3616
uint32_t counter;
3617
assert(!thd->fill_derived_tables());
3618
if (open_tables(thd, &tables, &counter, flags) ||
3619
mysql_handle_derived(thd->lex, &mysql_derived_prepare))
3617
assert(!session->fill_derived_tables());
3618
if (open_tables(session, &tables, &counter, flags) ||
3619
mysql_handle_derived(session->lex, &mysql_derived_prepare))
3620
3620
return(true); /* purecov: inspected */
3656
3656
3. Otherwise, statement-based logging is used.
3658
@param thd Client thread
3658
@param session Client thread
3659
3659
@param tables Tables involved in the query
3662
int decide_logging_format(Session *thd, TableList *tables)
3662
int decide_logging_format(Session *session, TableList *tables)
3664
if (mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG))
3664
if (mysql_bin_log.is_open() && (session->options & OPTION_BIN_LOG))
3666
3666
handler::Table_flags flags_some_set= handler::Table_flags();
3667
3667
handler::Table_flags flags_all_set= ~handler::Table_flags();
3687
3687
"Statement cannot be logged to the binary log in"
3688
3688
" row-based nor statement-based format");
3690
else if (thd->variables.binlog_format == BINLOG_FORMAT_STMT &&
3690
else if (session->variables.binlog_format == BINLOG_FORMAT_STMT &&
3691
3691
(flags_all_set & HA_BINLOG_STMT_CAPABLE) == 0)
3693
3693
my_error((error= ER_BINLOG_LOGGING_IMPOSSIBLE), MYF(0),
3694
3694
"Statement-based format required for this statement,"
3695
3695
" but not allowed by this combination of engines");
3697
else if ((thd->variables.binlog_format == BINLOG_FORMAT_ROW ||
3698
thd->lex->is_stmt_unsafe()) &&
3697
else if ((session->variables.binlog_format == BINLOG_FORMAT_ROW ||
3698
session->lex->is_stmt_unsafe()) &&
3699
3699
(flags_all_set & HA_BINLOG_ROW_CAPABLE) == 0)
3701
3701
my_error((error= ER_BINLOG_LOGGING_IMPOSSIBLE), MYF(0),
3750
3750
If query for which we are calling this function marked as requring
3751
3751
prelocking, this function will do implicit LOCK TABLES and change
3752
thd::prelocked_mode accordingly.
3752
session::prelocked_mode accordingly.
3759
int lock_tables(Session *thd, TableList *tables, uint32_t count, bool *need_reopen)
3759
int lock_tables(Session *session, TableList *tables, uint32_t count, bool *need_reopen)
3761
3761
TableList *table;
3767
3767
*need_reopen= false;
3770
return(decide_logging_format(thd, tables));
3770
return(decide_logging_format(session, tables));
3772
if (!thd->locked_tables)
3772
if (!session->locked_tables)
3774
assert(thd->lock == 0); // You must lock everything at once
3774
assert(session->lock == 0); // You must lock everything at once
3775
3775
Table **start,**ptr;
3776
3776
uint32_t lock_flag= DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN;
3778
if (!(ptr=start=(Table**) thd->alloc(sizeof(Table*)*count)))
3778
if (!(ptr=start=(Table**) session->alloc(sizeof(Table*)*count)))
3780
3780
for (table= tables; table; table= table->next_global)
3805
3805
table= table->next_global)
3807
3807
if (!table->placeholder() &&
3808
check_lock_and_start_stmt(thd, table->table, table->lock_type))
3808
check_lock_and_start_stmt(session, table->table, table->lock_type))
3815
return(decide_logging_format(thd, tables));
3815
return(decide_logging_format(session, tables));
3824
3824
close_tables_for_reopen()
3825
thd in Thread context
3825
session in Thread context
3826
3826
tables in/out List of tables which we were trying to open and lock
3830
void close_tables_for_reopen(Session *thd, TableList **tables)
3830
void close_tables_for_reopen(Session *session, TableList **tables)
3833
3833
If table list consists only from tables from prelocking set, table list
3834
3834
for new attempt should be empty, so we have to update list's root pointer.
3836
if (thd->lex->first_not_own_table() == *tables)
3836
if (session->lex->first_not_own_table() == *tables)
3838
thd->lex->chop_off_not_own_tables();
3838
session->lex->chop_off_not_own_tables();
3839
3839
for (TableList *tmp= *tables; tmp; tmp= tmp->next_global)
3841
close_thread_tables(thd);
3841
close_thread_tables(session);
3865
Table *open_temporary_table(Session *thd, const char *path, const char *db,
3865
Table *open_temporary_table(Session *session, const char *path, const char *db,
3866
3866
const char *table_name, bool link_in_list,
3867
3867
open_table_mode open_mode)
3875
3875
table_list.db= (char*) db;
3876
3876
table_list.table_name= (char*) table_name;
3877
3877
/* Create the cache_key for temporary tables */
3878
key_length= create_table_def_key(thd, cache_key, &table_list, 1);
3878
key_length= create_table_def_key(session, cache_key, &table_list, 1);
3880
3880
if (!(tmp_table= (Table*) my_malloc(sizeof(*tmp_table) + sizeof(*share) +
3881
3881
strlen(path)+1 + key_length,
3887
3887
saved_cache_key= my_stpcpy(tmp_path, path)+1;
3888
3888
memcpy(saved_cache_key, cache_key, key_length);
3890
init_tmp_table_share(thd, share, saved_cache_key, key_length,
3890
init_tmp_table_share(session, share, saved_cache_key, key_length,
3891
3891
strchr(saved_cache_key, '\0')+1, tmp_path);
3893
if (open_table_def(thd, share, 0) ||
3894
open_table_from_share(thd, share, table_name,
3893
if (open_table_def(session, share, 0) ||
3894
open_table_from_share(session, share, table_name,
3895
3895
(open_mode == OTM_ALTER) ? 0 :
3896
3896
(uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
3923
3923
if (link_in_list)
3925
3925
/* growing temp list at the head */
3926
tmp_table->next= thd->temporary_tables;
3926
tmp_table->next= session->temporary_tables;
3927
3927
if (tmp_table->next)
3928
3928
tmp_table->next->prev= tmp_table;
3929
thd->temporary_tables= tmp_table;
3930
thd->temporary_tables->prev= 0;
3931
if (thd->slave_thread)
3929
session->temporary_tables= tmp_table;
3930
session->temporary_tables->prev= 0;
3931
if (session->slave_thread)
3932
3932
slave_open_temp_tables++;
3934
3934
tmp_table->pos_in_table_list= 0;
3946
3946
if (my_delete(path,MYF(0)))
3947
3947
error=1; /* purecov: inspected */
3948
3948
*ext= 0; // remove extension
3949
file= get_new_handler((TABLE_SHARE*) 0, current_thd->mem_root, base);
3949
file= get_new_handler((TABLE_SHARE*) 0, current_session->mem_root, base);
3950
3950
if (!frm_only && file && file->ha_delete_table(path))
3974
3974
#define WRONG_GRANT (Field*) -1
3976
static void update_field_dependencies(Session *thd, Field *field, Table *table)
3976
static void update_field_dependencies(Session *session, Field *field, Table *table)
3978
if (thd->mark_used_columns != MARK_COLUMNS_NONE)
3978
if (session->mark_used_columns != MARK_COLUMNS_NONE)
3980
3980
MY_BITMAP *current_bitmap, *other_bitmap;
4047
find_field_in_natural_join(Session *thd, TableList *table_ref, const char *name,
4047
find_field_in_natural_join(Session *session, TableList *table_ref, const char *name,
4048
4048
uint32_t length __attribute__((unused)),
4049
4049
Item **ref __attribute__((unused)), bool register_tree_change __attribute__((unused)),
4050
4050
TableList **actual_table)
4076
4076
/* This is a base table. */
4077
4077
assert(nj_col->table_ref->table == nj_col->table_field->table);
4078
4078
found_field= nj_col->table_field;
4079
update_field_dependencies(thd, found_field, nj_col->table_ref->table);
4079
update_field_dependencies(session, found_field, nj_col->table_ref->table);
4082
4082
*actual_table= nj_col->table_ref;
4107
find_field_in_table(Session *thd, Table *table, const char *name, uint32_t length,
4107
find_field_in_table(Session *session, Table *table, const char *name, uint32_t length,
4108
4108
bool allow_rowid, uint32_t *cached_field_index_ptr)
4110
4110
Field **field_ptr, *field;
4151
4151
1) this procedure is called for a read-only operation (SELECT), and
4152
4152
2) the virtual column is not phycically stored in the table
4154
if ((thd->mark_used_columns != MARK_COLUMNS_WRITE) &&
4154
if ((session->mark_used_columns != MARK_COLUMNS_WRITE) &&
4155
4155
(not (*field_ptr)->is_stored))
4156
4156
bitmap_set_bit((*field_ptr)->table->write_set, (*field_ptr)->field_index);
4220
find_field_in_table_ref(Session *thd, TableList *table_list,
4220
find_field_in_table_ref(Session *session, TableList *table_list,
4221
4221
const char *name, uint32_t length,
4222
4222
const char *item_name, const char *db_name,
4223
4223
const char *table_name, Item **ref,
4272
4272
/* 'table_list' is a stored table. */
4273
4273
assert(table_list->table);
4274
if ((fld= find_field_in_table(thd, table_list->table, name, length,
4274
if ((fld= find_field_in_table(session, table_list->table, name, length,
4276
4276
cached_field_index_ptr)))
4277
4277
*actual_table= table_list;
4291
4291
TableList *table;
4292
4292
while ((table= it++))
4294
if ((fld= find_field_in_table_ref(thd, table, name, length, item_name,
4294
if ((fld= find_field_in_table_ref(session, table, name, length, item_name,
4295
4295
db_name, table_name, ref,
4296
4296
check_privileges, allow_rowid,
4297
4297
cached_field_index_ptr,
4306
4306
natural join, thus if the field is not qualified, we will search
4307
4307
directly the top-most NATURAL/USING join.
4309
fld= find_field_in_natural_join(thd, table_list, name, length, ref,
4309
fld= find_field_in_natural_join(session, table_list, name, length, ref,
4310
4310
register_tree_change, actual_table);
4315
if (thd->mark_used_columns != MARK_COLUMNS_NONE)
4315
if (session->mark_used_columns != MARK_COLUMNS_NONE)
4318
4318
Get rw_set correct for this field so that the handler
4431
find_field_in_tables(Session *thd, Item_ident *item,
4431
find_field_in_tables(Session *session, Item_ident *item,
4432
4432
TableList *first_table, TableList *last_table,
4433
4433
Item **ref, find_item_error_report_type report_error,
4434
4434
bool check_privileges, bool register_tree_change)
4469
4469
when table_ref->field_translation != NULL.
4471
4471
if (table_ref->table)
4472
found= find_field_in_table(thd, table_ref->table, name, length,
4472
found= find_field_in_table(session, table_ref->table, name, length,
4473
4473
true, &(item->cached_field_index));
4475
found= find_field_in_table_ref(thd, table_ref, name, length, item->name,
4475
found= find_field_in_table_ref(session, table_ref, name, length, item->name,
4476
4476
NULL, NULL, ref, check_privileges,
4477
4477
true, &(item->cached_field_index),
4478
4478
register_tree_change,
4490
SELECT_LEX *current_sel= thd->lex->current_select;
4490
SELECT_LEX *current_sel= session->lex->current_select;
4491
4491
SELECT_LEX *last_select= table_ref->select_lex;
4493
4493
If the field was an outer referencee, mark all selects using this
4494
4494
sub query as dependent on the outer query
4496
4496
if (current_sel != last_select)
4497
mark_select_range_as_dependent(thd, last_select, current_sel,
4497
mark_select_range_as_dependent(session, last_select, current_sel,
4498
4498
found, *ref, item);
4519
4519
for (; cur_table != last_table ;
4520
4520
cur_table= cur_table->next_name_resolution_table)
4522
Field *cur_field= find_field_in_table_ref(thd, cur_table, name, length,
4522
Field *cur_field= find_field_in_table_ref(session, cur_table, name, length,
4523
4523
item->name, db, table_name, ref,
4524
(thd->lex->sql_command ==
4524
(session->lex->sql_command ==
4525
4525
SQLCOM_SHOW_FIELDS)
4526
4526
? false : check_privileges,
4533
4533
if (cur_field == WRONG_GRANT)
4535
if (thd->lex->sql_command != SQLCOM_SHOW_FIELDS)
4535
if (session->lex->sql_command != SQLCOM_SHOW_FIELDS)
4536
4536
return (Field*) 0;
4539
cur_field= find_field_in_table_ref(thd, cur_table, name, length,
4538
session->clear_error();
4539
cur_field= find_field_in_table_ref(session, cur_table, name, length,
4540
4540
item->name, db, table_name, ref,
4600
4600
strxnmov(buff,sizeof(buff)-1,db,".",table_name,NULL);
4601
4601
table_name=buff;
4603
my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, thd->where);
4603
my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, session->where);
4607
4607
if (report_error == REPORT_ALL_ERRORS ||
4608
4608
report_error == REPORT_EXCEPT_NON_UNIQUE)
4609
my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), thd->where);
4609
my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), session->where);
4611
4611
found= not_found_field;
4925
set_new_item_local_context(Session *thd, Item_ident *item, TableList *table_ref)
4925
set_new_item_local_context(Session *session, Item_ident *item, TableList *table_ref)
4927
4927
Name_resolution_context *context;
4928
if (!(context= new (thd->mem_root) Name_resolution_context))
4928
if (!(context= new (session->mem_root) Name_resolution_context))
4930
4930
context->init();
4931
4931
context->first_name_resolution_table=
4970
mark_common_columns(Session *thd, TableList *table_ref_1, TableList *table_ref_2,
4970
mark_common_columns(Session *session, TableList *table_ref_1, TableList *table_ref_2,
4971
4971
List<String> *using_fields, uint32_t *found_using_fields)
4973
4973
Field_iterator_table_ref it_1, it_2;
5058
5058
if (nj_col_2 && (!using_fields ||is_using_column_1))
5060
Item *item_1= nj_col_1->create_item(thd);
5061
Item *item_2= nj_col_2->create_item(thd);
5060
Item *item_1= nj_col_1->create_item(session);
5061
Item *item_2= nj_col_2->create_item(session);
5062
5062
Field *field_1= nj_col_1->field();
5063
5063
Field *field_2= nj_col_2->field();
5064
5064
Item_ident *item_ident_1, *item_ident_2;
5088
5088
resolution of these items, and to enable proper name resolution of
5089
5089
the items during the execute phase of PS.
5091
if (set_new_item_local_context(thd, item_ident_1, nj_col_1->table_ref) ||
5092
set_new_item_local_context(thd, item_ident_2, nj_col_2->table_ref))
5091
if (set_new_item_local_context(session, item_ident_1, nj_col_1->table_ref) ||
5092
set_new_item_local_context(session, item_ident_2, nj_col_2->table_ref))
5095
5095
if (!(eq_cond= new Item_func_eq(item_ident_1, item_ident_2)))
5348
5348
same_level_right_neighbor : right_neighbor;
5350
5350
if (cur_table_ref->nested_join &&
5351
store_top_level_join_columns(thd, cur_table_ref,
5351
store_top_level_join_columns(session, cur_table_ref,
5352
5352
real_left_neighbor, real_right_neighbor))
5354
5354
same_level_right_neighbor= cur_table_ref;
5381
5381
if (table_ref_2->outer_join & JOIN_TYPE_RIGHT)
5382
5382
std::swap(table_ref_1, table_ref_2);
5383
if (mark_common_columns(thd, table_ref_1, table_ref_2,
5383
if (mark_common_columns(session, table_ref_1, table_ref_2,
5384
5384
using_fields, &found_using_fields))
5392
5392
if (table_ref_1->outer_join & JOIN_TYPE_RIGHT)
5393
5393
std::swap(table_ref_1, table_ref_2);
5394
if (store_natural_using_join_columns(thd, table_ref, table_ref_1,
5394
if (store_natural_using_join_columns(session, table_ref, table_ref_1,
5395
5395
table_ref_2, using_fields,
5396
5396
found_using_fields))
5459
static bool setup_natural_join_row_types(Session *thd,
5459
static bool setup_natural_join_row_types(Session *session,
5460
5460
List<TableList> *from_clause,
5461
5461
Name_resolution_context *context)
5463
thd->where= "from clause";
5463
session->where= "from clause";
5464
5464
if (from_clause->elements == 0)
5465
5465
return false; /* We come here in the case of UNIONs. */
5506
5506
** Expand all '*' in given fields
5507
5507
****************************************************************************/
5509
int setup_wild(Session *thd,
5509
int setup_wild(Session *session,
5510
5510
TableList *tables __attribute__((unused)),
5511
5511
List<Item> &fields,
5512
5512
List<Item> *sum_func_list,
5540
5540
it.replace(new Item_int("Not_used", (int64_t) 1,
5541
5541
MY_INT64_NUM_DECIMAL_DIGITS));
5543
else if (insert_fields(thd, ((Item_field*) item)->context,
5543
else if (insert_fields(session, ((Item_field*) item)->context,
5544
5544
((Item_field*) item)->db_name,
5545
5545
((Item_field*) item)->table_name, &it,
5546
5546
any_privileges))
5569
5569
** Check that all given fields exists and fill struct with current data
5570
5570
****************************************************************************/
5572
bool setup_fields(Session *thd, Item **ref_pointer_array,
5572
bool setup_fields(Session *session, Item **ref_pointer_array,
5573
5573
List<Item> &fields, enum_mark_columns mark_used_columns,
5574
5574
List<Item> *sum_func_list, bool allow_sum_func)
5576
5576
register Item *item;
5577
enum_mark_columns save_mark_used_columns= thd->mark_used_columns;
5578
nesting_map save_allow_sum_func= thd->lex->allow_sum_func;
5577
enum_mark_columns save_mark_used_columns= session->mark_used_columns;
5578
nesting_map save_allow_sum_func= session->lex->allow_sum_func;
5579
5579
List_iterator<Item> it(fields);
5580
5580
bool save_is_item_list_lookup;
5582
thd->mark_used_columns= mark_used_columns;
5582
session->mark_used_columns= mark_used_columns;
5583
5583
if (allow_sum_func)
5584
thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
5585
thd->where= Session::DEFAULT_WHERE;
5586
save_is_item_list_lookup= thd->lex->current_select->is_item_list_lookup;
5587
thd->lex->current_select->is_item_list_lookup= 0;
5584
session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
5585
session->where= Session::DEFAULT_WHERE;
5586
save_is_item_list_lookup= session->lex->current_select->is_item_list_lookup;
5587
session->lex->current_select->is_item_list_lookup= 0;
5590
5590
To prevent fail on forward lookup we fill it with zerows,
5601
5601
memset(ref_pointer_array, 0, sizeof(Item *) * fields.elements);
5603
5603
Item **ref= ref_pointer_array;
5604
thd->lex->current_select->cur_pos_in_select_list= 0;
5604
session->lex->current_select->cur_pos_in_select_list= 0;
5605
5605
while ((item= it++))
5607
if ((!item->fixed && item->fix_fields(thd, it.ref())) || (item= *(it.ref()))->check_cols(1))
5607
if ((!item->fixed && item->fix_fields(session, it.ref())) || (item= *(it.ref()))->check_cols(1))
5609
thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
5610
thd->lex->allow_sum_func= save_allow_sum_func;
5611
thd->mark_used_columns= save_mark_used_columns;
5609
session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
5610
session->lex->allow_sum_func= save_allow_sum_func;
5611
session->mark_used_columns= save_mark_used_columns;
5612
5612
return(true); /* purecov: inspected */
5615
5615
*(ref++)= item;
5616
5616
if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM &&
5618
item->split_sum_func(thd, ref_pointer_array, *sum_func_list);
5619
thd->used_tables|= item->used_tables();
5620
thd->lex->current_select->cur_pos_in_select_list++;
5618
item->split_sum_func(session, ref_pointer_array, *sum_func_list);
5619
session->used_tables|= item->used_tables();
5620
session->lex->current_select->cur_pos_in_select_list++;
5622
thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
5623
thd->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
5622
session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
5623
session->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
5625
thd->lex->allow_sum_func= save_allow_sum_func;
5626
thd->mark_used_columns= save_mark_used_columns;
5627
return(test(thd->is_error()));
5625
session->lex->allow_sum_func= save_allow_sum_func;
5626
session->mark_used_columns= save_mark_used_columns;
5627
return(test(session->is_error()));
5762
5762
TableList *leaves_tmp= NULL;
5763
5763
bool first_table= true;
5765
if (setup_tables(thd, context, from_clause, tables,
5765
if (setup_tables(session, context, from_clause, tables,
5766
5766
&leaves_tmp, select_insert))
5839
insert_fields(Session *thd, Name_resolution_context *context, const char *db_name,
5839
insert_fields(Session *session, Name_resolution_context *context, const char *db_name,
5840
5840
const char *table_name, List_iterator<Item> *it,
5841
5841
bool any_privileges __attribute__((unused)))
5998
5998
false if all is OK
6001
int setup_conds(Session *thd, TableList *tables __attribute__((unused)),
6001
int setup_conds(Session *session, TableList *tables __attribute__((unused)),
6002
6002
TableList *leaves,
6005
SELECT_LEX *select_lex= thd->lex->current_select;
6005
SELECT_LEX *select_lex= session->lex->current_select;
6006
6006
TableList *table= NULL; // For HP compilers
6007
void *save_thd_marker= thd->thd_marker;
6007
void *save_session_marker= session->session_marker;
6009
6009
it_is_update set to true when tables of primary SELECT_LEX (SELECT_LEX
6010
6010
which belong to LEX, i.e. most up SELECT) will be updated by
6016
6016
bool save_is_item_list_lookup= select_lex->is_item_list_lookup;
6017
6017
select_lex->is_item_list_lookup= 0;
6019
thd->mark_used_columns= MARK_COLUMNS_READ;
6019
session->mark_used_columns= MARK_COLUMNS_READ;
6020
6020
select_lex->cond_count= 0;
6021
6021
select_lex->between_count= 0;
6022
6022
select_lex->max_equal_elems= 0;
6024
thd->thd_marker= (void*)1;
6024
session->session_marker= (void*)1;
6027
thd->where="where clause";
6028
if ((!(*conds)->fixed && (*conds)->fix_fields(thd, conds)) ||
6027
session->where="where clause";
6028
if ((!(*conds)->fixed && (*conds)->fix_fields(session, conds)) ||
6029
6029
(*conds)->check_cols(1))
6030
6030
goto err_no_arena;
6032
thd->thd_marker= save_thd_marker;
6032
session->session_marker= save_session_marker;
6035
6035
Apply fix_fields() to all ON clauses at all levels of nesting,
6045
6045
if (embedded->on_expr)
6047
6047
/* Make a join an a expression */
6048
thd->thd_marker= (void*)embedded;
6049
thd->where="on clause";
6050
if ((!embedded->on_expr->fixed && embedded->on_expr->fix_fields(thd, &embedded->on_expr)) ||
6048
session->session_marker= (void*)embedded;
6049
session->where="on clause";
6050
if ((!embedded->on_expr->fixed && embedded->on_expr->fix_fields(session, &embedded->on_expr)) ||
6051
6051
embedded->on_expr->check_cols(1))
6052
6052
goto err_no_arena;
6053
6053
select_lex->cond_count++;
6058
6058
embedding->nested_join->join_list.head() == embedded);
6061
thd->thd_marker= save_thd_marker;
6061
session->session_marker= save_session_marker;
6063
thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
6064
return(test(thd->is_error()));
6063
session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
6064
return(test(session->is_error()));
6067
6067
select_lex->is_item_list_lookup= save_is_item_list_lookup;
6099
fill_record(Session * thd, List<Item> &fields, List<Item> &values, bool ignore_errors)
6099
fill_record(Session * session, List<Item> &fields, List<Item> &values, bool ignore_errors)
6101
6101
List_iterator_fast<Item> f(fields),v(values);
6102
6102
Item *value, *fld;
6103
6103
Item_field *field;
6104
6104
Table *table= 0;
6105
6105
List<Table> tbl_list;
6106
bool abort_on_warning_saved= thd->abort_on_warning;
6106
bool abort_on_warning_saved= session->abort_on_warning;
6107
6107
tbl_list.empty();
6143
6143
value->type() != Item::NULL_ITEM &&
6144
6144
table->s->table_category != TABLE_CATEGORY_TEMPORARY)
6146
thd->abort_on_warning= false;
6147
push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
6146
session->abort_on_warning= false;
6147
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
6148
6148
ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN,
6149
6149
ER(ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN),
6150
6150
rfield->field_name, table->s->table_name.str);
6151
thd->abort_on_warning= abort_on_warning_saved;
6151
session->abort_on_warning= abort_on_warning_saved;
6153
6153
if ((value->save_in_field(rfield, 0) < 0) && !ignore_errors)
6246
6246
value->type() != Item::NULL_ITEM &&
6247
6247
table->s->table_category != TABLE_CATEGORY_TEMPORARY)
6249
thd->abort_on_warning= false;
6250
push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
6249
session->abort_on_warning= false;
6250
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
6251
6251
ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN,
6252
6252
ER(ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN),
6253
6253
field->field_name, table->s->table_name.str);
6254
thd->abort_on_warning= abort_on_warning_saved;
6254
session->abort_on_warning= abort_on_warning_saved;
6256
6256
if (value->save_in_field(field, 0) < 0)
6258
6258
tbl_list.push_back(table);
6260
6260
/* Update virtual fields*/
6261
thd->abort_on_warning= false;
6261
session->abort_on_warning= false;
6262
6262
if (tbl_list.head())
6264
6264
List_iterator_fast<Table> t(tbl_list);
6338
6338
/* We should cut file extention before deleting of table */
6339
6339
memcpy(filePathCopy, filePath, filePath_len - ext_len);
6340
6340
filePathCopy[filePath_len - ext_len]= 0;
6341
init_tmp_table_share(thd, &share, "", 0, "", filePathCopy);
6342
if (!open_table_def(thd, &share, 0) &&
6343
((handler_file= get_new_handler(&share, thd->mem_root,
6341
init_tmp_table_share(session, &share, "", 0, "", filePathCopy);
6342
if (!open_table_def(session, &share, 0) &&
6343
((handler_file= get_new_handler(&share, session->mem_root,
6344
6344
share.db_type()))))
6346
6346
handler_file->ha_delete_table(filePathCopy);
6480
6480
open_tables list. Aborting the MERGE lock after a child was
6481
6481
closed and before the parent is closed would be fatal.
6483
for (Table *thd_table= in_use->open_tables;
6485
thd_table= thd_table->next)
6483
for (Table *session_table= in_use->open_tables;
6485
session_table= session_table->next)
6487
6487
/* Do not handle locks of MERGE children. */
6488
if (thd_table->db_stat) // If table is open
6489
signalled|= mysql_lock_abort_for_thread(thd, thd_table);
6488
if (session_table->db_stat) // If table is open
6489
signalled|= mysql_lock_abort_for_thread(session, session_table);