~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_base.cc

  • Committer: Stewart Smith
  • Date: 2011-01-14 05:13:52 UTC
  • mto: (2086.1.3 build)
  • mto: This revision was merged to the branch mainline in revision 2087.
  • Revision ID: stewart@flamingspork.com-20110114051352-ytdw2wn6thbf4dr8
fix tpyo

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 
16
16
 
17
17
/* Basic functions needed by many modules */
18
 
#include <config.h>
 
18
#include "config.h"
19
19
#include <assert.h>
20
20
 
21
21
#include <signal.h>
30
30
#  include <time.h>
31
31
# endif
32
32
#endif
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"
35
35
 
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>
 
47
#include "drizzled/cached_directory.h"
48
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>
59
 
#include <drizzled/plugin/storage_engine.h>
60
 
#include <drizzled/session.h>
61
 
 
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"
63
59
 
64
60
using namespace std;
65
61
 
114
110
    This has to be done to ensure that the table share is removed from
115
111
    the table defintion cache as soon as the last instance is removed
116
112
  */
117
 
  identifier::Table identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), message::Table::INTERNAL);
118
 
  const identifier::Table::Key &key(identifier.getKey());
 
113
  TableIdentifier identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), message::Table::INTERNAL);
 
114
  const TableIdentifier::Key &key(identifier.getKey());
119
115
  TableShare *share= new TableShare(identifier.getType(),
120
116
                                    identifier,
121
117
                                    const_cast<char *>(key.vector()),  static_cast<uint32_t>(table->getShare()->getCacheKeySize()));
122
118
 
123
119
  table->cursor->close();
124
120
  table->db_stat= 0;                            // Mark cursor closed
125
 
  table::instance::release(table->getMutableShare());
 
121
  TableShare::release(table->getMutableShare());
126
122
  table->setShare(share);
127
123
}
128
124
 
148
144
  if (sort.io_cache)
149
145
  {
150
146
    sort.io_cache->close_cached_file();
151
 
    safe_delete(sort.io_cache);
 
147
    delete sort.io_cache;
 
148
    sort.io_cache= 0;
152
149
  }
153
150
}
154
151
 
174
171
  Session *session= this;
175
172
 
176
173
  {
177
 
    boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex()); /* Optionally lock for remove tables from open_cahe if not in use */
 
174
    table::Cache::singleton().mutex().lock(); /* Optionally lock for remove tables from open_cahe if not in use */
178
175
 
179
176
    if (tables == NULL)
180
177
    {
236
233
      bool found= false;
237
234
      for (TableList *table= tables; table; table= table->next_local)
238
235
      {
239
 
        identifier::Table identifier(table->getSchemaName(), table->getTableName());
 
236
        TableIdentifier identifier(table->getSchemaName(), table->getTableName());
240
237
        if (table::Cache::singleton().removeTable(session, identifier,
241
238
                                    RTFC_OWNED_BY_Session_FLAG))
242
239
        {
290
287
                                                     (table->open_placeholder && wait_for_placeholders)))
291
288
          {
292
289
            found= true;
293
 
            COND_refresh.wait(scopedLock);
 
290
            boost_unique_lock_t scoped(table::Cache::singleton().mutex(), boost::adopt_lock_t());
 
291
            COND_refresh.wait(scoped);
 
292
            scoped.release();
294
293
            break;
295
294
          }
296
295
        }
300
299
        old locks. This should always succeed (unless some external process
301
300
        has removed the tables)
302
301
      */
303
 
      result= session->reopen_tables();
 
302
      result= session->reopen_tables(true, true);
304
303
 
305
304
      /* Set version for table */
306
305
      for (Table *table= session->open_tables; table ; table= table->getNext())
313
312
          table->getMutableShare()->refreshVersion();
314
313
      }
315
314
    }
 
315
 
 
316
    table::Cache::singleton().mutex().unlock();
316
317
  }
317
318
 
318
319
  if (wait_for_refresh)
331
332
  move one table to free list 
332
333
*/
333
334
 
334
 
bool Session::free_cached_table(boost::mutex::scoped_lock &scopedLock)
 
335
bool Session::free_cached_table()
335
336
{
336
337
  bool found_old_table= false;
337
 
 
338
 
  (void)scopedLock;
339
 
 
340
338
  table::Concurrent *table= static_cast<table::Concurrent *>(open_tables);
341
339
 
342
340
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
388
386
 
389
387
  while (open_tables)
390
388
  {
391
 
    found_old_table|= free_cached_table(scoped_lock);
 
389
    found_old_table|= free_cached_table();
392
390
  }
393
391
  some_tables_deleted= false;
394
392
 
424
422
{
425
423
  for (; table; table= table->*link )
426
424
  {
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)
430
 
    {
 
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)
431
428
      break;
432
 
    }
433
429
  }
