~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_base.cc

  • Committer: Olaf van der Spek
  • Date: 2011-03-28 14:32:36 UTC
  • mto: (2257.1.1 build) (2276.1.2 build)
  • mto: This revision was merged to the branch mainline in revision 2258.
  • Revision ID: olafvdspek@gmail.com-20110328143236-4ge1d793iqaktfq0
Common fwd

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"
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/refresh_version.h>
 
64
#include <drizzled/catalog/local.h>
59
65
 
60
66
using namespace std;
61
67
 
62
 
namespace drizzled
63
 
{
 
68
namespace drizzled {
64
69
 
65
70
extern bool volatile shutdown_in_progress;
66
71
 
110
115
    This has to be done to ensure that the table share is removed from
111
116
    the table defintion cache as soon as the last instance is removed
112
117
  */
113
 
  TableIdentifier identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), message::Table::INTERNAL);
114
 
  const TableIdentifier::Key &key(identifier.getKey());
 
118
  identifier::Table identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), message::Table::INTERNAL);
 
119
  const identifier::Table::Key &key(identifier.getKey());
115
120
  TableShare *share= new TableShare(identifier.getType(),
116
121
                                    identifier,
117
122
                                    const_cast<char *>(key.vector()),  static_cast<uint32_t>(table->getShare()->getCacheKeySize()));
118
123
 
119
124
  table->cursor->close();
120
125
  table->db_stat= 0;                            // Mark cursor closed
121
 
  TableShare::release(table->getMutableShare());
 
126
  table::instance::release(table->getMutableShare());
122
127
  table->setShare(share);
123
128
}
124
129
 
144
149
  if (sort.io_cache)
145
150
  {
146
151
    sort.io_cache->close_cached_file();
147
 
    delete sort.io_cache;
148
 
    sort.io_cache= 0;
 
152
    safe_delete(sort.io_cache);
149
153
  }
150
154
}
151
155
 
171
175
  Session *session= this;
172
176
 
173
177
  {
174
 
    table::Cache::singleton().mutex().lock(); /* Optionally lock for remove tables from open_cahe if not in use */
 
178
    boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex()); /* Optionally lock for remove tables from open_cahe if not in use */
175
179
 
176
180
    if (tables == NULL)
177
181
    {
218
222
          after the call to Session::close_old_data_files() i.e. after removal of
219
223
          current thread locks.
220
224
        */
221
 
        for (table::CacheMap::const_iterator iter= table::getCache().begin();
222
 
             iter != table::getCache().end();
223
 
             iter++)
 
225
        BOOST_FOREACH(table::CacheMap::const_reference iter, table::getCache())
224
226
        {
225
 
          Table *table= (*iter).second;
226
 
          if (table->in_use)
227
 
            table->in_use->some_tables_deleted= false;
 
227
          if (iter.second->in_use)
 
228
            iter.second->in_use->some_tables_deleted= false;
228
229
        }
229
230
      }
230
231
    }
233
234
      bool found= false;
234
235
      for (TableList *table= tables; table; table= table->next_local)
235
236
      {
236
 
        TableIdentifier identifier(table->getSchemaName(), table->getTableName());
 
237
        identifier::Table identifier(table->getSchemaName(), table->getTableName());
237
238
        if (table::Cache::singleton().removeTable(session, identifier,
238
239
                                    RTFC_OWNED_BY_Session_FLAG))
239
240
        {
265
266
             iter != table::getCache().end();
266
267
             iter++)
267
268
        {
268
 
          Table *table= (*iter).second;
 
269
          Table *table= iter->second;
269
270
          /* Avoid a self-deadlock. */
270
271
          if (table->in_use == session)
271
272
            continue;
287
288
                                                     (table->open_placeholder && wait_for_placeholders)))
288
289
          {
289
290
            found= true;
290
 
            boost_unique_lock_t scoped(table::Cache::singleton().mutex(), boost::adopt_lock_t());
291
 
            COND_refresh.wait(scoped);
292
 
            scoped.release();
 
291
            COND_refresh.wait(scopedLock);
293
292
            break;
294
293
          }
295
294
        }
299
298
        old locks. This should always succeed (unless some external process
300
299
        has removed the tables)
301
300
      */
302
 
      result= session->reopen_tables(true, true);
 
301
      result= session->reopen_tables();
303
302
 
304
303
      /* Set version for table */
305
304
      for (Table *table= session->open_tables; table ; table= table->getNext())
312
311
          table->getMutableShare()->refreshVersion();
313
312
      }
314
313
    }
315
 
 
316
 
    table::Cache::singleton().mutex().unlock();
317
314
  }
318
315
 
319
316
  if (wait_for_refresh)
329
326
 
330
327
 
331
328
/**
332
 
  move one table to free list 
 
329
  move one table to free list
333
330
*/
334
331
 
335
 
bool Session::free_cached_table()
 
332
bool Session::free_cached_table(boost::mutex::scoped_lock &scopedLock)
336
333
{
337
334
  bool found_old_table= false;
 
335
 
 
336
  (void)scopedLock;
 
337
 
338
338
  table::Concurrent *table= static_cast<table::Concurrent *>(open_tables);
339
339
 
340
340
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
386
386
 
387
387
  while (open_tables)
388
388
  {
389
 
    found_old_table|= free_cached_table();
 
389
    found_old_table|= free_cached_table(scoped_lock);
390
390
  }
391
391
  some_tables_deleted= false;
392
392
 
422
422
{
423
423
  for (; table; table= table->*link )
424
424
  {
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)
 
425
    if ((table->table == 0 || table->table->getShare()->getType() == message::Table::STANDARD) and
 
426
        my_strcasecmp(system_charset_info, table->getSchemaName(), db_name) == 0 and
 
427
        my_strcasecmp(system_charset_info, table->getTableName(), table_name) == 0)
 
428
    {
428
429
      break;
 
430
    }
429
431
  }
430
432
  return table;
431
433
}
517
519
}
518
520
 
519
521
 
520
 
