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>
37
19
#include <drizzled/sql_select.h>
38
20
#include <mysys/my_dir.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>
21
#include <drizzled/drizzled_error_messages.h>
22
#include <libdrizzle/gettext.h>
24
#define FLAGSTR(S,F) ((S) & (F) ? #F " " : "")
51
27
@defgroup Data_Dictionary Data Dictionary
58
34
static pthread_mutex_t LOCK_table_share;
59
35
static bool table_def_inited= 0;
61
static int open_unireg_entry(Session *session, Table *entry, TableList *table_list,
37
static int open_unireg_entry(THD *thd, Table *entry, TableList *table_list,
63
39
char *cache_key, uint32_t cache_key_length);
64
extern "C" void free_cache_entry(void *entry);
65
static void close_old_data_files(Session *session, Table *table, bool morph_locks,
40
static void free_cache_entry(Table *entry);
41
static void close_old_data_files(THD *thd, Table *table, bool morph_locks,
66
42
bool send_refresh);
69
45
extern "C" unsigned char *table_cache_key(const unsigned char *record, size_t *length,
46
bool not_used __attribute__((unused)))
72
48
Table *entry=(Table*) record;
73
49
*length= entry->s->table_cache_key.length;
127
uint32_t create_table_def_key(Session *session, char *key, TableList *table_list,
102
uint32_t create_table_def_key(THD *thd, char *key, TableList *table_list,
132
key_pos= strcpy(key_pos, table_list->db) + strlen(table_list->db);
133
key_pos= strcpy(key_pos+1, table_list->table_name) +
134
strlen(table_list->table_name);
135
key_length= (uint32_t)(key_pos-key)+1;
105
uint32_t key_length= (uint) (my_stpcpy(my_stpcpy(key, table_list->db)+1,
106
table_list->table_name)-key)+1;
139
int4store(key + key_length, session->server_id);
140
int4store(key + key_length + 4, session->variables.pseudo_thread_id);
109
int4store(key + key_length, thd->server_id);
110
int4store(key + key_length + 4, thd->variables.pseudo_thread_id);
141
111
key_length+= TMP_TABLE_KEY_EXTRA;
143
113
return key_length;
334
304
static TABLE_SHARE
335
*get_table_share_with_create(Session *session, TableList *table_list,
305
*get_table_share_with_create(THD *thd, TableList *table_list,
336
306
char *key, uint32_t key_length,
337
307
uint32_t db_flags, int *error)
339
309
TABLE_SHARE *share;
341
share= get_table_share(session, table_list, key, key_length, db_flags, error);
312
share= get_table_share(thd, table_list, key, key_length, db_flags, error);
343
314
If share is not NULL, we found an existing share.
345
316
If share is NULL, and there is no error, we're inside
346
317
pre-locking, which silences 'ER_NO_SUCH_TABLE' errors
347
with the intention to silently drop non-existing tables
318
with the intention to silently drop non-existing tables
348
319
from the pre-locking list. In this case we still need to try
349
320
auto-discover before returning a NULL share.
351
322
If share is NULL and the error is ER_NO_SUCH_TABLE, this is
352
the same as above, only that the error was not silenced by
323
the same as above, only that the error was not silenced by
353
324
pre-locking. Once again, we need to try to auto-discover
359
330
@todo Rework alternative ways to deal with ER_NO_SUCH Table.
361
if (share || (session->is_error() && (session->main_da.sql_errno() != ER_NO_SUCH_TABLE)))
332
if (share || (thd->is_error() && (thd->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,
370
360
Mark that we are not using table share anymore.
745
736
If there is any table that has a lower refresh_version, wait until
746
737
this is closed (or this thread is killed) before returning
748
session->mysys_var->current_mutex= &LOCK_open;
749
session->mysys_var->current_cond= &COND_refresh;
750
session->set_proc_info("Flushing tables");
739
thd->mysys_var->current_mutex= &LOCK_open;
740
thd->mysys_var->current_cond= &COND_refresh;
741
thd_proc_info(thd, "Flushing tables");
752
close_old_data_files(session,session->open_tables,1,1);
743
close_old_data_files(thd,thd->open_tables,1,1);
755
747
/* Wait until all threads has closed all the tables we had locked */
756
while (found && ! session->killed)
748
while (found && ! thd->killed)
759
751
for (uint32_t idx=0 ; idx < open_cache.records ; idx++)
761
753
Table *table=(Table*) hash_element(&open_cache,idx);
762
754
/* Avoid a self-deadlock. */
763
if (table->in_use == session)
755
if (table->in_use == thd)
766
758
Note that we wait here only for tables which are actually open, and
859
851
tmp.table_name= share->table_name.str;
860
852
tmp.next_local= tables;
862
tables= (TableList *) memdup_root(session->mem_root, (char*)&tmp,
854
tables= (TableList *) memdup_root(thd->mem_root, (char*)&tmp,
863
855
sizeof(TableList));
867
result= close_cached_tables(session, tables, true, false, false);
859
result= close_cached_tables(thd, tables, true, false, false);
870
862
pthread_mutex_unlock(&LOCK_open);
872
864
if (if_wait_for_refresh)
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);
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);
992
984
leave prelocked mode if needed.
995
void close_thread_tables(Session *session)
987
void close_thread_tables(THD *thd)
1000
We are assuming here that session->derived_tables contains ONLY derived
992
We are assuming here that thd->derived_tables contains ONLY derived
1001
993
tables for this substatement. i.e. instead of approach which uses
1002
994
query_id matching for determining which of the derived tables belong
1003
995
to this substatement we rely on the ability of substatements to
1004
save/restore session->derived_tables during their execution.
996
save/restore thd->derived_tables during their execution.
1006
998
TODO: Probably even better approach is to simply associate list of
1007
999
derived tables with (sub-)statement instead of thread and destroy
1008
1000
them at the end of its execution.
1010
if (session->derived_tables)
1002
if (thd->derived_tables)
1014
1006
Close all derived tables generated in queries like
1015
1007
SELECT * FROM (SELECT * FROM t1)
1017
for (table= session->derived_tables ; table ; table= next)
1009
for (table= thd->derived_tables ; table ; table= next)
1019
1011
next= table->next;
1020
table->free_tmp_table(session);
1012
table->free_tmp_table(thd);
1022
session->derived_tables= 0;
1014
thd->derived_tables= 0;
1026
1018
Mark all temporary tables used by this statement as free for reuse.
1028
mark_temp_tables_as_free_for_reuse(session);
1020
mark_temp_tables_as_free_for_reuse(thd);
1030
1022
Let us commit transaction for statement. Since in 5.0 we only have
1031
1023
one statement transaction and don't allow several nested statement
1034
1026
does not belong to statement for which we do close_thread_tables()).
1035
1027
TODO: This should be fixed in later releases.
1037
if (!(session->state_flags & Open_tables_state::BACKUPS_AVAIL))
1029
if (!(thd->state_flags & Open_tables_state::BACKUPS_AVAIL))
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();
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();
1045
if (session->locked_tables)
1037
if (thd->locked_tables)
1048
1040
/* Ensure we are calling ha_reset() for all used tables */
1049
mark_used_tables_as_free_for_reuse(session, session->open_tables);
1041
mark_used_tables_as_free_for_reuse(thd, thd->open_tables);
1052
1044
We are under simple LOCK TABLES so should not do anything else.
1124
1117
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;
1128
1273
Find table in list.
1265
1410
void update_non_unique_table_error(TableList *update,
1411
const char *operation __attribute__((unused)),
1412
TableList *duplicate __attribute__((unused)))
1269
1414
my_error(ER_UPDATE_TABLE_USED, MYF(0), update->alias);
1273
Table *find_temporary_table(Session *session, const char *db, const char *table_name)
1418
Table *find_temporary_table(THD *thd, const char *db, const char *table_name)
1275
1420
TableList table_list;
1277
1422
table_list.db= (char*) db;
1278
1423
table_list.table_name= (char*) table_name;
1279
return find_temporary_table(session, &table_list);
1424
return find_temporary_table(thd, &table_list);
1283
Table *find_temporary_table(Session *session, TableList *table_list)
1428
Table *find_temporary_table(THD *thd, TableList *table_list)
1285
1430
char key[MAX_DBKEY_LENGTH];
1286
1431
uint key_length;
1289
key_length= create_table_def_key(session, key, table_list, 1);
1290
for (table=session->temporary_tables ; table ; table= table->next)
1434
key_length= create_table_def_key(thd, key, table_list, 1);
1435
for (table=thd->temporary_tables ; table ; table= table->next)
1292
1437
if (table->s->table_cache_key.length == key_length &&
1293
1438
!memcmp(table->s->table_cache_key.str, key, key_length))
1341
1486
If LOCK TABLES list is not empty and contains this table,
1342
1487
unlock the table and remove the table from this list.
1344
mysql_lock_remove(session, session->locked_tables, table, false);
1345
close_temporary_table(session, table, 1, 1);
1489
mysql_lock_remove(thd, thd->locked_tables, table, false);
1490
close_temporary_table(thd, table, 1, 1);
1350
unlink from session->temporary tables and close temporary table
1495
unlink from thd->temporary tables and close temporary table
1353
void close_temporary_table(Session *session, Table *table,
1498
void close_temporary_table(THD *thd, Table *table,
1354
1499
bool free_share, bool delete_table)
1356
1501
if (table->prev)
1364
1509
/* removing the item from the list */
1365
assert(table == session->temporary_tables);
1510
assert(table == thd->temporary_tables);
1367
1512
slave must reset its temporary list pointer to zero to exclude
1368
1513
passing non-zero value to end_slave via rli->save_temporary_tables
1369
1514
when no temp tables opened, see an invariant below.
1371
session->temporary_tables= table->next;
1372
if (session->temporary_tables)
1516
thd->temporary_tables= table->next;
1517
if (thd->temporary_tables)
1373
1518
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--;
1375
1526
close_temporary(table, free_share, delete_table);
1480
1633
Closing a MERGE child before the parent would be fatal if the
1481
1634
other thread tries to abort the MERGE lock in between.
1483
for (prev= &session->open_tables; *prev; )
1636
for (prev= &thd->open_tables; *prev; )
1487
1640
if (list->s->table_cache_key.length == key_length &&
1488
1641
!memcmp(list->s->table_cache_key.str, key, key_length))
1490
if (unlock && session->locked_tables)
1491
mysql_lock_remove(session, session->locked_tables, list, true);
1643
if (unlock && thd->locked_tables)
1644
mysql_lock_remove(thd, thd->locked_tables, list, true);
1493
1646
/* Remove table from open_tables list. */
1494
1647
*prev= list->next;
1554
1707
wait_for_condition()
1555
session Thread handler
1556
1709
mutex mutex that is currently hold that is associated with condition
1557
Will be unlocked on return
1710
Will be unlocked on return
1558
1711
cond Condition to wait for
1561
void wait_for_condition(Session *session, pthread_mutex_t *mutex, pthread_cond_t *cond)
1714
void wait_for_condition(THD *thd, pthread_mutex_t *mutex, pthread_cond_t *cond)
1563
1716
/* Wait until the current table is up to date */
1564
1717
const char *proc_info;
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)
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");
1570
1723
(void) pthread_cond_wait(cond, mutex);
1594
1747
Exclusively name-lock a table that is already write-locked by the
1595
1748
current thread.
1597
@param session current thread context
1750
@param thd current thread context
1598
1751
@param tables table list containing one table to open.
1600
1753
@return false on success, true otherwise.
1603
bool name_lock_locked_table(Session *session, TableList *tables)
1756
bool name_lock_locked_table(THD *thd, TableList *tables)
1605
1758
/* Under LOCK TABLES we must only accept write locked tables. */
1606
tables->table= find_locked_table(session, tables->db, tables->table_name);
1759
tables->table= find_locked_table(thd, tables->db, tables->table_name);
1608
1761
if (!tables->table)
1609
1762
my_error(ER_TABLE_NOT_LOCKED, MYF(0), tables->alias);
1784
1937
@retval false Success. 'table' parameter set according to above rules.
1787
bool lock_table_name_if_not_cached(Session *session, const char *db,
1940
bool lock_table_name_if_not_cached(THD *thd, const char *db,
1788
1941
const char *table_name, Table **table)
1790
1943
char key[MAX_DBKEY_LENGTH];
1792
1944
uint32_t key_length;
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;
1946
key_length= (uint)(my_stpcpy(my_stpcpy(key, db) + 1, table_name) - key) + 1;
1798
1947
pthread_mutex_lock(&LOCK_open);
1800
1949
if (hash_search(&open_cache, (unsigned char *)key, key_length))
1806
if (!(*table= table_cache_insert_placeholder(session, key, key_length)))
1955
if (!(*table= table_cache_insert_placeholder(thd, key, key_length)))
1808
1957
pthread_mutex_unlock(&LOCK_open);
1811
1960
(*table)->open_placeholder= 1;
1812
(*table)->next= session->open_tables;
1813
session->open_tables= *table;
1961
(*table)->next= thd->open_tables;
1962
thd->open_tables= *table;
1814
1963
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.
1824
2037
table_list Open first table in list.
1825
2038
refresh INOUT Pointer to memory that will be set to 1 if
1826
2039
we need to close all tables and reopen them.
1856
2069
char *alias= table_list->alias;
1857
2070
HASH_SEARCH_STATE state;
1859
/* Parsing of partitioning information from .frm needs session->lex set up. */
1860
assert(session->lex->is_lex_started);
2072
/* Parsing of partitioning information from .frm needs thd->lex set up. */
2073
assert(thd->lex->is_lex_started);
1862
2075
/* find a unused table in the open table cache */
1866
2079
/* an open table operation needs a lot of the stack space */
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) -
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) -
1874
2087
TMP_TABLE_KEY_EXTRA);
1881
2094
TODO: move this block into a separate function.
1884
for (table= session->temporary_tables; table ; table=table->next)
2097
for (table= thd->temporary_tables; table ; table=table->next)
1886
2099
if (table->s->table_cache_key.length == key_length +
1887
TMP_TABLE_KEY_EXTRA && !memcmp(table->s->table_cache_key.str, key,
1888
key_length + TMP_TABLE_KEY_EXTRA))
2100
TMP_TABLE_KEY_EXTRA &&
2101
!memcmp(table->s->table_cache_key.str, key,
2102
key_length + TMP_TABLE_KEY_EXTRA))
1891
2105
We're trying to use the same temporary table twice in a query.
1892
2106
Right now we don't support this because a temporary table
1893
is always represented by only one Table object in Session, and
2107
is always represented by only one Table object in THD, and
1894
2108
it can not be cloned. Emit an error for an unsupported behaviour.
1896
if (table->query_id)
1898
my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
1901
table->query_id= session->query_id;
1902
session->thread_specific_used= true;
2110
if (table->query_id)
2112
my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
2115
table->query_id= thd->query_id;
2116
thd->thread_specific_used= true;
1918
2132
open not pre-opened tables in pre-locked/LOCK TABLES mode.
1919
2133
TODO: move this block into a separate function.
1921
if (session->locked_tables)
1922
{ // Using table locks
2135
if (thd->locked_tables)
2136
{ // Using table locks
1923
2137
Table *best_table= 0;
1924
2138
int best_distance= INT_MIN;
1925
2139
bool check_if_used= false;
1926
for (table=session->open_tables; table ; table=table->next)
2140
for (table=thd->open_tables; table ; table=table->next)
1928
2142
if (table->s->table_cache_key.length == key_length &&
1929
!memcmp(table->s->table_cache_key.str, key, key_length))
2143
!memcmp(table->s->table_cache_key.str, key, key_length))
1931
2145
if (check_if_used && table->query_id &&
1932
table->query_id != session->query_id)
2146
table->query_id != thd->query_id)
1935
2149
If we are in stored function or trigger we should ensure that
2185
2415
/* make a new table */
2186
table= (Table *) malloc(sizeof(*table));
2416
if (!(table=(Table*) my_malloc(sizeof(*table),MYF(MY_WME))))
2189
2418
pthread_mutex_unlock(&LOCK_open);
2193
error= open_unireg_entry(session, table, table_list, alias, key, key_length);
2422
error= open_unireg_entry(thd, table, table_list, alias, key, key_length);
2423
/* Combine the follow two */
2426
free((unsigned char*)table);
2197
2427
pthread_mutex_unlock(&LOCK_open);
2432
free((unsigned char*)table);
2433
pthread_mutex_unlock(&LOCK_open);
2200
2436
my_hash_insert(&open_cache,(unsigned char*) table);
2203
2439
pthread_mutex_unlock(&LOCK_open);
2206
table->next=session->open_tables; /* Link into simple list */
2207
session->open_tables=table;
2442
table->next=thd->open_tables; /* Link into simple list */
2443
thd->open_tables=table;
2209
table->reginfo.lock_type=TL_READ; /* Assume read */
2445
table->reginfo.lock_type=TL_READ; /* Assume read */
2212
2448
assert(table->s->ref_count > 0 || table->s->tmp_table != NO_TMP_TABLE);
2214
if (session->lex->need_correct_ident())
2450
if (thd->lex->need_correct_ident())
2215
2451
table->alias_name_used= my_strcasecmp(table_alias_charset,
2216
2452
table->s->table_name.str, alias);
2217
2453
/* Fix alias if table name changes */
2218
2454
if (strcmp(table->alias, alias))
2220
uint32_t length=(uint32_t) strlen(alias)+1;
2221
table->alias= (char*) realloc((char*) table->alias, length);
2456
uint32_t length=(uint) strlen(alias)+1;
2457
table->alias= (char*) my_realloc((char*) table->alias, length,
2222
2459
memcpy((void*) table->alias, alias, length);
2224
2461
/* These variables are also set in reopen_table() */
2225
table->tablenr=session->current_tablenr++;
2462
table->tablenr=thd->current_tablenr++;
2226
2463
table->used_fields=0;
2227
2464
table->const_table=0;
2228
2465
table->null_row= false;
2245
Table *find_locked_table(Session *session, const char *db,const char *table_name)
2482
Table *find_locked_table(THD *thd, const char *db,const char *table_name)
2247
char key[MAX_DBKEY_LENGTH];
2249
uint32_t key_length;
2251
key_pos= strcpy(key_pos, db) + strlen(db);
2252
key_pos= strcpy(key_pos+1, table_name) + strlen(table_name);
2253
key_length= (uint32_t)(key_pos-key)+1;
2255
for (Table *table=session->open_tables; table ; table=table->next)
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)
2257
2489
if (table->s->table_cache_key.length == key_length &&
2258
!memcmp(table->s->table_cache_key.str, key, key_length))
2490
!memcmp(table->s->table_cache_key.str, key, key_length))
2398
2630
for target table name if we process ALTER Table ... RENAME.
2399
2631
So loop below makes sense even if we are not under LOCK TABLES.
2401
for (table=session->open_tables; table ; table=table->next)
2633
for (table=thd->open_tables; table ; table=table->next)
2403
2635
if (!strcmp(table->s->table_name.str, table_name) &&
2404
2636
!strcmp(table->s->db.str, db))
2406
if (session->locked_tables)
2638
if (thd->locked_tables)
2408
mysql_lock_remove(session, session->locked_tables, table, true);
2640
mysql_lock_remove(thd, thd->locked_tables, table, true);
2410
2642
table->open_placeholder= 1;
2411
2643
close_handle_and_leave_table_as_lock(table);
2650
2882
/* Wait until all used tables are refreshed */
2652
bool wait_for_tables(Session *session)
2884
bool wait_for_tables(THD *thd)
2656
session->set_proc_info("Waiting for tables");
2888
thd_proc_info(thd, "Waiting for tables");
2657
2889
pthread_mutex_lock(&LOCK_open);
2658
while (!session->killed)
2890
while (!thd->killed)
2660
session->some_tables_deleted=0;
2661
close_old_data_files(session,session->open_tables,0,dropping_tables != 0);
2662
if (!table_is_used(session->open_tables,1))
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))
2664
2897
(void) pthread_cond_wait(&COND_refresh,&LOCK_open);
2666
if (session->killed)
2667
2900
result= 1; // aborted
2670
2903
/* Now we can open all tables without any interference */
2671
session->set_proc_info("Reopen tables");
2672
session->version= refresh_version;
2673
result=reopen_tables(session,0,0);
2904
thd_proc_info(thd, "Reopen tables");
2905
thd->version= refresh_version;
2906
result=reopen_tables(thd,0,0);
2675
2908
pthread_mutex_unlock(&LOCK_open);
2676
session->set_proc_info(0);
2909
thd_proc_info(thd, 0);
2677
2910
return(result);
2762
2995
other threads trying to get the lock.
2765
void abort_locked_tables(Session *session,const char *db, const char *table_name)
2998
void abort_locked_tables(THD *thd,const char *db, const char *table_name)
2768
for (table= session->open_tables; table ; table= table->next)
3001
for (table= thd->open_tables; table ; table= table->next)
2770
3003
if (!strcmp(table->s->table_name.str, table_name) &&
2771
3004
!strcmp(table->s->db.str, db))
2773
3006
/* If MERGE child, forward lock handling to parent. */
2774
mysql_lock_abort(session, table, true);
3007
mysql_lock_abort(thd, table, true);
2862
3095
safe_mutex_assert_owner(&LOCK_open);
2864
if (!(share= get_table_share_with_create(session, table_list, cache_key,
3097
if (!(share= get_table_share_with_create(thd, table_list, cache_key,
2866
3099
table_list->i_s_requested_object,
2870
while ((error= open_table_from_share(session, share, alias,
2871
(uint32_t) (HA_OPEN_KEYFILE |
3103
while ((error= open_table_from_share(thd, share, alias,
3104
(uint) (HA_OPEN_KEYFILE |
2872
3105
HA_OPEN_RNDFILE |
2874
3107
HA_TRY_READ_ONLY),
2875
3108
(EXTRA_RECORD),
2876
session->open_options, entry, OTM_OPEN)))
3109
thd->open_options, entry, OTM_OPEN)))
2878
3111
if (error == 7) // Table def changed
2915
3150
if (!entry->s || !entry->s->crashed)
2917
3152
// Code below is for repairing a crashed file
2918
if ((error= lock_table_name(session, table_list, true)))
3153
if ((error= lock_table_name(thd, table_list, true)))
2922
if (wait_for_locked_table_names(session, table_list))
3157
if (wait_for_locked_table_names(thd, table_list))
2924
unlock_table_name(session, table_list);
3159
unlock_table_name(thd, table_list);
2928
3163
pthread_mutex_unlock(&LOCK_open);
2929
session->clear_error(); // Clear error message
3164
thd->clear_error(); // Clear error message
2931
if (open_table_from_share(session, share, alias,
2932
(uint32_t) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
3166
if (open_table_from_share(thd, share, alias,
3167
(uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
2934
3169
HA_TRY_READ_ONLY),
2936
3171
ha_open_options | HA_OPEN_FOR_REPAIR,
2937
3172
entry, OTM_OPEN) || ! entry->file ||
2938
(entry->file->is_crashed() && entry->file->ha_check_and_repair(session)))
3173
(entry->file->is_crashed() && entry->file->ha_check_and_repair(thd)))
2940
3175
/* Give right error message */
2941
session->clear_error();
2942
3177
my_error(ER_NOT_KEYFILE, MYF(0), share->table_name.str, my_errno);
2943
errmsg_printf(ERRMSG_LVL_ERROR, _("Couldn't repair table: %s.%s"), share->db.str,
3178
sql_print_error(_("Couldn't repair table: %s.%s"), share->db.str,
2944
3179
share->table_name.str);
2945
3180
if (entry->file)
2946
entry->closefrm(false);
2950
session->clear_error(); // Clear error message
3185
thd->clear_error(); // Clear error message
2951
3186
pthread_mutex_lock(&LOCK_open);
2952
unlock_table_name(session, table_list);
3187
unlock_table_name(thd, table_list);
2963
3198
if (unlikely(entry->file->implicit_emptied))
2965
3200
entry->file->implicit_emptied= 0;
3201
if (mysql_bin_log.is_open())
2967
3203
char *query, *end;
2968
3204
uint32_t query_buf_size= 20 + share->db.length + share->table_name.length +1;
2969
if ((query= (char*) malloc(query_buf_size)))
3205
if ((query= (char*) my_malloc(query_buf_size,MYF(MY_WME))))
2972
"this DELETE FROM is needed even with row-based binlogging"
2974
We inherited this from MySQL. TODO: fix it to issue a propper truncate
2975
of the table (though that may not be completely right sematics).
2978
end+= sprintf(query, "DELETE FROM `%s`.`%s`", share->db.str,
2979
share->table_name.str);
2980
(void)replicator_statement(session, query, (size_t)(end - query));
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);
2985
errmsg_printf(ERRMSG_LVL_ERROR, _("When opening HEAP table, could not allocate memory "
2986
"to write 'DELETE FROM `%s`.`%s`' to replication"),
2987
table_list->db, table_list->table_name);
2988
my_error(ER_OUTOFMEMORY, MYF(0), query_buf_size);
2989
entry->closefrm(false);
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);
3247
3482
table Opened table
3250
3485
If ok, the following are also set:
3251
3486
table_list->lock_type lock_type
3252
3487
table_list->table table
3255
Table *open_ltable(Session *session, TableList *table_list, thr_lock_type lock_type,
3490
Table *open_ltable(THD *thd, TableList *table_list, thr_lock_type lock_type,
3256
3491
uint32_t lock_flags)
3261
session->set_proc_info("Opening table");
3262
session->current_tablenr= 0;
3263
while (!(table= open_table(session, table_list, &refresh, 0)) &&
3496
thd_proc_info(thd, "Opening table");
3497
thd->current_tablenr= 0;
3498
while (!(table= open_table(thd, table_list, &refresh, 0)) &&
3269
3504
table_list->lock_type= lock_type;
3270
3505
table_list->table= table;
3271
if (session->locked_tables)
3506
if (thd->locked_tables)
3273
if (check_lock_and_start_stmt(session, table, lock_type))
3508
if (check_lock_and_start_stmt(thd, table, lock_type))
3278
assert(session->lock == 0); // You must lock everything at once
3513
assert(thd->lock == 0); // You must lock everything at once
3279
3514
if ((table->reginfo.lock_type= lock_type) != TL_UNLOCK)
3280
if (! (session->lock= mysql_lock_tables(session, &table_list->table, 1,
3515
if (! (thd->lock= mysql_lock_tables(thd, &table_list->table, 1,
3281
3516
lock_flags, &refresh)))
3286
session->set_proc_info(0);
3521
thd_proc_info(thd, 0);
3308
3543
There are two convenience functions:
3309
- simple_open_n_lock_tables(session, tables) without derived handling
3310
- open_and_lock_tables(session, tables) with derived handling
3544
- simple_open_n_lock_tables(thd, tables) without derived handling
3545
- open_and_lock_tables(thd, tables) with derived handling
3311
3546
Both inline functions call open_and_lock_tables_derived() with
3312
3547
the third argument set appropriately.
3315
int open_and_lock_tables_derived(Session *session, TableList *tables, bool derived)
3550
int open_and_lock_tables_derived(THD *thd, TableList *tables, bool derived)
3317
3552
uint32_t counter;
3318
3553
bool need_reopen;
3322
if (open_tables(session, &tables, &counter, 0))
3557
if (open_tables(thd, &tables, &counter, 0))
3325
if (!lock_tables(session, tables, counter, &need_reopen))
3560
if (!lock_tables(thd, tables, counter, &need_reopen))
3327
3562
if (!need_reopen)
3329
close_tables_for_reopen(session, &tables);
3564
close_tables_for_reopen(thd, &tables);
3332
(mysql_handle_derived(session->lex, &mysql_derived_prepare) ||
3333
(session->fill_derived_tables() &&
3334
mysql_handle_derived(session->lex, &mysql_derived_filling))))
3567
(mysql_handle_derived(thd->lex, &mysql_derived_prepare) ||
3568
(thd->fill_derived_tables() &&
3569
mysql_handle_derived(thd->lex, &mysql_derived_filling))))
3335
3570
return(true); /* purecov: inspected */
3356
3591
This is to be used on prepare stage when you don't read any
3357
3592
data from the tables.
3360
bool open_normal_and_derived_tables(Session *session, TableList *tables, uint32_t flags)
3595
bool open_normal_and_derived_tables(THD *thd, TableList *tables, uint32_t flags)
3362
3597
uint32_t counter;
3363
assert(!session->fill_derived_tables());
3364
if (open_tables(session, &tables, &counter, flags) ||
3365
mysql_handle_derived(session->lex, &mysql_derived_prepare))
3598
assert(!thd->fill_derived_tables());
3599
if (open_tables(thd, &tables, &counter, flags) ||
3600
mysql_handle_derived(thd->lex, &mysql_derived_prepare))
3366
3601
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();
3371
3713
Lock all tables in list
3375
session Thread handler
3376
3718
tables Tables to lock
3377
3719
count Number of opened tables
3378
3720
need_reopen Out parameter which if true indicates that some
3463
3805
close_tables_for_reopen()
3464
session in Thread context
3806
thd in Thread context
3465
3807
tables in/out List of tables which we were trying to open and lock
3469
void close_tables_for_reopen(Session *session, TableList **tables)
3811
void close_tables_for_reopen(THD *thd, TableList **tables)
3472
3814
If table list consists only from tables from prelocking set, table list
3473
3815
for new attempt should be empty, so we have to update list's root pointer.
3475
if (session->lex->first_not_own_table() == *tables)
3817
if (thd->lex->first_not_own_table() == *tables)
3477
session->lex->chop_off_not_own_tables();
3819
thd->lex->chop_off_not_own_tables();
3478
3820
for (TableList *tmp= *tables; tmp; tmp= tmp->next_global)
3480
close_thread_tables(session);
3822
close_thread_tables(thd);
3504
Table *open_temporary_table(Session *session, const char *path, const char *db,
3846
Table *open_temporary_table(THD *thd, const char *path, const char *db,
3505
3847
const char *table_name, bool link_in_list,
3506
3848
open_table_mode open_mode)
3508
3850
Table *tmp_table;
3509
3851
TABLE_SHARE *share;
3510
3852
char cache_key[MAX_DBKEY_LENGTH], *saved_cache_key, *tmp_path;
3511
uint32_t key_length, path_length;
3853
uint32_t key_length;
3512
3854
TableList table_list;
3514
3856
table_list.db= (char*) db;
3515
3857
table_list.table_name= (char*) table_name;
3516
3858
/* Create the cache_key for temporary tables */
3517
key_length= create_table_def_key(session, cache_key, &table_list, 1);
3518
path_length= strlen(path);
3859
key_length= create_table_def_key(thd, cache_key, &table_list, 1);
3520
if (!(tmp_table= (Table*) malloc(sizeof(*tmp_table) + sizeof(*share) +
3521
path_length + 1 + key_length)))
3861
if (!(tmp_table= (Table*) my_malloc(sizeof(*tmp_table) + sizeof(*share) +
3862
strlen(path)+1 + key_length,
3864
return(0); /* purecov: inspected */
3524
3866
share= (TABLE_SHARE*) (tmp_table+1);
3525
3867
tmp_path= (char*) (share+1);
3526
saved_cache_key= strcpy(tmp_path, path)+path_length+1;
3868
saved_cache_key= my_stpcpy(tmp_path, path)+1;
3527
3869
memcpy(saved_cache_key, cache_key, key_length);
3529
init_tmp_table_share(session, share, saved_cache_key, key_length,
3871
init_tmp_table_share(thd, share, saved_cache_key, key_length,
3530
3872
strchr(saved_cache_key, '\0')+1, tmp_path);
3532
if (open_table_def(session, share, 0) ||
3533
open_table_from_share(session, share, table_name,
3874
if (open_table_def(thd, share, 0) ||
3875
open_table_from_share(thd, share, table_name,
3534
3876
(open_mode == OTM_ALTER) ? 0 :
3535
(uint32_t) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
3877
(uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
3537
3879
(open_mode == OTM_ALTER) ?
3538
3880
(EXTRA_RECORD | OPEN_FRM_FILE_ONLY)
3562
3904
if (link_in_list)
3564
3906
/* growing temp list at the head */
3565
tmp_table->next= session->temporary_tables;
3907
tmp_table->next= thd->temporary_tables;
3566
3908
if (tmp_table->next)
3567
3909
tmp_table->next->prev= tmp_table;
3568
session->temporary_tables= tmp_table;
3569
session->temporary_tables->prev= 0;
3910
thd->temporary_tables= tmp_table;
3911
thd->temporary_tables->prev= 0;
3912
if (thd->slave_thread)
3913
slave_open_temp_tables++;
3571
3915
tmp_table->pos_in_table_list= 0;
3572
3916
return(tmp_table);
3576
bool rm_temporary_table(handlerton *base, char *path)
3920
bool rm_temporary_table(handlerton *base, char *path, bool frm_only)
3581
if(delete_table_proto_file(path))
3926
my_stpcpy(ext= strchr(path, '\0'), reg_ext);
3927
if (my_delete(path,MYF(0)))
3582
3928
error=1; /* purecov: inspected */
3584
file= get_new_handler((TABLE_SHARE*) 0, current_session->mem_root, base);
3585
if (file && file->ha_delete_table(path))
3929
*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))
3588
errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
3934
sql_print_warning(_("Could not remove temporary table: '%s', error: %d"),
3589
3935
path, my_errno);
4099
4433
when table_ref->field_translation != NULL.
4101
4435
if (table_ref->table)
4102
found= find_field_in_table(session, table_ref->table, name, length,
4436
found= find_field_in_table(thd, table_ref->table, name, length,
4103
4437
true, &(item->cached_field_index));
4105
found= find_field_in_table_ref(session, table_ref, name, length, item->name,
4439
found= find_field_in_table_ref(thd, table_ref, name, length, item->name,
4106
4440
NULL, NULL, ref, check_privileges,
4107
4441
true, &(item->cached_field_index),
4108
4442
register_tree_change,
4227
4561
char buff[NAME_LEN*2+1];
4228
4562
if (db && db[0])
4230
/* We're in an error condition, two extra strlen's aren't going
4232
assert(strlen(db) <= NAME_LEN);
4233
assert(strlen(table_name) <= NAME_LEN);
4236
strcat(buff, table_name);
4564
strxnmov(buff,sizeof(buff)-1,db,".",table_name,NULL);
4237
4565
table_name=buff;
4239
my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, session->where);
4567
my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, thd->where);
4243
4571
if (report_error == REPORT_ALL_ERRORS ||
4244
4572
report_error == REPORT_EXCEPT_NON_UNIQUE)
4245
my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), session->where);
4573
my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), thd->where);
4247
4575
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;
5176
5533
** Check that all given fields exists and fill struct with current data
5177
5534
****************************************************************************/
5179
bool setup_fields(Session *session, Item **ref_pointer_array,
5536
bool setup_fields(THD *thd, Item **ref_pointer_array,
5180
5537
List<Item> &fields, enum_mark_columns mark_used_columns,
5181
5538
List<Item> *sum_func_list, bool allow_sum_func)
5183
5540
register Item *item;
5184
enum_mark_columns save_mark_used_columns= session->mark_used_columns;
5185
nesting_map save_allow_sum_func= session->lex->allow_sum_func;
5541
enum_mark_columns save_mark_used_columns= thd->mark_used_columns;
5542
nesting_map save_allow_sum_func= thd->lex->allow_sum_func;
5186
5543
List_iterator<Item> it(fields);
5187
5544
bool save_is_item_list_lookup;
5189
session->mark_used_columns= mark_used_columns;
5546
thd->mark_used_columns= mark_used_columns;
5190
5547
if (allow_sum_func)
5191
session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
5192
session->where= Session::DEFAULT_WHERE;
5193
save_is_item_list_lookup= session->lex->current_select->is_item_list_lookup;
5194
session->lex->current_select->is_item_list_lookup= 0;
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;
5197
5554
To prevent fail on forward lookup we fill it with zerows,
5208
5565
memset(ref_pointer_array, 0, sizeof(Item *) * fields.elements);
5210
5567
Item **ref= ref_pointer_array;
5211
session->lex->current_select->cur_pos_in_select_list= 0;
5568
thd->lex->current_select->cur_pos_in_select_list= 0;
5212
5569
while ((item= it++))
5214
if ((!item->fixed && item->fix_fields(session, it.ref())) || (item= *(it.ref()))->check_cols(1))
5571
if ((!item->fixed && item->fix_fields(thd, it.ref())) || (item= *(it.ref()))->check_cols(1))
5216
session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
5217
session->lex->allow_sum_func= save_allow_sum_func;
5218
session->mark_used_columns= save_mark_used_columns;
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;
5219
5576
return(true); /* purecov: inspected */
5222
5579
*(ref++)= item;
5223
5580
if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM &&
5225
item->split_sum_func(session, ref_pointer_array, *sum_func_list);
5226
session->used_tables|= item->used_tables();
5227
session->lex->current_select->cur_pos_in_select_list++;
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++;
5229
session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
5230
session->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
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;
5232
session->lex->allow_sum_func= save_allow_sum_func;
5233
session->mark_used_columns= save_mark_used_columns;
5234
return(test(session->is_error()));
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()));
5623
5969
bool save_is_item_list_lookup= select_lex->is_item_list_lookup;
5624
5970
select_lex->is_item_list_lookup= 0;
5626
session->mark_used_columns= MARK_COLUMNS_READ;
5972
thd->mark_used_columns= MARK_COLUMNS_READ;
5627
5973
select_lex->cond_count= 0;
5628
5974
select_lex->between_count= 0;
5629
5975
select_lex->max_equal_elems= 0;
5631
session->session_marker= (void*)1;
5977
thd->thd_marker= (void*)1;
5634
session->where="where clause";
5635
if ((!(*conds)->fixed && (*conds)->fix_fields(session, conds)) ||
5980
thd->where="where clause";
5981
if ((!(*conds)->fixed && (*conds)->fix_fields(thd, conds)) ||
5636
5982
(*conds)->check_cols(1))
5637
5983
goto err_no_arena;
5639
session->session_marker= save_session_marker;
5985
thd->thd_marker= save_thd_marker;
5642
5988
Apply fix_fields() to all ON clauses at all levels of nesting,
5745
6088
table= rfield->table;
5746
6089
if (rfield == table->next_number_field)
5747
6090
table->auto_increment_field_not_null= true;
5748
if (rfield->vcol_info &&
5749
value->type() != Item::DEFAULT_VALUE_ITEM &&
5750
value->type() != Item::NULL_ITEM &&
5751
table->s->table_category != TABLE_CATEGORY_TEMPORARY)
5753
session->abort_on_warning= false;
5754
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
5755
ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN,
5756
ER(ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN),
5757
rfield->field_name, table->s->table_name.str);
5758
session->abort_on_warning= abort_on_warning_saved;
5760
6091
if ((value->save_in_field(rfield, 0) < 0) && !ignore_errors)
5762
6093
my_message(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), MYF(0));
5765
tbl_list.push_back(table);
5767
/* Update virtual fields*/
5768
session->abort_on_warning= false;
5769
if (tbl_list.head())
5771
List_iterator_fast<Table> t(tbl_list);
5772
Table *prev_table= 0;
5773
while ((table= t++))
5776
Do simple optimization to prevent unnecessary re-generating
5777
values for virtual fields
5779
if (table != prev_table)
5784
if (update_virtual_fields_marked_for_write(table, false))
5790
session->abort_on_warning= abort_on_warning_saved;
5791
return(session->is_error());
6097
return(thd->is_error());
5793
session->abort_on_warning= abort_on_warning_saved;
5795
6100
table->auto_increment_field_not_null= false;
5842
6144
table= (*ptr)->table;
5843
6145
table->auto_increment_field_not_null= false;
5845
while ((field = *ptr++) && ! session->is_error())
6147
while ((field = *ptr++) && ! thd->is_error())
5848
6150
table= field->table;
5849
6151
if (field == table->next_number_field)
5850
6152
table->auto_increment_field_not_null= true;
5851
if (field->vcol_info &&
5852
value->type() != Item::DEFAULT_VALUE_ITEM &&
5853
value->type() != Item::NULL_ITEM &&
5854
table->s->table_category != TABLE_CATEGORY_TEMPORARY)
5856
session->abort_on_warning= false;
5857
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
5858
ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN,
5859
ER(ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN),
5860
field->field_name, table->s->table_name.str);
5861
session->abort_on_warning= abort_on_warning_saved;
5863
6153
if (value->save_in_field(field, 0) < 0)
5865
tbl_list.push_back(table);
5867
/* Update virtual fields*/
5868
session->abort_on_warning= false;
5869
if (tbl_list.head())
5871
List_iterator_fast<Table> t(tbl_list);
5872
Table *prev_table= 0;
5873
while ((table= t++))
5876
Do simple optimization to prevent unnecessary re-generating
5877
values for virtual fields
5879
if (table != prev_table)
5884
if (update_virtual_fields_marked_for_write(table, false))
5892
session->abort_on_warning= abort_on_warning_saved;
5893
return(session->is_error());
6156
return(thd->is_error());
5896
session->abort_on_warning= abort_on_warning_saved;
5898
6160
table->auto_increment_field_not_null= false;
5903
bool drizzle_rm_tmp_tables(void)
6165
bool mysql_rm_tmp_tables(void)
5906
char filePath[FN_REFLEN], filePathCopy[FN_REFLEN];
6168
char filePath[FN_REFLEN], *tmpdir, filePathCopy[FN_REFLEN];
5908
6170
FILEINFO *file;
5909
6171
TABLE_SHARE share;
5912
assert(drizzle_tmpdir);
5914
if (!(session= new Session))
5916
session->thread_stack= (char*) &session;
5917
session->store_globals();
5919
/* Remove all temp tables in the tmpdir */
5920
/* See if the directory exists */
5921
if ((dirp = my_dir(drizzle_tmpdir ,MYF(MY_WME | MY_DONT_SORT))))
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++)
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))))
5923
6186
/* Remove all SQLxxx tables from directory */
5924
for (idx=0 ; idx < (uint32_t) dirp->number_off_files ; idx++)
6188
for (idx=0 ; idx < (uint) dirp->number_off_files ; idx++)
5926
6190
file=dirp->dir_entry+idx;
5930
6194
(file->name[1] == '.' && !file->name[2])))
5933
if (!memcmp(file->name, TMP_FILE_PREFIX, TMP_FILE_PREFIX_LENGTH))
6197
if (!memcmp(file->name, tmp_file_prefix, tmp_file_prefix_length))
5935
6199
char *ext= fn_ext(file->name);
5936
6200
uint32_t ext_len= strlen(ext);
5937
6201
uint32_t filePath_len= snprintf(filePath, sizeof(filePath),
5938
"%s%c%s", drizzle_tmpdir, FN_LIBCHAR,
5940
if (!memcmp(".dfe", ext, ext_len))
6202
"%s%c%s", tmpdir, FN_LIBCHAR,
6204
if (!memcmp(reg_ext, ext, ext_len))
5942
6206
handler *handler_file= 0;
5943
6207
/* We should cut file extention before deleting of table */
5944
6208
memcpy(filePathCopy, filePath, filePath_len - ext_len);
5945
6209
filePathCopy[filePath_len - ext_len]= 0;
5946
init_tmp_table_share(session, &share, "", 0, "", filePathCopy);
5947
if (!open_table_def(session, &share, 0) &&
5948
((handler_file= get_new_handler(&share, session->mem_root,
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,
5949
6213
share.db_type()))))
5951
6215
handler_file->ha_delete_table(filePathCopy);
6090
6349
open_tables list. Aborting the MERGE lock after a child was
6091
6350
closed and before the parent is closed would be fatal.
6093
for (Table *session_table= in_use->open_tables;
6095
session_table= session_table->next)
6352
for (Table *thd_table= in_use->open_tables;
6354
thd_table= thd_table->next)
6097
6356
/* Do not handle locks of MERGE children. */
6098
if (session_table->db_stat) // If table is open
6099
signalled|= mysql_lock_abort_for_thread(session, session_table);
6357
if (thd_table->db_stat) // If table is open
6358
signalled|= mysql_lock_abort_for_thread(thd, thd_table);
6103
result= result || (flags & RTFC_OWNED_BY_Session_FLAG);
6362
result= result || (flags & RTFC_OWNED_BY_THD_FLAG);
6105
6364
while (unused_tables && !unused_tables->s->version)
6106
6365
hash_delete(&open_cache,(unsigned char*) unused_tables);