17
17
/* Basic functions needed by many modules */
18
18
#include <drizzled/server_includes.h>
19
#include <drizzled/virtual_column_info.h>
20
#include <drizzled/field/timestamp.h>
21
#include <drizzled/field/null.h>
25
#if TIME_WITH_SYS_TIME
26
# include <sys/time.h>
30
# include <sys/time.h>
35
#include <mysys/my_pthread.h>
19
37
#include <drizzled/sql_select.h>
20
38
#include <mysys/my_dir.h>
21
#include <drizzled/drizzled_error_messages.h>
22
#include <libdrizzle/gettext.h>
39
#include <drizzled/error.h>
40
#include <drizzled/gettext.h>
41
#include <drizzled/nested_join.h>
42
#include <drizzled/sql_base.h>
43
#include <drizzled/show.h>
44
#include <drizzled/item/cmpfunc.h>
45
#include <drizzled/replicator.h>
46
#include <drizzled/check_stack_overrun.h>
47
#include <drizzled/lock.h>
24
#define FLAGSTR(S,F) ((S) & (F) ? #F " " : "")
27
51
@defgroup Data_Dictionary Data Dictionary
34
58
static pthread_mutex_t LOCK_table_share;
35
59
static bool table_def_inited= 0;
37
static int open_unireg_entry(THD *thd, Table *entry, TableList *table_list,
61
static int open_unireg_entry(Session *session, Table *entry, TableList *table_list,
39
63
char *cache_key, uint32_t cache_key_length);
40
static void free_cache_entry(Table *entry);
41
static void close_old_data_files(THD *thd, Table *table, bool morph_locks,
64
static void free_cache_entry(void *entry);
65
static void close_old_data_files(Session *session, Table *table, bool morph_locks,
42
66
bool send_refresh);
45
69
extern "C" unsigned char *table_cache_key(const unsigned char *record, size_t *length,
46
bool not_used __attribute__((unused)))
48
72
Table *entry=(Table*) record;
49
73
*length= entry->s->table_cache_key.length;
102
uint32_t create_table_def_key(THD *thd, char *key, TableList *table_list,
126
uint32_t create_table_def_key(Session *session, char *key, TableList *table_list,
105
uint32_t key_length= (uint) (my_stpcpy(my_stpcpy(key, table_list->db)+1,
106
table_list->table_name)-key)+1;
131
key_pos= strcpy(key_pos, table_list->db) + strlen(table_list->db);
132
key_pos= strcpy(key_pos+1, table_list->table_name) +
133
strlen(table_list->table_name);
134
key_length= (uint32_t)(key_pos-key)+1;
109
int4store(key + key_length, thd->server_id);
110
int4store(key + key_length + 4, thd->variables.pseudo_thread_id);
138
int4store(key + key_length, session->server_id);
139
int4store(key + key_length + 4, session->variables.pseudo_thread_id);
111
140
key_length+= TMP_TABLE_KEY_EXTRA;
113
142
return key_length;
304
333
static TABLE_SHARE
305
*get_table_share_with_create(THD *thd, TableList *table_list,
334
*get_table_share_with_create(Session *session, TableList *table_list,
306
335
char *key, uint32_t key_length,
307
336
uint32_t db_flags, int *error)
309
338
TABLE_SHARE *share;
312
share= get_table_share(thd, table_list, key, key_length, db_flags, error);
340
share= get_table_share(session, table_list, key, key_length, db_flags, error);
314
342
If share is not NULL, we found an existing share.
316
344
If share is NULL, and there is no error, we're inside
317
345
pre-locking, which silences 'ER_NO_SUCH_TABLE' errors
318
with the intention to silently drop non-existing tables
346
with the intention to silently drop non-existing tables
319
347
from the pre-locking list. In this case we still need to try
320
348
auto-discover before returning a NULL share.
322
350
If share is NULL and the error is ER_NO_SUCH_TABLE, this is
323
the same as above, only that the error was not silenced by
351
the same as above, only that the error was not silenced by
324
352
pre-locking. Once again, we need to try to auto-discover
330
358
@todo Rework alternative ways to deal with ER_NO_SUCH Table.
332
if (share || (thd->is_error() && (thd->main_da.sql_errno() != ER_NO_SUCH_TABLE)))
360
if (share || (session->is_error() && (session->main_da.sql_errno() != ER_NO_SUCH_TABLE)))
336
/* Table didn't exist. Check if some engine can provide it */
337
if ((tmp= ha_create_table_from_engine(thd, table_list->db,
338
table_list->table_name)) < 0)
343
/* Give right error message */
345
my_printf_error(ER_UNKNOWN_ERROR,
346
"Failed to open '%-.64s', error while "
347
"unpacking from engine",
348
MYF(0), table_list->table_name);
351
/* Table existed in engine. Let's open it */
352
drizzle_reset_errors(thd, 1); // Clear warnings
353
thd->clear_error(); // Clear error message
354
return(get_table_share(thd, table_list, key, key_length,
360
369
Mark that we are not using table share anymore.
736
744
If there is any table that has a lower refresh_version, wait until
737
745
this is closed (or this thread is killed) before returning
739
thd->mysys_var->current_mutex= &LOCK_open;
740
thd->mysys_var->current_cond= &COND_refresh;
741
thd_proc_info(thd, "Flushing tables");
747
session->mysys_var->current_mutex= &LOCK_open;
748
session->mysys_var->current_cond= &COND_refresh;
749
session->set_proc_info("Flushing tables");
743
close_old_data_files(thd,thd->open_tables,1,1);
751
close_old_data_files(session,session->open_tables,1,1);
752
mysql_ha_flush(session);
747
755
/* Wait until all threads has closed all the tables we had locked */
748
while (found && ! thd->killed)
756
while (found && ! session->killed)
751
759
for (uint32_t idx=0 ; idx < open_cache.records ; idx++)
753
761
Table *table=(Table*) hash_element(&open_cache,idx);
754
762
/* Avoid a self-deadlock. */
755
if (table->in_use == thd)
763
if (table->in_use == session)
758
766
Note that we wait here only for tables which are actually open, and
851
859
tmp.table_name= share->table_name.str;
852
860
tmp.next_local= tables;
854
tables= (TableList *) memdup_root(thd->mem_root, (char*)&tmp,
862
tables= (TableList *) memdup_root(session->mem_root, (char*)&tmp,
855
863
sizeof(TableList));
859
result= close_cached_tables(thd, tables, true, false, false);
867
result= close_cached_tables(session, tables, true, false, false);
862
870
pthread_mutex_unlock(&LOCK_open);
864
872
if (if_wait_for_refresh)
866
pthread_mutex_lock(&thd->mysys_var->mutex);
867
thd->mysys_var->current_mutex= 0;
868
thd->mysys_var->current_cond= 0;
869
thd->set_proc_info(0);
870
pthread_mutex_unlock(&thd->mysys_var->mutex);
874
pthread_mutex_lock(&session->mysys_var->mutex);
875
session->mysys_var->current_mutex= 0;
876
session->mysys_var->current_cond= 0;
877
session->set_proc_info(0);
878
pthread_mutex_unlock(&session->mysys_var->mutex);
984
992
leave prelocked mode if needed.
987
void close_thread_tables(THD *thd)
995
void close_thread_tables(Session *session)
992
We are assuming here that thd->derived_tables contains ONLY derived
1000
We are assuming here that session->derived_tables contains ONLY derived
993
1001
tables for this substatement. i.e. instead of approach which uses
994
1002
query_id matching for determining which of the derived tables belong
995
1003
to this substatement we rely on the ability of substatements to
996
save/restore thd->derived_tables during their execution.
1004
save/restore session->derived_tables during their execution.
998
1006
TODO: Probably even better approach is to simply associate list of
999
1007
derived tables with (sub-)statement instead of thread and destroy
1000
1008
them at the end of its execution.
1002
if (thd->derived_tables)
1010
if (session->derived_tables)
1006
1014
Close all derived tables generated in queries like
1007
1015
SELECT * FROM (SELECT * FROM t1)
1009
for (table= thd->derived_tables ; table ; table= next)
1017
for (table= session->derived_tables ; table ; table= next)
1011
1019
next= table->next;
1012
table->free_tmp_table(thd);
1020
table->free_tmp_table(session);
1014
thd->derived_tables= 0;
1022
session->derived_tables= 0;
1018
1026
Mark all temporary tables used by this statement as free for reuse.
1020
mark_temp_tables_as_free_for_reuse(thd);
1028
mark_temp_tables_as_free_for_reuse(session);
1022
1030
Let us commit transaction for statement. Since in 5.0 we only have
1023
1031
one statement transaction and don't allow several nested statement
1026
1034
does not belong to statement for which we do close_thread_tables()).
1027
1035
TODO: This should be fixed in later releases.
1029
if (!(thd->state_flags & Open_tables_state::BACKUPS_AVAIL))
1037
if (!(session->state_flags & Open_tables_state::BACKUPS_AVAIL))
1031
thd->main_da.can_overwrite_status= true;
1032
ha_autocommit_or_rollback(thd, thd->is_error());
1033
thd->main_da.can_overwrite_status= false;
1034
thd->transaction.stmt.reset();
1039
session->main_da.can_overwrite_status= true;
1040
ha_autocommit_or_rollback(session, session->is_error());
1041
session->main_da.can_overwrite_status= false;
1042
session->transaction.stmt.reset();
1037
if (thd->locked_tables)
1045
if (session->locked_tables)
1040
1048
/* Ensure we are calling ha_reset() for all used tables */
1041
mark_used_tables_as_free_for_reuse(thd, thd->open_tables);
1049
mark_used_tables_as_free_for_reuse(session, session->open_tables);
1044
1052
We are under simple LOCK TABLES so should not do anything else.
1117
1124
return(found_old_table);
1121
/* close_temporary_tables' internal, 4 is due to uint4korr definition */
1122
static inline uint32_t tmpkeyval(THD *thd __attribute__((unused)),
1125
return uint4korr(table->s->table_cache_key.str + table->s->table_cache_key.length - 4);
1130
Close all temporary tables created by 'CREATE TEMPORARY TABLE' for thread
1131
creates one DROP TEMPORARY Table binlog event for each pseudo-thread
1134
void close_temporary_tables(THD *thd)
1139
/* Assume thd->options has OPTION_QUOTE_SHOW_CREATE */
1140
bool was_quote_show= true;
1142
if (!thd->temporary_tables)
1145
if (!mysql_bin_log.is_open() || thd->current_stmt_binlog_row_based)
1148
for (table= thd->temporary_tables; table; table= tmp_next)
1150
tmp_next= table->next;
1151
close_temporary(table, 1, 1);
1153
thd->temporary_tables= 0;
1157
/* Better add "if exists", in case a RESET MASTER has been done */
1158
const char stub[]= "DROP /*!40005 TEMPORARY */ Table IF EXISTS ";
1159
uint32_t stub_len= sizeof(stub) - 1;
1161
String s_query= String(buf, sizeof(buf), system_charset_info);
1162
bool found_user_tables= false;
1164
memcpy(buf, stub, stub_len);
1167
Insertion sort of temp tables by pseudo_thread_id to build ordered list
1168
of sublists of equal pseudo_thread_id
1171
for (prev_table= thd->temporary_tables, table= prev_table->next;
1173
prev_table= table, table= table->next)
1175
Table *prev_sorted /* same as for prev_table */, *sorted;
1176
if (is_user_table(table))
1178
if (!found_user_tables)
1179
found_user_tables= true;
1180
for (prev_sorted= NULL, sorted= thd->temporary_tables; sorted != table;
1181
prev_sorted= sorted, sorted= sorted->next)
1183
if (!is_user_table(sorted) ||
1184
tmpkeyval(thd, sorted) > tmpkeyval(thd, table))
1186
/* move into the sorted part of the list from the unsorted */
1187
prev_table->next= table->next;
1188
table->next= sorted;
1191
prev_sorted->next= table;
1195
thd->temporary_tables= table;
1204
/* We always quote db,table names though it is slight overkill */
1205
if (found_user_tables &&
1206
!(was_quote_show= test(thd->options & OPTION_QUOTE_SHOW_CREATE)))
1208
thd->options |= OPTION_QUOTE_SHOW_CREATE;
1211
/* scan sorted tmps to generate sequence of DROP */
1212
for (table= thd->temporary_tables; table; table= next)
1214
if (is_user_table(table))
1216
my_thread_id save_pseudo_thread_id= thd->variables.pseudo_thread_id;
1217
/* Set pseudo_thread_id to be that of the processed table */
1218
thd->variables.pseudo_thread_id= tmpkeyval(thd, table);
1220
Loop forward through all tables within the sublist of
1221
common pseudo_thread_id to create single DROP query.
1223
for (s_query.length(stub_len);
1224
table && is_user_table(table) &&
1225
tmpkeyval(thd, table) == thd->variables.pseudo_thread_id;
1229
We are going to add 4 ` around the db/table names and possible more
1230
due to special characters in the names
1232
append_identifier(thd, &s_query, table->s->db.str, strlen(table->s->db.str));
1233
s_query.append('.');
1234
append_identifier(thd, &s_query, table->s->table_name.str,
1235
strlen(table->s->table_name.str));
1236
s_query.append(',');
1238
close_temporary(table, 1, 1);
1241
const CHARSET_INFO * const cs_save= thd->variables.character_set_client;
1242
thd->variables.character_set_client= system_charset_info;
1243
Query_log_event qinfo(thd, s_query.ptr(),
1244
s_query.length() - 1 /* to remove trailing ',' */,
1246
thd->variables.character_set_client= cs_save;
1248
Imagine the thread had created a temp table, then was doing a
1249
SELECT, and the SELECT was killed. Then it's not clever to
1250
mark the statement above as "killed", because it's not really
1251
a statement updating data, and there are 99.99% chances it
1252
will succeed on slave. If a real update (one updating a
1253
persistent table) was killed on the master, then this real
1254
update will be logged with error_code=killed, rightfully
1255
causing the slave to stop.
1257
qinfo.error_code= 0;
1258
mysql_bin_log.write(&qinfo);
1259
thd->variables.pseudo_thread_id= save_pseudo_thread_id;
1264
close_temporary(table, 1, 1);
1267
if (!was_quote_show)
1268
thd->options&= ~OPTION_QUOTE_SHOW_CREATE; /* restore option */
1269
thd->temporary_tables=0;
1273
1128
Find table in list.
1410
1265
void update_non_unique_table_error(TableList *update,
1411
const char *operation __attribute__((unused)),
1412
TableList *duplicate __attribute__((unused)))
1414
1269
my_error(ER_UPDATE_TABLE_USED, MYF(0), update->alias);
1418
Table *find_temporary_table(THD *thd, const char *db, const char *table_name)
1273
Table *find_temporary_table(Session *session, const char *db, const char *table_name)
1420
1275
TableList table_list;
1422
1277
table_list.db= (char*) db;
1423
1278
table_list.table_name= (char*) table_name;
1424
return find_temporary_table(thd, &table_list);
1279
return find_temporary_table(session, &table_list);
1428
Table *find_temporary_table(THD *thd, TableList *table_list)
1283
Table *find_temporary_table(Session *session, TableList *table_list)
1430
1285
char key[MAX_DBKEY_LENGTH];
1431
1286
uint key_length;
1434
key_length= create_table_def_key(thd, key, table_list, 1);
1435
for (table=thd->temporary_tables ; table ; table= table->next)
1289
key_length= create_table_def_key(session, key, table_list, 1);
1290
for (table=session->temporary_tables ; table ; table= table->next)
1437
1292
if (table->s->table_cache_key.length == key_length &&
1438
1293
!memcmp(table->s->table_cache_key.str, key, key_length))
1486
1341
If LOCK TABLES list is not empty and contains this table,
1487
1342
unlock the table and remove the table from this list.
1489
mysql_lock_remove(thd, thd->locked_tables, table, false);
1490
close_temporary_table(thd, table, 1, 1);
1344
mysql_lock_remove(session, session->locked_tables, table, false);
1345
close_temporary_table(session, table, 1, 1);
1495
unlink from thd->temporary tables and close temporary table
1350
unlink from session->temporary tables and close temporary table
1498
void close_temporary_table(THD *thd, Table *table,
1353
void close_temporary_table(Session *session, Table *table,
1499
1354
bool free_share, bool delete_table)
1501
1356
if (table->prev)
1509
1364
/* removing the item from the list */
1510
assert(table == thd->temporary_tables);
1365
assert(table == session->temporary_tables);
1512
1367
slave must reset its temporary list pointer to zero to exclude
1513
1368
passing non-zero value to end_slave via rli->save_temporary_tables
1514
1369
when no temp tables opened, see an invariant below.
1516
thd->temporary_tables= table->next;
1517
if (thd->temporary_tables)
1371
session->temporary_tables= table->next;
1372
if (session->temporary_tables)
1518
1373
table->next->prev= 0;
1520
if (thd->slave_thread)
1522
/* natural invariant of temporary_tables */
1523
assert(slave_open_temp_tables || !thd->temporary_tables);
1524
slave_open_temp_tables--;
1526
1375
close_temporary(table, free_share, delete_table);
1633
1480
Closing a MERGE child before the parent would be fatal if the
1634
1481
other thread tries to abort the MERGE lock in between.
1636
for (prev= &thd->open_tables; *prev; )
1483
for (prev= &session->open_tables; *prev; )
1640
1487
if (list->s->table_cache_key.length == key_length &&
1641
1488
!memcmp(list->s->table_cache_key.str, key, key_length))
1643
if (unlock && thd->locked_tables)
1644
mysql_lock_remove(thd, thd->locked_tables, list, true);
1490
if (unlock && session->locked_tables)
1491
mysql_lock_remove(session, session->locked_tables, list, true);
1646
1493
/* Remove table from open_tables list. */
1647
1494
*prev= list->next;
1707
1554
wait_for_condition()
1555
session Thread handler
1709
1556
mutex mutex that is currently hold that is associated with condition
1710
Will be unlocked on return
1557
Will be unlocked on return
1711
1558
cond Condition to wait for
1714
void wait_for_condition(THD *thd, pthread_mutex_t *mutex, pthread_cond_t *cond)
1561
void wait_for_condition(Session *session, pthread_mutex_t *mutex, pthread_cond_t *cond)
1716
1563
/* Wait until the current table is up to date */
1717
1564
const char *proc_info;
1718
thd->mysys_var->current_mutex= mutex;
1719
thd->mysys_var->current_cond= cond;
1720
proc_info=thd->get_proc_info();
1721
thd_proc_info(thd, "Waiting for table");
1565
session->mysys_var->current_mutex= mutex;
1566
session->mysys_var->current_cond= cond;
1567
proc_info=session->get_proc_info();
1568
session->set_proc_info("Waiting for table");
1569
if (!session->killed)
1723
1570
(void) pthread_cond_wait(cond, mutex);
1747
1594
Exclusively name-lock a table that is already write-locked by the
1748
1595
current thread.
1750
@param thd current thread context
1597
@param session current thread context
1751
1598
@param tables table list containing one table to open.
1753
1600
@return false on success, true otherwise.
1756
bool name_lock_locked_table(THD *thd, TableList *tables)
1603
bool name_lock_locked_table(Session *session, TableList *tables)
1758
1605
/* Under LOCK TABLES we must only accept write locked tables. */
1759
tables->table= find_locked_table(thd, tables->db, tables->table_name);
1606
tables->table= find_locked_table(session, tables->db, tables->table_name);
1761
1608
if (!tables->table)
1762
1609
my_error(ER_TABLE_NOT_LOCKED, MYF(0), tables->alias);
1937
1784
@retval false Success. 'table' parameter set according to above rules.
1940
bool lock_table_name_if_not_cached(THD *thd, const char *db,
1787
bool lock_table_name_if_not_cached(Session *session, const char *db,
1941
1788
const char *table_name, Table **table)
1943
1790
char key[MAX_DBKEY_LENGTH];
1944
1792
uint32_t key_length;
1946
key_length= (uint)(my_stpcpy(my_stpcpy(key, db) + 1, table_name) - key) + 1;
1794
key_pos= strcpy(key_pos, db) + strlen(db);
1795
key_pos= strcpy(key_pos+1, table_name) + strlen(table_name);
1796
key_length= (uint32_t) (key_pos-key)+1;
1947
1798
pthread_mutex_lock(&LOCK_open);
1949
1800
if (hash_search(&open_cache, (unsigned char *)key, key_length))
1955
if (!(*table= table_cache_insert_placeholder(thd, key, key_length)))
1806
if (!(*table= table_cache_insert_placeholder(session, key, key_length)))
1957
1808
pthread_mutex_unlock(&LOCK_open);
1960
1811
(*table)->open_placeholder= 1;
1961
(*table)->next= thd->open_tables;
1962
thd->open_tables= *table;
1812
(*table)->next= session->open_tables;
1813
session->open_tables= *table;
1963
1814
pthread_mutex_unlock(&LOCK_open);
1969
Check that table exists in table definition cache, on disk
1970
or in some storage engine.
1972
@param thd Thread context
1973
@param table Table list element
1974
@param[out] exists Out parameter which is set to true if table
1975
exists and to false otherwise.
1977
@note This function assumes that caller owns LOCK_open mutex.
1978
It also assumes that the fact that there are no name-locks
1979
on the table was checked beforehand.
1981
@note If there is no .FRM file for the table but it exists in one
1982
of engines (e.g. it was created on another node of NDB cluster)
1983
this function will fetch and create proper .FRM file for it.
1985
@retval true Some error occured
1986
@retval false No error. 'exists' out parameter set accordingly.
1989
bool check_if_table_exists(THD *thd, TableList *table, bool *exists)
1991
char path[FN_REFLEN];
1994
safe_mutex_assert_owner(&LOCK_open);
1998
if (get_cached_table_share(table->db, table->table_name))
2001
build_table_filename(path, sizeof(path) - 1, table->db, table->table_name,
2004
if (!access(path, F_OK))
2007
/* .FRM file doesn't exist. Check if some engine can provide it. */
2009
rc= ha_create_table_from_engine(thd, table->db, table->table_name);
2013
/* Table does not exists in engines as well. */
2019
/* Table exists in some engine and .FRM for it was created. */
2024
my_printf_error(ER_UNKNOWN_ERROR, "Failed to open '%-.64s', error while "
2025
"unpacking from engine", MYF(0), table->table_name);
1823
session Thread context.
2037
1824
table_list Open first table in list.
2038
1825
refresh INOUT Pointer to memory that will be set to 1 if
2039
1826
we need to close all tables and reopen them.
2069
1856
char *alias= table_list->alias;
2070
1857
HASH_SEARCH_STATE state;
2072
/* Parsing of partitioning information from .frm needs thd->lex set up. */
2073
assert(thd->lex->is_lex_started);
1859
/* Parsing of partitioning information from .frm needs session->lex set up. */
1860
assert(session->lex->is_lex_started);
2075
1862
/* find a unused table in the open table cache */
2079
1866
/* an open table operation needs a lot of the stack space */
2080
if (check_stack_overrun(thd, STACK_MIN_SIZE_FOR_OPEN, (unsigned char *)&alias))
2086
key_length= (create_table_def_key(thd, key, table_list, 1) -
1867
if (check_stack_overrun(session, STACK_MIN_SIZE_FOR_OPEN, (unsigned char *)&alias))
1870
if (session->killed)
1873
key_length= (create_table_def_key(session, key, table_list, 1) -
2087
1874
TMP_TABLE_KEY_EXTRA);
2415
2201
/* make a new table */
2416
if (!(table=(Table*) my_malloc(sizeof(*table),MYF(MY_WME))))
2202
table= (Table *) malloc(sizeof(*table));
2418
2205
pthread_mutex_unlock(&LOCK_open);
2422
error= open_unireg_entry(thd, table, table_list, alias, key, key_length);
2423
/* Combine the follow two */
2209
error= open_unireg_entry(session, table, table_list, alias, key, key_length);
2426
free((unsigned char*)table);
2427
2213
pthread_mutex_unlock(&LOCK_open);
2432
free((unsigned char*)table);
2433
pthread_mutex_unlock(&LOCK_open);
2436
2216
my_hash_insert(&open_cache,(unsigned char*) table);
2439
2219
pthread_mutex_unlock(&LOCK_open);
2442
table->next=thd->open_tables; /* Link into simple list */
2443
thd->open_tables=table;
2222
table->next=session->open_tables; /* Link into simple list */
2223
session->open_tables=table;
2445
2225
table->reginfo.lock_type=TL_READ; /* Assume read */
2448
2228
assert(table->s->ref_count > 0 || table->s->tmp_table != NO_TMP_TABLE);
2450
if (thd->lex->need_correct_ident())
2230
if (session->lex->need_correct_ident())
2451
2231
table->alias_name_used= my_strcasecmp(table_alias_charset,
2452
2232
table->s->table_name.str, alias);
2453
2233
/* Fix alias if table name changes */
2454
2234
if (strcmp(table->alias, alias))
2456
2236
uint32_t length=(uint) strlen(alias)+1;
2457
table->alias= (char*) my_realloc((char*) table->alias, length,
2237
table->alias= (char*) realloc((char*) table->alias, length);
2459
2238
memcpy((void*) table->alias, alias, length);
2461
2240
/* These variables are also set in reopen_table() */
2462
table->tablenr=thd->current_tablenr++;
2241
table->tablenr=session->current_tablenr++;
2463
2242
table->used_fields=0;
2464
2243
table->const_table=0;
2465
2244
table->null_row= false;
2482
Table *find_locked_table(THD *thd, const char *db,const char *table_name)
2261
Table *find_locked_table(Session *session, const char *db,const char *table_name)
2484
char key[MAX_DBKEY_LENGTH];
2485
uint32_t key_length=(uint) (my_stpcpy(my_stpcpy(key,db)+1,table_name)-key)+1;
2487
for (Table *table=thd->open_tables; table ; table=table->next)
2263
char key[MAX_DBKEY_LENGTH];
2265
uint32_t key_length;
2267
key_pos= strcpy(key_pos, db) + strlen(db);
2268
key_pos= strcpy(key_pos+1, table_name) + strlen(table_name);
2269
key_length= (uint32_t)(key_pos-key)+1;
2271
for (Table *table=session->open_tables; table ; table=table->next)
2489
2273
if (table->s->table_cache_key.length == key_length &&
2490
2274
!memcmp(table->s->table_cache_key.str, key, key_length))
2630
2414
for target table name if we process ALTER Table ... RENAME.
2631
2415
So loop below makes sense even if we are not under LOCK TABLES.
2633
for (table=thd->open_tables; table ; table=table->next)
2417
for (table=session->open_tables; table ; table=table->next)
2635
2419
if (!strcmp(table->s->table_name.str, table_name) &&
2636
2420
!strcmp(table->s->db.str, db))
2638
if (thd->locked_tables)
2422
if (session->locked_tables)
2640
mysql_lock_remove(thd, thd->locked_tables, table, true);
2424
mysql_lock_remove(session, session->locked_tables, table, true);
2642
2426
table->open_placeholder= 1;
2643
2427
close_handle_and_leave_table_as_lock(table);
2882
2666
/* Wait until all used tables are refreshed */
2884
bool wait_for_tables(THD *thd)
2668
bool wait_for_tables(Session *session)
2888
thd_proc_info(thd, "Waiting for tables");
2672
session->set_proc_info("Waiting for tables");
2889
2673
pthread_mutex_lock(&LOCK_open);
2890
while (!thd->killed)
2674
while (!session->killed)
2892
thd->some_tables_deleted=0;
2893
close_old_data_files(thd,thd->open_tables,0,dropping_tables != 0);
2894
mysql_ha_flush(thd);
2895
if (!table_is_used(thd->open_tables,1))
2676
session->some_tables_deleted=0;
2677
close_old_data_files(session,session->open_tables,0,dropping_tables != 0);
2678
mysql_ha_flush(session);
2679
if (!table_is_used(session->open_tables,1))
2897
2681
(void) pthread_cond_wait(&COND_refresh,&LOCK_open);
2683
if (session->killed)
2900
2684
result= 1; // aborted
2903
2687
/* Now we can open all tables without any interference */
2904
thd_proc_info(thd, "Reopen tables");
2905
thd->version= refresh_version;
2906
result=reopen_tables(thd,0,0);
2688
session->set_proc_info("Reopen tables");
2689
session->version= refresh_version;
2690
result=reopen_tables(session,0,0);
2908
2692
pthread_mutex_unlock(&LOCK_open);
2909
thd_proc_info(thd, 0);
2693
session->set_proc_info(0);
2910
2694
return(result);
2995
2779
other threads trying to get the lock.
2998
void abort_locked_tables(THD *thd,const char *db, const char *table_name)
2782
void abort_locked_tables(Session *session,const char *db, const char *table_name)
3001
for (table= thd->open_tables; table ; table= table->next)
2785
for (table= session->open_tables; table ; table= table->next)
3003
2787
if (!strcmp(table->s->table_name.str, table_name) &&
3004
2788
!strcmp(table->s->db.str, db))
3006
2790
/* If MERGE child, forward lock handling to parent. */
3007
mysql_lock_abort(thd, table, true);
2791
mysql_lock_abort(session, table, true);
3095
2879
safe_mutex_assert_owner(&LOCK_open);
3097
if (!(share= get_table_share_with_create(thd, table_list, cache_key,
2881
if (!(share= get_table_share_with_create(session, table_list, cache_key,
3099
2883
table_list->i_s_requested_object,
3103
while ((error= open_table_from_share(thd, share, alias,
2887
while ((error= open_table_from_share(session, share, alias,
3104
2888
(uint) (HA_OPEN_KEYFILE |
3105
2889
HA_OPEN_RNDFILE |
3107
2891
HA_TRY_READ_ONLY),
3108
2892
(EXTRA_RECORD),
3109
thd->open_options, entry, OTM_OPEN)))
2893
session->open_options, entry, OTM_OPEN)))
3111
2895
if (error == 7) // Table def changed
3150
2932
if (!entry->s || !entry->s->crashed)
3152
2934
// Code below is for repairing a crashed file
3153
if ((error= lock_table_name(thd, table_list, true)))
2935
if ((error= lock_table_name(session, table_list, true)))
3157
if (wait_for_locked_table_names(thd, table_list))
2939
if (wait_for_locked_table_names(session, table_list))
3159
unlock_table_name(thd, table_list);
2941
unlock_table_name(session, table_list);
3163
2945
pthread_mutex_unlock(&LOCK_open);
3164
thd->clear_error(); // Clear error message
2946
session->clear_error(); // Clear error message
3166
if (open_table_from_share(thd, share, alias,
2948
if (open_table_from_share(session, share, alias,
3167
2949
(uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
3169
2951
HA_TRY_READ_ONLY),
3171
2953
ha_open_options | HA_OPEN_FOR_REPAIR,
3172
2954
entry, OTM_OPEN) || ! entry->file ||
3173
(entry->file->is_crashed() && entry->file->ha_check_and_repair(thd)))
2955
(entry->file->is_crashed() && entry->file->ha_check_and_repair(session)))
3175
2957
/* Give right error message */
2958
session->clear_error();
3177
2959
my_error(ER_NOT_KEYFILE, MYF(0), share->table_name.str, my_errno);
3178
sql_print_error(_("Couldn't repair table: %s.%s"), share->db.str,
2960
errmsg_printf(ERRMSG_LVL_ERROR, _("Couldn't repair table: %s.%s"), share->db.str,
3179
2961
share->table_name.str);
3180
2962
if (entry->file)
2963
entry->closefrm(false);
3185
thd->clear_error(); // Clear error message
2967
session->clear_error(); // Clear error message
3186
2968
pthread_mutex_lock(&LOCK_open);
3187
unlock_table_name(thd, table_list);
2969
unlock_table_name(session, table_list);
3198
2980
if (unlikely(entry->file->implicit_emptied))
3200
2982
entry->file->implicit_emptied= 0;
3201
if (mysql_bin_log.is_open())
3203
2984
char *query, *end;
3204
2985
uint32_t query_buf_size= 20 + share->db.length + share->table_name.length +1;
3205
if ((query= (char*) my_malloc(query_buf_size,MYF(MY_WME))))
2986
if ((query= (char*) malloc(query_buf_size)))
3207
/* this DELETE FROM is needed even with row-based binlogging */
3208
end = strxmov(my_stpcpy(query, "DELETE FROM `"),
3209
share->db.str,"`.`",share->table_name.str,"`", NULL);
3210
thd->binlog_query(THD::STMT_QUERY_TYPE,
3211
query, (ulong)(end-query), false, false);
2989
"this DELETE FROM is needed even with row-based binlogging"
2991
We inherited this from MySQL. TODO: fix it to issue a propper truncate
2992
of the table (though that may not be completely right sematics).
2995
end+= sprintf(query, "DELETE FROM `%s`.`%s`", share->db.str,
2996
share->table_name.str);
2997
(void)replicator_statement(session, query, (size_t)(end - query));
3217
As replication is maybe going to be corrupted, we need to warn the
3218
DBA on top of warning the client (which will automatically be done
3219
because of MYF(MY_WME) in my_malloc() above).
3221
sql_print_error(_("When opening HEAP table, could not allocate memory "
3222
"to write 'DELETE FROM `%s`.`%s`' to the binary log"),
3223
table_list->db, table_list->table_name);
3002
errmsg_printf(ERRMSG_LVL_ERROR, _("When opening HEAP table, could not allocate memory "
3003
"to write 'DELETE FROM `%s`.`%s`' to replication"),
3004
table_list->db, table_list->table_name);
3005
my_error(ER_OUTOFMEMORY, MYF(0), query_buf_size);
3006
entry->closefrm(false);
3482
3264
table Opened table
3485
3267
If ok, the following are also set:
3486
3268
table_list->lock_type lock_type
3487
3269
table_list->table table
3490
Table *open_ltable(THD *thd, TableList *table_list, thr_lock_type lock_type,
3272
Table *open_ltable(Session *session, TableList *table_list, thr_lock_type lock_type,
3491
3273
uint32_t lock_flags)
3496
thd_proc_info(thd, "Opening table");
3497
thd->current_tablenr= 0;
3498
while (!(table= open_table(thd, table_list, &refresh, 0)) &&
3278
session->set_proc_info("Opening table");
3279
session->current_tablenr= 0;
3280
while (!(table= open_table(session, table_list, &refresh, 0)) &&
3504
3286
table_list->lock_type= lock_type;
3505
3287
table_list->table= table;
3506
if (thd->locked_tables)
3288
if (session->locked_tables)
3508
if (check_lock_and_start_stmt(thd, table, lock_type))
3290
if (check_lock_and_start_stmt(session, table, lock_type))
3513
assert(thd->lock == 0); // You must lock everything at once
3295
assert(session->lock == 0); // You must lock everything at once
3514
3296
if ((table->reginfo.lock_type= lock_type) != TL_UNLOCK)
3515
if (! (thd->lock= mysql_lock_tables(thd, &table_list->table, 1,
3297
if (! (session->lock= mysql_lock_tables(session, &table_list->table, 1,
3516
3298
lock_flags, &refresh)))
3521
thd_proc_info(thd, 0);
3303
session->set_proc_info(0);
3543
3325
There are two convenience functions:
3544
- simple_open_n_lock_tables(thd, tables) without derived handling
3545
- open_and_lock_tables(thd, tables) with derived handling
3326
- simple_open_n_lock_tables(session, tables) without derived handling
3327
- open_and_lock_tables(session, tables) with derived handling
3546
3328
Both inline functions call open_and_lock_tables_derived() with
3547
3329
the third argument set appropriately.
3550
int open_and_lock_tables_derived(THD *thd, TableList *tables, bool derived)
3332
int open_and_lock_tables_derived(Session *session, TableList *tables, bool derived)
3552
3334
uint32_t counter;
3553
3335
bool need_reopen;
3557
if (open_tables(thd, &tables, &counter, 0))
3339
if (open_tables(session, &tables, &counter, 0))
3560
if (!lock_tables(thd, tables, counter, &need_reopen))
3342
if (!lock_tables(session, tables, counter, &need_reopen))
3562
3344
if (!need_reopen)
3564
close_tables_for_reopen(thd, &tables);
3346
close_tables_for_reopen(session, &tables);
3567
(mysql_handle_derived(thd->lex, &mysql_derived_prepare) ||
3568
(thd->fill_derived_tables() &&
3569
mysql_handle_derived(thd->lex, &mysql_derived_filling))))
3349
(mysql_handle_derived(session->lex, &mysql_derived_prepare) ||
3350
(session->fill_derived_tables() &&
3351
mysql_handle_derived(session->lex, &mysql_derived_filling))))
3570
3352
return(true); /* purecov: inspected */
3591
3373
This is to be used on prepare stage when you don't read any
3592
3374
data from the tables.
3595
bool open_normal_and_derived_tables(THD *thd, TableList *tables, uint32_t flags)
3377
bool open_normal_and_derived_tables(Session *session, TableList *tables, uint32_t flags)
3597
3379
uint32_t counter;
3598
assert(!thd->fill_derived_tables());
3599
if (open_tables(thd, &tables, &counter, flags) ||
3600
mysql_handle_derived(thd->lex, &mysql_derived_prepare))
3380
assert(!session->fill_derived_tables());
3381
if (open_tables(session, &tables, &counter, flags) ||
3382
mysql_handle_derived(session->lex, &mysql_derived_prepare))
3601
3383
return(true); /* purecov: inspected */
3607
Decide on logging format to use for the statement.
3609
Compute the capabilities vector for the involved storage engines
3610
and mask out the flags for the binary log. Right now, the binlog
3611
flags only include the capabilities of the storage engines, so this
3614
We now have three alternatives that prevent the statement from
3617
1. If there are no capabilities left (all flags are clear) it is
3618
not possible to log the statement at all, so we roll back the
3619
statement and report an error.
3621
2. Statement mode is set, but the capabilities indicate that
3622
statement format is not possible.
3624
3. Row mode is set, but the capabilities indicate that row
3625
format is not possible.
3627
4. Statement is unsafe, but the capabilities indicate that row
3628
format is not possible.
3630
If we are in MIXED mode, we then decide what logging format to use:
3632
1. If the statement is unsafe, row-based logging is used.
3634
2. If statement-based logging is not possible, row-based logging is
3637
3. Otherwise, statement-based logging is used.
3639
@param thd Client thread
3640
@param tables Tables involved in the query
3643
int decide_logging_format(THD *thd, TableList *tables)
3645
if (mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG))
3647
handler::Table_flags flags_some_set= handler::Table_flags();
3648
handler::Table_flags flags_all_set= ~handler::Table_flags();
3649
bool multi_engine= false;
3650
void* prev_ht= NULL;
3651
for (TableList *table= tables; table; table= table->next_global)
3653
if (!table->placeholder() && table->lock_type >= TL_WRITE_ALLOW_WRITE)
3655
uint64_t const flags= table->table->file->ha_table_flags();
3656
if (prev_ht && prev_ht != table->table->file->ht)
3658
prev_ht= table->table->file->ht;
3659
flags_all_set &= flags;
3660
flags_some_set |= flags;
3665
if (flags_all_set == 0)
3667
my_error((error= ER_BINLOG_LOGGING_IMPOSSIBLE), MYF(0),
3668
"Statement cannot be logged to the binary log in"
3669
" row-based nor statement-based format");
3671
else if (thd->variables.binlog_format == BINLOG_FORMAT_STMT &&
3672
(flags_all_set & HA_BINLOG_STMT_CAPABLE) == 0)
3674
my_error((error= ER_BINLOG_LOGGING_IMPOSSIBLE), MYF(0),
3675
"Statement-based format required for this statement,"
3676
" but not allowed by this combination of engines");
3678
else if ((thd->variables.binlog_format == BINLOG_FORMAT_ROW ||
3679
thd->lex->is_stmt_unsafe()) &&
3680
(flags_all_set & HA_BINLOG_ROW_CAPABLE) == 0)
3682
my_error((error= ER_BINLOG_LOGGING_IMPOSSIBLE), MYF(0),
3683
"Row-based format required for this statement,"
3684
" but not allowed by this combination of engines");
3691
We switch to row-based format if we are in mixed mode and one of
3692
the following are true:
3694
1. If the statement is unsafe
3695
2. If statement format cannot be used
3697
Observe that point to cannot be decided before the tables
3698
involved in a statement has been checked, i.e., we cannot put
3699
this code in reset_current_stmt_binlog_row_based(), it has to be
3702
if (thd->lex->is_stmt_unsafe() ||
3703
(flags_all_set & HA_BINLOG_STMT_CAPABLE) == 0)
3705
thd->set_current_stmt_binlog_row_based_if_mixed();
3713
3388
Lock all tables in list
3392
session Thread handler
3718
3393
tables Tables to lock
3719
3394
count Number of opened tables
3720
3395
need_reopen Out parameter which if true indicates that some
3805
3480
close_tables_for_reopen()
3806
thd in Thread context
3481
session in Thread context
3807
3482
tables in/out List of tables which we were trying to open and lock
3811
void close_tables_for_reopen(THD *thd, TableList **tables)
3486
void close_tables_for_reopen(Session *session, TableList **tables)
3814
3489
If table list consists only from tables from prelocking set, table list
3815
3490
for new attempt should be empty, so we have to update list's root pointer.
3817
if (thd->lex->first_not_own_table() == *tables)
3492
if (session->lex->first_not_own_table() == *tables)
3819
thd->lex->chop_off_not_own_tables();
3494
session->lex->chop_off_not_own_tables();
3820
3495
for (TableList *tmp= *tables; tmp; tmp= tmp->next_global)
3822
close_thread_tables(thd);
3497
close_thread_tables(session);
3846
Table *open_temporary_table(THD *thd, const char *path, const char *db,
3521
Table *open_temporary_table(Session *session, const char *path, const char *db,
3847
3522
const char *table_name, bool link_in_list,
3848
3523
open_table_mode open_mode)
3850
3525
Table *tmp_table;
3851
3526
TABLE_SHARE *share;
3852
3527
char cache_key[MAX_DBKEY_LENGTH], *saved_cache_key, *tmp_path;
3853
uint32_t key_length;
3528
uint32_t key_length, path_length;
3854
3529
TableList table_list;
3856
3531
table_list.db= (char*) db;
3857
3532
table_list.table_name= (char*) table_name;
3858
3533
/* Create the cache_key for temporary tables */
3859
key_length= create_table_def_key(thd, cache_key, &table_list, 1);
3534
key_length= create_table_def_key(session, cache_key, &table_list, 1);
3535
path_length= strlen(path);
3861
if (!(tmp_table= (Table*) my_malloc(sizeof(*tmp_table) + sizeof(*share) +
3862
strlen(path)+1 + key_length,
3864
return(0); /* purecov: inspected */
3537
if (!(tmp_table= (Table*) malloc(sizeof(*tmp_table) + sizeof(*share) +
3538
path_length + 1 + key_length)))
3866
3541
share= (TABLE_SHARE*) (tmp_table+1);
3867
3542
tmp_path= (char*) (share+1);
3868
saved_cache_key= my_stpcpy(tmp_path, path)+1;
3543
saved_cache_key= strcpy(tmp_path, path)+path_length+1;
3869
3544
memcpy(saved_cache_key, cache_key, key_length);
3871
init_tmp_table_share(thd, share, saved_cache_key, key_length,
3546
init_tmp_table_share(session, share, saved_cache_key, key_length,
3872
3547
strchr(saved_cache_key, '\0')+1, tmp_path);
3874
if (open_table_def(thd, share, 0) ||
3875
open_table_from_share(thd, share, table_name,
3549
if (open_table_def(session, share, 0) ||
3550
open_table_from_share(session, share, table_name,
3876
3551
(open_mode == OTM_ALTER) ? 0 :
3877
3552
(uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
3904
3579
if (link_in_list)
3906
3581
/* growing temp list at the head */
3907
tmp_table->next= thd->temporary_tables;
3582
tmp_table->next= session->temporary_tables;
3908
3583
if (tmp_table->next)
3909
3584
tmp_table->next->prev= tmp_table;
3910
thd->temporary_tables= tmp_table;
3911
thd->temporary_tables->prev= 0;
3912
if (thd->slave_thread)
3913
slave_open_temp_tables++;
3585
session->temporary_tables= tmp_table;
3586
session->temporary_tables->prev= 0;
3915
3588
tmp_table->pos_in_table_list= 0;
3916
3589
return(tmp_table);
3920
bool rm_temporary_table(handlerton *base, char *path, bool frm_only)
3593
bool rm_temporary_table(handlerton *base, char *path)
3926
my_stpcpy(ext= strchr(path, '\0'), reg_ext);
3599
delete_table_proto_file(path);
3601
strcpy(ext= strchr(path, '\0'), reg_ext);
3927
3602
if (my_delete(path,MYF(0)))
3928
3603
error=1; /* purecov: inspected */
3929
3604
*ext= 0; // remove extension
3930
file= get_new_handler((TABLE_SHARE*) 0, current_thd->mem_root, base);
3931
if (!frm_only && file && file->ha_delete_table(path))
3605
file= get_new_handler((TABLE_SHARE*) 0, current_session->mem_root, base);
3606
if (file && file->ha_delete_table(path))
3934
sql_print_warning(_("Could not remove temporary table: '%s', error: %d"),
3609
errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
3935
3610
path, my_errno);
4433
4120
when table_ref->field_translation != NULL.
4435
4122
if (table_ref->table)
4436
found= find_field_in_table(thd, table_ref->table, name, length,
4123
found= find_field_in_table(session, table_ref->table, name, length,
4437
4124
true, &(item->cached_field_index));
4439
found= find_field_in_table_ref(thd, table_ref, name, length, item->name,
4126
found= find_field_in_table_ref(session, table_ref, name, length, item->name,
4440
4127
NULL, NULL, ref, check_privileges,
4441
4128
true, &(item->cached_field_index),
4442
4129
register_tree_change,
4561
4248
char buff[NAME_LEN*2+1];
4562
4249
if (db && db[0])
4564
strxnmov(buff,sizeof(buff)-1,db,".",table_name,NULL);
4251
/* We're in an error condition, two extra strlen's aren't going
4253
assert(strlen(db) <= NAME_LEN);
4254
assert(strlen(table_name) <= NAME_LEN);
4257
strcat(buff, table_name);
4565
4258
table_name=buff;
4567
my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, thd->where);
4260
my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, session->where);
4571
4264
if (report_error == REPORT_ALL_ERRORS ||
4572
4265
report_error == REPORT_EXCEPT_NON_UNIQUE)
4573
my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), thd->where);
4266
my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), session->where);
4575
4268
found= not_found_field;
4775
else if (table_name && item->type() == Item::REF_ITEM &&
4776
((Item_ref *)item)->ref_type() == Item_ref::VIEW_REF)
4779
TODO:Here we process prefixed view references only. What we should
4780
really do is process all types of Item_refs. But this will currently
4781
lead to a clash with the way references to outer SELECTs (from the
4782
HAVING clause) are handled in e.g. :
4783
SELECT 1 FROM t1 AS t1_o GROUP BY a
4784
HAVING (SELECT t1_o.a FROM t1 AS t1_i GROUP BY t1_i.a LIMIT 1).
4785
Processing all Item_refs here will cause t1_o.a to resolve to itself.
4786
We still need to process the special case of Item_direct_view_ref
4787
because in the context of views they have the same meaning as
4788
Item_field for tables.
4790
Item_ident *item_ref= (Item_ident *) item;
4791
if (item_ref->name && item_ref->table_name &&
4792
!my_strcasecmp(system_charset_info, item_ref->name, field_name) &&
4793
!my_strcasecmp(table_alias_charset, item_ref->table_name,
4795
(!db_name || (item_ref->db_name &&
4796
!strcmp (item_ref->db_name, db_name))))
4800
*resolution= RESOLVED_IGNORING_ALIAS;
5533
5197
** Check that all given fields exists and fill struct with current data
5534
5198
****************************************************************************/
5536
bool setup_fields(THD *thd, Item **ref_pointer_array,
5200
bool setup_fields(Session *session, Item **ref_pointer_array,
5537
5201
List<Item> &fields, enum_mark_columns mark_used_columns,
5538
5202
List<Item> *sum_func_list, bool allow_sum_func)
5540
5204
register Item *item;
5541
enum_mark_columns save_mark_used_columns= thd->mark_used_columns;
5542
nesting_map save_allow_sum_func= thd->lex->allow_sum_func;
5205
enum_mark_columns save_mark_used_columns= session->mark_used_columns;
5206
nesting_map save_allow_sum_func= session->lex->allow_sum_func;
5543
5207
List_iterator<Item> it(fields);
5544
5208
bool save_is_item_list_lookup;
5546
thd->mark_used_columns= mark_used_columns;
5210
session->mark_used_columns= mark_used_columns;
5547
5211
if (allow_sum_func)
5548
thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
5549
thd->where= THD::DEFAULT_WHERE;
5550
save_is_item_list_lookup= thd->lex->current_select->is_item_list_lookup;
5551
thd->lex->current_select->is_item_list_lookup= 0;
5212
session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
5213
session->where= Session::DEFAULT_WHERE;
5214
save_is_item_list_lookup= session->lex->current_select->is_item_list_lookup;
5215
session->lex->current_select->is_item_list_lookup= 0;
5554
5218
To prevent fail on forward lookup we fill it with zerows,
5565
5229
memset(ref_pointer_array, 0, sizeof(Item *) * fields.elements);
5567
5231
Item **ref= ref_pointer_array;
5568
thd->lex->current_select->cur_pos_in_select_list= 0;
5232
session->lex->current_select->cur_pos_in_select_list= 0;
5569
5233
while ((item= it++))
5571
if ((!item->fixed && item->fix_fields(thd, it.ref())) || (item= *(it.ref()))->check_cols(1))
5235
if ((!item->fixed && item->fix_fields(session, it.ref())) || (item= *(it.ref()))->check_cols(1))
5573
thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
5574
thd->lex->allow_sum_func= save_allow_sum_func;
5575
thd->mark_used_columns= save_mark_used_columns;
5237
session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
5238
session->lex->allow_sum_func= save_allow_sum_func;
5239
session->mark_used_columns= save_mark_used_columns;
5576
5240
return(true); /* purecov: inspected */
5579
5243
*(ref++)= item;
5580
5244
if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM &&
5582
item->split_sum_func(thd, ref_pointer_array, *sum_func_list);
5583
thd->used_tables|= item->used_tables();
5584
thd->lex->current_select->cur_pos_in_select_list++;
5246
item->split_sum_func(session, ref_pointer_array, *sum_func_list);
5247
session->used_tables|= item->used_tables();
5248
session->lex->current_select->cur_pos_in_select_list++;
5586
thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
5587
thd->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
5250
session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
5251
session->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
5589
thd->lex->allow_sum_func= save_allow_sum_func;
5590
thd->mark_used_columns= save_mark_used_columns;
5591
return(test(thd->is_error()));
5253
session->lex->allow_sum_func= save_allow_sum_func;
5254
session->mark_used_columns= save_mark_used_columns;
5255
return(test(session->is_error()));
5969
5644
bool save_is_item_list_lookup= select_lex->is_item_list_lookup;
5970
5645
select_lex->is_item_list_lookup= 0;
5972
thd->mark_used_columns= MARK_COLUMNS_READ;
5647
session->mark_used_columns= MARK_COLUMNS_READ;
5973
5648
select_lex->cond_count= 0;
5974
5649
select_lex->between_count= 0;
5975
5650
select_lex->max_equal_elems= 0;
5977
thd->thd_marker= (void*)1;
5652
session->session_marker= (void*)1;
5980
thd->where="where clause";
5981
if ((!(*conds)->fixed && (*conds)->fix_fields(thd, conds)) ||
5655
session->where="where clause";
5656
if ((!(*conds)->fixed && (*conds)->fix_fields(session, conds)) ||
5982
5657
(*conds)->check_cols(1))
5983
5658
goto err_no_arena;
5985
thd->thd_marker= save_thd_marker;
5660
session->session_marker= save_session_marker;
5988
5663
Apply fix_fields() to all ON clauses at all levels of nesting,
6088
5766
table= rfield->table;
6089
5767
if (rfield == table->next_number_field)
6090
5768
table->auto_increment_field_not_null= true;
5769
if (rfield->vcol_info &&
5770
value->type() != Item::DEFAULT_VALUE_ITEM &&
5771
value->type() != Item::NULL_ITEM &&
5772
table->s->table_category != TABLE_CATEGORY_TEMPORARY)
5774
session->abort_on_warning= false;
5775
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
5776
ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN,
5777
ER(ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN),
5778
rfield->field_name, table->s->table_name.str);
5779
session->abort_on_warning= abort_on_warning_saved;
6091
5781
if ((value->save_in_field(rfield, 0) < 0) && !ignore_errors)
6093
5783
my_message(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), MYF(0));
6097
return(thd->is_error());
5786
tbl_list.push_back(table);
5788
/* Update virtual fields*/
5789
session->abort_on_warning= false;
5790
if (tbl_list.head())
5792
List_iterator_fast<Table> t(tbl_list);
5793
Table *prev_table= 0;
5794
while ((table= t++))
5797
Do simple optimization to prevent unnecessary re-generating
5798
values for virtual fields
5800
if (table != prev_table)
5805
if (update_virtual_fields_marked_for_write(table, false))
5811
session->abort_on_warning= abort_on_warning_saved;
5812
return(session->is_error());
5814
session->abort_on_warning= abort_on_warning_saved;
6100
5816
table->auto_increment_field_not_null= false;
6144
5863
table= (*ptr)->table;
6145
5864
table->auto_increment_field_not_null= false;
6147
while ((field = *ptr++) && ! thd->is_error())
5866
while ((field = *ptr++) && ! session->is_error())
6150
5869
table= field->table;
6151
5870
if (field == table->next_number_field)
6152
5871
table->auto_increment_field_not_null= true;
5872
if (field->vcol_info &&
5873
value->type() != Item::DEFAULT_VALUE_ITEM &&
5874
value->type() != Item::NULL_ITEM &&
5875
table->s->table_category != TABLE_CATEGORY_TEMPORARY)
5877
session->abort_on_warning= false;
5878
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
5879
ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN,
5880
ER(ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN),
5881
field->field_name, table->s->table_name.str);
5882
session->abort_on_warning= abort_on_warning_saved;
6153
5884
if (value->save_in_field(field, 0) < 0)
6156
return(thd->is_error());
5886
tbl_list.push_back(table);
5888
/* Update virtual fields*/
5889
session->abort_on_warning= false;
5890
if (tbl_list.head())
5892
List_iterator_fast<Table> t(tbl_list);
5893
Table *prev_table= 0;
5894
while ((table= t++))
5897
Do simple optimization to prevent unnecessary re-generating
5898
values for virtual fields
5900
if (table != prev_table)
5905
if (update_virtual_fields_marked_for_write(table, false))
5913
session->abort_on_warning= abort_on_warning_saved;
5914
return(session->is_error());
5917
session->abort_on_warning= abort_on_warning_saved;
6160
5919
table->auto_increment_field_not_null= false;
6165
bool mysql_rm_tmp_tables(void)
5924
bool drizzle_rm_tmp_tables(void)
6168
char filePath[FN_REFLEN], *tmpdir, filePathCopy[FN_REFLEN];
5927
char filePath[FN_REFLEN], filePathCopy[FN_REFLEN];
6170
5929
FILEINFO *file;
6171
5930
TABLE_SHARE share;
6174
if (!(thd= new THD))
6176
thd->thread_stack= (char*) &thd;
6177
thd->store_globals();
6179
for (i=0; i<=mysql_tmpdir_list.max; i++)
5933
assert(drizzle_tmpdir);
5935
if (!(session= new Session))
5937
session->thread_stack= (char*) &session;
5938
session->store_globals();
5940
/* Remove all temp tables in the tmpdir */
5941
/* See if the directory exists */
5942
if ((dirp = my_dir(drizzle_tmpdir ,MYF(MY_WME | MY_DONT_SORT))))
6181
tmpdir=mysql_tmpdir_list.list[i];
6182
/* See if the directory exists */
6183
if (!(dirp = my_dir(tmpdir,MYF(MY_WME | MY_DONT_SORT))))
6186
5944
/* Remove all SQLxxx tables from directory */
6188
5945
for (idx=0 ; idx < (uint) dirp->number_off_files ; idx++)
6190
5947
file=dirp->dir_entry+idx;
6194
5951
(file->name[1] == '.' && !file->name[2])))
6197
if (!memcmp(file->name, tmp_file_prefix, tmp_file_prefix_length))
5954
if (!memcmp(file->name, TMP_FILE_PREFIX, TMP_FILE_PREFIX_LENGTH))
6199
5956
char *ext= fn_ext(file->name);
6200
5957
uint32_t ext_len= strlen(ext);
6201
5958
uint32_t filePath_len= snprintf(filePath, sizeof(filePath),
6202
"%s%c%s", tmpdir, FN_LIBCHAR,
5959
"%s%c%s", drizzle_tmpdir, FN_LIBCHAR,
6204
5961
if (!memcmp(reg_ext, ext, ext_len))
6206
5963
handler *handler_file= 0;
6207
5964
/* We should cut file extention before deleting of table */
6208
5965
memcpy(filePathCopy, filePath, filePath_len - ext_len);
6209
5966
filePathCopy[filePath_len - ext_len]= 0;
6210
init_tmp_table_share(thd, &share, "", 0, "", filePathCopy);
6211
if (!open_table_def(thd, &share, 0) &&
6212
((handler_file= get_new_handler(&share, thd->mem_root,
5967
init_tmp_table_share(session, &share, "", 0, "", filePathCopy);
5968
if (!open_table_def(session, &share, 0) &&
5969
((handler_file= get_new_handler(&share, session->mem_root,
6213
5970
share.db_type()))))
6215
5972
handler_file->ha_delete_table(filePathCopy);
6349
6111
open_tables list. Aborting the MERGE lock after a child was
6350
6112
closed and before the parent is closed would be fatal.
6352
for (Table *thd_table= in_use->open_tables;
6354
thd_table= thd_table->next)
6114
for (Table *session_table= in_use->open_tables;
6116
session_table= session_table->next)
6356
6118
/* Do not handle locks of MERGE children. */
6357
if (thd_table->db_stat) // If table is open
6358
signalled|= mysql_lock_abort_for_thread(thd, thd_table);
6119
if (session_table->db_stat) // If table is open
6120
signalled|= mysql_lock_abort_for_thread(session, session_table);
6362
result= result || (flags & RTFC_OWNED_BY_THD_FLAG);
6124
result= result || (flags & RTFC_OWNED_BY_Session_FLAG);
6364
6126
while (unused_tables && !unused_tables->s->version)
6365
6127
hash_delete(&open_cache,(unsigned char*) unused_tables);
6422
6184
@} (end of group Data_Dictionary)
6187
void kill_drizzle(void)
6190
#if defined(SIGNALS_DONT_BREAK_READ)
6191
abort_loop=1; // Break connection loops
6192
close_server_sock(); // Force accept to wake up
6195
#if defined(HAVE_PTHREAD_KILL)
6196
pthread_kill(signal_thread, SIGTERM);
6197
#elif !defined(SIGNALS_DONT_BREAK_READ)
6198
kill(current_pid, SIGTERM);
6200
shutdown_in_progress=1; // Safety if kill didn't work
6201
#ifdef SIGNALS_DONT_BREAK_READ
6202
if (!kill_in_progress)
6206
if (pthread_create(&tmp,&connection_attrib, kill_server_thread,
6208
errmsg_printf(ERRMSG_LVL_ERROR, _("Can't create thread to kill server"));