33
#include "drizzled/internal/my_pthread.h"
34
#include "drizzled/internal/thread_var.h"
33
#include <drizzled/internal/my_pthread.h>
34
#include <drizzled/internal/thread_var.h>
36
36
#include <drizzled/sql_select.h>
37
37
#include <drizzled/error.h>
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/timestamp.h>
47
#include <drizzled/cached_directory.h>
48
#include <drizzled/field/epoch.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"
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>
61
#include <drizzled/item/subselect.h>
62
#include <drizzled/sql_lex.h>
63
#include <drizzled/catalog/local.h>
64
#include <drizzled/open_tables_state.h>
65
#include <drizzled/table/cache.h>
60
67
using namespace std;
65
71
extern bool volatile shutdown_in_progress;
77
83
void table_cache_free(void)
79
refresh_version++; // Force close of open tables
85
g_refresh_version++; // Force close of open tables
81
87
table::getUnused().clear();
82
88
table::getCache().clear();
110
116
This has to be done to ensure that the table share is removed from
111
117
the table defintion cache as soon as the last instance is removed
113
TableIdentifier identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), message::Table::INTERNAL);
114
const TableIdentifier::Key &key(identifier.getKey());
119
identifier::Table identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), message::Table::INTERNAL);
120
const identifier::Table::Key &key(identifier.getKey());
115
121
TableShare *share= new TableShare(identifier.getType(),
117
123
const_cast<char *>(key.vector()), static_cast<uint32_t>(table->getShare()->getCacheKeySize()));
119
125
table->cursor->close();
120
126
table->db_stat= 0; // Mark cursor closed
121
TableShare::release(table->getMutableShare());
127
table::instance::release(table->getMutableShare());
122
128
table->setShare(share);
156
161
@param session Thread context (may be NULL)
157
162
@param tables List of tables to remove from the cache
158
@param have_lock If table::Cache::singleton().mutex() is locked
163
@param have_lock If table::Cache::mutex() is locked
159
164
@param wait_for_refresh Wait for a impending flush
160
165
@param wait_for_placeholders Wait for tables being reopened so that the GRL
161
166
won't proceed while write-locked tables are being reopened by other
171
176
Session *session= this;
174
table::Cache::singleton().mutex().lock(); /* Optionally lock for remove tables from open_cahe if not in use */
179
boost::mutex::scoped_lock scopedLock(table::Cache::mutex()); /* Optionally lock for remove tables from open_cahe if not in use */
176
181
if (tables == NULL)
178
refresh_version++; // Force close of open tables
183
g_refresh_version++; // Force close of open tables
180
185
table::getUnused().clear();
208
213
again. There they will wait until we update all tables version
211
Setting some_tables_deleted is done by table::Cache::singleton().removeTable()
216
Setting some_tables_deleted is done by table::Cache::removeTable()
212
217
in the other branch.
214
219
In other words (reviewer suggestion): You need this setting of
218
223
after the call to Session::close_old_data_files() i.e. after removal of
219
224
current thread locks.
221
for (table::CacheMap::const_iterator iter= table::getCache().begin();
222
iter != table::getCache().end();
226
BOOST_FOREACH(table::CacheMap::const_reference iter, table::getCache())
225
Table *table= (*iter).second;
227
table->in_use->some_tables_deleted= false;
228
if (iter.second->in_use)
229
iter.second->in_use->some_tables_deleted= false;
233
235
bool found= false;
234
236
for (TableList *table= tables; table; table= table->next_local)
236
TableIdentifier identifier(table->getSchemaName(), table->getTableName());
237
if (table::Cache::singleton().removeTable(session, identifier,
238
RTFC_OWNED_BY_Session_FLAG))
238
if (table::Cache::removeTable(*session, identifier::Table(table->getSchemaName(), table->getTableName()), RTFC_OWNED_BY_Session_FLAG))
250
250
If there is any table that has a lower refresh_version, wait until
251
251
this is closed (or this thread is killed) before returning
253
session->mysys_var->current_mutex= &table::Cache::singleton().mutex();
253
session->mysys_var->current_mutex= &table::Cache::mutex();
254
254
session->mysys_var->current_cond= &COND_refresh;
255
255
session->set_proc_info("Flushing tables");
265
265
iter != table::getCache().end();
268
Table *table= (*iter).second;
268
Table *table= iter->second;
269
269
/* Avoid a self-deadlock. */
270
270
if (table->in_use == session)
287
287
(table->open_placeholder && wait_for_placeholders)))
290
boost_unique_lock_t scoped(table::Cache::singleton().mutex(), boost::adopt_lock_t());
291
COND_refresh.wait(scoped);
290
COND_refresh.wait(scopedLock);
299
297
old locks. This should always succeed (unless some external process
300
298
has removed the tables)
302
result= session->reopen_tables(true, true);
300
result= session->reopen_tables();
304
302
/* Set version for table */
305
for (Table *table= session->open_tables; table ; table= table->getNext())
303
for (Table *table= session->open_tables.open_tables_; table ; table= table->getNext())
308
306
Preserve the version (0) of write locked tables so that a impending
312
310
table->getMutableShare()->refreshVersion();
316
table::Cache::singleton().mutex().unlock();
319
315
if (wait_for_refresh)
321
boost_unique_lock_t scopedLock(session->mysys_var->mutex);
317
boost::mutex::scoped_lock scopedLock(session->mysys_var->mutex);
322
318
session->mysys_var->current_mutex= 0;
323
319
session->mysys_var->current_cond= 0;
324
320
session->set_proc_info(0);
332
move one table to free list
328
move one table to free list
335
bool Session::free_cached_table()
331
bool Session::free_cached_table(boost::mutex::scoped_lock &scopedLock)
337
333
bool found_old_table= false;
338
table::Concurrent *table= static_cast<table::Concurrent *>(open_tables);
340
safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
337
table::Concurrent *table= static_cast<table::Concurrent *>(open_tables.open_tables_);
339
safe_mutex_assert_owner(table::Cache::mutex().native_handle());
341
340
assert(table->key_read == 0);
342
341
assert(!table->cursor || table->cursor->inited == Cursor::NONE);
344
open_tables= table->getNext();
343
open_tables.open_tables_= table->getNext();
346
345
if (table->needs_reopen_or_name_lock() ||
347
version != refresh_version || !table->db_stat)
346
open_tables.version != g_refresh_version || !table->db_stat)
349
348
table::remove_table(table);
350
349
found_old_table= true;
381
380
bool found_old_table= false;
383
safe_mutex_assert_not_owner(table::Cache::singleton().mutex().native_handle());
385
boost_unique_lock_t scoped_lock(table::Cache::singleton().mutex()); /* Close all open tables on Session */
382
safe_mutex_assert_not_owner(table::Cache::mutex().native_handle());
384
boost::mutex::scoped_lock scoped_lock(table::Cache::mutex()); /* Close all open tables on Session */
386
while (open_tables.open_tables_)
389
found_old_table|= free_cached_table();
388
found_old_table|= free_cached_table(scoped_lock);
391
390
some_tables_deleted= false;
423
422
for (; table; table= table->*link )
425
if ((table->table == 0 || table->table->getShare()->getType() == message::Table::STANDARD) &&
426
strcasecmp(table->getSchemaName(), db_name) == 0 &&
427
strcasecmp(table->getTableName(), table_name) == 0)
424
if ((table->table == 0 || table->table->getShare()->getType() == message::Table::STANDARD) and
425
my_strcasecmp(system_charset_info, table->getSchemaName(), db_name) == 0 and
426
my_strcasecmp(system_charset_info, table->getTableName(), table_name) == 0)
520
void Open_tables_state::doGetTableNames(const SchemaIdentifier &schema_identifier,
521
void Open_tables_state::doGetTableNames(const identifier::Schema &schema_identifier,
521
522
std::set<std::string>& set_of_names)
523
524
for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
532
533
void Open_tables_state::doGetTableNames(CachedDirectory &,
533
const SchemaIdentifier &schema_identifier,
534
const identifier::Schema &schema_identifier,
534
535
std::set<std::string> &set_of_names)
536
537
doGetTableNames(schema_identifier, set_of_names);
539
void Open_tables_state::doGetTableIdentifiers(const SchemaIdentifier &schema_identifier,
540
TableIdentifier::vector &set_of_identifiers)
540
void Open_tables_state::doGetTableIdentifiers(const identifier::Schema &schema_identifier,
541
identifier::table::vector &set_of_identifiers)
542
543
for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
544
545
if (schema_identifier.compare(table->getShare()->getSchemaName()))
546
set_of_identifiers.push_back(TableIdentifier(table->getShare()->getSchemaName(),
547
set_of_identifiers.push_back(identifier::Table(table->getShare()->getSchemaName(),
547
548
table->getShare()->getTableName(),
548
549
table->getShare()->getPath()));
553
554
void Open_tables_state::doGetTableIdentifiers(CachedDirectory &,
554
const SchemaIdentifier &schema_identifier,
555
TableIdentifier::vector &set_of_identifiers)
555
const identifier::Schema &schema_identifier,
556
identifier::table::vector &set_of_identifiers)
557
558
doGetTableIdentifiers(schema_identifier, set_of_identifiers);
560
bool Open_tables_state::doDoesTableExist(const TableIdentifier &identifier)
561
bool Open_tables_state::doDoesTableExist(const identifier::Table &identifier)
562
563
for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
576
int Open_tables_state::doGetTableDefinition(const TableIdentifier &identifier,
577
message::Table &table_proto)
577
int Open_tables_state::doGetTableDefinition(const identifier::Table &identifier,
578
message::Table &table_proto)
579
580
for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
630
631
@retval -1 the table is in use by a outer query
633
int Open_tables_state::drop_temporary_table(const drizzled::TableIdentifier &identifier)
634
int Open_tables_state::drop_temporary_table(const drizzled::identifier::Table &identifier)
637
if (not (table= find_temporary_table(identifier)))
636
Table* table= find_temporary_table(identifier);
640
640
/* Table might be in use by some outer statement. */
641
if (table->query_id && table->query_id != getQueryId())
641
if (table->query_id && table->query_id != session_.getQueryId())
643
643
my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->getAlias());
647
646
close_temporary_table(table);
663
661
void Session::unlink_open_table(Table *find)
665
const TableIdentifier::Key find_key(find->getShare()->getCacheKey());
663
const identifier::Table::Key find_key(find->getShare()->getCacheKey());
667
safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
665
safe_mutex_assert_owner(table::Cache::mutex().native_handle());
670
Note that we need to hold table::Cache::singleton().mutex() while changing the
668
Note that we need to hold table::Cache::mutex() while changing the
671
669
open_tables list. Another thread may work on it.
672
(See: table::Cache::singleton().removeTable(), mysql_wait_completed_table())
670
(See: table::Cache::removeTable(), wait_completed_table())
673
671
Closing a MERGE child before the parent would be fatal if the
674
672
other thread tries to abort the MERGE lock in between.
676
for (prev= &open_tables; *prev; )
674
for (prev= &open_tables.open_tables_; *prev; )
678
676
Table *list= *prev;
716
714
table that was locked with LOCK TABLES.
719
void Session::drop_open_table(Table *table, const TableIdentifier &identifier)
717
void Session::drop_open_table(Table *table, const identifier::Table &identifier)
721
719
if (table->getShare()->getType())
723
close_temporary_table(table);
721
open_tables.close_temporary_table(table);
727
boost_unique_lock_t scoped_lock(table::Cache::singleton().mutex()); /* Close and drop a table (AUX routine) */
725
boost::mutex::scoped_lock scoped_lock(table::Cache::mutex()); /* Close and drop a table (AUX routine) */
729
727
unlink_open_table() also tells threads waiting for refresh or close
730
728
that something has happened.
732
730
unlink_open_table(table);
733
plugin::StorageEngine::dropTable(*this, identifier);
731
(void)plugin::StorageEngine::dropTable(*this, identifier);
765
763
condition variables that are guranteed to not disapper (freed) even if this
766
764
mutex is unlocked
768
boost_unique_lock_t scopedLock(mutex, boost::adopt_lock_t());
766
boost::mutex::scoped_lock scopedLock(mutex, boost::adopt_lock_t());
769
767
if (not getKilled())
771
769
cond.wait(scopedLock);
774
boost_unique_lock_t mysys_scopedLock(mysys_var->mutex);
772
boost::mutex::scoped_lock mysys_scopedLock(mysys_var->mutex);
775
773
mysys_var->current_mutex= 0;
776
774
mysys_var->current_cond= 0;
777
775
set_proc_info(saved_proc_info);
794
table::Placeholder *Session::table_cache_insert_placeholder(const drizzled::TableIdentifier &arg)
792
table::Placeholder& Session::table_cache_insert_placeholder(const drizzled::identifier::Table &arg)
796
safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
794
safe_mutex_assert_owner(table::Cache::mutex().native_handle());
799
797
Create a table entry with the right key and with an old refresh version
801
TableIdentifier identifier(arg.getSchemaName(), arg.getTableName(), message::Table::INTERNAL);
802
table::Placeholder *table= new table::Placeholder(this, identifier);
804
if (not table::Cache::singleton().insert(table))
799
identifier::Table identifier(arg.getSchemaName(), arg.getTableName(), message::Table::INTERNAL);
800
table::Placeholder* table= new table::Placeholder(this, identifier);
801
table::Cache::insert(table);
833
824
@retval true Error occured (OOM)
834
825
@retval false Success. 'table' parameter set according to above rules.
836
bool Session::lock_table_name_if_not_cached(const TableIdentifier &identifier, Table **table)
827
bool Session::lock_table_name_if_not_cached(const identifier::Table &identifier, Table **table)
838
const TableIdentifier::Key &key(identifier.getKey());
840
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) */
842
table::CacheMap::iterator iter;
844
iter= table::getCache().find(key);
846
if (iter != table::getCache().end())
829
const identifier::Table::Key &key(identifier.getKey());
831
boost::mutex::scoped_lock scope_lock(table::Cache::mutex()); /* Obtain a name lock even though table is not in cache (like for create table) */
833
if (find_ptr(table::getCache(), key))
852
if (not (*table= table_cache_insert_placeholder(identifier)))
839
*table= &table_cache_insert_placeholder(identifier);
856
840
(*table)->open_placeholder= true;
857
(*table)->setNext(open_tables);
841
(*table)->setNext(open_tables.open_tables_);
842
open_tables.open_tables_= *table;
844
return false; //return void
899
883
const char *alias= table_list->alias;
901
885
/* Parsing of partitioning information from .frm needs session->lex set up. */
902
assert(lex->is_lex_started);
886
assert(lex().is_lex_started);
904
888
/* find a unused table in the open table cache */
915
TableIdentifier identifier(table_list->getSchemaName(), table_list->getTableName());
916
const TableIdentifier::Key &key(identifier.getKey());
899
identifier::Table identifier(table_list->getSchemaName(), table_list->getTableName());
900
const identifier::Table::Key &key(identifier.getKey());
917
901
table::CacheRange ppp;
924
908
TODO -> move this block into a separate function.
926
910
bool reset= false;
927
for (table= getTemporaryTables(); table ; table=table->getNext())
911
for (table= open_tables.getTemporaryTables(); table ; table=table->getNext())
929
913
if (table->getShare()->getCacheKey() == key)
950
934
if (flags & DRIZZLE_OPEN_TEMPORARY_ONLY)
952
my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->getSchemaName(), table_list->getTableName());
936
my_error(ER_TABLE_UNKNOWN, identifier);
963
947
Note-> refresh_version is currently changed only during FLUSH TABLES.
949
if (!open_tables.open_tables_)
967
version= refresh_version;
951
open_tables.version= g_refresh_version;
969
else if ((version != refresh_version) &&
953
else if ((open_tables.version != g_refresh_version) &&
970
954
! (flags & DRIZZLE_LOCK_IGNORE_FLUSH))
972
956
/* Someone did a refresh while thread was opening tables */
980
Before we test the global cache, we test our local session cache.
984
assert(false); /* Not implemented yet */
988
964
Non pre-locked/LOCK TABLES mode, and the table is not temporary:
989
965
this is the normal use case.
994
970
until no one holds a name lock on the table.
995
971
- if there is no such Table in the name cache, read the table definition
996
972
and insert it into the cache.
997
We perform all of the above under table::Cache::singleton().mutex() which currently protects
973
We perform all of the above under table::Cache::mutex() which currently protects
998
974
the open cache (also known as table cache) and table definitions stored
1003
table::Cache::singleton().mutex().lock(); /* Lock for FLUSH TABLES for open table */
979
boost::mutex::scoped_lock scopedLock(table::Cache::mutex());
1006
982
Actually try to find the table in the open_cache.
1015
991
ppp= table::getCache().equal_range(key);
1018
for (table::CacheMap::const_iterator iter= ppp.first;
1019
iter != ppp.second; ++iter, table= NULL)
994
for (table::CacheMap::const_iterator iter= ppp.first; iter != ppp.second; ++iter, table= NULL)
1021
table= (*iter).second;
1023
998
if (not table->in_use)
1045
1020
if (flags & DRIZZLE_LOCK_IGNORE_FLUSH)
1047
1022
/* Force close at once after usage */
1048
version= table->getShare()->getVersion();
1023
open_tables.version= table->getShare()->getVersion();
1052
1027
/* Avoid self-deadlocks by detecting self-dependencies. */
1053
1028
if (table->open_placeholder && table->in_use == this)
1055
table::Cache::singleton().mutex().unlock();
1056
1030
my_error(ER_UPDATE_TABLE_USED, MYF(0), table->getShare()->getTableName());
1086
1060
if (table->in_use != this)
1088
/* wait_for_conditionwill unlock table::Cache::singleton().mutex() for us */
1089
wait_for_condition(table::Cache::singleton().mutex(), COND_refresh);
1062
/* wait_for_conditionwill unlock table::Cache::mutex() for us */
1063
wait_for_condition(table::Cache::mutex(), COND_refresh);
1064
scopedLock.release();
1093
table::Cache::singleton().mutex().unlock();
1068
scopedLock.unlock();
1096
1072
There is a refresh in progress for this table.
1097
1073
Signal the caller that it has to try again.
1100
1076
*refresh= true;
1106
1084
table::getUnused().unlink(static_cast<table::Concurrent *>(table));
1111
1089
/* Insert a new Table instance into the open cache */
1113
1090
/* Free cache if too big */
1114
1091
table::getUnused().cull();
1116
1093
if (table_list->isCreate())
1118
TableIdentifier lock_table_identifier(table_list->getSchemaName(), table_list->getTableName(), message::Table::STANDARD);
1095
identifier::Table lock_table_identifier(table_list->getSchemaName(), table_list->getTableName(), message::Table::STANDARD);
1120
1097
if (not plugin::StorageEngine::doesTableExist(*this, lock_table_identifier))
1123
1100
Table to be created, so we need to create placeholder in table-cache.
1125
if (!(table= table_cache_insert_placeholder(lock_table_identifier)))
1127
table::Cache::singleton().mutex().unlock();
1102
table= &table_cache_insert_placeholder(lock_table_identifier);
1131
1104
Link placeholder to the open tables list so it will be automatically
1132
1105
removed once tables are closed. Also mark it so it won't be ignored
1133
1106
by other trying to take name-lock.
1135
1108
table->open_placeholder= true;
1136
table->setNext(open_tables);
1138
table::Cache::singleton().mutex().unlock();
1109
table->setNext(open_tables.open_tables_);
1110
open_tables.open_tables_= table;
1147
1119
table::Concurrent *new_table= new table::Concurrent;
1148
1120
table= new_table;
1149
if (new_table == NULL)
1151
table::Cache::singleton().mutex().unlock();
1155
error= new_table->open_unireg_entry(this, alias, identifier);
1121
if (new_table->open_unireg_entry(this, alias, identifier))
1158
1123
delete new_table;
1159
table::Cache::singleton().mutex().unlock();
1162
(void)table::Cache::singleton().insert(new_table);
1126
(void)table::Cache::insert(new_table);
1166
table::Cache::singleton().mutex().unlock();
1170
table->setNext(open_tables); /* Link into simple list */
1133
table->setNext(open_tables.open_tables_); /* Link into simple list */
1134
open_tables.open_tables_= table;
1173
1136
table->reginfo.lock_type= TL_READ; /* Assume read */
1222
1185
the strings are used in a loop even after the share may be freed.
1225
void Session::close_data_files_and_morph_locks(const TableIdentifier &identifier)
1188
void Session::close_data_files_and_morph_locks(const identifier::Table &identifier)
1227
safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle()); /* Adjust locks at the end of ALTER TABLEL */
1190
safe_mutex_assert_owner(table::Cache::mutex().native_handle()); /* Adjust locks at the end of ALTER TABLEL */
1192
if (open_tables.lock)
1232
1195
If we are not under LOCK TABLES we should have only one table
1233
1196
open and locked so it makes sense to remove the lock at once.
1198
unlockTables(open_tables.lock);
1199
open_tables.lock= 0;
1241
1204
for target table name if we process ALTER Table ... RENAME.
1242
1205
So loop below makes sense even if we are not under LOCK TABLES.
1244
for (Table *table= open_tables; table ; table=table->getNext())
1207
for (Table *table= open_tables.open_tables_; table ; table=table->getNext())
1246
1209
if (table->getShare()->getCacheKey() == identifier.getKey())
1267
1230
combination when one needs tables to be reopened (for
1268
1231
example see openTablesLock()).
1270
@note One should have lock on table::Cache::singleton().mutex() when calling this.
1233
@note One should have lock on table::Cache::mutex() when calling this.
1272
1235
@return false in case of success, true - otherwise.
1275
bool Session::reopen_tables(bool get_locks, bool)
1238
bool Session::reopen_tables()
1277
1240
Table *table,*next,**prev;
1278
Table **tables,**tables_ptr; // For locks
1279
bool error=0, not_used;
1241
Table **tables= 0; // For locks
1242
Table **tables_ptr= 0; // For locks
1280
1244
const uint32_t flags= DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN |
1281
1245
DRIZZLE_LOCK_IGNORE_GLOBAL_READ_LOCK |
1282
1246
DRIZZLE_LOCK_IGNORE_FLUSH;
1284
if (open_tables == NULL)
1248
if (open_tables.open_tables_ == NULL)
1287
safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
1251
safe_mutex_assert_owner(table::Cache::mutex().native_handle());
1291
1254
The ptr is checked later
1294
1257
uint32_t opens= 0;
1296
for (table= open_tables; table ; table=table->getNext())
1259
for (table= open_tables.open_tables_; table ; table=table->getNext())
1300
1263
tables= new Table *[opens];
1304
tables= &open_tables;
1306
1266
tables_ptr =tables;
1309
for (table= open_tables; table ; table=next)
1268
prev= &open_tables.open_tables_;
1269
for (table= open_tables.open_tables_; table ; table=next)
1311
1271
next= table->getNext();
1318
1279
if (tables != tables_ptr) // Should we get back old locks
1320
1281
DrizzleLock *local_lock;
1322
1283
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
1284
wait_for_tables() as it tries to acquire table::Cache::mutex(), which is
1324
1285
already locked.
1326
1287
some_tables_deleted= false;
1328
if ((local_lock= lockTables(tables, (uint32_t) (tables_ptr - tables),
1289
if ((local_lock= lockTables(tables, (uint32_t) (tables_ptr - tables), flags)))
1440
/* Wait until all used tables are refreshed */
1442
bool wait_for_tables(Session *session)
1446
session->set_proc_info("Waiting for tables");
1448
boost_unique_lock_t lock(table::Cache::singleton().mutex());
1449
while (not session->getKilled())
1451
session->some_tables_deleted= false;
1452
session->close_old_data_files(false, dropping_tables != 0);
1453
if (not table::Cache::singleton().areTablesUsed(session->open_tables, 1))
1457
COND_refresh.wait(lock);
1459
if (session->getKilled())
1460
result= true; // aborted
1463
/* Now we can open all tables without any interference */
1464
session->set_proc_info("Reopen tables");
1465
session->version= refresh_version;
1466
result= session->reopen_tables(false, false);
1469
session->set_proc_info(0);
1476
1400
drop tables from locked list
1499
Table *drop_locked_tables(Session *session, const drizzled::TableIdentifier &identifier)
1423
Table *drop_locked_tables(Session *session, const drizzled::identifier::Table &identifier)
1501
1425
Table *table,*next,**prev, *found= 0;
1502
prev= &session->open_tables;
1426
prev= &session->open_tables.open_tables_;
1505
Note that we need to hold table::Cache::singleton().mutex() while changing the
1429
Note that we need to hold table::Cache::mutex() while changing the
1506
1430
open_tables list. Another thread may work on it.
1507
(See: table::Cache::singleton().removeTable(), mysql_wait_completed_table())
1431
(See: table::Cache::removeTable(), wait_completed_table())
1508
1432
Closing a MERGE child before the parent would be fatal if the
1509
1433
other thread tries to abort the MERGE lock in between.
1511
for (table= session->open_tables; table ; table=next)
1435
for (table= session->open_tables.open_tables_; table ; table=next)
1513
1437
next=table->getNext();
1514
1438
if (table->getShare()->getCacheKey() == identifier.getKey())
1551
1476
other threads trying to get the lock.
1554
void abort_locked_tables(Session *session, const drizzled::TableIdentifier &identifier)
1479
void abort_locked_tables(Session *session, const drizzled::identifier::Table &identifier)
1557
for (table= session->open_tables; table ; table= table->getNext())
1482
for (table= session->open_tables.open_tables_; table ; table= table->getNext())
1559
1484
if (table->getShare()->getCacheKey() == identifier.getKey())
1561
1486
/* If MERGE child, forward lock handling to parent. */
1562
1487
session->abortLock(table);
1632
1558
* to see if it exists so that an unauthorized user cannot phish for
1633
1559
* table/schema information via error messages
1635
TableIdentifier the_table(tables->getSchemaName(), tables->getTableName());
1636
if (not plugin::Authorization::isAuthorized(getSecurityContext(),
1561
identifier::Table the_table(tables->getSchemaName(), tables->getTableName());
1562
if (not plugin::Authorization::isAuthorized(*user(), the_table))
1639
1564
result= -1; // Fatal error
1732
1657
set_proc_info("Opening table");
1734
while (!(table= openTable(table_list, &refresh)) &&
1658
open_tables.current_tablenr= 0;
1659
while (!(table= openTable(table_list, &refresh)) && refresh) ;
1740
1663
table_list->lock_type= lock_type;
1741
1664
table_list->table= table;
1743
assert(lock == 0); // You must lock everything at once
1666
assert(open_tables.lock == 0); // You must lock everything at once
1744
1667
if ((table->reginfo.lock_type= lock_type) != TL_UNLOCK)
1745
if (! (lock= lockTables(&table_list->table, 1, 0, &refresh)))
1669
if (not (open_tables.lock= lockTables(&table_list->table, 1, 0)))
1749
1674
set_proc_info(0);
1793
1718
if (tables == NULL)
1796
assert(session->lock == 0); // You must lock everything at once
1721
assert(session->open_tables.lock == 0); // You must lock everything at once
1797
1722
Table **start,**ptr;
1798
1723
uint32_t lock_flag= DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN;
1800
if (!(ptr=start=(Table**) session->alloc(sizeof(Table*)*count)))
1725
if (!(ptr=start=(Table**) session->getMemRoot()->allocate(sizeof(Table*)*count)))
1802
1728
for (table= tables; table; table= table->next_global)
1804
1730
if (!table->placeholder())
1805
1731
*(ptr++)= table->table;
1808
if (!(session->lock= session->lockTables(start, (uint32_t) (ptr - start), lock_flag, need_reopen)))
1734
if (not (session->open_tables.lock= session->lockTables(start, (uint32_t) (ptr - start), lock_flag)))
1837
Table *Open_tables_state::open_temporary_table(const TableIdentifier &identifier,
1763
Table* Session::open_temporary_table(const identifier::Table &identifier, bool link_in_list)
1840
1765
assert(identifier.isTmp());
1843
1768
table::Temporary *new_tmp_table= new table::Temporary(identifier.getType(),
1845
const_cast<char *>(const_cast<TableIdentifier&>(identifier).getPath().c_str()),
1770
const_cast<char *>(const_cast<identifier::Table&>(identifier).getPath().c_str()),
1846
1771
static_cast<uint32_t>(identifier.getPath().length()));
1847
1772
if (not new_tmp_table)
1869
1794
if (link_in_list)
1871
1796
/* growing temp list at the head */
1872
new_tmp_table->setNext(this->temporary_tables);
1797
new_tmp_table->setNext(open_tables.temporary_tables);
1873
1798
if (new_tmp_table->getNext())
1875
1800
new_tmp_table->getNext()->setPrev(new_tmp_table);
1877
this->temporary_tables= new_tmp_table;
1878
this->temporary_tables->setPrev(0);
1802
open_tables.temporary_tables= new_tmp_table;
1803
open_tables.temporary_tables->setPrev(0);
1880
1805
new_tmp_table->pos_in_table_list= 0;
1964
1889
const char *name, uint32_t , Item **,
1965
1890
bool, TableList **actual_table)
1967
List_iterator_fast<Natural_join_column>
1968
field_it(*(table_ref->join_columns));
1892
List<Natural_join_column>::iterator
1893
field_it(table_ref->join_columns->begin());
1969
1894
Natural_join_column *nj_col, *curr_nj_col;
1970
1895
Field *found_field;
1982
my_error(ER_NON_UNIQ_ERROR, MYF(0), name, session->where);
1907
my_error(ER_NON_UNIQ_ERROR, MYF(0), name, session->where());
1985
1910
nj_col= curr_nj_col;
2333
Select_Lex *current_sel= session->lex->current_select;
2258
Select_Lex *current_sel= session->lex().current_select;
2334
2259
Select_Lex *last_select= table_ref->select_lex;
2336
2261
If the field was an outer referencee, mark all selects using this
2389
2314
if (report_error == REPORT_ALL_ERRORS ||
2390
2315
report_error == IGNORE_EXCEPT_NON_UNIQUE)
2391
2316
my_error(ER_NON_UNIQ_ERROR, MYF(0),
2392
table_name ? item->full_name() : name, session->where);
2317
table_name ? item->full_name() : name, session->where());
2393
2318
return (Field*) 0;
2395
2320
found= cur_field;
2422
2347
strcat(buff, table_name);
2423
2348
table_name=buff;
2425
my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, session->where);
2350
my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, session->where());
2429
2354
if (report_error == REPORT_ALL_ERRORS ||
2430
2355
report_error == REPORT_EXCEPT_NON_UNIQUE)
2431
my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), session->where);
2356
my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), session->where());
2433
2358
found= not_found_field;
2479
2404
find_item_error_report_type report_error,
2480
2405
enum_resolution_type *resolution)
2482
List_iterator<Item> li(items);
2407
List<Item>::iterator li(items.begin());
2483
2408
Item **found=0, **found_unaliased= 0, *item;
2484
2409
const char *db_name=0;
2485
2410
const char *field_name=0;
2556
2481
if (report_error != IGNORE_ERRORS)
2557
2482
my_error(ER_NON_UNIQ_ERROR, MYF(0),
2558
find->full_name(), session->where);
2483
find->full_name(), session->where());
2559
2484
return (Item**) 0;
2561
2486
found_unaliased= li.ref();
2586
2511
continue; // Same field twice
2587
2512
if (report_error != IGNORE_ERRORS)
2588
2513
my_error(ER_NON_UNIQ_ERROR, MYF(0),
2589
find->full_name(), session->where);
2514
find->full_name(), session->where());
2590
2515
return (Item**) 0;
2592
2517
found= li.ref();
2639
2564
if (report_error != IGNORE_ERRORS)
2640
2565
my_error(ER_NON_UNIQ_ERROR, MYF(0),
2641
find->full_name(), session->where);
2566
find->full_name(), session->where());
2642
2567
return (Item **) 0;
2644
2569
if (found_unaliased)
2655
2580
if (report_error == REPORT_ALL_ERRORS)
2656
2581
my_error(ER_BAD_FIELD_ERROR, MYF(0),
2657
find->full_name(), session->where);
2582
find->full_name(), session->where());
2658
2583
return (Item **) 0;
2683
2608
test_if_string_in_list(const char *find, List<String> *str_list)
2685
List_iterator<String> str_list_it(*str_list);
2610
List<String>::iterator str_list_it(str_list->begin());
2686
2611
String *curr_str;
2687
2612
size_t find_length= strlen(find);
2688
2613
while ((curr_str= str_list_it++))
2825
2750
if (cur_nj_col_2->is_common ||
2826
2751
(found && (!using_fields || is_using_column_1)))
2828
my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1, session->where);
2753
my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1, session->where());
2829
2754
return(result);
2831
2756
nj_col_2= cur_nj_col_2;
3013
2938
columns. If this is not the case, report the first one that was
3014
2939
not found in an error.
3016
if (using_fields && found_using_fields < using_fields->elements)
2941
if (using_fields && found_using_fields < using_fields->size())
3018
2943
String *using_field_name;
3019
List_iterator_fast<String> using_fields_it(*using_fields);
2944
List<String>::iterator using_fields_it(using_fields->begin());
3020
2945
while ((using_field_name= using_fields_it++))
3022
2947
const char *using_field_name_ptr= using_field_name->c_ptr();
3023
List_iterator_fast<Natural_join_column>
3024
it(*(natural_using_join->join_columns));
2948
List<Natural_join_column>::iterator
2949
it(natural_using_join->join_columns->begin());
3025
2950
Natural_join_column *common_field;
3030
2955
if (!(common_field= it++))
3032
2957
my_error(ER_BAD_FIELD_ERROR, MYF(0), using_field_name_ptr,
3034
2959
return(result);
3036
2961
if (!my_strcasecmp(system_charset_info,
3103
3028
/* Call the procedure recursively for each nested table reference. */
3104
3029
if (table_ref->getNestedJoin())
3106
List_iterator_fast<TableList> nested_it(table_ref->getNestedJoin()->join_list);
3031
List<TableList>::iterator nested_it(table_ref->getNestedJoin()->join_list.begin());
3107
3032
TableList *same_level_left_neighbor= nested_it++;
3108
3033
TableList *same_level_right_neighbor= NULL;
3109
3034
/* Left/right-most neighbors, possibly at higher levels in the join tree. */
3128
3053
cur_table_ref->outer_join & JOIN_TYPE_RIGHT)
3130
3055
/* This can happen only for JOIN ... ON. */
3131
assert(table_ref->getNestedJoin()->join_list.elements == 2);
3056
assert(table_ref->getNestedJoin()->join_list.size() == 2);
3132
3057
std::swap(same_level_left_neighbor, cur_table_ref);
3156
3081
if (table_ref->is_natural_join)
3158
3083
assert(table_ref->getNestedJoin() &&
3159
table_ref->getNestedJoin()->join_list.elements == 2);
3160
List_iterator_fast<TableList> operand_it(table_ref->getNestedJoin()->join_list);
3084
table_ref->getNestedJoin()->join_list.size() == 2);
3085
List<TableList>::iterator operand_it(table_ref->getNestedJoin()->join_list.begin());
3162
3087
Notice that the order of join operands depends on whether table_ref
3163
3088
represents a LEFT or a RIGHT join. In a RIGHT join, the operands are
3253
3178
List<TableList> *from_clause,
3254
3179
Name_resolution_context *context)
3256
session->where= "from clause";
3257
if (from_clause->elements == 0)
3181
session->setWhere("from clause");
3182
if (from_clause->size() == 0)
3258
3183
return false; /* We come here in the case of UNIONs. */
3260
List_iterator_fast<TableList> table_ref_it(*from_clause);
3185
List<TableList>::iterator table_ref_it(from_clause->begin());
3261
3186
TableList *table_ref; /* Current table reference. */
3262
3187
/* Table reference to the left of the current. */
3263
3188
TableList *left_neighbor;
3310
List_iterator<Item> it(fields);
3235
List<Item>::iterator it(fields.begin());
3312
session->lex->current_select->cur_pos_in_select_list= 0;
3237
session->lex().current_select->cur_pos_in_select_list= 0;
3313
3238
while (wild_num && (item= it++))
3315
3240
if (item->type() == Item::FIELD_ITEM &&
3317
3242
((Item_field*) item)->field_name[0] == '*' &&
3318
3243
!((Item_field*) item)->field)
3320
uint32_t elem= fields.elements;
3245
uint32_t elem= fields.size();
3321
3246
bool any_privileges= ((Item_field *) item)->any_privileges;
3322
Item_subselect *subsel= session->lex->current_select->master_unit()->item;
3247
Item_subselect *subsel= session->lex().current_select->master_unit()->item;
3324
3249
subsel->substype() == Item_subselect::EXISTS_SUBS)
3345
3270
Because of this we have to update the element count also for this
3346
3271
list after expanding the '*' entry.
3348
sum_func_list->elements+= fields.elements - elem;
3273
sum_func_list->set_size(sum_func_list->size() + fields.size() - elem);
3353
session->lex->current_select->cur_pos_in_select_list++;
3278
session->lex().current_select->cur_pos_in_select_list++;
3355
session->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
3280
session->lex().current_select->cur_pos_in_select_list= UNDEF_POS;
3368
3293
register Item *item;
3369
3294
enum_mark_columns save_mark_used_columns= session->mark_used_columns;
3370
nesting_map save_allow_sum_func= session->lex->allow_sum_func;
3371
List_iterator<Item> it(fields);
3295
nesting_map save_allow_sum_func= session->lex().allow_sum_func;
3296
List<Item>::iterator it(fields.begin());
3372
3297
bool save_is_item_list_lookup;
3374
3299
session->mark_used_columns= mark_used_columns;
3375
3300
if (allow_sum_func)
3376
session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
3377
session->where= Session::DEFAULT_WHERE;
3378
save_is_item_list_lookup= session->lex->current_select->is_item_list_lookup;
3379
session->lex->current_select->is_item_list_lookup= 0;
3301
session->lex().allow_sum_func|= 1 << session->lex().current_select->nest_level;
3302
session->setWhere(Session::DEFAULT_WHERE);
3303
save_is_item_list_lookup= session->lex().current_select->is_item_list_lookup;
3304
session->lex().current_select->is_item_list_lookup= 0;
3382
3307
To prevent fail on forward lookup we fill it with zerows,
3386
3311
There is other way to solve problem: fill array with pointers to list,
3387
3312
but it will be slower.
3389
TODO: remove it when (if) we made one list for allfields and
3314
TODO-> remove it when (if) we made one list for allfields and ref_pointer_array
3392
3316
if (ref_pointer_array)
3393
memset(ref_pointer_array, 0, sizeof(Item *) * fields.elements);
3318
memset(ref_pointer_array, 0, sizeof(Item *) * fields.size());
3395
3321
Item **ref= ref_pointer_array;
3396
session->lex->current_select->cur_pos_in_select_list= 0;
3322
session->lex().current_select->cur_pos_in_select_list= 0;
3397
3323
while ((item= it++))
3399
3325
if ((!item->fixed && item->fix_fields(session, it.ref())) || (item= *(it.ref()))->check_cols(1))
3401
session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
3402
session->lex->allow_sum_func= save_allow_sum_func;
3327
session->lex().current_select->is_item_list_lookup= save_is_item_list_lookup;
3328
session->lex().allow_sum_func= save_allow_sum_func;
3403
3329
session->mark_used_columns= save_mark_used_columns;
3410
3336
item->split_sum_func(session, ref_pointer_array, *sum_func_list);
3411
3337
session->used_tables|= item->used_tables();
3412
session->lex->current_select->cur_pos_in_select_list++;
3338
session->lex().current_select->cur_pos_in_select_list++;
3414
session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
3415
session->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
3340
session->lex().current_select->is_item_list_lookup= save_is_item_list_lookup;
3341
session->lex().current_select->cur_pos_in_select_list= UNDEF_POS;
3417
session->lex->allow_sum_func= save_allow_sum_func;
3343
session->lex().allow_sum_func= save_allow_sum_func;
3418
3344
session->mark_used_columns= save_mark_used_columns;
3419
3345
return(test(session->is_error()));
3585
3511
insert_fields(Session *session, Name_resolution_context *context, const char *db_name,
3586
const char *table_name, List_iterator<Item> *it,
3512
const char *table_name, List<Item>::iterator *it,
3589
3515
Field_iterator_table_ref field_iterator;
3622
3548
assert(tables->is_leaf_for_name_resolution());
3624
3550
if ((table_name && my_strcasecmp(table_alias_charset, table_name, tables->alias)) ||
3625
(db_name && strcasecmp(tables->getSchemaName(),db_name)))
3551
(db_name && my_strcasecmp(system_charset_info, tables->getSchemaName(),db_name)))
3689
3616
session->used_tables|= item->used_tables();
3690
session->lex->current_select->cur_pos_in_select_list++;
3619
session->lex().current_select->cur_pos_in_select_list++;
3693
3622
In case of stored tables, all fields are considered as used,
3706
3635
qualified '*', and all columns were coalesced, we have to give a more
3707
3636
meaningful message than ER_BAD_TABLE_ERROR.
3710
3640
my_message(ER_NO_TABLES_USED, ER(ER_NO_TABLES_USED), MYF(0));
3712
3644
my_error(ER_BAD_TABLE_ERROR, MYF(0), table_name);
3736
3669
int Session::setup_conds(TableList *leaves, COND **conds)
3738
3671
Session *session= this;
3739
Select_Lex *select_lex= session->lex->current_select;
3672
Select_Lex *select_lex= session->lex().current_select;
3740
3673
TableList *table= NULL; // For HP compilers
3741
3674
void *save_session_marker= session->session_marker;
3758
3691
session->session_marker= (void*)1;
3761
session->where="where clause";
3694
session->setWhere("where clause");
3762
3695
if ((!(*conds)->fixed && (*conds)->fix_fields(session, conds)) ||
3763
3696
(*conds)->check_cols(1))
3764
3697
goto err_no_arena;
3781
3714
/* Make a join an a expression */
3782
3715
session->session_marker= (void*)embedded;
3783
session->where="on clause";
3716
session->setWhere("on clause");
3784
3717
if ((!embedded->on_expr->fixed && embedded->on_expr->fix_fields(session, &embedded->on_expr)) ||
3785
3718
embedded->on_expr->check_cols(1))
3786
3719
goto err_no_arena;
3789
3722
embedding= embedded->getEmbedding();
3791
3724
while (embedding &&
3792
embedding->getNestedJoin()->join_list.head() == embedded);
3725
&embedding->getNestedJoin()->join_list.front() == embedded);
3795
3728
session->session_marker= save_session_marker;
3797
session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
3730
session->lex().current_select->is_item_list_lookup= save_is_item_list_lookup;
3798
3731
return(test(session->is_error()));
3833
3766
fill_record(Session *session, List<Item> &fields, List<Item> &values, bool ignore_errors)
3835
List_iterator_fast<Item> f(fields),v(values);
3768
List<Item>::iterator f(fields.begin());
3769
List<Item>::iterator v(values.begin());
3837
3771
Item_field *field;
3898
3832
bool fill_record(Session *session, Field **ptr, List<Item> &values, bool)
3900
List_iterator_fast<Item> v(values);
3834
List<Item>::iterator v(values.begin());
3902
3836
Table *table= 0;
3915
3849
table= (*ptr)->getTable();
3916
3850
table->auto_increment_field_not_null= false;
3918
3853
while ((field = *ptr++) && ! session->is_error())
3921
3856
table= field->getTable();
3922
3858
if (field == table->next_number_field)
3923
3859
table->auto_increment_field_not_null= true;
3924
3861
if (value->save_in_field(field, 0) < 0)
3937
3874
bool drizzle_rm_tmp_tables()
3941
3877
assert(drizzle_tmpdir.size());
3878
Session::shared_ptr session= Session::make_shared(plugin::Listen::getNullClient(), catalog::local());
3943
if (!(session= new Session(plugin::Listen::getNullClient())))
3945
session->thread_stack= (char*) &session;
3882
session->thread_stack= (char*) session.get();
3946
3883
session->storeGlobals();
3948
3885
plugin::StorageEngine::removeLostTemporaryTables(*session, drizzle_tmpdir.c_str());