void Open_tables_state::doGetTableNames(const SchemaIdentifier &schema_identifier,
 
522
void Open_tables_state::doGetTableNames(const identifier::Schema &schema_identifier,
521
523
                                        std::set<std::string>& set_of_names)
522
524
{
523
525
  for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
530
532
}
531
533
 
532
534
void Open_tables_state::doGetTableNames(CachedDirectory &,
533
 
                                        const SchemaIdentifier &schema_identifier,
 
535
                                        const identifier::Schema &schema_identifier,
534
536
                                        std::set<std::string> &set_of_names)
535
537
{
536
538
  doGetTableNames(schema_identifier, set_of_names);
537
539
}
538
540
 
539
 
void Open_tables_state::doGetTableIdentifiers(const SchemaIdentifier &schema_identifier,
540
 
                                              TableIdentifier::vector &set_of_identifiers)
 
541
void Open_tables_state::doGetTableIdentifiers(const identifier::Schema &schema_identifier,
 
542
                                              identifier::Table::vector &set_of_identifiers)
541
543
{
542
544
  for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
543
545
  {
544
546
    if (schema_identifier.compare(table->getShare()->getSchemaName()))
545
547
    {
546
 
      set_of_identifiers.push_back(TableIdentifier(table->getShare()->getSchemaName(),
 
548
      set_of_identifiers.push_back(identifier::Table(table->getShare()->getSchemaName(),
547
549
                                                   table->getShare()->getTableName(),
548
550
                                                   table->getShare()->getPath()));
549
551
    }
551
553
}
552
554
 
553
555
void Open_tables_state::doGetTableIdentifiers(CachedDirectory &,
554
 
                                              const SchemaIdentifier &schema_identifier,
555
 
                                              TableIdentifier::vector &set_of_identifiers)
 
556
                                              const identifier::Schema &schema_identifier,
 
557
                                              identifier::Table::vector &set_of_identifiers)
556
558
{
557
559
  doGetTableIdentifiers(schema_identifier, set_of_identifiers);
558
560
}
559
561
 
560
 
bool Open_tables_state::doDoesTableExist(const TableIdentifier &identifier)
 
562
bool Open_tables_state::doDoesTableExist(const identifier::Table &identifier)
561
563
{
562
564
  for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
563
565
  {
573
575
  return false;
574
576
}
575
577
 
576
 
int Open_tables_state::doGetTableDefinition(const TableIdentifier &identifier,
577
 
                                  message::Table &table_proto)
 
578
int Open_tables_state::doGetTableDefinition(const identifier::Table &identifier,
 
579
                                            message::Table &table_proto)
578
580
{
579
581
  for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
580
582
  {
582
584
    {
583
585
      if (identifier.getKey() == table->getShare()->getCacheKey())
584
586
      {
585
 
        table_proto.CopyFrom(*(table->getShare()->getTableProto()));
 
587
        table_proto.CopyFrom(*(table->getShare()->getTableMessage()));
586
588
 
587
589
        return EEXIST;
588
590
      }
592
594
  return ENOENT;
593
595
}
594
596
 
595
 
Table *Open_tables_state::find_temporary_table(const TableIdentifier &identifier)
 
597
Table *Open_tables_state::find_temporary_table(const identifier::Table &identifier)
596
598
{
597
599
  for (Table *table= temporary_tables ; table ; table= table->getNext())
598
600
  {
630
632
  @retval -1  the table is in use by a outer query
631
633
*/
632
634
 
633
 
int Open_tables_state::drop_temporary_table(const drizzled::TableIdentifier &identifier)
 
635
int Open_tables_state::drop_temporary_table(const drizzled::identifier::Table &identifier)
634
636
{
635
637
  Table *table;
636
638
 
662
664
 
663
665
void Session::unlink_open_table(Table *find)
664
666
{
665
 
  const TableIdentifier::Key find_key(find->getShare()->getCacheKey());
 
667
  const identifier::Table::Key find_key(find->getShare()->getCacheKey());
666
668
  Table **prev;
667
669
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
668
670
 
669
671
  /*
670
672
    Note that we need to hold table::Cache::singleton().mutex() while changing the
671
673
    open_tables list. Another thread may work on it.
672
 
    (See: table::Cache::singleton().removeTable(), mysql_wait_completed_table())
 
674
    (See: table::Cache::singleton().removeTable(), wait_completed_table())
673
675
    Closing a MERGE child before the parent would be fatal if the
674
676
    other thread tries to abort the MERGE lock in between.
675
677
  */
716
718
  table that was locked with LOCK TABLES.
717
719
*/
718
720
 
719
 
void Session::drop_open_table(Table *table, const TableIdentifier &identifier)
 
721
void Session::drop_open_table(Table *table, const identifier::Table &identifier)
720
722
{
721
723
  if (table->getShare()->getType())
722
724
  {
730
732
      that something has happened.
731
733
    */
732
734
    unlink_open_table(table);
733
 
    plugin::StorageEngine::dropTable(*this, identifier);
 
735
    (void)plugin::StorageEngine::dropTable(*this, identifier);
734
736
  }
735
737
}
736
738
 
791
793
  case of failure.
792
794
*/
793
795
 
794
 
table::Placeholder *Session::table_cache_insert_placeholder(const drizzled::TableIdentifier &arg)
 
796
table::Placeholder *Session::table_cache_insert_placeholder(const drizzled::identifier::Table &arg)
795
797
{
796
798
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
797
799
 
798
800
  /*
799
801
    Create a table entry with the right key and with an old refresh version
800
802
  */
801
 
  TableIdentifier identifier(arg.getSchemaName(), arg.getTableName(), message::Table::INTERNAL);
 
803
  identifier::Table identifier(arg.getSchemaName(), arg.getTableName(), message::Table::INTERNAL);
802
804
  table::Placeholder *table= new table::Placeholder(this, identifier);
803
805
 
804
806
  if (not table::Cache::singleton().insert(table))
805
807
  {
806
 
    delete table;
 
808
    safe_delete(table);
807
809
 
808
810
    return NULL;
809
811
  }
833
835
  @retval  true   Error occured (OOM)
834
836
  @retval  false  Success. 'table' parameter set according to above rules.
835
837
*/
836
 
bool Session::lock_table_name_if_not_cached(const TableIdentifier &identifier, Table **table)
 
838
bool Session::lock_table_name_if_not_cached(const identifier::Table &identifier, Table **table)
837
839
{
838
 
  const TableIdentifier::Key &key(identifier.getKey());
 
840
  const identifier::Table::Key &key(identifier.getKey());
839
841
 
840
842
  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)  */
841
843
 
842
 
  table::CacheMap::iterator iter;
843
 
 
844
 
  iter= table::getCache().find(key);
845
 
 
846
 
  if (iter != table::getCache().end())
 
844
  if (find_ptr(table::getCache(), key))
847
845
  {
848
846
    *table= 0;
849
847
    return false;
899
897
  const char *alias= table_list->alias;
900
898
 
901
899
  /* Parsing of partitioning information from .frm needs session->lex set up. */
902
 
  assert(lex->is_lex_started);
 
900
  assert(lex().is_lex_started);
903
901
 
904
902
  /* find a unused table in the open table cache */
905
903
  if (refresh)
912
910
  if (getKilled())
913
911
    return NULL;
914
912
 
915
 
  TableIdentifier identifier(table_list->getSchemaName(), table_list->getTableName());
916
 
  const TableIdentifier::Key &key(identifier.getKey());
 
913
  identifier::Table identifier(table_list->getSchemaName(), table_list->getTableName());
 
914
  const identifier::Table::Key &key(identifier.getKey());
917
915
  table::CacheRange ppp;
918
916
 
919
917
  /*
949
947
  {
950
948
    if (flags & DRIZZLE_OPEN_TEMPORARY_ONLY)
951
949
    {
952
 
      my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->getSchemaName(), table_list->getTableName());
 
950
      my_error(ER_TABLE_UNKNOWN, identifier);
953
951
      return NULL;
954
952
    }
955
953
 
977
975
    }
978
976
 
979
977
    /*
980
 
      Before we test the global cache, we test our local session cache.
981
 
    */
982
 
    if (cached_table)
983
 
    {
984
 
      assert(false); /* Not implemented yet */
985
 
    }
986
 
 
987
 
    /*
988
978
      Non pre-locked/LOCK TABLES mode, and the table is not temporary:
989
979
      this is the normal use case.
990
980
      Now we should:
1000
990
    */
1001
991
 
1002
992
    {
1003
 
      table::Cache::singleton().mutex().lock(); /* Lock for FLUSH TABLES for open table */
 
993
      boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex());
1004
994
 
1005
995
      /*
1006
996
        Actually try to find the table in the open_cache.
1015
1005
      ppp= table::getCache().equal_range(key);
1016
1006
 
1017
1007
      table= NULL;
1018
 
      for (table::CacheMap::const_iterator iter= ppp.first;
1019
 
           iter != ppp.second; ++iter, table= NULL)
 
1008
      for (table::CacheMap::const_iterator iter= ppp.first; iter != ppp.second; ++iter, table= NULL)
1020
1009
      {
1021
 
        table= (*iter).second;
 
1010
        table= iter->second;
1022
1011
 
1023
1012
        if (not table->in_use)
1024
1013
          break;
1052
1041
          /* Avoid self-deadlocks by detecting self-dependencies. */
1053
1042
          if (table->open_placeholder && table->in_use == this)
1054
1043
          {
1055
 
            table::Cache::singleton().mutex().unlock();
1056
1044
            my_error(ER_UPDATE_TABLE_USED, MYF(0), table->getShare()->getTableName());
1057
1045
            return NULL;
1058
1046
          }
1087
1075
          {
1088
1076
            /* wait_for_conditionwill unlock table::Cache::singleton().mutex() for us */
1089
1077
            wait_for_condition(table::Cache::singleton().mutex(), COND_refresh);
 
1078
            scopedLock.release();
1090
1079
          }
1091
1080
          else
1092
1081
          {
1093
 
            table::Cache::singleton().mutex().unlock();
 
1082
            scopedLock.unlock();
1094
1083
          }
 
1084
 
1095
1085
          /*
1096
1086
            There is a refresh in progress for this table.
1097
1087
            Signal the caller that it has to try again.
1098
1088
          */
1099
1089
          if (refresh)
1100
1090
            *refresh= true;
 
1091
 
1101
1092
          return NULL;
1102
1093
        }
1103
1094
      }
 
1095
 
1104
1096
      if (table)
1105
1097
      {
1106
1098
        table::getUnused().unlink(static_cast<table::Concurrent *>(table));
1115
1107
 
1116
1108
        if (table_list->isCreate())
1117
1109
        {
1118
 
          TableIdentifier  lock_table_identifier(table_list->getSchemaName(), table_list->getTableName(), message::Table::STANDARD);
 
1110
          identifier::Table  lock_table_identifier(table_list->getSchemaName(), table_list->getTableName(), message::Table::STANDARD);
1119
1111
 
1120
1112
          if (not plugin::StorageEngine::doesTableExist(*this, lock_table_identifier))
1121
1113
          {
1124
1116
            */
1125
1117
            if (!(table= table_cache_insert_placeholder(lock_table_identifier)))
1126
1118
            {
1127
 
              table::Cache::singleton().mutex().unlock();
1128
1119
              return NULL;
1129
1120
            }
1130
1121
            /*
1135
1126
            table->open_placeholder= true;
1136
1127
            table->setNext(open_tables);
1137
1128
            open_tables= table;
1138
 
            table::Cache::singleton().mutex().unlock();
1139
1129
 
1140
1130
            return table ;
1141
1131
          }
1146
1136
        {
1147
1137
          table::Concurrent *new_table= new table::Concurrent;
1148
1138
          table= new_table;
1149
 
          if (new_table == NULL)
1150
 
          {
1151
 
            table::Cache::singleton().mutex().unlock();
1152
 
            return NULL;
1153
 
          }
1154
 
 
1155
1139
          error= new_table->open_unireg_entry(this, alias, identifier);
1156
1140
          if (error != 0)
1157
1141
          {
1158
1142
            delete new_table;
1159
 
            table::Cache::singleton().mutex().unlock();
1160
1143
            return NULL;
1161
1144
          }
1162
1145
          (void)table::Cache::singleton().insert(new_table);
1163
1146
        }
1164
1147
      }
 
1148
    }
1165
1149
 
1166
 
      table::Cache::singleton().mutex().unlock();
1167
 
    }
1168
1150
    if (refresh)
1169
1151
    {
1170
1152
      table->setNext(open_tables); /* Link into simple list */
1222
1204
  the strings are used in a loop even after the share may be freed.
1223
1205
*/
1224
1206
 
1225
 
void Session::close_data_files_and_morph_locks(const TableIdentifier &identifier)
 
1207
void Session::close_data_files_and_morph_locks(const identifier::Table &identifier)
1226
1208
{
1227
1209
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle()); /* Adjust locks at the end of ALTER TABLEL */
1228
1210
 
1272
1254
  @return false in case of success, true - otherwise.
1273
1255
*/
1274
1256
 
1275
 
bool Session::reopen_tables(bool get_locks, bool)
 
1257
bool Session::reopen_tables()
1276
1258
{
1277
1259
  Table *table,*next,**prev;
1278
 
  Table **tables,**tables_ptr;                  // For locks
1279
 
  bool error=0, not_used;
 
1260
  Table **tables= 0;                    // For locks
 
1261
  Table **tables_ptr= 0;                        // For locks
 
1262
  bool error= false;
1280
1263
  const uint32_t flags= DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN |
1281
1264
    DRIZZLE_LOCK_IGNORE_GLOBAL_READ_LOCK |
1282
1265
    DRIZZLE_LOCK_IGNORE_FLUSH;
1285
1268
    return false;
1286
1269
 
1287
1270
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
1288
 
  if (get_locks)
1289
1271
  {
1290
1272
    /*
1291
1273
      The ptr is checked later
1299
1281
    }
1300
1282
    tables= new Table *[opens];
1301
1283
  }
1302
 
  else
1303
 
  {
1304
 
    tables= &open_tables;
1305
 
  }
 
1284
 
1306
1285
  tables_ptr =tables;
1307
1286
 
1308
1287
  prev= &open_tables;
1315
1294
    error= 1;
1316
1295
  }
1317
1296
  *prev=0;
 
1297
 
1318
1298
  if (tables != tables_ptr)                     // Should we get back old locks
1319
1299
  {
1320
1300
    DrizzleLock *local_lock;
1325
1305
    */
1326
1306
    some_tables_deleted= false;
1327
1307
 
1328
 
    if ((local_lock= lockTables(tables, (uint32_t) (tables_ptr - tables),
1329
 
                                       flags, &not_used)))
 
1308
    if ((local_lock= lockTables(tables, (uint32_t) (tables_ptr - tables), flags)))
1330
1309
    {
1331
1310
      /* unused */
1332
1311
    }
1342
1321
    }
1343
1322
  }
1344
1323
 
1345
 
  if (get_locks && tables)
1346
 
    delete [] tables;
 
1324
  delete [] tables;
1347
1325
 
1348
1326
  locking::broadcast_refresh();
1349
1327
 
1350
 
  return(error);
 
1328
  return error;
1351
1329
}
1352
1330
 
1353
1331
 
1378
1356
    */
1379
1357
    if (table->needs_reopen_or_name_lock())
1380
1358
    {
1381
 
      found=1;
 
1359
      found= true;
1382
1360
      if (table->db_stat)
1383
1361
      {
1384
1362
        if (morph_locks)
1437
1415
}
1438
1416
 
1439
1417
 
1440
 
/* Wait until all used tables are refreshed */
1441
 
 
1442
 
bool wait_for_tables(Session *session)
1443
 
{
1444
 
  bool result;
1445
 
 
1446
 
  session->set_proc_info("Waiting for tables");
1447
 
  {
1448
 
    boost_unique_lock_t lock(table::Cache::singleton().mutex());
1449
 
    while (not session->getKilled())
1450
 
    {
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))
1454
 
      {
1455
 
        break;
1456
 
      }
1457
 
      COND_refresh.wait(lock);
1458
 
    }
1459
 
    if (session->getKilled())
1460
 
      result= true;                                     // aborted
1461
 
    else
1462
 
    {
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);
1467
 
    }
1468
 
  }
1469
 
  session->set_proc_info(0);
1470
 
 
1471
 
  return result;
1472
 
}
1473
 
 
1474
 
 
1475
1418
/*
1476
1419
  drop tables from locked list
1477
1420
 
1496
1439
*/
1497
1440
 
1498
1441
 
1499
 
Table *drop_locked_tables(Session *session, const drizzled::TableIdentifier &identifier)
 
1442
Table *drop_locked_tables(Session *session, const drizzled::identifier::Table &identifier)
1500
1443
{
1501
1444
  Table *table,*next,**prev, *found= 0;
1502
1445
  prev= &session->open_tables;
1504
1447
  /*
1505
1448
    Note that we need to hold table::Cache::singleton().mutex() while changing the
1506
1449
    open_tables list. Another thread may work on it.
1507
 
    (See: table::Cache::singleton().removeTable(), mysql_wait_completed_table())
 
1450
    (See: table::Cache::singleton().removeTable(), wait_completed_table())
1508
1451
    Closing a MERGE child before the parent would be fatal if the
1509
1452
    other thread tries to abort the MERGE lock in between.
1510
1453
  */
1538
1481
    }
1539
1482
  }
1540
1483
  *prev=0;
 
1484
 
1541
1485
  if (found)
1542
1486
    locking::broadcast_refresh();
1543
1487
 
1544
 
  return(found);
 
1488
  return found;
1545
1489
}
1546
1490
 
1547
1491
 
1551
1495
  other threads trying to get the lock.
1552
1496
*/
1553
1497
 
1554
 
void abort_locked_tables(Session *session, const drizzled::TableIdentifier &identifier)
 
1498
void abort_locked_tables(Session *session, const drizzled::identifier::Table &identifier)
1555
1499
{
1556
1500
  Table *table;
1557
1501
  for (table= session->open_tables; table ; table= table->getNext())
1560
1504
    {
1561
1505
      /* If MERGE child, forward lock handling to parent. */
1562
1506
      session->abortLock(table);
 
1507
      assert(0);
1563
1508
      break;
1564
1509
    }
1565
1510
  }
1632
1577
     * to see if it exists so that an unauthorized user cannot phish for
1633
1578
     * table/schema information via error messages
1634
1579
     */
1635
 
    TableIdentifier the_table(tables->getSchemaName(), tables->getTableName());
1636
 
    if (not plugin::Authorization::isAuthorized(user(), the_table))
 
1580
    identifier::Table the_table(tables->getSchemaName(), tables->getTableName());
 
1581
    if (not plugin::Authorization::isAuthorized(*user(), the_table))
1637
1582
    {
1638
1583
      result= -1;                               // Fatal error
1639
1584
      break;
1730
1675
 
1731
1676
  set_proc_info("Opening table");
1732
1677
  current_tablenr= 0;
1733
 
  while (!(table= openTable(table_list, &refresh)) &&
1734
 
         refresh)
1735
 
    ;
 
1678
  while (!(table= openTable(table_list, &refresh)) && refresh) ;
1736
1679
 
1737
1680
  if (table)
1738
1681
  {
1741
1684
 
1742
1685
    assert(lock == 0);  // You must lock everything at once
1743
1686
    if ((table->reginfo.lock_type= lock_type) != TL_UNLOCK)
1744
 
      if (! (lock= lockTables(&table_list->table, 1, 0, &refresh)))
1745
 
        table= 0;
 
1687
    {
 
1688
      if (not (lock= lockTables(&table_list->table, 1, 0)))
 
1689
        table= NULL;
 
1690
    }
1746
1691
  }
1747
1692
 
1748
1693
  set_proc_info(0);
1796
1741
  Table **start,**ptr;
1797
1742
  uint32_t lock_flag= DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN;
1798
1743
 
1799
 
  if (!(ptr=start=(Table**) session->alloc(sizeof(Table*)*count)))
 
1744
  if (!(ptr=start=(Table**) session->getMemRoot()->allocate(sizeof(Table*)*count)))
1800
1745
    return -1;
 
1746
 
1801
1747
  for (table= tables; table; table= table->next_global)
1802
1748
  {
1803
1749
    if (!table->placeholder())
1804
1750
      *(ptr++)= table->table;
1805
1751
  }
1806
1752
 
1807
 
  if (!(session->lock= session->lockTables(start, (uint32_t) (ptr - start), lock_flag, need_reopen)))
 
1753
  if (not (session->lock= session->lockTables(start, (uint32_t) (ptr - start), lock_flag)))
1808
1754
  {
1809
1755
    return -1;
1810
1756
  }
1833
1779
#  Table object
1834
1780
*/
1835
1781
 
1836
 
Table *Open_tables_state::open_temporary_table(const TableIdentifier &identifier,
 
1782
Table *Open_tables_state::open_temporary_table(const identifier::Table &identifier,
1837
1783
                                               bool link_in_list)
1838
1784
{
1839
1785
  assert(identifier.isTmp());
1841
1787
 
1842
1788
  table::Temporary *new_tmp_table= new table::Temporary(identifier.getType(),
1843
1789
                                                        identifier,
1844
 
                                                        const_cast<char *>(const_cast<TableIdentifier&>(identifier).getPath().c_str()),
 
1790
                                                        const_cast<char *>(const_cast<identifier::Table&>(identifier).getPath().c_str()),
1845
1791
                                                        static_cast<uint32_t>(identifier.getPath().length()));
1846
1792
  if (not new_tmp_table)
1847
1793
    return NULL;
1963
1909
                           const char *name, uint32_t , Item **,
1964
1910
                           bool, TableList **actual_table)
1965
1911
{
1966
 
  List_iterator_fast<Natural_join_column>
1967
 
    field_it(*(table_ref->join_columns));
 
1912
  List<Natural_join_column>::iterator
 
1913
    field_it(table_ref->join_columns->begin());
1968
1914
  Natural_join_column *nj_col, *curr_nj_col;
1969
1915
  Field *found_field;
1970
1916
 
1978
1924
    {
1979
1925
      if (nj_col)
1980
1926
      {
1981
 
        my_error(ER_NON_UNIQ_ERROR, MYF(0), name, session->where);
 
1927
        my_error(ER_NON_UNIQ_ERROR, MYF(0), name, session->where());
1982
1928
        return NULL;
1983
1929
      }
1984
1930
      nj_col= curr_nj_col;
2179
2125
    */
2180
2126
    if (table_name && table_name[0])
2181
2127
    {
2182
 
      List_iterator<TableList> it(table_list->getNestedJoin()->join_list);
 
2128
      List<TableList>::iterator it(table_list->getNestedJoin()->join_list.begin());
2183
2129
      TableList *table;
2184
2130
      while ((table= it++))
2185
2131
      {
2329
2275
        fields.
2330
2276
      */
2331
2277
      {
2332
 
        Select_Lex *current_sel= session->lex->current_select;
 
2278
        Select_Lex *current_sel= session->lex().current_select;
2333
2279
        Select_Lex *last_select= table_ref->select_lex;
2334
2280
        /*
2335
2281
          If the field was an outer referencee, mark all selects using this
2375
2321
      */
2376
2322
      item->cached_table= found ?  0 : actual_table;
2377
2323
 
2378
 
      assert(session->where);
 
2324
      assert(session->where());
2379
2325
      /*
2380
2326
        If we found a fully qualified field we return it directly as it can't
2381
2327
        have duplicates.
2388
2334
        if (report_error == REPORT_ALL_ERRORS ||
2389
2335
            report_error == IGNORE_EXCEPT_NON_UNIQUE)
2390
2336
          my_error(ER_NON_UNIQ_ERROR, MYF(0),
2391
 
                   table_name ? item->full_name() : name, session->where);
 
2337
                   table_name ? item->full_name() : name, session->where());
2392
2338
        return (Field*) 0;
2393
2339
      }
2394
2340
      found= cur_field;
2421
2367
      strcat(buff, table_name);
2422
2368
      table_name=buff;
2423
2369
    }
2424
 
    my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, session->where);
 
2370
    my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, session->where());
2425
2371
  }
2426
2372
  else
2427
2373
  {
2428
2374
    if (report_error == REPORT_ALL_ERRORS ||
2429
2375
        report_error == REPORT_EXCEPT_NON_UNIQUE)
2430
 
      my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), session->where);
 
2376
      my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), session->where());
2431
2377
    else
2432
2378
      found= not_found_field;
2433
2379
  }
2478
2424
                  find_item_error_report_type report_error,
2479
2425
                  enum_resolution_type *resolution)
2480
2426
{
2481
 
  List_iterator<Item> li(items);
 
2427
  List<Item>::iterator li(items.begin());
2482
2428
  Item **found=0, **found_unaliased= 0, *item;
2483
2429
  const char *db_name=0;
2484
2430
  const char *field_name=0;
2554
2500
            */
2555
2501
            if (report_error != IGNORE_ERRORS)
2556
2502
              my_error(ER_NON_UNIQ_ERROR, MYF(0),
2557
 
                       find->full_name(), session->where);
 
2503
                       find->full_name(), session->where());
2558
2504
            return (Item**) 0;
2559
2505
          }
2560
2506
          found_unaliased= li.ref();
2585
2531
              continue;                           // Same field twice
2586
2532
            if (report_error != IGNORE_ERRORS)
2587
2533
              my_error(ER_NON_UNIQ_ERROR, MYF(0),
2588
 
                       find->full_name(), session->where);
 
2534
                       find->full_name(), session->where());
2589
2535
            return (Item**) 0;
2590
2536
          }
2591
2537
          found= li.ref();
2637
2583
    {
2638
2584
      if (report_error != IGNORE_ERRORS)
2639
2585
        my_error(ER_NON_UNIQ_ERROR, MYF(0),
2640
 
                 find->full_name(), session->where);
 
2586
                 find->full_name(), session->where());
2641
2587
      return (Item **) 0;
2642
2588
    }
2643
2589
    if (found_unaliased)
2653
2599
  {
2654
2600
    if (report_error == REPORT_ALL_ERRORS)
2655
2601
      my_error(ER_BAD_FIELD_ERROR, MYF(0),
2656
 
               find->full_name(), session->where);
 
2602
               find->full_name(), session->where());
2657
2603
    return (Item **) 0;
2658
2604
  }
2659
2605
  else
2681
2627
static bool
2682
2628
test_if_string_in_list(const char *find, List<String> *str_list)
2683
2629
{
2684
 
  List_iterator<String> str_list_it(*str_list);
 
2630
  List<String>::iterator str_list_it(str_list->begin());
2685
2631
  String *curr_str;
2686
2632
  size_t find_length= strlen(find);
2687
2633
  while ((curr_str= str_list_it++))
2824
2770
        if (cur_nj_col_2->is_common ||
2825
2771
            (found && (!using_fields || is_using_column_1)))
2826
2772
        {
2827
 
          my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1, session->where);
 
2773
          my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1, session->where());
2828
2774
          return(result);
2829
2775
        }
2830
2776
        nj_col_2= cur_nj_col_2;
3012
2958
    columns. If this is not the case, report the first one that was
3013
2959
    not found in an error.
3014
2960
  */
3015
 
  if (using_fields && found_using_fields < using_fields->elements)
 
2961
  if (using_fields && found_using_fields < using_fields->size())
3016
2962
  {
3017
2963
    String *using_field_name;
3018
 
    List_iterator_fast<String> using_fields_it(*using_fields);
 
2964
    List<String>::iterator using_fields_it(using_fields->begin());
3019
2965
    while ((using_field_name= using_fields_it++))
3020
2966
    {
3021
2967
      const char *using_field_name_ptr= using_field_name->c_ptr();
3022
 
      List_iterator_fast<Natural_join_column>
3023
 
        it(*(natural_using_join->join_columns));
 
2968
      List<Natural_join_column>::iterator
 
2969
        it(natural_using_join->join_columns->begin());
3024
2970
      Natural_join_column *common_field;
3025
2971
 
3026
2972
      for (;;)
3029
2975
        if (!(common_field= it++))
3030
2976
        {
3031
2977
          my_error(ER_BAD_FIELD_ERROR, MYF(0), using_field_name_ptr,
3032
 
                   session->where);
 
2978
                   session->where());
3033
2979
          return(result);
3034
2980
        }
3035
2981
        if (!my_strcasecmp(system_charset_info,
3052
2998
    }
3053
2999
  }
3054
3000
 
3055
 
  if (non_join_columns->elements > 0)
 
3001
  if (non_join_columns->size() > 0)
3056
3002
    natural_using_join->join_columns->concat(non_join_columns);
3057
3003
  natural_using_join->is_join_columns_complete= true;
3058
3004
 
3102
3048
  /* Call the procedure recursively for each nested table reference. */
3103
3049
  if (table_ref->getNestedJoin())
3104
3050
  {
3105
 
    List_iterator_fast<TableList> nested_it(table_ref->getNestedJoin()->join_list);
 
3051
    List<TableList>::iterator nested_it(table_ref->getNestedJoin()->join_list.begin());
3106
3052
    TableList *same_level_left_neighbor= nested_it++;
3107
3053
    TableList *same_level_right_neighbor= NULL;
3108
3054
    /* Left/right-most neighbors, possibly at higher levels in the join tree. */
3127
3073
          cur_table_ref->outer_join & JOIN_TYPE_RIGHT)
3128
3074
      {
3129
3075
        /* This can happen only for JOIN ... ON. */
3130
 
        assert(table_ref->getNestedJoin()->join_list.elements == 2);
 
3076
        assert(table_ref->getNestedJoin()->join_list.size() == 2);
3131
3077
        std::swap(same_level_left_neighbor, cur_table_ref);
3132
3078
      }
3133
3079
 
3155
3101
  if (table_ref->is_natural_join)
3156
3102
  {
3157
3103
    assert(table_ref->getNestedJoin() &&
3158
 
           table_ref->getNestedJoin()->join_list.elements == 2);
3159
 
    List_iterator_fast<TableList> operand_it(table_ref->getNestedJoin()->join_list);
 
3104
           table_ref->getNestedJoin()->join_list.size() == 2);
 
3105
    List<TableList>::iterator operand_it(table_ref->getNestedJoin()->join_list.begin());
3160
3106
    /*
3161
3107
      Notice that the order of join operands depends on whether table_ref
3162
3108
      represents a LEFT or a RIGHT join. In a RIGHT join, the operands are
3252
3198
                                         List<TableList> *from_clause,
3253
3199
                                         Name_resolution_context *context)
3254
3200
{
3255
 
  session->where= "from clause";
3256
 
  if (from_clause->elements == 0)
 
3201
  session->setWhere("from clause");
 
3202
  if (from_clause->size() == 0)
3257
3203
    return false; /* We come here in the case of UNIONs. */
3258
3204
 
3259
 
  List_iterator_fast<TableList> table_ref_it(*from_clause);
 
3205
  List<TableList>::iterator table_ref_it(from_clause->begin());
3260
3206
  TableList *table_ref; /* Current table reference. */
3261
3207
  /* Table reference to the left of the current. */
3262
3208
  TableList *left_neighbor;
3306
3252
    return 0;
3307
3253
 
3308
3254
  Item *item;
3309
 
  List_iterator<Item> it(fields);
 
3255
  List<Item>::iterator it(fields.begin());
3310
3256
 
3311
 
  session->lex->current_select->cur_pos_in_select_list= 0;
 
3257
  session->lex().current_select->cur_pos_in_select_list= 0;
3312
3258
  while (wild_num && (item= it++))
3313
3259
  {
3314
3260
    if (item->type() == Item::FIELD_ITEM &&
3316
3262
        ((Item_field*) item)->field_name[0] == '*' &&
3317
3263
        !((Item_field*) item)->field)
3318
3264
    {
3319
 
      uint32_t elem= fields.elements;
 
3265
      uint32_t elem= fields.size();
3320
3266
      bool any_privileges= ((Item_field *) item)->any_privileges;
3321
 
      Item_subselect *subsel= session->lex->current_select->master_unit()->item;
 
3267
      Item_subselect *subsel= session->lex().current_select->master_unit()->item;
3322
3268
      if (subsel &&
3323
3269
          subsel->substype() == Item_subselect::EXISTS_SUBS)
3324
3270
      {
3344
3290
          Because of this we have to update the element count also for this
3345
3291
          list after expanding the '*' entry.
3346
3292
        */
3347
 
        sum_func_list->elements+= fields.elements - elem;
 
3293
        sum_func_list->set_size(sum_func_list->size() + fields.size() - elem);
3348
3294
      }
3349
3295
      wild_num--;
3350
3296
    }
3351
3297
    else
3352
 
      session->lex->current_select->cur_pos_in_select_list++;
 
3298
      session->lex().current_select->cur_pos_in_select_list++;
3353
3299
  }
3354
 
  session->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
 
3300
  session->lex().current_select->cur_pos_in_select_list= UNDEF_POS;
3355
3301
 
3356
3302
  return 0;
3357
3303
}
3366
3312
{
3367
3313
  register Item *item;
3368
3314
  enum_mark_columns save_mark_used_columns= session->mark_used_columns;
3369
 
  nesting_map save_allow_sum_func= session->lex->allow_sum_func;
3370
 
  List_iterator<Item> it(fields);
 
3315
  nesting_map save_allow_sum_func= session->lex().allow_sum_func;
 
3316
  List<Item>::iterator it(fields.begin());
3371
3317
  bool save_is_item_list_lookup;
3372
3318
 
3373
3319
  session->mark_used_columns= mark_used_columns;
3374
3320
  if (allow_sum_func)
3375
 
    session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
3376
 
  session->where= Session::DEFAULT_WHERE;
3377
 
  save_is_item_list_lookup= session->lex->current_select->is_item_list_lookup;
3378
 
  session->lex->current_select->is_item_list_lookup= 0;
 
3321
    session->lex().allow_sum_func|= 1 << session->lex().current_select->nest_level;
 
3322
  session->setWhere(Session::DEFAULT_WHERE);
 
3323
  save_is_item_list_lookup= session->lex().current_select->is_item_list_lookup;
 
3324
  session->lex().current_select->is_item_list_lookup= 0;
3379
3325
 
3380
3326
  /*
3381
3327
    To prevent fail on forward lookup we fill it with zerows,
3385
3331
    There is other way to solve problem: fill array with pointers to list,
3386
3332
    but it will be slower.
3387
3333
 
3388
 
TODO: remove it when (if) we made one list for allfields and
3389
 
ref_pointer_array
 
3334
    TODO-> remove it when (if) we made one list for allfields and ref_pointer_array
3390
3335
  */
3391
3336
  if (ref_pointer_array)
3392
 
    memset(ref_pointer_array, 0, sizeof(Item *) * fields.elements);
 
3337
  {
 
3338
    memset(ref_pointer_array, 0, sizeof(Item *) * fields.size());
 
3339
  }
3393
3340
 
3394
3341
  Item **ref= ref_pointer_array;
3395
 
  session->lex->current_select->cur_pos_in_select_list= 0;
 
3342
  session->lex().current_select->cur_pos_in_select_list= 0;
3396
3343
  while ((item= it++))
3397
3344
  {
3398
3345
    if ((!item->fixed && item->fix_fields(session, it.ref())) || (item= *(it.ref()))->check_cols(1))
3399
3346
    {
3400
 
      session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
3401
 
      session->lex->allow_sum_func= save_allow_sum_func;
 
3347
      session->lex().current_select->is_item_list_lookup= save_is_item_list_lookup;
 
3348
      session->lex().allow_sum_func= save_allow_sum_func;
3402
3349
      session->mark_used_columns= save_mark_used_columns;
3403
3350
      return true;
3404
3351
    }
3408
3355
        sum_func_list)
3409
3356
      item->split_sum_func(session, ref_pointer_array, *sum_func_list);
3410
3357
    session->used_tables|= item->used_tables();
3411
 
    session->lex->current_select->cur_pos_in_select_list++;
 
3358
    session->lex().current_select->cur_pos_in_select_list++;
3412
3359
  }
3413
 
  session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
3414
 
  session->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
 
3360
  session->lex().current_select->is_item_list_lookup= save_is_item_list_lookup;
 
3361
  session->lex().current_select->cur_pos_in_select_list= UNDEF_POS;
3415
3362
 
3416
 
  session->lex->allow_sum_func= save_allow_sum_func;
 
3363
  session->lex().allow_sum_func= save_allow_sum_func;
3417
3364
  session->mark_used_columns= save_mark_used_columns;
3418
3365
  return(test(session->is_error()));
3419
3366
}
3582
3529
 
3583
3530
bool
3584
3531
insert_fields(Session *session, Name_resolution_context *context, const char *db_name,
3585
 
              const char *table_name, List_iterator<Item> *it,
 
3532
              const char *table_name, List<Item>::iterator *it,
3586
3533
              bool )
3587
3534
{
3588
3535
  Field_iterator_table_ref field_iterator;
3621
3568
    assert(tables->is_leaf_for_name_resolution());
3622
3569
 
3623
3570
    if ((table_name && my_strcasecmp(table_alias_charset, table_name, tables->alias)) ||
3624
 
        (db_name && strcasecmp(tables->getSchemaName(),db_name)))
 
3571
        (db_name && my_strcasecmp(system_charset_info, tables->getSchemaName(),db_name)))
3625
3572
      continue;
3626
3573
 
3627
3574
    /*
3685
3632
        }
3686
3633
      }
3687
3634
      else
 
3635
      {
3688
3636
        session->used_tables|= item->used_tables();
3689
 
      session->lex->current_select->cur_pos_in_select_list++;
 
3637
      }
 
3638
 
 
3639
      session->lex().current_select->cur_pos_in_select_list++;
3690
3640
    }
3691
3641
    /*
3692
3642
      In case of stored tables, all fields are considered as used,
3705
3655
    qualified '*', and all columns were coalesced, we have to give a more
3706
3656
    meaningful message than ER_BAD_TABLE_ERROR.
3707
3657
  */
3708
 
  if (!table_name)
 
3658
  if (not table_name)
 
3659
  {
3709
3660
    my_message(ER_NO_TABLES_USED, ER(ER_NO_TABLES_USED), MYF(0));
 
3661
  }
3710
3662
  else
 
3663
  {
3711
3664
    my_error(ER_BAD_TABLE_ERROR, MYF(0), table_name);
 
3665
  }
3712
3666
 
3713
3667
  return true;
3714
3668
}
3735
3689
int Session::setup_conds(TableList *leaves, COND **conds)
3736
3690
{
3737
3691
  Session *session= this;
3738
 
  Select_Lex *select_lex= session->lex->current_select;
 
3692
  Select_Lex *select_lex= session->lex().current_select;
3739
3693
  TableList *table= NULL;       // For HP compilers
3740
3694
  void *save_session_marker= session->session_marker;
3741
3695
  /*
3757
3711
  session->session_marker= (void*)1;
3758
3712
  if (*conds)
3759
3713
  {
3760
 
    session->where="where clause";
 
3714
    session->setWhere("where clause");
3761
3715
    if ((!(*conds)->fixed && (*conds)->fix_fields(session, conds)) ||
3762
3716
        (*conds)->check_cols(1))
3763
3717
      goto err_no_arena;
3779
3733
      {
3780
3734
        /* Make a join an a expression */
3781
3735
        session->session_marker= (void*)embedded;
3782
 
        session->where="on clause";
 
3736
        session->setWhere("on clause");
3783
3737
        if ((!embedded->on_expr->fixed && embedded->on_expr->fix_fields(session, &embedded->on_expr)) ||
3784
3738
            embedded->on_expr->check_cols(1))
3785
3739
          goto err_no_arena;
3788
3742
      embedding= embedded->getEmbedding();
3789
3743
    }
3790
3744
    while (embedding &&
3791
 
           embedding->getNestedJoin()->join_list.head() == embedded);
 
3745
           &embedding->getNestedJoin()->join_list.front() == embedded);
3792
3746
 
3793
3747
  }
3794
3748
  session->session_marker= save_session_marker;
3795
3749
 
3796
 
  session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
 
3750
  session->lex().current_select->is_item_list_lookup= save_is_item_list_lookup;
3797
3751
  return(test(session->is_error()));
3798
3752
 
3799
3753
err_no_arena:
3831
3785
bool
3832
3786
fill_record(Session *session, List<Item> &fields, List<Item> &values, bool ignore_errors)
3833
3787
{
3834
 
  List_iterator_fast<Item> f(fields),v(values);
 
3788
  List<Item>::iterator f(fields.begin());
 
3789
  List<Item>::iterator v(values.begin());
3835
3790
  Item *value;
3836
3791
  Item_field *field;
3837
3792
  Table *table;
3840
3795
    Reset the table->auto_increment_field_not_null as it is valid for
3841
3796
    only one row.
3842
3797
  */
3843
 
  if (fields.elements)
 
3798
  if (fields.size())
3844
3799
  {
3845
3800
    /*
3846
3801
      On INSERT or UPDATE fields are checked to be from the same table,
3849
3804
    field= static_cast<Item_field *>(f++);
3850
3805
    table= field->field->getTable();
3851
3806
    table->auto_increment_field_not_null= false;
3852
 
    f.rewind();
 
3807
    f= fields.begin();
3853
3808
  }
3854
3809
 
3855
3810
  while ((field= static_cast<Item_field *>(f++)))
3896
3851
 
3897
3852
bool fill_record(Session *session, Field **ptr, List<Item> &values, bool)
3898
3853
{
3899
 
  List_iterator_fast<Item> v(values);
 
3854
  List<Item>::iterator v(values.begin());
3900
3855
  Item *value;
3901
3856
  Table *table= 0;
3902
3857
  Field *field;
3914
3869
    table= (*ptr)->getTable();
3915
3870
    table->auto_increment_field_not_null= false;
3916
3871
  }
 
3872
 
3917
3873
  while ((field = *ptr++) && ! session->is_error())
3918
3874
  {
3919
3875
    value=v++;
3920
3876
    table= field->getTable();
 
3877
 
3921
3878
    if (field == table->next_number_field)
3922
3879
      table->auto_increment_field_not_null= true;
 
3880
 
3923
3881
    if (value->save_in_field(field, 0) < 0)
3924
3882
    {
3925
3883
      if (table)
3935
3893
 
3936
3894
bool drizzle_rm_tmp_tables()
3937
3895
{
3938
 
  Session *session;
3939
3896
 
3940
3897
  assert(drizzle_tmpdir.size());
 
3898
  Session::shared_ptr session= Session::make_shared(plugin::Listen::getNullClient(), catalog::local());
3941
3899
 
3942
 
  if (!(session= new Session(plugin::Listen::getNullClient())))
 
3900
  if (not session)
3943
3901
    return true;
3944
 
  session->thread_stack= (char*) &session;
 
3902
  session->thread_stack= (char*) session.get();
3945
3903
  session->storeGlobals();
3946
3904
 
3947
3905
  plugin::StorageEngine::removeLostTemporaryTables(*session, drizzle_tmpdir.c_str());
3948
3906
 
3949
 
  delete session;
3950
 
 
3951
3907
  return false;
3952
3908
}
3953
3909