44
44
#include <drizzled/check_stack_overrun.h>
45
45
#include <drizzled/lock.h>
46
46
#include <drizzled/plugin/listen.h>
47
#include <drizzled/cached_directory.h>
48
#include <drizzled/field/epoch.h>
47
#include "drizzled/cached_directory.h"
48
#include <drizzled/field/timestamp.h>
49
49
#include <drizzled/field/null.h>
50
#include <drizzled/sql_table.h>
51
#include <drizzled/global_charset_info.h>
52
#include <drizzled/pthread_globals.h>
53
#include <drizzled/internal/iocache.h>
54
#include <drizzled/drizzled.h>
55
#include <drizzled/plugin/authorization.h>
56
#include <drizzled/table/temporary.h>
57
#include <drizzled/table/placeholder.h>
58
#include <drizzled/table/unused.h>
59
#include <drizzled/plugin/storage_engine.h>
60
#include <drizzled/session.h>
62
#include <drizzled/refresh_version.h>
50
#include "drizzled/sql_table.h"
51
#include "drizzled/global_charset_info.h"
52
#include "drizzled/pthread_globals.h"
53
#include "drizzled/internal/iocache.h"
54
#include "drizzled/drizzled.h"
55
#include "drizzled/plugin/authorization.h"
56
#include "drizzled/table/temporary.h"
57
#include "drizzled/table/placeholder.h"
64
59
using namespace std;
69
64
extern bool volatile shutdown_in_progress;
66
TableOpenCache &get_open_cache()
68
static TableOpenCache open_cache; /* Used by mysql_test */
73
static void free_cache_entry(table::Concurrent *entry);
75
void remove_table(table::Concurrent *arg)
77
TableOpenCacheRange ppp;
78
ppp= get_open_cache().equal_range(arg->getShare()->getCacheKey());
80
for (TableOpenCache::const_iterator iter= ppp.first;
81
iter != ppp.second; ++iter)
83
table::Concurrent *found_table= (*iter).second;
85
if (found_table == arg)
87
free_cache_entry(arg);
88
get_open_cache().erase(iter);
94
static bool add_table(table::Concurrent *arg)
96
TableOpenCache &open_cache(get_open_cache());
98
TableOpenCache::iterator returnable= open_cache.insert(make_pair(arg->getShare()->getCacheKey(), arg));
100
return not (returnable == open_cache.end());
104
table::Concurrent *tables; /* Used by mysql_test */
106
table::Concurrent *getTable() const
111
table::Concurrent *setTable(Table *arg)
113
return tables= dynamic_cast<table::Concurrent *>(arg);
120
/* Free cache if too big */
121
while (cached_open_tables() > table_cache_size && getTable())
122
remove_table(getTable());
127
while (getTable() && not getTable()->getShare()->getVersion())
128
remove_table(getTable());
131
void link(table::Concurrent *table)
135
table->setNext(getTable()); /* Link in last */
136
table->setPrev(getTable()->getPrev());
137
getTable()->setPrev(table);
138
table->getPrev()->setNext(table);
142
table->setPrev(setTable(table));
143
table->setNext(table->getPrev());
144
assert(table->getNext() == table && table->getPrev() == table);
149
void unlink(table::Concurrent *table)
153
/* Unlink the table from "unused_tables" list. */
154
if (table == getTable())
156
setTable(getTable()->getNext()); // Remove from link
157
if (table == getTable())
162
/* move table first in unused links */
164
void relink(table::Concurrent *table)
166
if (table != getTable())
170
table->setNext(getTable()); /* Link in unused tables */
171
table->setPrev(getTable()->getPrev());
172
getTable()->getPrev()->setNext(table);
173
getTable()->setPrev(table);
182
remove_table(getTable());
194
static UnusedTables unused_tables;
195
static int open_unireg_entry(Session *session,
198
TableIdentifier &identifier);
200
unsigned char *table_cache_key(const unsigned char *record,
204
unsigned char *table_cache_key(const unsigned char *record,
208
Table *entry=(Table*) record;
209
*length= entry->getShare()->getCacheKey().size();
210
return (unsigned char*) &entry->getShare()->getCacheKey()[0];
71
213
bool table_cache_init(void)
114
256
This has to be done to ensure that the table share is removed from
115
257
the table defintion cache as soon as the last instance is removed
117
identifier::Table identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), message::Table::INTERNAL);
118
const identifier::Table::Key &key(identifier.getKey());
259
TableIdentifier identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), message::Table::INTERNAL);
260
const TableIdentifier::Key &key(identifier.getKey());
119
261
TableShare *share= new TableShare(identifier.getType(),
121
const_cast<char *>(key.vector()), static_cast<uint32_t>(table->getShare()->getCacheKeySize()));
263
const_cast<char *>(&key[0]), static_cast<uint32_t>(table->getShare()->getCacheKeySize()));
123
265
table->cursor->close();
124
266
table->db_stat= 0; // Mark cursor closed
125
table::instance::release(table->getMutableShare());
267
TableShare::release(table->getMutableShare());
126
268
table->setShare(share);
269
table->cursor->change_table_ptr(table, table->getMutableShare());
536
void Open_tables_state::doGetTableNames(CachedDirectory &,
537
const identifier::Schema &schema_identifier,
538
std::set<std::string> &set_of_names)
701
void Session::doGetTableNames(CachedDirectory &,
702
const SchemaIdentifier &schema_identifier,
703
std::set<std::string> &set_of_names)
540
705
doGetTableNames(schema_identifier, set_of_names);
543
void Open_tables_state::doGetTableIdentifiers(const identifier::Schema &schema_identifier,
544
identifier::Table::vector &set_of_identifiers)
708
void Session::doGetTableIdentifiers(const SchemaIdentifier &schema_identifier,
709
TableIdentifiers &set_of_identifiers)
546
for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
711
for (Table *table= temporary_tables ; table ; table= table->getNext())
548
713
if (schema_identifier.compare(table->getShare()->getSchemaName()))
550
set_of_identifiers.push_back(identifier::Table(table->getShare()->getSchemaName(),
715
set_of_identifiers.push_back(TableIdentifier(table->getShare()->getSchemaName(),
551
716
table->getShare()->getTableName(),
552
717
table->getShare()->getPath()));
557
void Open_tables_state::doGetTableIdentifiers(CachedDirectory &,
558
const identifier::Schema &schema_identifier,
559
identifier::Table::vector &set_of_identifiers)
722
void Session::doGetTableIdentifiers(CachedDirectory &,
723
const SchemaIdentifier &schema_identifier,
724
TableIdentifiers &set_of_identifiers)
561
726
doGetTableIdentifiers(schema_identifier, set_of_identifiers);
564
bool Open_tables_state::doDoesTableExist(const identifier::Table &identifier)
729
bool Session::doDoesTableExist(const TableIdentifier &identifier)
566
for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
731
for (Table *table= temporary_tables ; table ; table= table->getNext())
568
733
if (table->getShare()->getType() == message::Table::TEMPORARY)
599
Table *Open_tables_state::find_temporary_table(const identifier::Table &identifier)
764
Table *Session::find_temporary_table(const char *new_db, const char *table_name)
766
char key[MAX_DBKEY_LENGTH];
769
key_length= TableIdentifier::createKey(key, new_db, table_name);
771
for (Table *table= temporary_tables ; table ; table= table->getNext())
773
const TableIdentifier::Key &share_key(table->getShare()->getCacheKey());
774
if (share_key.size() == key_length &&
775
not memcmp(&share_key[0], key, key_length))
780
return NULL; // Not a temporary table
783
Table *Session::find_temporary_table(TableList *table_list)
785
return find_temporary_table(table_list->db, table_list->table_name);
788
Table *Session::find_temporary_table(TableIdentifier &identifier)
601
790
for (Table *table= temporary_tables ; table ; table= table->getNext())
661
850
@param session Thread context
662
851
@param find Table to remove
664
@note because we risk the chance of deleting the share, we can't assume that it will exist past, this should be modified once we can use a TableShare::shared_ptr here.
853
@note because we risk the chance of deleting the share, we can't assume that it will exist past, this should be modified once we can use a TableSharePtr here.
667
856
void Session::unlink_open_table(Table *find)
669
const identifier::Table::Key find_key(find->getShare()->getCacheKey());
858
const TableIdentifier::Key find_key(find->getShare()->getCacheKey());
671
safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
860
safe_mutex_assert_owner(LOCK_open.native_handle());
674
Note that we need to hold table::Cache::singleton().mutex() while changing the
863
Note that we need to hold LOCK_open while changing the
675
864
open_tables list. Another thread may work on it.
676
(See: table::Cache::singleton().removeTable(), wait_completed_table())
865
(See: remove_table_from_cache(), mysql_wait_completed_table())
677
866
Closing a MERGE child before the parent would be fatal if the
678
867
other thread tries to abort the MERGE lock in between.
975
Open table which is already name-locked by this thread.
978
reopen_name_locked_table()
979
session Thread handle
980
table_list TableList object for table to be open, TableList::table
981
member should point to Table object which was used for
983
link_in true - if Table object for table to be opened should be
984
linked into Session::open_tables list.
985
false - placeholder used for name-locking is already in
986
this list so we only need to preserve Table::next
990
This function assumes that its caller already acquired LOCK_open mutex.
997
bool Session::reopen_name_locked_table(TableList* table_list)
999
Table *table= table_list->table;
1000
char *table_name= table_list->table_name;
1002
safe_mutex_assert_owner(LOCK_open.native_handle());
1004
if (killed || not table)
1007
TableIdentifier identifier(table_list->db, table_list->table_name);
1008
if (open_unireg_entry(this, table, table_name, identifier))
1010
table->intern_close_table();
1015
We want to prevent other connections from opening this table until end
1016
of statement as it is likely that modifications of table's metadata are
1017
not yet finished (for example CREATE TRIGGER have to change .TRG cursor,
1018
or we might want to drop table if CREATE TABLE ... SELECT fails).
1019
This also allows us to assume that no other connection will sneak in
1020
before we will get table-level lock on this table.
1022
table->getMutableShare()->resetVersion();
1023
table->in_use = this;
1025
table->tablenr= current_tablenr++;
1026
table->used_fields= 0;
1027
table->const_table= 0;
1028
table->null_row= false;
1029
table->maybe_null= false;
1030
table->force_index= false;
1031
table->status= STATUS_NO_RECORD;
786
1038
Create and insert into table cache placeholder for table
787
1039
which will prevent its opening (or creation) (a.k.a lock
795
1047
case of failure.
798
table::Placeholder *Session::table_cache_insert_placeholder(const drizzled::identifier::Table &arg)
1050
Table *Session::table_cache_insert_placeholder(const char *db_name, const char *table_name)
800
safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
1052
safe_mutex_assert_owner(LOCK_open.native_handle());
803
1055
Create a table entry with the right key and with an old refresh version
805
identifier::Table identifier(arg.getSchemaName(), arg.getTableName(), message::Table::INTERNAL);
1057
TableIdentifier identifier(db_name, table_name, message::Table::INTERNAL);
806
1058
table::Placeholder *table= new table::Placeholder(this, identifier);
808
if (not table::Cache::singleton().insert(table))
1060
if (not add_table(table))
837
1089
@retval true Error occured (OOM)
838
1090
@retval false Success. 'table' parameter set according to above rules.
840
bool Session::lock_table_name_if_not_cached(const identifier::Table &identifier, Table **table)
1092
bool Session::lock_table_name_if_not_cached(TableIdentifier &identifier, Table **table)
842
const identifier::Table::Key &key(identifier.getKey());
844
boost_unique_lock_t scope_lock(table::Cache::singleton().mutex()); /* Obtain a name lock even though table is not in cache (like for create table) */
846
table::CacheMap::iterator iter;
848
iter= table::getCache().find(key);
850
if (iter != table::getCache().end())
1094
const TableIdentifier::Key &key(identifier.getKey());
1096
boost_unique_lock_t scope_lock(LOCK_open); /* Obtain a name lock even though table is not in cache (like for create table) */
1098
TableOpenCache::iterator iter;
1100
iter= get_open_cache().find(key);
1102
if (iter != get_open_cache().end())
856
if (not (*table= table_cache_insert_placeholder(identifier)))
1108
if (not (*table= table_cache_insert_placeholder(identifier.getSchemaName().c_str(), identifier.getTableName().c_str())))
1118
1367
/* Insert a new Table instance into the open cache */
1120
1369
/* Free cache if too big */
1121
table::getUnused().cull();
1370
unused_tables.cull();
1123
1372
if (table_list->isCreate())
1125
identifier::Table lock_table_identifier(table_list->getSchemaName(), table_list->getTableName(), message::Table::STANDARD);
1374
TableIdentifier lock_table_identifier(table_list->db, table_list->table_name, message::Table::STANDARD);
1127
1376
if (not plugin::StorageEngine::doesTableExist(*this, lock_table_identifier))
1130
1379
Table to be created, so we need to create placeholder in table-cache.
1132
if (!(table= table_cache_insert_placeholder(lock_table_identifier)))
1381
if (!(table= table_cache_insert_placeholder(table_list->db, table_list->table_name)))
1269
1525
combination when one needs tables to be reopened (for
1270
1526
example see openTablesLock()).
1272
@note One should have lock on table::Cache::singleton().mutex() when calling this.
1528
@note One should have lock on LOCK_open when calling this.
1274
1530
@return false in case of success, true - otherwise.
1277
bool Session::reopen_tables()
1533
bool Session::reopen_tables(bool get_locks, bool)
1279
1535
Table *table,*next,**prev;
1280
Table **tables= 0; // For locks
1281
Table **tables_ptr= 0; // For locks
1536
Table **tables,**tables_ptr; // For locks
1537
bool error=0, not_used;
1283
1538
const uint32_t flags= DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN |
1284
1539
DRIZZLE_LOCK_IGNORE_GLOBAL_READ_LOCK |
1285
1540
DRIZZLE_LOCK_IGNORE_FLUSH;
1310
1569
next= table->getNext();
1312
1571
my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->getAlias());
1313
table::remove_table(static_cast<table::Concurrent *>(table));
1572
remove_table(dynamic_cast<table::Concurrent *>(table));
1318
1576
if (tables != tables_ptr) // Should we get back old locks
1320
1578
DrizzleLock *local_lock;
1322
1580
We should always get these locks. Anyway, we must not go into
1323
wait_for_tables() as it tries to acquire table::Cache::singleton().mutex(), which is
1581
wait_for_tables() as it tries to acquire LOCK_open, which is
1324
1582
already locked.
1326
1584
some_tables_deleted= false;
1328
if ((local_lock= lockTables(tables, (uint32_t) (tables_ptr - tables), flags)))
1586
if ((local_lock= mysql_lock_tables(this, tables, (uint32_t) (tables_ptr - tables),
1434
locking::broadcast_refresh();
1694
broadcast_refresh();
1699
Wait until all threads has closed the tables in the list
1700
We have also to wait if there is thread that has a lock on this table even
1701
if the table is closed
1704
bool table_is_used(Table *table, bool wait_for_name_lock)
1708
const TableIdentifier::Key &key(table->getShare()->getCacheKey());
1710
TableOpenCacheRange ppp;
1711
ppp= get_open_cache().equal_range(key);
1713
for (TableOpenCache::const_iterator iter= ppp.first;
1714
iter != ppp.second; ++iter)
1716
Table *search= (*iter).second;
1717
if (search->in_use == table->in_use)
1718
continue; // Name locked by this thread
1720
We can't use the table under any of the following conditions:
1721
- There is an name lock on it (Table is to be deleted or altered)
1722
- If we are in flush table and we didn't execute the flush
1723
- If the table engine is open and it's an old version
1724
(We must wait until all engines are shut down to use the table)
1726
if ( (search->locked_by_name && wait_for_name_lock) ||
1727
(search->is_name_opened() && search->needs_reopen_or_name_lock()))
1730
} while ((table=table->getNext()));
1735
/* Wait until all used tables are refreshed */
1737
bool wait_for_tables(Session *session)
1741
session->set_proc_info("Waiting for tables");
1743
boost_unique_lock_t lock(LOCK_open);
1744
while (!session->killed)
1746
session->some_tables_deleted= false;
1747
session->close_old_data_files(false, dropping_tables != 0);
1748
if (!table_is_used(session->open_tables, 1))
1750
COND_refresh.wait(lock);
1752
if (session->killed)
1753
result= true; // aborted
1756
/* Now we can open all tables without any interference */
1757
session->set_proc_info("Reopen tables");
1758
session->version= refresh_version;
1759
result= session->reopen_tables(false, false);
1762
session->set_proc_info(0);
1462
Table *drop_locked_tables(Session *session, const drizzled::identifier::Table &identifier)
1792
Table *drop_locked_tables(Session *session, const drizzled::TableIdentifier &identifier)
1464
1794
Table *table,*next,**prev, *found= 0;
1465
1795
prev= &session->open_tables;
1468
Note that we need to hold table::Cache::singleton().mutex() while changing the
1798
Note that we need to hold LOCK_open while changing the
1469
1799
open_tables list. Another thread may work on it.
1470
(See: table::Cache::singleton().removeTable(), wait_completed_table())
1800
(See: remove_table_from_cache(), mysql_wait_completed_table())
1471
1801
Closing a MERGE child before the parent would be fatal if the
1472
1802
other thread tries to abort the MERGE lock in between.
1523
1852
if (table->getShare()->getCacheKey() == identifier.getKey())
1525
1854
/* If MERGE child, forward lock handling to parent. */
1526
session->abortLock(table);
1855
mysql_lock_abort(session, table);
1862
Load a table definition from cursor and open unireg table
1866
session Thread handle
1867
entry Store open table definition here
1868
table_list TableList with db, table_name
1870
cache_key Key for share_cache
1871
cache_key_length length of cache_key
1874
Extra argument for open is taken from session->open_options
1875
One must have a lock on LOCK_open when calling this function
1882
static int open_unireg_entry(Session *session,
1885
TableIdentifier &identifier)
1888
TableSharePtr share;
1889
uint32_t discover_retry_count= 0;
1891
safe_mutex_assert_owner(LOCK_open.native_handle());
1893
if (not (share= TableShare::getShareCreate(session,
1898
while ((error= share->open_table_from_share(session,
1901
(uint32_t) (HA_OPEN_KEYFILE |
1905
session->open_options, *entry)))
1907
if (error == 7) // Table def changed
1909
share->resetVersion(); // Mark share as old
1910
if (discover_retry_count++) // Retry once
1912
TableShare::release(share);
1918
Here we should wait until all threads has released the table.
1919
For now we do one retry. This may cause a deadlock if there
1920
is other threads waiting for other tables used by this thread.
1922
Proper fix would be to if the second retry failed:
1923
- Mark that table def changed
1924
- Return from open table
1925
- Close all tables used by this thread
1926
- Start waiting that the share is released
1927
- Retry by opening all tables again
1932
To avoid deadlock, only wait for release if no one else is
1935
if (share->getTableCount() != 1)
1937
TableShare::release(share);
1940
/* Free share and wait until it's released by all threads */
1941
TableShare::release(share);
1943
if (!session->killed)
1945
drizzle_reset_errors(session, 1); // Clear warnings
1946
session->clear_error(); // Clear error message
1952
TableShare::release(share);
1535
1962
Open all tables in list
1802
Table *Open_tables_state::open_temporary_table(const identifier::Table &identifier,
2230
Table *Session::open_temporary_table(TableIdentifier &identifier,
1805
2235
assert(identifier.isTmp());
1808
table::Temporary *new_tmp_table= new table::Temporary(identifier.getType(),
1810
const_cast<char *>(const_cast<identifier::Table&>(identifier).getPath().c_str()),
1811
static_cast<uint32_t>(identifier.getPath().length()));
2236
share= new TableShare(identifier.getType(),
2238
const_cast<char *>(identifier.getPath().c_str()), static_cast<uint32_t>(identifier.getPath().length()));
2241
table::Temporary *new_tmp_table= new table::Temporary;
1812
2242
if (not new_tmp_table)
1816
2246
First open the share, and then open the table from the share we just opened.
1818
if (new_tmp_table->getMutableShare()->open_table_def(*static_cast<Session *>(this), identifier) ||
1819
new_tmp_table->getMutableShare()->open_table_from_share(static_cast<Session *>(this), identifier, identifier.getTableName().c_str(),
1820
(uint32_t) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
2248
if (share->open_table_def(*this, identifier) ||
2249
share->open_table_from_share(this, identifier, identifier.getTableName().c_str(),
2250
(uint32_t) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
1825
2255
/* No need to lock share->mutex as this is not needed for tmp tables */
1826
delete new_tmp_table->getMutableShare();
1827
2257
delete new_tmp_table;
2387
2817
strcat(buff, table_name);
2388
2818
table_name=buff;
2390
my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, session->where());
2820
my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, session->where);
2394
2824
if (report_error == REPORT_ALL_ERRORS ||
2395
2825
report_error == REPORT_EXCEPT_NON_UNIQUE)
2396
my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), session->where());
2826
my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), session->where);
2398
2828
found= not_found_field;
3333
3763
register Item *item;
3334
3764
enum_mark_columns save_mark_used_columns= session->mark_used_columns;
3335
nesting_map save_allow_sum_func= session->getLex()->allow_sum_func;
3336
List<Item>::iterator it(fields.begin());
3765
nesting_map save_allow_sum_func= session->lex->allow_sum_func;
3766
List_iterator<Item> it(fields);
3337
3767
bool save_is_item_list_lookup;
3339
3769
session->mark_used_columns= mark_used_columns;
3340
3770
if (allow_sum_func)
3341
session->getLex()->allow_sum_func|= 1 << session->getLex()->current_select->nest_level;
3342
session->setWhere(Session::DEFAULT_WHERE);
3343
save_is_item_list_lookup= session->getLex()->current_select->is_item_list_lookup;
3344
session->getLex()->current_select->is_item_list_lookup= 0;
3771
session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
3772
session->where= Session::DEFAULT_WHERE;
3773
save_is_item_list_lookup= session->lex->current_select->is_item_list_lookup;
3774
session->lex->current_select->is_item_list_lookup= 0;
3347
3777
To prevent fail on forward lookup we fill it with zerows,
3351
3781
There is other way to solve problem: fill array with pointers to list,
3352
3782
but it will be slower.
3354
TODO-> remove it when (if) we made one list for allfields and ref_pointer_array
3784
TODO: remove it when (if) we made one list for allfields and
3356
3787
if (ref_pointer_array)
3358
3788
memset(ref_pointer_array, 0, sizeof(Item *) * fields.elements);
3361
3790
Item **ref= ref_pointer_array;
3362
session->getLex()->current_select->cur_pos_in_select_list= 0;
3791
session->lex->current_select->cur_pos_in_select_list= 0;
3363
3792
while ((item= it++))
3365
3794
if ((!item->fixed && item->fix_fields(session, it.ref())) || (item= *(it.ref()))->check_cols(1))
3367
session->getLex()->current_select->is_item_list_lookup= save_is_item_list_lookup;
3368
session->getLex()->allow_sum_func= save_allow_sum_func;
3796
session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
3797
session->lex->allow_sum_func= save_allow_sum_func;
3369
3798
session->mark_used_columns= save_mark_used_columns;
3376
3805
item->split_sum_func(session, ref_pointer_array, *sum_func_list);
3377
3806
session->used_tables|= item->used_tables();
3378
session->getLex()->current_select->cur_pos_in_select_list++;
3807
session->lex->current_select->cur_pos_in_select_list++;
3380
session->getLex()->current_select->is_item_list_lookup= save_is_item_list_lookup;
3381
session->getLex()->current_select->cur_pos_in_select_list= UNDEF_POS;
3809
session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
3810
session->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
3383
session->getLex()->allow_sum_func= save_allow_sum_func;
3812
session->lex->allow_sum_func= save_allow_sum_func;
3384
3813
session->mark_used_columns= save_mark_used_columns;
3385
3814
return(test(session->is_error()));
3933
4354
unireg support functions
3934
4355
*****************************************************************************/
4358
Invalidate any cache entries that are for some DB
4361
remove_db_from_cache()
4362
db Database name. This will be in lower case if
4363
lower_case_table_name is set
4366
We can't use hash_delete when looping hash_elements. We mark them first
4367
and afterwards delete those marked unused.
4370
void remove_db_from_cache(const SchemaIdentifier &schema_identifier)
4372
safe_mutex_assert_owner(LOCK_open.native_handle());
4374
for (TableOpenCache::const_iterator iter= get_open_cache().begin();
4375
iter != get_open_cache().end();
4378
table::Concurrent *table= (*iter).second;
4380
if (not schema_identifier.getPath().compare(table->getShare()->getSchemaName()))
4382
table->getMutableShare()->resetVersion(); /* Free when thread is ready */
4383
if (not table->in_use)
4384
unused_tables.relink(table);
4388
unused_tables.cullByVersion();
4393
Mark all entries with the table as deleted to force an reopen of the table
4395
The table will be closed (not stored in cache) by the current thread when
4396
close_thread_tables() is called.
4402
0 This thread now have exclusive access to this table and no other thread
4403
can access the table until close_thread_tables() is called.
4404
1 Table is in use by another thread
4407
bool remove_table_from_cache(Session *session, TableIdentifier &identifier, uint32_t flags)
4409
const TableIdentifier::Key &key(identifier.getKey());
4411
bool signalled= false;
4415
result= signalled= false;
4417
TableOpenCacheRange ppp;
4418
ppp= get_open_cache().equal_range(key);
4420
for (TableOpenCache::const_iterator iter= ppp.first;
4421
iter != ppp.second; ++iter)
4423
table::Concurrent *table= (*iter).second;
4426
table->getMutableShare()->resetVersion(); /* Free when thread is ready */
4427
if (not (in_use= table->in_use))
4429
unused_tables.relink(table);
4431
else if (in_use != session)
4434
Mark that table is going to be deleted from cache. This will
4435
force threads that are in mysql_lock_tables() (but not yet
4436
in thr_multi_lock()) to abort it's locks, close all tables and retry
4438
in_use->some_tables_deleted= true;
4439
if (table->is_name_opened())
4444
Now we must abort all tables locks used by this thread
4445
as the thread may be waiting to get a lock for another table.
4446
Note that we need to hold LOCK_open while going through the
4447
list. So that the other thread cannot change it. The other
4448
thread must also hold LOCK_open whenever changing the
4449
open_tables list. Aborting the MERGE lock after a child was
4450
closed and before the parent is closed would be fatal.
4452
for (Table *session_table= in_use->open_tables;
4454
session_table= session_table->getNext())
4456
/* Do not handle locks of MERGE children. */
4457
if (session_table->db_stat) // If table is open
4458
signalled|= mysql_lock_abort_for_thread(session, session_table);
4463
result= result || (flags & RTFC_OWNED_BY_Session_FLAG);
4467
unused_tables.cullByVersion();
4469
/* Remove table from table definition cache if it's not in use */
4470
TableShare::release(identifier);
4472
if (result && (flags & RTFC_WAIT_OTHER_THREAD_FLAG))
4475
Signal any thread waiting for tables to be freed to
4478
broadcast_refresh();
4479
if (!(flags & RTFC_CHECK_KILLED_FLAG) || !session->killed)
4482
if (likely(signalled))
4484
boost_unique_lock_t scoped(LOCK_open, boost::adopt_lock_t());
4485
COND_refresh.wait(scoped);
4491
It can happen that another thread has opened the
4492
table but has not yet locked any table at all. Since
4493
it can be locked waiting for a table that our thread
4494
has done LOCK Table x WRITE on previously, we need to
4495
ensure that the thread actually hears our signal
4496
before we go to sleep. Thus we wait for a short time
4497
and then we retry another loop in the
4498
remove_table_from_cache routine.
4501
xtime_get(&xt, boost::TIME_UTC);
4503
boost_unique_lock_t scoped(LOCK_open, boost::adopt_lock_t());
4504
COND_refresh.timed_wait(scoped, xt);