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/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"
58
#include "drizzled/table/unused.h"
64
60
using namespace std;
69
65
extern bool volatile shutdown_in_progress;
67
static bool add_table(table::Concurrent *arg)
69
table::CacheMap &open_cache(table::getCache());
71
table::CacheMap::iterator returnable= open_cache.insert(make_pair(arg->getShare()->getCacheKey(), arg));
73
return not (returnable == open_cache.end());
71
76
bool table_cache_init(void)
97
102
By leaving the table in the table cache, it disallows any other thread
100
session->getKilled() will be set if we run out of memory
105
session->killed will be set if we run out of memory
102
107
If closing a MERGE child, the calling function has to take care for
103
108
closing the parent too, if necessary.
114
119
This has to be done to ensure that the table share is removed from
115
120
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());
122
TableIdentifier identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), message::Table::INTERNAL);
123
const TableIdentifier::Key &key(identifier.getKey());
119
124
TableShare *share= new TableShare(identifier.getType(),
121
126
const_cast<char *>(key.vector()), static_cast<uint32_t>(table->getShare()->getCacheKeySize()));
123
128
table->cursor->close();
124
129
table->db_stat= 0; // Mark cursor closed
125
table::instance::release(table->getMutableShare());
130
TableShare::release(table->getMutableShare());
126
131
table->setShare(share);
159
165
@param session Thread context (may be NULL)
160
166
@param tables List of tables to remove from the cache
161
@param have_lock If table::Cache::singleton().mutex() is locked
167
@param have_lock If LOCK_open is locked
162
168
@param wait_for_refresh Wait for a impending flush
163
169
@param wait_for_placeholders Wait for tables being reopened so that the GRL
164
170
won't proceed while write-locked tables are being reopened by other
236
242
bool found= false;
237
243
for (TableList *table= tables; table; table= table->next_local)
239
identifier::Table identifier(table->getSchemaName(), table->getTableName());
245
TableIdentifier identifier(table->getSchemaName(), table->getTableName());
240
246
if (table::Cache::singleton().removeTable(session, identifier,
241
247
RTFC_OWNED_BY_Session_FLAG))
253
259
If there is any table that has a lower refresh_version, wait until
254
260
this is closed (or this thread is killed) before returning
256
session->mysys_var->current_mutex= &table::Cache::singleton().mutex();
262
session->mysys_var->current_mutex= &LOCK_open;
257
263
session->mysys_var->current_cond= &COND_refresh;
258
264
session->set_proc_info("Flushing tables");
290
296
(table->open_placeholder && wait_for_placeholders)))
293
COND_refresh.wait(scopedLock);
299
boost_unique_lock_t scoped(LOCK_open, boost::adopt_lock_t());
300
COND_refresh.wait(scoped);
300
308
old locks. This should always succeed (unless some external process
301
309
has removed the tables)
303
result= session->reopen_tables();
311
result= session->reopen_tables(true, true);
305
313
/* Set version for table */
306
314
for (Table *table= session->open_tables; table ; table= table->getNext())
331
341
move one table to free list
334
bool Session::free_cached_table(boost::mutex::scoped_lock &scopedLock)
344
bool Session::free_cached_table()
336
346
bool found_old_table= false;
340
347
table::Concurrent *table= static_cast<table::Concurrent *>(open_tables);
342
safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
349
safe_mutex_assert_owner(LOCK_open.native_handle());
343
350
assert(table->key_read == 0);
344
351
assert(!table->cursor || table->cursor->inited == Cursor::NONE);
383
390
bool found_old_table= false;
385
safe_mutex_assert_not_owner(table::Cache::singleton().mutex().native_handle());
392
safe_mutex_assert_not_owner(LOCK_open.native_handle());
387
boost_unique_lock_t scoped_lock(table::Cache::singleton().mutex()); /* Close all open tables on Session */
394
boost_unique_lock_t scoped_lock(LOCK_open); /* Close all open tables on Session */
389
396
while (open_tables)
391
found_old_table|= free_cached_table(scoped_lock);
398
found_old_table|= free_cached_table();
393
400
some_tables_deleted= false;
395
402
if (found_old_table)
397
404
/* Tell threads waiting for refresh that something has happened */
398
locking::broadcast_refresh();
425
432
for (; table; table= table->*link )
427
if ((table->table == 0 || table->table->getShare()->getType() == message::Table::STANDARD) and
428
my_strcasecmp(system_charset_info, table->getSchemaName(), db_name) == 0 and
429
my_strcasecmp(system_charset_info, table->getTableName(), table_name) == 0)
434
if ((table->table == 0 || table->table->getShare()->getType() == message::Table::STANDARD) &&
435
strcasecmp(table->getSchemaName(), db_name) == 0 &&
436
strcasecmp(table->getTableName(), table_name) == 0)
524
void Open_tables_state::doGetTableNames(const identifier::Schema &schema_identifier,
525
std::set<std::string>& set_of_names)
529
void Session::doGetTableNames(const SchemaIdentifier &schema_identifier,
530
std::set<std::string>& set_of_names)
527
for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
532
for (Table *table= temporary_tables ; table ; table= table->getNext())
529
534
if (schema_identifier.compare(table->getShare()->getSchemaName()))
536
void Open_tables_state::doGetTableNames(CachedDirectory &,
537
const identifier::Schema &schema_identifier,
538
std::set<std::string> &set_of_names)
541
void Session::doGetTableNames(CachedDirectory &,
542
const SchemaIdentifier &schema_identifier,
543
std::set<std::string> &set_of_names)
540
545
doGetTableNames(schema_identifier, set_of_names);
543
void Open_tables_state::doGetTableIdentifiers(const identifier::Schema &schema_identifier,
544
identifier::Table::vector &set_of_identifiers)
548
void Session::doGetTableIdentifiers(const SchemaIdentifier &schema_identifier,
549
TableIdentifiers &set_of_identifiers)
546
for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
551
for (Table *table= temporary_tables ; table ; table= table->getNext())
548
553
if (schema_identifier.compare(table->getShare()->getSchemaName()))
550
set_of_identifiers.push_back(identifier::Table(table->getShare()->getSchemaName(),
555
set_of_identifiers.push_back(TableIdentifier(table->getShare()->getSchemaName(),
551
556
table->getShare()->getTableName(),
552
557
table->getShare()->getPath()));
557
void Open_tables_state::doGetTableIdentifiers(CachedDirectory &,
558
const identifier::Schema &schema_identifier,
559
identifier::Table::vector &set_of_identifiers)
562
void Session::doGetTableIdentifiers(CachedDirectory &,
563
const SchemaIdentifier &schema_identifier,
564
TableIdentifiers &set_of_identifiers)
561
566
doGetTableIdentifiers(schema_identifier, set_of_identifiers);
564
bool Open_tables_state::doDoesTableExist(const identifier::Table &identifier)
569
bool Session::doDoesTableExist(const TableIdentifier &identifier)
566
for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
571
for (Table *table= temporary_tables ; table ; table= table->getNext())
568
573
if (table->getShare()->getType() == message::Table::TEMPORARY)
580
int Open_tables_state::doGetTableDefinition(const identifier::Table &identifier,
581
message::Table &table_proto)
585
int Session::doGetTableDefinition(const TableIdentifier &identifier,
586
message::Table &table_proto)
583
for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
588
for (Table *table= temporary_tables ; table ; table= table->getNext())
585
590
if (table->getShare()->getType() == message::Table::TEMPORARY)
587
592
if (identifier.getKey() == table->getShare()->getCacheKey())
589
table_proto.CopyFrom(*(table->getShare()->getTableMessage()));
594
table_proto.CopyFrom(*(table->getShare()->getTableProto()));
644
649
/* Table might be in use by some outer statement. */
645
if (table->query_id && table->query_id != getQueryId())
650
if (table->query_id && table->query_id != query_id)
647
652
my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->getAlias());
661
666
@param session Thread context
662
667
@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.
669
@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
672
void Session::unlink_open_table(Table *find)
669
const identifier::Table::Key find_key(find->getShare()->getCacheKey());
674
const TableIdentifier::Key find_key(find->getShare()->getCacheKey());
671
safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
676
safe_mutex_assert_owner(LOCK_open.native_handle());
674
Note that we need to hold table::Cache::singleton().mutex() while changing the
679
Note that we need to hold LOCK_open while changing the
675
680
open_tables list. Another thread may work on it.
676
(See: table::Cache::singleton().removeTable(), wait_completed_table())
681
(See: table::Cache::singleton().removeTable(), mysql_wait_completed_table())
677
682
Closing a MERGE child before the parent would be fatal if the
678
683
other thread tries to abort the MERGE lock in between.
720
725
table that was locked with LOCK TABLES.
723
void Session::drop_open_table(Table *table, const identifier::Table &identifier)
728
void Session::drop_open_table(Table *table, TableIdentifier &identifier)
725
730
if (table->getShare()->getType())
731
boost_unique_lock_t scoped_lock(table::Cache::singleton().mutex()); /* Close and drop a table (AUX routine) */
736
boost_unique_lock_t scoped_lock(LOCK_open); /* Close and drop a table (AUX routine) */
733
738
unlink_open_table() also tells threads waiting for refresh or close
734
739
that something has happened.
736
741
unlink_open_table(table);
737
(void)plugin::StorageEngine::dropTable(*this, identifier);
742
quick_rm_table(*this, identifier);
798
table::Placeholder *Session::table_cache_insert_placeholder(const drizzled::identifier::Table &arg)
803
table::Placeholder *Session::table_cache_insert_placeholder(const drizzled::TableIdentifier &arg)
800
safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
805
safe_mutex_assert_owner(LOCK_open.native_handle());
803
808
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);
810
TableIdentifier identifier(arg.getSchemaName(), arg.getTableName(), message::Table::INTERNAL);
806
811
table::Placeholder *table= new table::Placeholder(this, identifier);
808
if (not table::Cache::singleton().insert(table))
813
if (not add_table(table))
837
842
@retval true Error occured (OOM)
838
843
@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)
845
bool Session::lock_table_name_if_not_cached(TableIdentifier &identifier, Table **table)
842
const identifier::Table::Key &key(identifier.getKey());
847
const TableIdentifier::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) */
849
boost_unique_lock_t scope_lock(LOCK_open); /* Obtain a name lock even though table is not in cache (like for create table) */
846
851
table::CacheMap::iterator iter;
913
918
if (check_stack_overrun(this, STACK_MIN_SIZE_FOR_OPEN, (unsigned char *)&alias))
919
identifier::Table identifier(table_list->getSchemaName(), table_list->getTableName());
920
const identifier::Table::Key &key(identifier.getKey());
924
TableIdentifier identifier(table_list->getSchemaName(), table_list->getTableName());
925
const TableIdentifier::Key &key(identifier.getKey());
921
926
table::CacheRange ppp;
954
959
if (flags & DRIZZLE_OPEN_TEMPORARY_ONLY)
956
my_error(ER_TABLE_UNKNOWN, identifier);
961
my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->getSchemaName(), table_list->getTableName());
998
1003
until no one holds a name lock on the table.
999
1004
- if there is no such Table in the name cache, read the table definition
1000
1005
and insert it into the cache.
1001
We perform all of the above under table::Cache::singleton().mutex() which currently protects
1006
We perform all of the above under LOCK_open which currently protects
1002
1007
the open cache (also known as table cache) and table definitions stored
1007
boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex());
1012
LOCK_open.lock(); /* Lock for FLUSH TABLES for open table */
1010
1015
Actually try to find the table in the open_cache.
1089
1095
if (table->in_use != this)
1091
/* wait_for_conditionwill unlock table::Cache::singleton().mutex() for us */
1092
wait_for_condition(table::Cache::singleton().mutex(), COND_refresh);
1093
scopedLock.release();
1097
/* wait_for_conditionwill unlock LOCK_open for us */
1098
wait_for_condition(LOCK_open, COND_refresh);
1097
scopedLock.unlock();
1101
1105
There is a refresh in progress for this table.
1102
1106
Signal the caller that it has to try again.
1105
1109
*refresh= true;
1113
1115
table::getUnused().unlink(static_cast<table::Concurrent *>(table));
1123
1125
if (table_list->isCreate())
1125
identifier::Table lock_table_identifier(table_list->getSchemaName(), table_list->getTableName(), message::Table::STANDARD);
1127
TableIdentifier lock_table_identifier(table_list->getSchemaName(), table_list->getTableName(), message::Table::STANDARD);
1127
1129
if (not plugin::StorageEngine::doesTableExist(*this, lock_table_identifier))
1224
1231
the strings are used in a loop even after the share may be freed.
1227
void Session::close_data_files_and_morph_locks(const identifier::Table &identifier)
1234
void Session::close_data_files_and_morph_locks(TableIdentifier &identifier)
1229
safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle()); /* Adjust locks at the end of ALTER TABLEL */
1236
safe_mutex_assert_owner(LOCK_open.native_handle()); /* Adjust locks at the end of ALTER TABLEL */
1269
1276
combination when one needs tables to be reopened (for
1270
1277
example see openTablesLock()).
1272
@note One should have lock on table::Cache::singleton().mutex() when calling this.
1279
@note One should have lock on LOCK_open when calling this.
1274
1281
@return false in case of success, true - otherwise.
1277
bool Session::reopen_tables()
1284
bool Session::reopen_tables(bool get_locks, bool)
1279
1286
Table *table,*next,**prev;
1280
Table **tables= 0; // For locks
1281
Table **tables_ptr= 0; // For locks
1287
Table **tables,**tables_ptr; // For locks
1288
bool error=0, not_used;
1283
1289
const uint32_t flags= DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN |
1284
1290
DRIZZLE_LOCK_IGNORE_GLOBAL_READ_LOCK |
1285
1291
DRIZZLE_LOCK_IGNORE_FLUSH;
1318
1327
if (tables != tables_ptr) // Should we get back old locks
1320
1329
DrizzleLock *local_lock;
1322
1331
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
1332
wait_for_tables() as it tries to acquire LOCK_open, which is
1324
1333
already locked.
1326
1335
some_tables_deleted= false;
1328
if ((local_lock= lockTables(tables, (uint32_t) (tables_ptr - tables), flags)))
1337
if ((local_lock= mysql_lock_tables(this, tables, (uint32_t) (tables_ptr - tables),
1390
1401
lock on it. This will also give them a chance to close their
1391
1402
instances of this table.
1394
removeLock(ulcktbl);
1404
mysql_lock_abort(this, ulcktbl);
1405
mysql_lock_remove(this, ulcktbl);
1395
1406
ulcktbl->lock_count= 0;
1397
1408
if ((ulcktbl != table) && ulcktbl->db_stat)
1434
locking::broadcast_refresh();
1445
broadcast_refresh();
1449
/* Wait until all used tables are refreshed */
1451
bool wait_for_tables(Session *session)
1455
session->set_proc_info("Waiting for tables");
1457
boost_unique_lock_t lock(LOCK_open);
1458
while (!session->killed)
1460
session->some_tables_deleted= false;
1461
session->close_old_data_files(false, dropping_tables != 0);
1462
if (not table::Cache::singleton().areTablesUsed(session->open_tables, 1))
1466
COND_refresh.wait(lock);
1468
if (session->killed)
1469
result= true; // aborted
1472
/* Now we can open all tables without any interference */
1473
session->set_proc_info("Reopen tables");
1474
session->version= refresh_version;
1475
result= session->reopen_tables(false, false);
1478
session->set_proc_info(0);
1462
Table *drop_locked_tables(Session *session, const drizzled::identifier::Table &identifier)
1508
Table *drop_locked_tables(Session *session, const drizzled::TableIdentifier &identifier)
1464
1510
Table *table,*next,**prev, *found= 0;
1465
1511
prev= &session->open_tables;
1468
Note that we need to hold table::Cache::singleton().mutex() while changing the
1514
Note that we need to hold LOCK_open while changing the
1469
1515
open_tables list. Another thread may work on it.
1470
(See: table::Cache::singleton().removeTable(), wait_completed_table())
1516
(See: table::Cache::singleton().removeTable(), mysql_wait_completed_table())
1471
1517
Closing a MERGE child before the parent would be fatal if the
1472
1518
other thread tries to abort the MERGE lock in between.
1515
1560
other threads trying to get the lock.
1518
void abort_locked_tables(Session *session, const drizzled::identifier::Table &identifier)
1563
void abort_locked_tables(Session *session, const drizzled::TableIdentifier &identifier)
1521
1566
for (table= session->open_tables; table ; table= table->getNext())
1523
1568
if (table->getShare()->getCacheKey() == identifier.getKey())
1525
1570
/* If MERGE child, forward lock handling to parent. */
1526
session->abortLock(table);
1571
mysql_lock_abort(session, table);
1597
1641
* to see if it exists so that an unauthorized user cannot phish for
1598
1642
* table/schema information via error messages
1600
identifier::Table the_table(tables->getSchemaName(), tables->getTableName());
1601
if (not plugin::Authorization::isAuthorized(*user(), the_table))
1644
TableIdentifier the_table(tables->getSchemaName(), tables->getTableName());
1645
if (not plugin::Authorization::isAuthorized(getSecurityContext(),
1603
1648
result= -1; // Fatal error
1705
1752
assert(lock == 0); // You must lock everything at once
1706
1753
if ((table->reginfo.lock_type= lock_type) != TL_UNLOCK)
1708
if (not (lock= lockTables(&table_list->table, 1, 0)))
1754
if (! (lock= mysql_lock_tables(this, &table_list->table, 1, 0, &refresh)))
1713
1758
set_proc_info(0);
1761
1806
Table **start,**ptr;
1762
1807
uint32_t lock_flag= DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN;
1764
if (!(ptr=start=(Table**) session->getMemRoot()->allocate(sizeof(Table*)*count)))
1809
if (!(ptr=start=(Table**) session->alloc(sizeof(Table*)*count)))
1767
1811
for (table= tables; table; table= table->next_global)
1769
1813
if (!table->placeholder())
1770
1814
*(ptr++)= table->table;
1773
if (not (session->lock= session->lockTables(start, (uint32_t) (ptr - start), lock_flag)))
1817
if (!(session->lock= mysql_lock_tables(session, start, (uint32_t) (ptr - start),
1818
lock_flag, need_reopen)))
1802
Table *Open_tables_state::open_temporary_table(const identifier::Table &identifier,
1847
Table *Session::open_temporary_table(TableIdentifier &identifier,
1805
1850
assert(identifier.isTmp());
1808
1853
table::Temporary *new_tmp_table= new table::Temporary(identifier.getType(),
1810
const_cast<char *>(const_cast<identifier::Table&>(identifier).getPath().c_str()),
1855
const_cast<char *>(identifier.getPath().c_str()),
1811
1856
static_cast<uint32_t>(identifier.getPath().length()));
1812
1857
if (not new_tmp_table)
1816
1861
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(),
1863
if (new_tmp_table->getMutableShare()->open_table_def(*this, identifier) ||
1864
new_tmp_table->getMutableShare()->open_table_from_share(this, identifier, identifier.getTableName().c_str(),
1820
1865
(uint32_t) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
1822
1867
ha_open_options,
1884
1929
current_bitmap= table->write_set;
1887
//if (current_bitmap->testAndSet(field->position()))
1888
if (current_bitmap->test(field->position()))
1932
//if (current_bitmap->testAndSet(field->field_index))
1933
if (current_bitmap->test(field->field_index))
1890
1935
if (session->mark_used_columns == MARK_COLUMNS_WRITE)
1891
1936
session->dup_field= field;
1929
1974
const char *name, uint32_t , Item **,
1930
1975
bool, TableList **actual_table)
1932
List<Natural_join_column>::iterator
1933
field_it(table_ref->join_columns->begin());
1977
List_iterator_fast<Natural_join_column>
1978
field_it(*(table_ref->join_columns));
1934
1979
Natural_join_column *nj_col, *curr_nj_col;
1935
1980
Field *found_field;
1947
my_error(ER_NON_UNIQ_ERROR, MYF(0), name, session->where());
1992
my_error(ER_NON_UNIQ_ERROR, MYF(0), name, session->where);
1950
1995
nj_col= curr_nj_col;
2196
2241
Table *table= field_to_set->getTable();
2197
2242
if (session->mark_used_columns == MARK_COLUMNS_READ)
2198
table->setReadSet(field_to_set->position());
2243
table->setReadSet(field_to_set->field_index);
2200
table->setWriteSet(field_to_set->position());
2245
table->setWriteSet(field_to_set->field_index);
2298
Select_Lex *current_sel= session->getLex()->current_select;
2343
Select_Lex *current_sel= session->lex->current_select;
2299
2344
Select_Lex *last_select= table_ref->select_lex;
2301
2346
If the field was an outer referencee, mark all selects using this
2354
2399
if (report_error == REPORT_ALL_ERRORS ||
2355
2400
report_error == IGNORE_EXCEPT_NON_UNIQUE)
2356
2401
my_error(ER_NON_UNIQ_ERROR, MYF(0),
2357
table_name ? item->full_name() : name, session->where());
2402
table_name ? item->full_name() : name, session->where);
2358
2403
return (Field*) 0;
2360
2405
found= cur_field;
2387
2432
strcat(buff, table_name);
2388
2433
table_name=buff;
2390
my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, session->where());
2435
my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, session->where);
2394
2439
if (report_error == REPORT_ALL_ERRORS ||
2395
2440
report_error == REPORT_EXCEPT_NON_UNIQUE)
2396
my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), session->where());
2441
my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), session->where);
2398
2443
found= not_found_field;
2444
2489
find_item_error_report_type report_error,
2445
2490
enum_resolution_type *resolution)
2447
List<Item>::iterator li(items.begin());
2492
List_iterator<Item> li(items);
2448
2493
Item **found=0, **found_unaliased= 0, *item;
2449
2494
const char *db_name=0;
2450
2495
const char *field_name=0;
2521
2566
if (report_error != IGNORE_ERRORS)
2522
2567
my_error(ER_NON_UNIQ_ERROR, MYF(0),
2523
find->full_name(), session->where());
2568
find->full_name(), session->where);
2524
2569
return (Item**) 0;
2526
2571
found_unaliased= li.ref();
2551
2596
continue; // Same field twice
2552
2597
if (report_error != IGNORE_ERRORS)
2553
2598
my_error(ER_NON_UNIQ_ERROR, MYF(0),
2554
find->full_name(), session->where());
2599
find->full_name(), session->where);
2555
2600
return (Item**) 0;
2557
2602
found= li.ref();
2604
2649
if (report_error != IGNORE_ERRORS)
2605
2650
my_error(ER_NON_UNIQ_ERROR, MYF(0),
2606
find->full_name(), session->where());
2651
find->full_name(), session->where);
2607
2652
return (Item **) 0;
2609
2654
if (found_unaliased)
2620
2665
if (report_error == REPORT_ALL_ERRORS)
2621
2666
my_error(ER_BAD_FIELD_ERROR, MYF(0),
2622
find->full_name(), session->where());
2667
find->full_name(), session->where);
2623
2668
return (Item **) 0;
2648
2693
test_if_string_in_list(const char *find, List<String> *str_list)
2650
List<String>::iterator str_list_it(str_list->begin());
2695
List_iterator<String> str_list_it(*str_list);
2651
2696
String *curr_str;
2652
2697
size_t find_length= strlen(find);
2653
2698
while ((curr_str= str_list_it++))
2790
2835
if (cur_nj_col_2->is_common ||
2791
2836
(found && (!using_fields || is_using_column_1)))
2793
my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1, session->where());
2838
my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1, session->where);
2794
2839
return(result);
2796
2841
nj_col_2= cur_nj_col_2;
2870
2915
Table *table_1= nj_col_1->table_ref->table;
2871
2916
/* Mark field_1 used for table cache. */
2872
table_1->setReadSet(field_1->position());
2917
table_1->setReadSet(field_1->field_index);
2873
2918
table_1->covering_keys&= field_1->part_of_key;
2874
2919
table_1->merge_keys|= field_1->part_of_key;
2878
2923
Table *table_2= nj_col_2->table_ref->table;
2879
2924
/* Mark field_2 used for table cache. */
2880
table_2->setReadSet(field_2->position());
2925
table_2->setReadSet(field_2->field_index);
2881
2926
table_2->covering_keys&= field_2->part_of_key;
2882
2927
table_2->merge_keys|= field_2->part_of_key;
2981
3026
if (using_fields && found_using_fields < using_fields->elements)
2983
3028
String *using_field_name;
2984
List<String>::iterator using_fields_it(using_fields->begin());
3029
List_iterator_fast<String> using_fields_it(*using_fields);
2985
3030
while ((using_field_name= using_fields_it++))
2987
3032
const char *using_field_name_ptr= using_field_name->c_ptr();
2988
List<Natural_join_column>::iterator
2989
it(natural_using_join->join_columns->begin());
3033
List_iterator_fast<Natural_join_column>
3034
it(*(natural_using_join->join_columns));
2990
3035
Natural_join_column *common_field;
2995
3040
if (!(common_field= it++))
2997
3042
my_error(ER_BAD_FIELD_ERROR, MYF(0), using_field_name_ptr,
2999
3044
return(result);
3001
3046
if (!my_strcasecmp(system_charset_info,
3068
3113
/* Call the procedure recursively for each nested table reference. */
3069
3114
if (table_ref->getNestedJoin())
3071
List<TableList>::iterator nested_it(table_ref->getNestedJoin()->join_list.begin());
3116
List_iterator_fast<TableList> nested_it(table_ref->getNestedJoin()->join_list);
3072
3117
TableList *same_level_left_neighbor= nested_it++;
3073
3118
TableList *same_level_right_neighbor= NULL;
3074
3119
/* Left/right-most neighbors, possibly at higher levels in the join tree. */
3123
3168
assert(table_ref->getNestedJoin() &&
3124
3169
table_ref->getNestedJoin()->join_list.elements == 2);
3125
List<TableList>::iterator operand_it(table_ref->getNestedJoin()->join_list.begin());
3170
List_iterator_fast<TableList> operand_it(table_ref->getNestedJoin()->join_list);
3127
3172
Notice that the order of join operands depends on whether table_ref
3128
3173
represents a LEFT or a RIGHT join. In a RIGHT join, the operands are
3218
3263
List<TableList> *from_clause,
3219
3264
Name_resolution_context *context)
3221
session->setWhere("from clause");
3266
session->where= "from clause";
3222
3267
if (from_clause->elements == 0)
3223
3268
return false; /* We come here in the case of UNIONs. */
3225
List<TableList>::iterator table_ref_it(from_clause->begin());
3270
List_iterator_fast<TableList> table_ref_it(*from_clause);
3226
3271
TableList *table_ref; /* Current table reference. */
3227
3272
/* Table reference to the left of the current. */
3228
3273
TableList *left_neighbor;
3275
List<Item>::iterator it(fields.begin());
3320
List_iterator<Item> it(fields);
3277
session->getLex()->current_select->cur_pos_in_select_list= 0;
3322
session->lex->current_select->cur_pos_in_select_list= 0;
3278
3323
while (wild_num && (item= it++))
3280
3325
if (item->type() == Item::FIELD_ITEM &&
3285
3330
uint32_t elem= fields.elements;
3286
3331
bool any_privileges= ((Item_field *) item)->any_privileges;
3287
Item_subselect *subsel= session->getLex()->current_select->master_unit()->item;
3332
Item_subselect *subsel= session->lex->current_select->master_unit()->item;
3289
3334
subsel->substype() == Item_subselect::EXISTS_SUBS)
3318
session->getLex()->current_select->cur_pos_in_select_list++;
3363
session->lex->current_select->cur_pos_in_select_list++;
3320
session->getLex()->current_select->cur_pos_in_select_list= UNDEF_POS;
3365
session->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
3333
3378
register Item *item;
3334
3379
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());
3380
nesting_map save_allow_sum_func= session->lex->allow_sum_func;
3381
List_iterator<Item> it(fields);
3337
3382
bool save_is_item_list_lookup;
3339
3384
session->mark_used_columns= mark_used_columns;
3340
3385
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;
3386
session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
3387
session->where= Session::DEFAULT_WHERE;
3388
save_is_item_list_lookup= session->lex->current_select->is_item_list_lookup;
3389
session->lex->current_select->is_item_list_lookup= 0;
3347
3392
To prevent fail on forward lookup we fill it with zerows,
3351
3396
There is other way to solve problem: fill array with pointers to list,
3352
3397
but it will be slower.
3354
TODO-> remove it when (if) we made one list for allfields and ref_pointer_array
3399
TODO: remove it when (if) we made one list for allfields and
3356
3402
if (ref_pointer_array)
3358
3403
memset(ref_pointer_array, 0, sizeof(Item *) * fields.elements);
3361
3405
Item **ref= ref_pointer_array;
3362
session->getLex()->current_select->cur_pos_in_select_list= 0;
3406
session->lex->current_select->cur_pos_in_select_list= 0;
3363
3407
while ((item= it++))
3365
3409
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;
3411
session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
3412
session->lex->allow_sum_func= save_allow_sum_func;
3369
3413
session->mark_used_columns= save_mark_used_columns;
3376
3420
item->split_sum_func(session, ref_pointer_array, *sum_func_list);
3377
3421
session->used_tables|= item->used_tables();
3378
session->getLex()->current_select->cur_pos_in_select_list++;
3422
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;
3424
session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
3425
session->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
3383
session->getLex()->allow_sum_func= save_allow_sum_func;
3427
session->lex->allow_sum_func= save_allow_sum_func;
3384
3428
session->mark_used_columns= save_mark_used_columns;
3385
3429
return(test(session->is_error()));
3551
3595
insert_fields(Session *session, Name_resolution_context *context, const char *db_name,
3552
const char *table_name, List<Item>::iterator *it,
3596
const char *table_name, List_iterator<Item> *it,
3555
3599
Field_iterator_table_ref field_iterator;
3588
3632
assert(tables->is_leaf_for_name_resolution());
3590
3634
if ((table_name && my_strcasecmp(table_alias_charset, table_name, tables->alias)) ||
3591
(db_name && my_strcasecmp(system_charset_info, tables->getSchemaName(),db_name)))
3635
(db_name && strcasecmp(tables->getSchemaName(),db_name)))
3624
3668
if ((field= field_iterator.field()))
3626
3670
/* Mark fields as used to allow storage engine to optimze access */
3627
field->getTable()->setReadSet(field->position());
3671
field->getTable()->setReadSet(field->field_index);
3630
3674
table->covering_keys&= field->part_of_key;
3656
3699
session->used_tables|= item->used_tables();
3659
session->getLex()->current_select->cur_pos_in_select_list++;
3700
session->lex->current_select->cur_pos_in_select_list++;
3662
3703
In case of stored tables, all fields are considered as used,
3675
3716
qualified '*', and all columns were coalesced, we have to give a more
3676
3717
meaningful message than ER_BAD_TABLE_ERROR.
3680
3720
my_message(ER_NO_TABLES_USED, ER(ER_NO_TABLES_USED), MYF(0));
3684
3722
my_error(ER_BAD_TABLE_ERROR, MYF(0), table_name);
3709
3746
int Session::setup_conds(TableList *leaves, COND **conds)
3711
3748
Session *session= this;
3712
Select_Lex *select_lex= session->getLex()->current_select;
3749
Select_Lex *select_lex= session->lex->current_select;
3713
3750
TableList *table= NULL; // For HP compilers
3714
3751
void *save_session_marker= session->session_marker;
3731
3768
session->session_marker= (void*)1;
3734
session->setWhere("where clause");
3771
session->where="where clause";
3735
3772
if ((!(*conds)->fixed && (*conds)->fix_fields(session, conds)) ||
3736
3773
(*conds)->check_cols(1))
3737
3774
goto err_no_arena;
3754
3791
/* Make a join an a expression */
3755
3792
session->session_marker= (void*)embedded;
3756
session->setWhere("on clause");
3793
session->where="on clause";
3757
3794
if ((!embedded->on_expr->fixed && embedded->on_expr->fix_fields(session, &embedded->on_expr)) ||
3758
3795
embedded->on_expr->check_cols(1))
3759
3796
goto err_no_arena;
3806
3843
fill_record(Session *session, List<Item> &fields, List<Item> &values, bool ignore_errors)
3808
List<Item>::iterator f(fields.begin());
3809
List<Item>::iterator v(values.begin());
3845
List_iterator_fast<Item> f(fields),v(values);
3811
3847
Item_field *field;
3872
3908
bool fill_record(Session *session, Field **ptr, List<Item> &values, bool)
3874
List<Item>::iterator v(values.begin());
3910
List_iterator_fast<Item> v(values);
3876
3912
Table *table= 0;
3889
3925
table= (*ptr)->getTable();
3890
3926
table->auto_increment_field_not_null= false;
3893
3928
while ((field = *ptr++) && ! session->is_error())
3896
3931
table= field->getTable();
3898
3932
if (field == table->next_number_field)
3899
3933
table->auto_increment_field_not_null= true;
3901
3934
if (value->save_in_field(field, 0) < 0)
3914
3947
bool drizzle_rm_tmp_tables()
3917
3951
assert(drizzle_tmpdir.size());
3918
Session::shared_ptr session= Session::make_shared(plugin::Listen::getNullClient(), catalog::local());
3953
if (!(session= new Session(plugin::Listen::getNullClient())))
3922
session->thread_stack= (char*) session.get();
3955
session->thread_stack= (char*) &session;
3923
3956
session->storeGlobals();
3925
3958
plugin::StorageEngine::removeLostTemporaryTables(*session, drizzle_tmpdir.c_str());
3960
session->lockForDelete();