434
430
  return table;
435
431
}
521
517
}
522
518
 
523
519
 
524
 
void Open_tables_state::doGetTableNames(const identifier::Schema &schema_identifier,
 
520
void Open_tables_state::doGetTableNames(const SchemaIdentifier &schema_identifier,
525
521
                                        std::set<std::string>& set_of_names)
526
522
{
527
523
  for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
534
530
}
535
531
 
536
532
void Open_tables_state::doGetTableNames(CachedDirectory &,
537
 
                                        const identifier::Schema &schema_identifier,
 
533
                                        const SchemaIdentifier &schema_identifier,
538
534
                                        std::set<std::string> &set_of_names)
539
535
{
540
536
  doGetTableNames(schema_identifier, set_of_names);
541
537
}
542
538
 
543
 
void Open_tables_state::doGetTableIdentifiers(const identifier::Schema &schema_identifier,
544
 
                                              identifier::Table::vector &set_of_identifiers)
 
539
void Open_tables_state::doGetTableIdentifiers(const SchemaIdentifier &schema_identifier,
 
540
                                              TableIdentifier::vector &set_of_identifiers)
545
541
{
546
542
  for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
547
543
  {
548
544
    if (schema_identifier.compare(table->getShare()->getSchemaName()))
549
545
    {
550
 
      set_of_identifiers.push_back(identifier::Table(table->getShare()->getSchemaName(),
 
546
      set_of_identifiers.push_back(TableIdentifier(table->getShare()->getSchemaName(),
551
547
                                                   table->getShare()->getTableName(),
552
548
                                                   table->getShare()->getPath()));
553
549
    }
555
551
}
556
552
 
557
553
void Open_tables_state::doGetTableIdentifiers(CachedDirectory &,
558
 
                                              const identifier::Schema &schema_identifier,
559
 
                                              identifier::Table::vector &set_of_identifiers)
 
554
                                              const SchemaIdentifier &schema_identifier,
 
555
                                              TableIdentifier::vector &set_of_identifiers)
560
556
{
561
557
  doGetTableIdentifiers(schema_identifier, set_of_identifiers);
562
558
}
563
559
 
564
 
bool Open_tables_state::doDoesTableExist(const identifier::Table &identifier)
 
560
bool Open_tables_state::doDoesTableExist(const TableIdentifier &identifier)
565
561
{
566
562
  for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
567
563
  {
577
573
  return false;
578
574
}
579
575
 
580
 
int Open_tables_state::doGetTableDefinition(const identifier::Table &identifier,
581
 
                                            message::Table &table_proto)
 
576
int Open_tables_state::doGetTableDefinition(const TableIdentifier &identifier,
 
577
                                  message::Table &table_proto)
582
578
{
583
579
  for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
584
580
  {
586
582
    {
587
583
      if (identifier.getKey() == table->getShare()->getCacheKey())
588
584
      {
589
 
        table_proto.CopyFrom(*(table->getShare()->getTableMessage()));
 
585
        table_proto.CopyFrom(*(table->getShare()->getTableProto()));
590
586
 
591
587
        return EEXIST;
592
588
      }
596
592
  return ENOENT;
597
593
}
598
594
 
599
 
Table *Open_tables_state::find_temporary_table(const identifier::Table &identifier)
 
595
Table *Open_tables_state::find_temporary_table(const TableIdentifier &identifier)
600
596
{
601
597
  for (Table *table= temporary_tables ; table ; table= table->getNext())
602
598
  {
634
630
  @retval -1  the table is in use by a outer query
635
631
*/
636
632
 
637
 
int Open_tables_state::drop_temporary_table(const drizzled::identifier::Table &identifier)
 
633
int Open_tables_state::drop_temporary_table(const drizzled::TableIdentifier &identifier)
638
634
{
639
635
  Table *table;
640
636
 
666
662
 
667
663
void Session::unlink_open_table(Table *find)
668
664
{
669
 
  const identifier::Table::Key find_key(find->getShare()->getCacheKey());
 
665
  const TableIdentifier::Key find_key(find->getShare()->getCacheKey());
670
666
  Table **prev;
671
667
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
672
668
 
720
716
  table that was locked with LOCK TABLES.
721
717
*/
722
718
 
723
 
void Session::drop_open_table(Table *table, const identifier::Table &identifier)
 
719
void Session::drop_open_table(Table *table, const TableIdentifier &identifier)
724
720
{
725
721
  if (table->getShare()->getType())
726
722
  {
795
791
  case of failure.
796
792
*/
797
793
 
798
 
table::Placeholder *Session::table_cache_insert_placeholder(const drizzled::identifier::Table &arg)
 
794
table::Placeholder *Session::table_cache_insert_placeholder(const drizzled::TableIdentifier &arg)
799
795
{
800
796
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
801
797
 
802
798
  /*
803
799
    Create a table entry with the right key and with an old refresh version
804
800
  */
805
 
  identifier::Table identifier(arg.getSchemaName(), arg.getTableName(), message::Table::INTERNAL);
 
801
  TableIdentifier identifier(arg.getSchemaName(), arg.getTableName(), message::Table::INTERNAL);
806
802
  table::Placeholder *table= new table::Placeholder(this, identifier);
807
803
 
808
804
  if (not table::Cache::singleton().insert(table))
809
805
  {
810
 
    safe_delete(table);
 
806
    delete table;
811
807
 
812
808
    return NULL;
813
809
  }
837
833
  @retval  true   Error occured (OOM)
838
834
  @retval  false  Success. 'table' parameter set according to above rules.
839
835
*/
840
 
bool Session::lock_table_name_if_not_cached(const identifier::Table &identifier, Table **table)
 
836
bool Session::lock_table_name_if_not_cached(const TableIdentifier &identifier, Table **table)
841
837
{
842
 
  const identifier::Table::Key &key(identifier.getKey());
 
838
  const TableIdentifier::Key &key(identifier.getKey());
843
839
 
844
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)  */
845
841
 
916
912
  if (getKilled())
917
913
    return NULL;
918
914
 
919
 
  identifier::Table identifier(table_list->getSchemaName(), table_list->getTableName());
920
 
  const identifier::Table::Key &key(identifier.getKey());
 
915
  TableIdentifier identifier(table_list->getSchemaName(), table_list->getTableName());
 
916
  const TableIdentifier::Key &key(identifier.getKey());
921
917
  table::CacheRange ppp;
922
918
 
923
919
  /*
953
949
  {
954
950
    if (flags & DRIZZLE_OPEN_TEMPORARY_ONLY)
955
951
    {
956
 
      my_error(ER_TABLE_UNKNOWN, identifier);
 
952
      my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->getSchemaName(), table_list->getTableName());
957
953
      return NULL;
958
954
    }
959
955
 
1004
1000
    */
1005
1001
 
1006
1002
    {
1007
 
      boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex());
 
1003
      table::Cache::singleton().mutex().lock(); /* Lock for FLUSH TABLES for open table */
1008
1004
 
1009
1005
      /*
1010
1006
        Actually try to find the table in the open_cache.
1056
1052
          /* Avoid self-deadlocks by detecting self-dependencies. */
1057
1053
          if (table->open_placeholder && table->in_use == this)
1058
1054
          {
 
1055
            table::Cache::singleton().mutex().unlock();
1059
1056
            my_error(ER_UPDATE_TABLE_USED, MYF(0), table->getShare()->getTableName());
1060
1057
            return NULL;
1061
1058
          }
1090
1087
          {
1091
1088
            /* wait_for_conditionwill unlock table::Cache::singleton().mutex() for us */
1092
1089
            wait_for_condition(table::Cache::singleton().mutex(), COND_refresh);
1093
 
            scopedLock.release();
1094
1090
          }
1095
1091
          else
1096
1092
          {
1097
 
            scopedLock.unlock();
 
1093
            table::Cache::singleton().mutex().unlock();
1098
1094
          }
1099
 
 
1100
1095
          /*
1101
1096
            There is a refresh in progress for this table.
1102
1097
            Signal the caller that it has to try again.
1103
1098
          */
1104
1099
          if (refresh)
1105
1100
            *refresh= true;
1106
 
 
1107
1101
          return NULL;
1108
1102
        }
1109
1103
      }
1110
 
 
1111
1104
      if (table)
1112
1105
      {
1113
1106
        table::getUnused().unlink(static_cast<table::Concurrent *>(table));
1122
1115
 
1123
1116
        if (table_list->isCreate())
1124
1117
        {
1125
 
          identifier::Table  lock_table_identifier(table_list->getSchemaName(), table_list->getTableName(), message::Table::STANDARD);
 
1118
          TableIdentifier  lock_table_identifier(table_list->getSchemaName(), table_list->getTableName(), message::Table::STANDARD);
1126
1119
 
1127
1120
          if (not plugin::StorageEngine::doesTableExist(*this, lock_table_identifier))
1128
1121
          {
1131
1124
            */
1132
1125
            if (!(table= table_cache_insert_placeholder(lock_table_identifier)))
1133
1126
            {
 
1127
              table::Cache::singleton().mutex().unlock();
1134
1128
              return NULL;
1135
1129
            }
1136
1130
            /*
1141
1135
            table->open_placeholder= true;
1142
1136
            table->setNext(open_tables);
1143
1137
            open_tables= table;
 
1138
            table::Cache::singleton().mutex().unlock();
1144
1139
 
1145
1140
            return table ;
1146
1141
          }
1153
1148
          table= new_table;
1154
1149
          if (new_table == NULL)
1155
1150
          {
 
1151
            table::Cache::singleton().mutex().unlock();
1156
1152
            return NULL;
1157
1153
          }
1158
1154
 
1160
1156
          if (error != 0)
1161
1157
          {
1162
1158
            delete new_table;
 
1159
            table::Cache::singleton().mutex().unlock();
1163
1160
            return NULL;
1164
1161
          }
1165
1162
          (void)table::Cache::singleton().insert(new_table);
1166
1163
        }
1167
1164
      }
 
1165
 
 
1166
      table::Cache::singleton().mutex().unlock();
1168
1167
    }
1169
 
 
1170
1168
    if (refresh)
1171
1169
    {
1172
1170
      table->setNext(open_tables); /* Link into simple list */
1224
1222
  the strings are used in a loop even after the share may be freed.
1225
1223
*/
1226
1224
 
1227
 
void Session::close_data_files_and_morph_locks(const identifier::Table &identifier)
 
1225
void Session::close_data_files_and_morph_locks(const TableIdentifier &identifier)
1228
1226
{
1229
1227
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle()); /* Adjust locks at the end of ALTER TABLEL */
1230
1228
 
1274
1272
  @return false in case of success, true - otherwise.
1275
1273
*/
1276
1274
 
1277
 
bool Session::reopen_tables()
 
1275
bool Session::reopen_tables(bool get_locks, bool)
1278
1276
{
1279
1277
  Table *table,*next,**prev;
1280
 
  Table **tables= 0;                    // For locks
1281
 
  Table **tables_ptr= 0;                        // For locks
 
1278
  Table **tables,**tables_ptr;                  // For locks
1282
1279
  bool error= false;
1283
1280
  const uint32_t flags= DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN |
1284
1281
    DRIZZLE_LOCK_IGNORE_GLOBAL_READ_LOCK |
1288
1285
    return false;
1289
1286
 
1290
1287
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
 
1288
  if (get_locks)
1291
1289
  {
1292
1290
    /*
1293
1291
      The ptr is checked later
1301
1299
    }
1302
1300
    tables= new Table *[opens];
1303
1301
  }
1304
 
 
 
1302
  else
 
1303
  {
 
1304
    tables= &open_tables;
 
1305
  }
1305
1306
  tables_ptr =tables;
1306
1307
 
1307
1308
  prev= &open_tables;
1341
1342
    }
1342
1343
  }
1343
1344
 
1344
 
  delete [] tables;
 
1345
  if (get_locks && tables)
 
1346
    delete [] tables;
1345
1347
 
1346
1348
  locking::broadcast_refresh();
1347
1349
 
1348
 
  return error;
 
1350
  return(error);
1349
1351
}
1350
1352
 
1351
1353
 
1376
1378
    */
1377
1379
    if (table->needs_reopen_or_name_lock())
1378
1380
    {
1379
 
      found= true;
 
1381
      found=1;
1380
1382
      if (table->db_stat)
1381
1383
      {
1382
1384
        if (morph_locks)
1459
1461
*/
1460
1462
 
1461
1463
 
1462
 
Table *drop_locked_tables(Session *session, const drizzled::identifier::Table &identifier)
 
1464
Table *drop_locked_tables(Session *session, const drizzled::TableIdentifier &identifier)
1463
1465
{
1464
1466
  Table *table,*next,**prev, *found= 0;
1465
1467
  prev= &session->open_tables;
1501
1503
    }
1502
1504
  }
1503
1505
  *prev=0;
1504
 
 
1505
1506
  if (found)
1506
1507
    locking::broadcast_refresh();
1507
1508
 
1508
 
  return found;
 
1509
  return(found);
1509
1510
}
1510
1511
 
1511
1512
 
1515
1516
  other threads trying to get the lock.
1516
1517
*/
1517
1518
 
1518
 
void abort_locked_tables(Session *session, const drizzled::identifier::Table &identifier)
 
1519
void abort_locked_tables(Session *session, const drizzled::TableIdentifier &identifier)
1519
1520
{
1520
1521
  Table *table;
1521
1522
  for (table= session->open_tables; table ; table= table->getNext())
1524
1525
    {
1525
1526
      /* If MERGE child, forward lock handling to parent. */
1526
1527
      session->abortLock(table);
1527
 
      assert(0);
1528
1528
      break;
1529
1529
    }
1530
1530
  }
1597
1597
     * to see if it exists so that an unauthorized user cannot phish for
1598
1598
     * table/schema information via error messages
1599
1599
     */
1600
 
    identifier::Table the_table(tables->getSchemaName(), tables->getTableName());
1601
 
    if (not plugin::Authorization::isAuthorized(*user(), the_table))
 
1600
    TableIdentifier the_table(tables->getSchemaName(), tables->getTableName());
 
1601
    if (not plugin::Authorization::isAuthorized(user(), the_table))
1602
1602
    {
1603
1603
      result= -1;                               // Fatal error
1604
1604
      break;
1761
1761
  Table **start,**ptr;
1762
1762
  uint32_t lock_flag= DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN;
1763
1763
 
1764
 
  if (!(ptr=start=(Table**) session->getMemRoot()->allocate(sizeof(Table*)*count)))
 
1764
  if (!(ptr=start=(Table**) session->alloc(sizeof(Table*)*count)))
1765
1765
    return -1;
1766
1766
 
1767
1767
  for (table= tables; table; table= table->next_global)
1799
1799
#  Table object
1800
1800
*/
1801
1801
 
1802
 
Table *Open_tables_state::open_temporary_table(const identifier::Table &identifier,
 
1802
Table *Open_tables_state::open_temporary_table(const TableIdentifier &identifier,
1803
1803
                                               bool link_in_list)
1804
1804
{
1805
1805
  assert(identifier.isTmp());
1807
1807
 
1808
1808
  table::Temporary *new_tmp_table= new table::Temporary(identifier.getType(),
1809
1809
                                                        identifier,
1810
 
                                                        const_cast<char *>(const_cast<identifier::Table&>(identifier).getPath().c_str()),
 
1810
                                                        const_cast<char *>(const_cast<TableIdentifier&>(identifier).getPath().c_str()),
1811
1811
                                                        static_cast<uint32_t>(identifier.getPath().length()));
1812
1812
  if (not new_tmp_table)
1813
1813
    return NULL;
1929
1929
                           const char *name, uint32_t , Item **,
1930
1930
                           bool, TableList **actual_table)
1931
1931
{
1932
 
  List<Natural_join_column>::iterator
1933
 
    field_it(table_ref->join_columns->begin());
 
1932
  List_iterator_fast<Natural_join_column>
 
1933
    field_it(*(table_ref->join_columns));
1934
1934
  Natural_join_column *nj_col, *curr_nj_col;
1935
1935
  Field *found_field;
1936
1936
 
1944
1944
    {
1945
1945
      if (nj_col)
1946
1946
      {
1947
 
        my_error(ER_NON_UNIQ_ERROR, MYF(0), name, session->where());
 
1947
        my_error(ER_NON_UNIQ_ERROR, MYF(0), name, session->where);
1948
1948
        return NULL;
1949
1949
      }
1950
1950
      nj_col= curr_nj_col;
2145
2145
    */
2146
2146
    if (table_name && table_name[0])
2147
2147
    {
2148
 
      List<TableList>::iterator it(table_list->getNestedJoin()->join_list.begin());
 
2148
      List_iterator<TableList> it(table_list->getNestedJoin()->join_list);
2149
2149
      TableList *table;
2150
2150
      while ((table= it++))
2151
2151
      {
2295
2295
        fields.
2296
2296
      */
2297
2297
      {
2298
 
        Select_Lex *current_sel= session->getLex()->current_select;
 
2298
        Select_Lex *current_sel= session->lex->current_select;
2299
2299
        Select_Lex *last_select= table_ref->select_lex;
2300
2300
        /*
2301
2301
          If the field was an outer referencee, mark all selects using this
2341
2341
      */
2342
2342
      item->cached_table= found ?  0 : actual_table;
2343
2343
 
2344
 
      assert(session->where());
 
2344
      assert(session->where);
2345
2345
      /*
2346
2346
        If we found a fully qualified field we return it directly as it can't
2347
2347
        have duplicates.
2354
2354
        if (report_error == REPORT_ALL_ERRORS ||
2355
2355
            report_error == IGNORE_EXCEPT_NON_UNIQUE)
2356
2356
          my_error(ER_NON_UNIQ_ERROR, MYF(0),
2357
 
                   table_name ? item->full_name() : name, session->where());
 
2357
                   table_name ? item->full_name() : name, session->where);
2358
2358
        return (Field*) 0;
2359
2359
      }
2360
2360
      found= cur_field;
2387
2387
      strcat(buff, table_name);
2388
2388
      table_name=buff;
2389
2389
    }
2390
 
    my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, session->where());
 
2390
    my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, session->where);
2391
2391
  }
2392
2392
  else
2393
2393
  {
2394
2394
    if (report_error == REPORT_ALL_ERRORS ||
2395
2395
        report_error == REPORT_EXCEPT_NON_UNIQUE)
2396
 
      my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), session->where());
 
2396
      my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), session->where);
2397
2397
    else
2398
2398
      found= not_found_field;
2399
2399
  }
2444
2444
                  find_item_error_report_type report_error,
2445
2445
                  enum_resolution_type *resolution)
2446
2446
{
2447
 
  List<Item>::iterator li(items.begin());
 
2447
  List_iterator<Item> li(items);
2448
2448
  Item **found=0, **found_unaliased= 0, *item;
2449
2449
  const char *db_name=0;
2450
2450
  const char *field_name=0;
2520
2520
            */
2521
2521
            if (report_error != IGNORE_ERRORS)
2522
2522
              my_error(ER_NON_UNIQ_ERROR, MYF(0),
2523
 
                       find->full_name(), session->where());
 
2523
                       find->full_name(), session->where);
2524
2524
            return (Item**) 0;
2525
2525
          }
2526
2526
          found_unaliased= li.ref();
2551
2551
              continue;                           // Same field twice
2552
2552
            if (report_error != IGNORE_ERRORS)
2553
2553
              my_error(ER_NON_UNIQ_ERROR, MYF(0),
2554
 
                       find->full_name(), session->where());
 
2554
                       find->full_name(), session->where);
2555
2555
            return (Item**) 0;
2556
2556
          }
2557
2557
          found= li.ref();
2603
2603
    {
2604
2604
      if (report_error != IGNORE_ERRORS)
2605
2605
        my_error(ER_NON_UNIQ_ERROR, MYF(0),
2606
 
                 find->full_name(), session->where());
 
2606
                 find->full_name(), session->where);
2607
2607
      return (Item **) 0;
2608
2608
    }
2609
2609
    if (found_unaliased)
2619
2619
  {
2620
2620
    if (report_error == REPORT_ALL_ERRORS)
2621
2621
      my_error(ER_BAD_FIELD_ERROR, MYF(0),
2622
 
               find->full_name(), session->where());
 
2622
               find->full_name(), session->where);
2623
2623
    return (Item **) 0;
2624
2624
  }
2625
2625
  else
2647
2647
static bool
2648
2648
test_if_string_in_list(const char *find, List<String> *str_list)
2649
2649
{
2650
 
  List<String>::iterator str_list_it(str_list->begin());
 
2650
  List_iterator<String> str_list_it(*str_list);
2651
2651
  String *curr_str;
2652
2652
  size_t find_length= strlen(find);
2653
2653
  while ((curr_str= str_list_it++))
2790
2790
        if (cur_nj_col_2->is_common ||
2791
2791
            (found && (!using_fields || is_using_column_1)))
2792
2792
        {
2793
 
          my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1, session->where());
 
2793
          my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1, session->where);
2794
2794
          return(result);
2795
2795
        }
2796
2796
        nj_col_2= cur_nj_col_2;
2981
2981
  if (using_fields && found_using_fields < using_fields->elements)
2982
2982
  {
2983
2983
    String *using_field_name;
2984
 
    List<String>::iterator using_fields_it(using_fields->begin());
 
2984
    List_iterator_fast<String> using_fields_it(*using_fields);
2985
2985
    while ((using_field_name= using_fields_it++))
2986
2986
    {
2987
2987
      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());
 
2988
      List_iterator_fast<Natural_join_column>
 
2989
        it(*(natural_using_join->join_columns));
2990
2990
      Natural_join_column *common_field;
2991
2991
 
2992
2992
      for (;;)
2995
2995
        if (!(common_field= it++))
2996
2996
        {
2997
2997
          my_error(ER_BAD_FIELD_ERROR, MYF(0), using_field_name_ptr,
2998
 
                   session->where());
 
2998
                   session->where);
2999
2999
          return(result);
3000
3000
        }
3001
3001
        if (!my_strcasecmp(system_charset_info,
3068
3068
  /* Call the procedure recursively for each nested table reference. */
3069
3069
  if (table_ref->getNestedJoin())
3070
3070
  {
3071
 
    List<TableList>::iterator nested_it(table_ref->getNestedJoin()->join_list.begin());
 
3071
    List_iterator_fast<TableList> nested_it(table_ref->getNestedJoin()->join_list);
3072
3072
    TableList *same_level_left_neighbor= nested_it++;
3073
3073
    TableList *same_level_right_neighbor= NULL;
3074
3074
    /* Left/right-most neighbors, possibly at higher levels in the join tree. */
3122
3122
  {
3123
3123
    assert(table_ref->getNestedJoin() &&
3124
3124
           table_ref->getNestedJoin()->join_list.elements == 2);
3125
 
    List<TableList>::iterator operand_it(table_ref->getNestedJoin()->join_list.begin());
 
3125
    List_iterator_fast<TableList> operand_it(table_ref->getNestedJoin()->join_list);
3126
3126
    /*
3127
3127
      Notice that the order of join operands depends on whether table_ref
3128
3128
      represents a LEFT or a RIGHT join. In a RIGHT join, the operands are
3218
3218
                                         List<TableList> *from_clause,
3219
3219
                                         Name_resolution_context *context)
3220
3220
{
3221
 
  session->setWhere("from clause");
 
3221
  session->where= "from clause";
3222
3222
  if (from_clause->elements == 0)
3223
3223
    return false; /* We come here in the case of UNIONs. */
3224
3224
 
3225
 
  List<TableList>::iterator table_ref_it(from_clause->begin());
 
3225
  List_iterator_fast<TableList> table_ref_it(*from_clause);
3226
3226
  TableList *table_ref; /* Current table reference. */
3227
3227
  /* Table reference to the left of the current. */
3228
3228
  TableList *left_neighbor;
3272
3272
    return 0;
3273
3273
 
3274
3274
  Item *item;
3275
 
  List<Item>::iterator it(fields.begin());
 
3275
  List_iterator<Item> it(fields);
3276
3276
 
3277
 
  session->getLex()->current_select->cur_pos_in_select_list= 0;
 
3277
  session->lex->current_select->cur_pos_in_select_list= 0;
3278
3278
  while (wild_num && (item= it++))
3279
3279
  {
3280
3280
    if (item->type() == Item::FIELD_ITEM &&
3284
3284
    {
3285
3285
      uint32_t elem= fields.elements;
3286
3286
      bool any_privileges= ((Item_field *) item)->any_privileges;
3287
 
      Item_subselect *subsel= session->getLex()->current_select->master_unit()->item;
 
3287
      Item_subselect *subsel= session->lex->current_select->master_unit()->item;
3288
3288
      if (subsel &&
3289
3289
          subsel->substype() == Item_subselect::EXISTS_SUBS)
3290
3290
      {
3315
3315
      wild_num--;
3316
3316
    }
3317
3317
    else
3318
 
      session->getLex()->current_select->cur_pos_in_select_list++;
 
3318
      session->lex->current_select->cur_pos_in_select_list++;
3319
3319
  }
3320
 
  session->getLex()->current_select->cur_pos_in_select_list= UNDEF_POS;
 
3320
  session->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
3321
3321
 
3322
3322
  return 0;
3323
3323
}
3332
3332
{
3333
3333
  register Item *item;
3334
3334
  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());
 
3335
  nesting_map save_allow_sum_func= session->lex->allow_sum_func;
 
3336
  List_iterator<Item> it(fields);
3337
3337
  bool save_is_item_list_lookup;
3338
3338
 
3339
3339
  session->mark_used_columns= mark_used_columns;
3340
3340
  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;
 
3341
    session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
 
3342
  session->where= Session::DEFAULT_WHERE;
 
3343
  save_is_item_list_lookup= session->lex->current_select->is_item_list_lookup;
 
3344
  session->lex->current_select->is_item_list_lookup= 0;
3345
3345
 
3346
3346
  /*
3347
3347
    To prevent fail on forward lookup we fill it with zerows,
3351
3351
    There is other way to solve problem: fill array with pointers to list,
3352
3352
    but it will be slower.
3353
3353
 
3354
 
    TODO-> remove it when (if) we made one list for allfields and ref_pointer_array
 
3354
TODO: remove it when (if) we made one list for allfields and
 
3355
ref_pointer_array
3355
3356
  */
3356
3357
  if (ref_pointer_array)
3357
 
  {
3358
3358
    memset(ref_pointer_array, 0, sizeof(Item *) * fields.elements);
3359
 
  }
3360
3359
 
3361
3360
  Item **ref= ref_pointer_array;
3362
 
  session->getLex()->current_select->cur_pos_in_select_list= 0;
 
3361
  session->lex->current_select->cur_pos_in_select_list= 0;
3363
3362
  while ((item= it++))
3364
3363
  {
3365
3364
    if ((!item->fixed && item->fix_fields(session, it.ref())) || (item= *(it.ref()))->check_cols(1))
3366
3365
    {
3367
 
      session->getLex()->current_select->is_item_list_lookup= save_is_item_list_lookup;
3368
 
      session->getLex()->allow_sum_func= save_allow_sum_func;
 
3366
      session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
 
3367
      session->lex->allow_sum_func= save_allow_sum_func;
3369
3368
      session->mark_used_columns= save_mark_used_columns;
3370
3369
      return true;
3371
3370
    }
3375
3374
        sum_func_list)
3376
3375
      item->split_sum_func(session, ref_pointer_array, *sum_func_list);
3377
3376
    session->used_tables|= item->used_tables();
3378
 
    session->getLex()->current_select->cur_pos_in_select_list++;
 
3377
    session->lex->current_select->cur_pos_in_select_list++;
3379
3378
  }
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;
 
3379
  session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
 
3380
  session->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
3382
3381
 
3383
 
  session->getLex()->allow_sum_func= save_allow_sum_func;
 
3382
  session->lex->allow_sum_func= save_allow_sum_func;
3384
3383
  session->mark_used_columns= save_mark_used_columns;
3385
3384
  return(test(session->is_error()));
3386
3385
}
3549
3548
 
3550
3549
bool
3551
3550
insert_fields(Session *session, Name_resolution_context *context, const char *db_name,
3552
 
              const char *table_name, List<Item>::iterator *it,
 
3551
              const char *table_name, List_iterator<Item> *it,
3553
3552
              bool )
3554
3553
{
3555
3554
  Field_iterator_table_ref field_iterator;
3588
3587
    assert(tables->is_leaf_for_name_resolution());
3589
3588
 
3590
3589
    if ((table_name && my_strcasecmp(table_alias_charset, table_name, tables->alias)) ||
3591
 
        (db_name && my_strcasecmp(system_charset_info, tables->getSchemaName(),db_name)))
 
3590
        (db_name && strcasecmp(tables->getSchemaName(),db_name)))
3592
3591
      continue;
3593
3592
 
3594
3593
    /*
3656
3655
        session->used_tables|= item->used_tables();
3657
3656
      }
3658
3657
 
3659
 
      session->getLex()->current_select->cur_pos_in_select_list++;
 
3658
      session->lex->current_select->cur_pos_in_select_list++;
3660
3659
    }
3661
3660
    /*
3662
3661
      In case of stored tables, all fields are considered as used,
3709
3708
int Session::setup_conds(TableList *leaves, COND **conds)
3710
3709
{
3711
3710
  Session *session= this;
3712
 
  Select_Lex *select_lex= session->getLex()->current_select;
 
3711
  Select_Lex *select_lex= session->lex->current_select;
3713
3712
  TableList *table= NULL;       // For HP compilers
3714
3713
  void *save_session_marker= session->session_marker;
3715
3714
  /*
3731
3730
  session->session_marker= (void*)1;
3732
3731
  if (*conds)
3733
3732
  {
3734
 
    session->setWhere("where clause");
 
3733
    session->where="where clause";
3735
3734
    if ((!(*conds)->fixed && (*conds)->fix_fields(session, conds)) ||
3736
3735
        (*conds)->check_cols(1))
3737
3736
      goto err_no_arena;
3753
3752
      {
3754
3753
        /* Make a join an a expression */
3755
3754
        session->session_marker= (void*)embedded;
3756
 
        session->setWhere("on clause");
 
3755
        session->where="on clause";
3757
3756
        if ((!embedded->on_expr->fixed && embedded->on_expr->fix_fields(session, &embedded->on_expr)) ||
3758
3757
            embedded->on_expr->check_cols(1))
3759
3758
          goto err_no_arena;
3767
3766
  }
3768
3767
  session->session_marker= save_session_marker;
3769
3768
 
3770
 
  session->getLex()->current_select->is_item_list_lookup= save_is_item_list_lookup;
 
3769
  session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
3771
3770
  return(test(session->is_error()));
3772
3771
 
3773
3772
err_no_arena:
3805
3804
bool
3806
3805
fill_record(Session *session, List<Item> &fields, List<Item> &values, bool ignore_errors)
3807
3806
{
3808
 
  List<Item>::iterator f(fields.begin());
3809
 
  List<Item>::iterator v(values.begin());
 
3807
  List_iterator_fast<Item> f(fields),v(values);
3810
3808
  Item *value;
3811
3809
  Item_field *field;
3812
3810
  Table *table;
3824
3822
    field= static_cast<Item_field *>(f++);
3825
3823
    table= field->field->getTable();
3826
3824
    table->auto_increment_field_not_null= false;
3827
 
    f= fields.begin();
 
3825
    f.rewind();
3828
3826
  }
3829
3827
 
3830
3828
  while ((field= static_cast<Item_field *>(f++)))
3871
3869
 
3872
3870
bool fill_record(Session *session, Field **ptr, List<Item> &values, bool)
3873
3871
{
3874
 
  List<Item>::iterator v(values.begin());
 
3872
  List_iterator_fast<Item> v(values);
3875
3873
  Item *value;
3876
3874
  Table *table= 0;
3877
3875
  Field *field;