~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_base.cc

Merge Monty - Added inter-plugin dependencies for controlling plugin load order

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/charset.h>
52
 
#include <drizzled/pthread_globals.h>
53
 
#include <drizzled/internal/iocache.h>
54
 
#include <drizzled/drizzled.h>
55
 
#include <drizzled/plugin/authorization.h>
56
 
#include <drizzled/table/temporary.h>
57
 
#include <drizzled/table/placeholder.h>
58
 
#include <drizzled/table/unused.h>
59
 
#include <drizzled/plugin/storage_engine.h>
60
 
#include <drizzled/session.h>
61
 
#include <drizzled/item/subselect.h>
62
 
#include <drizzled/sql_lex.h>
63
 
#include <drizzled/catalog/local.h>
64
 
#include <drizzled/open_tables_state.h>
65
 
#include <drizzled/table/cache.h>
 
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"
66
59
 
67
60
using namespace std;
68
61
 
69
 
namespace drizzled {
 
62
namespace drizzled
 
63
{
70
64
 
71
65
extern bool volatile shutdown_in_progress;
72
66
 
82
76
 
83
77
void table_cache_free(void)
84
78
{
85
 
  g_refresh_version++;                          // Force close of open tables
 
79
  refresh_version++;                            // Force close of open tables
86
80
 
87
81
  table::getUnused().clear();
88
82
  table::getCache().clear();
150
144
  if (sort.io_cache)
151
145
  {
152
146
    sort.io_cache->close_cached_file();
153
 
    safe_delete(sort.io_cache);
 
147
    delete sort.io_cache;
 
148
    sort.io_cache= 0;
154
149
  }
155
150
}
156
151
 
160
155
 
161
156
  @param session Thread context (may be NULL)
162
157
  @param tables List of tables to remove from the cache
163
 
  @param have_lock If table::Cache::mutex() is locked
 
158
  @param have_lock If table::Cache::singleton().mutex() is locked
164
159
  @param wait_for_refresh Wait for a impending flush
165
160
  @param wait_for_placeholders Wait for tables being reopened so that the GRL
166
161
  won't proceed while write-locked tables are being reopened by other
176
171
  Session *session= this;
177
172
 
178
173
  {
179
 
    boost::mutex::scoped_lock scopedLock(table::Cache::mutex()); /* Optionally lock for remove tables from open_cahe if not in use */
180
 
    if (not tables)
 
174
    boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex()); /* Optionally lock for remove tables from open_cahe if not in use */
 
175
 
 
176
    if (tables == NULL)
181
177
    {
182
 
      g_refresh_version++;                              // Force close of open tables
 
178
      refresh_version++;                                // Force close of open tables
 
179
 
183
180
      table::getUnused().clear();
 
181
 
 
182
      if (wait_for_refresh)
 
183
      {
 
184
        /*
 
185
          Other threads could wait in a loop in open_and_lock_tables(),
 
186
          trying to lock one or more of our tables.
 
187
 
 
188
          If they wait for the locks in thr_multi_lock(), their lock
 
189
          request is aborted. They loop in open_and_lock_tables() and
 
190
          enter open_table(). Here they notice the table is refreshed and
 
191
          wait for COND_refresh. Then they loop again in
 
192
          openTablesLock() and this time open_table() succeeds. At
 
193
          this moment, if we (the FLUSH TABLES thread) are scheduled and
 
194
          on another FLUSH TABLES enter close_cached_tables(), they could
 
195
          awake while we sleep below, waiting for others threads (us) to
 
196
          close their open tables. If this happens, the other threads
 
197
          would find the tables unlocked. They would get the locks, one
 
198
          after the other, and could do their destructive work. This is an
 
199
          issue if we have LOCK TABLES in effect.
 
200
 
 
201
          The problem is that the other threads passed all checks in
 
202
          open_table() before we refresh the table.
 
203
 
 
204
          The fix for this problem is to set some_tables_deleted for all
 
205
          threads with open tables. These threads can still get their
 
206
          locks, but will immediately release them again after checking
 
207
          this variable. They will then loop in openTablesLock()
 
208
          again. There they will wait until we update all tables version
 
209
          below.
 
210
 
 
211
          Setting some_tables_deleted is done by table::Cache::singleton().removeTable()
 
212
          in the other branch.
 
213
 
 
214
          In other words (reviewer suggestion): You need this setting of
 
215
          some_tables_deleted for the case when table was opened and all
 
216
          related checks were passed before incrementing refresh_version
 
217
          (which you already have) but attempt to lock the table happened
 
218
          after the call to Session::close_old_data_files() i.e. after removal of
 
219
          current thread locks.
 
220
        */
 
221
        for (table::CacheMap::const_iterator iter= table::getCache().begin();
 
222
             iter != table::getCache().end();
 
223
             iter++)
 
224
        {
 
225
          Table *table= (*iter).second;
 
226
          if (table->in_use)
 
227
            table->in_use->some_tables_deleted= false;
 
228
        }
 
229
      }
184
230
    }
185
231
    else
186
232
    {
187
233
      bool found= false;
188
234
      for (TableList *table= tables; table; table= table->next_local)
189
235
      {
190
 
        if (table::Cache::removeTable(*session, identifier::Table(table->getSchemaName(), table->getTableName()), RTFC_OWNED_BY_Session_FLAG))
 
236
        identifier::Table identifier(table->getSchemaName(), table->getTableName());
 
237
        if (table::Cache::singleton().removeTable(session, identifier,
 
238
                                    RTFC_OWNED_BY_Session_FLAG))
191
239
        {
192
240
          found= true;
193
241
        }
202
250
        If there is any table that has a lower refresh_version, wait until
203
251
        this is closed (or this thread is killed) before returning
204
252
      */
205
 
      session->mysys_var->current_mutex= &table::Cache::mutex();
 
253
      session->mysys_var->current_mutex= &table::Cache::singleton().mutex();
206
254
      session->mysys_var->current_cond= &COND_refresh;
207
255
      session->set_proc_info("Flushing tables");
208
256
 
217
265
             iter != table::getCache().end();
218
266
             iter++)
219
267
        {
220
 
          Table *table= iter->second;
 
268
          Table *table= (*iter).second;
221
269
          /* Avoid a self-deadlock. */
222
270
          if (table->in_use == session)
223
271
            continue;
252
300
      result= session->reopen_tables();
253
301
 
254
302
      /* Set version for table */
255
 
      for (Table *table= session->open_tables.open_tables_; table ; table= table->getNext())
 
303
      for (Table *table= session->open_tables; table ; table= table->getNext())
256
304
      {
257
305
        /*
258
306
          Preserve the version (0) of write locked tables so that a impending
266
314
 
267
315
  if (wait_for_refresh)
268
316
  {
269
 
    boost::mutex::scoped_lock scopedLock(session->mysys_var->mutex);
 
317
    boost_unique_lock_t scopedLock(session->mysys_var->mutex);
270
318
    session->mysys_var->current_mutex= 0;
271
319
    session->mysys_var->current_cond= 0;
272
320
    session->set_proc_info(0);
277
325
 
278
326
 
279
327
/**
280
 
  move one table to free list
 
328
  move one table to free list 
281
329
*/
282
330
 
283
 
bool Open_tables_state::free_cached_table()
 
331
bool Session::free_cached_table(boost::mutex::scoped_lock &scopedLock)
284
332
{
285
 
  table::Concurrent *table= static_cast<table::Concurrent *>(open_tables_);
286
 
 
287
 
  safe_mutex_assert_owner(table::Cache::mutex().native_handle());
 
333
  bool found_old_table= false;
 
334
 
 
335
  (void)scopedLock;
 
336
 
 
337
  table::Concurrent *table= static_cast<table::Concurrent *>(open_tables);
 
338
 
 
339
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
288
340
  assert(table->key_read == 0);
289
 
  assert(not table->cursor || table->cursor->inited == Cursor::NONE);
 
341
  assert(!table->cursor || table->cursor->inited == Cursor::NONE);
290
342
 
291
 
  open_tables_= table->getNext();
 
343
  open_tables= table->getNext();
292
344
 
293
345
  if (table->needs_reopen_or_name_lock() ||
294
 
      version != g_refresh_version || !table->db_stat)
 
346
      version != refresh_version || !table->db_stat)
295
347
  {
296
348
    table::remove_table(table);
297
 
    return true;
298
 
  }
299
 
  /*
300
 
    Open placeholders have Table::db_stat set to 0, so they should be
301
 
    handled by the first alternative.
302
 
  */
303
 
  assert(not table->open_placeholder);
304
 
 
305
 
  /* Free memory and reset for next loop */
306
 
  table->cursor->ha_reset();
307
 
  table->in_use= NULL;
308
 
 
309
 
  table::getUnused().link(table);
310
 
  return false;
 
349
    found_old_table= true;
 
350
  }
 
351
  else
 
352
  {
 
353
    /*
 
354
      Open placeholders have Table::db_stat set to 0, so they should be
 
355
      handled by the first alternative.
 
356
    */
 
357
    assert(not table->open_placeholder);
 
358
 
 
359
    /* Free memory and reset for next loop */
 
360
    table->cursor->ha_reset();
 
361
    table->in_use= NULL;
 
362
 
 
363
    table::getUnused().link(table);
 
364
  }
 
365
 
 
366
  return found_old_table;
311
367
}
312
368
 
313
369
 
319
375
  @remark It should not ordinarily be called directly.
320
376
*/
321
377
 
322
 
void Open_tables_state::close_open_tables()
 
378
void Session::close_open_tables()
323
379
{
324
380
  bool found_old_table= false;
325
381
 
326
 
  safe_mutex_assert_not_owner(table::Cache::mutex().native_handle());
327
 
 
328
 
  boost::mutex::scoped_lock scoped_lock(table::Cache::mutex()); /* Close all open tables on Session */
329
 
 
330
 
  while (open_tables_)
 
382
  safe_mutex_assert_not_owner(table::Cache::singleton().mutex().native_handle());
 
383
 
 
384
  boost_unique_lock_t scoped_lock(table::Cache::singleton().mutex()); /* Close all open tables on Session */
 
385
 
 
386
  while (open_tables)
331
387
  {
332
 
    found_old_table|= free_cached_table();
 
388
    found_old_table|= free_cached_table(scoped_lock);
333
389
  }
 
390
  some_tables_deleted= false;
 
391
 
334
392
  if (found_old_table)
335
393
  {
336
394
    /* Tell threads waiting for refresh that something has happened */
480
538
}
481
539
 
482
540
void Open_tables_state::doGetTableIdentifiers(const identifier::Schema &schema_identifier,
483
 
                                              identifier::table::vector &set_of_identifiers)
 
541
                                              identifier::Table::vector &set_of_identifiers)
484
542
{
485
543
  for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
486
544
  {
495
553
 
496
554
void Open_tables_state::doGetTableIdentifiers(CachedDirectory &,
497
555
                                              const identifier::Schema &schema_identifier,
498
 
                                              identifier::table::vector &set_of_identifiers)
 
556
                                              identifier::Table::vector &set_of_identifiers)
499
557
{
500
558
  doGetTableIdentifiers(schema_identifier, set_of_identifiers);
501
559
}
517
575
}
518
576
 
519
577
int Open_tables_state::doGetTableDefinition(const identifier::Table &identifier,
520
 
                                            message::Table &table_proto)
 
578
                                  message::Table &table_proto)
521
579
{
522
580
  for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
523
581
  {
525
583
    {
526
584
      if (identifier.getKey() == table->getShare()->getCacheKey())
527
585
      {
528
 
        table_proto.CopyFrom(*(table->getShare()->getTableMessage()));
 
586
        table_proto.CopyFrom(*(table->getShare()->getTableProto()));
529
587
 
530
588
        return EEXIST;
531
589
      }
575
633
 
576
634
int Open_tables_state::drop_temporary_table(const drizzled::identifier::Table &identifier)
577
635
{
578
 
  Table* table= find_temporary_table(identifier);
579
 
  if (not table)
 
636
  Table *table;
 
637
 
 
638
  if (not (table= find_temporary_table(identifier)))
580
639
    return 1;
581
640
 
582
641
  /* Table might be in use by some outer statement. */
583
 
  if (table->query_id && table->query_id != session_.getQueryId())
 
642
  if (table->query_id && table->query_id != getQueryId())
584
643
  {
585
644
    my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->getAlias());
586
645
    return -1;
587
646
  }
 
647
 
588
648
  close_temporary_table(table);
 
649
 
589
650
  return 0;
590
651
}
591
652
 
604
665
{
605
666
  const identifier::Table::Key find_key(find->getShare()->getCacheKey());
606
667
  Table **prev;
607
 
  safe_mutex_assert_owner(table::Cache::mutex().native_handle());
 
668
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
608
669
 
609
670
  /*
610
 
    Note that we need to hold table::Cache::mutex() while changing the
 
671
    Note that we need to hold table::Cache::singleton().mutex() while changing the
611
672
    open_tables list. Another thread may work on it.
612
 
    (See: table::Cache::removeTable(), wait_completed_table())
 
673
    (See: table::Cache::singleton().removeTable(), wait_completed_table())
613
674
    Closing a MERGE child before the parent would be fatal if the
614
675
    other thread tries to abort the MERGE lock in between.
615
676
  */
616
 
  for (prev= &open_tables.open_tables_; *prev; )
 
677
  for (prev= &open_tables; *prev; )
617
678
  {
618
679
    Table *list= *prev;
619
680
 
660
721
{
661
722
  if (table->getShare()->getType())
662
723
  {
663
 
    open_tables.close_temporary_table(table);
 
724
    close_temporary_table(table);
664
725
  }
665
726
  else
666
727
  {
667
 
    boost::mutex::scoped_lock scoped_lock(table::Cache::mutex()); /* Close and drop a table (AUX routine) */
 
728
    boost_unique_lock_t scoped_lock(table::Cache::singleton().mutex()); /* Close and drop a table (AUX routine) */
668
729
    /*
669
730
      unlink_open_table() also tells threads waiting for refresh or close
670
731
      that something has happened.
705
766
      condition variables that are guranteed to not disapper (freed) even if this
706
767
      mutex is unlocked
707
768
    */
708
 
    boost::mutex::scoped_lock scopedLock(mutex, boost::adopt_lock_t());
 
769
    boost_unique_lock_t scopedLock(mutex, boost::adopt_lock_t());
709
770
    if (not getKilled())
710
771
    {
711
772
      cond.wait(scopedLock);
712
773
    }
713
774
  }
714
 
  boost::mutex::scoped_lock mysys_scopedLock(mysys_var->mutex);
 
775
  boost_unique_lock_t mysys_scopedLock(mysys_var->mutex);
715
776
  mysys_var->current_mutex= 0;
716
777
  mysys_var->current_cond= 0;
717
778
  set_proc_info(saved_proc_info);
731
792
  case of failure.
732
793
*/
733
794
 
734
 
table::Placeholder& Session::table_cache_insert_placeholder(const drizzled::identifier::Table &arg)
 
795
table::Placeholder *Session::table_cache_insert_placeholder(const drizzled::identifier::Table &arg)
735
796
{
736
 
  safe_mutex_assert_owner(table::Cache::mutex().native_handle());
 
797
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
737
798
 
738
799
  /*
739
800
    Create a table entry with the right key and with an old refresh version
740
801
  */
741
802
  identifier::Table identifier(arg.getSchemaName(), arg.getTableName(), message::Table::INTERNAL);
742
 
  table::Placeholder* table= new table::Placeholder(this, identifier);
743
 
  table::Cache::insert(table);
744
 
  return *table;
 
803
  table::Placeholder *table= new table::Placeholder(this, identifier);
 
804
 
 
805
  if (not table::Cache::singleton().insert(table))
 
806
  {
 
807
    delete table;
 
808
 
 
809
    return NULL;
 
810
  }
 
811
 
 
812
  return table;
745
813
}
746
814
 
747
815
 
766
834
  @retval  true   Error occured (OOM)
767
835
  @retval  false  Success. 'table' parameter set according to above rules.
768
836
*/
769
 
Table* Session::lock_table_name_if_not_cached(const identifier::Table &identifier)
 
837
bool Session::lock_table_name_if_not_cached(const identifier::Table &identifier, Table **table)
770
838
{
771
839
  const identifier::Table::Key &key(identifier.getKey());
772
 
  boost::mutex::scoped_lock scope_lock(table::Cache::mutex()); /* Obtain a name lock even though table is not in cache (like for create table)  */
773
 
  if (find_ptr(table::getCache(), key))
774
 
    return NULL;
775
 
  Table& table= table_cache_insert_placeholder(identifier);
776
 
  table.open_placeholder= true;
777
 
  table.setNext(open_tables.open_tables_);
778
 
  open_tables.open_tables_= &table;
779
 
  return &table;
 
840
 
 
841
  boost_unique_lock_t scope_lock(table::Cache::singleton().mutex()); /* Obtain a name lock even though table is not in cache (like for create table)  */
 
842
 
 
843
  table::CacheMap::iterator iter;
 
844
 
 
845
  iter= table::getCache().find(key);
 
846
 
 
847
  if (iter != table::getCache().end())
 
848
  {
 
849
    *table= 0;
 
850
    return false;
 
851
  }
 
852
 
 
853
  if (not (*table= table_cache_insert_placeholder(identifier)))
 
854
  {
 
855
    return true;
 
856
  }
 
857
  (*table)->open_placeholder= true;
 
858
  (*table)->setNext(open_tables);
 
859
  open_tables= *table;
 
860
 
 
861
  return false;
780
862
}
781
863
 
782
864
/*
818
900
  const char *alias= table_list->alias;
819
901
 
820
902
  /* Parsing of partitioning information from .frm needs session->lex set up. */
821
 
  assert(lex().is_lex_started);
 
903
  assert(lex->is_lex_started);
822
904
 
823
905
  /* find a unused table in the open table cache */
824
906
  if (refresh)
843
925
    TODO -> move this block into a separate function.
844
926
  */
845
927
  bool reset= false;
846
 
  for (table= open_tables.getTemporaryTables(); table ; table=table->getNext())
 
928
  for (table= getTemporaryTables(); table ; table=table->getNext())
847
929
  {
848
930
    if (table->getShare()->getCacheKey() == key)
849
931
    {
868
950
  {
869
951
    if (flags & DRIZZLE_OPEN_TEMPORARY_ONLY)
870
952
    {
871
 
      my_error(ER_TABLE_UNKNOWN, identifier);
 
953
      my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->getSchemaName(), table_list->getTableName());
872
954
      return NULL;
873
955
    }
874
956
 
881
963
 
882
964
      Note-> refresh_version is currently changed only during FLUSH TABLES.
883
965
    */
884
 
    if (!open_tables.open_tables_)
 
966
    if (!open_tables)
885
967
    {
886
 
      open_tables.version= g_refresh_version;
 
968
      version= refresh_version;
887
969
    }
888
 
    else if ((open_tables.version != g_refresh_version) &&
 
970
    else if ((version != refresh_version) &&
889
971
             ! (flags & DRIZZLE_LOCK_IGNORE_FLUSH))
890
972
    {
891
973
      /* Someone did a refresh while thread was opening tables */
896
978
    }
897
979
 
898
980
    /*
 
981
      Before we test the global cache, we test our local session cache.
 
982
    */
 
983
    if (cached_table)
 
984
    {
 
985
      assert(false); /* Not implemented yet */
 
986
    }
 
987
 
 
988
    /*
899
989
      Non pre-locked/LOCK TABLES mode, and the table is not temporary:
900
990
      this is the normal use case.
901
991
      Now we should:
905
995
      until no one holds a name lock on the table.
906
996
      - if there is no such Table in the name cache, read the table definition
907
997
      and insert it into the cache.
908
 
      We perform all of the above under table::Cache::mutex() which currently protects
 
998
      We perform all of the above under table::Cache::singleton().mutex() which currently protects
909
999
      the open cache (also known as table cache) and table definitions stored
910
1000
      on disk.
911
1001
    */
912
1002
 
913
1003
    {
914
 
      boost::mutex::scoped_lock scopedLock(table::Cache::mutex());
 
1004
      table::Cache::singleton().mutex().lock(); /* Lock for FLUSH TABLES for open table */
915
1005
 
916
1006
      /*
917
1007
        Actually try to find the table in the open_cache.
926
1016
      ppp= table::getCache().equal_range(key);
927
1017
 
928
1018
      table= NULL;
929
 
      for (table::CacheMap::const_iterator iter= ppp.first; iter != ppp.second; ++iter, table= NULL)
 
1019
      for (table::CacheMap::const_iterator iter= ppp.first;
 
1020
           iter != ppp.second; ++iter, table= NULL)
930
1021
      {
931
 
        table= iter->second;
 
1022
        table= (*iter).second;
932
1023
 
933
1024
        if (not table->in_use)
934
1025
          break;
955
1046
          if (flags & DRIZZLE_LOCK_IGNORE_FLUSH)
956
1047
          {
957
1048
            /* Force close at once after usage */
958
 
            open_tables.version= table->getShare()->getVersion();
 
1049
            version= table->getShare()->getVersion();
959
1050
            continue;
960
1051
          }
961
1052
 
962
1053
          /* Avoid self-deadlocks by detecting self-dependencies. */
963
1054
          if (table->open_placeholder && table->in_use == this)
964
1055
          {
 
1056
            table::Cache::singleton().mutex().unlock();
965
1057
            my_error(ER_UPDATE_TABLE_USED, MYF(0), table->getShare()->getTableName());
966
1058
            return NULL;
967
1059
          }
994
1086
          */
995
1087
          if (table->in_use != this)
996
1088
          {
997
 
            /* wait_for_conditionwill unlock table::Cache::mutex() for us */
998
 
            wait_for_condition(table::Cache::mutex(), COND_refresh);
999
 
            scopedLock.release();
 
1089
            /* wait_for_conditionwill unlock table::Cache::singleton().mutex() for us */
 
1090
            wait_for_condition(table::Cache::singleton().mutex(), COND_refresh);
1000
1091
          }
1001
1092
          else
1002
1093
          {
1003
 
            scopedLock.unlock();
 
1094
            table::Cache::singleton().mutex().unlock();
1004
1095
          }
1005
 
 
1006
1096
          /*
1007
1097
            There is a refresh in progress for this table.
1008
1098
            Signal the caller that it has to try again.
1009
1099
          */
1010
1100
          if (refresh)
1011
1101
            *refresh= true;
1012
 
 
1013
1102
          return NULL;
1014
1103
        }
1015
1104
      }
1016
 
 
1017
1105
      if (table)
1018
1106
      {
1019
1107
        table::getUnused().unlink(static_cast<table::Concurrent *>(table));
1022
1110
      else
1023
1111
      {
1024
1112
        /* Insert a new Table instance into the open cache */
 
1113
        int error;
1025
1114
        /* Free cache if too big */
1026
1115
        table::getUnused().cull();
1027
1116
 
1034
1123
            /*
1035
1124
              Table to be created, so we need to create placeholder in table-cache.
1036
1125
            */
1037
 
            table= &table_cache_insert_placeholder(lock_table_identifier);
 
1126
            if (!(table= table_cache_insert_placeholder(lock_table_identifier)))
 
1127
            {
 
1128
              table::Cache::singleton().mutex().unlock();
 
1129
              return NULL;
 
1130
            }
1038
1131
            /*
1039
1132
              Link placeholder to the open tables list so it will be automatically
1040
1133
              removed once tables are closed. Also mark it so it won't be ignored
1041
1134
              by other trying to take name-lock.
1042
1135
            */
1043
1136
            table->open_placeholder= true;
1044
 
            table->setNext(open_tables.open_tables_);
1045
 
            open_tables.open_tables_= table;
 
1137
            table->setNext(open_tables);
 
1138
            open_tables= table;
 
1139
            table::Cache::singleton().mutex().unlock();
1046
1140
 
1047
1141
            return table ;
1048
1142
          }
1053
1147
        {
1054
1148
          table::Concurrent *new_table= new table::Concurrent;
1055
1149
          table= new_table;
1056
 
          if (new_table->open_unireg_entry(this, alias, identifier))
 
1150
          if (new_table == NULL)
 
1151
          {
 
1152
            table::Cache::singleton().mutex().unlock();
 
1153
            return NULL;
 
1154
          }
 
1155
 
 
1156
          error= new_table->open_unireg_entry(this, alias, identifier);
 
1157
          if (error != 0)
1057
1158
          {
1058
1159
            delete new_table;
 
1160
            table::Cache::singleton().mutex().unlock();
1059
1161
            return NULL;
1060
1162
          }
1061
 
          (void)table::Cache::insert(new_table);
 
1163
          (void)table::Cache::singleton().insert(new_table);
1062
1164
        }
1063
1165
      }
 
1166
 
 
1167
      table::Cache::singleton().mutex().unlock();
1064
1168
    }
1065
 
 
1066
1169
    if (refresh)
1067
1170
    {
1068
 
      table->setNext(open_tables.open_tables_); /* Link into simple list */
1069
 
      open_tables.open_tables_= table;
 
1171
      table->setNext(open_tables); /* Link into simple list */
 
1172
      open_tables= table;
1070
1173
    }
1071
1174
    table->reginfo.lock_type= TL_READ; /* Assume read */
1072
1175
 
1080
1183
  }
1081
1184
 
1082
1185
  /* These variables are also set in reopen_table() */
1083
 
  table->tablenr= open_tables.current_tablenr++;
 
1186
  table->tablenr= current_tablenr++;
1084
1187
  table->used_fields= 0;
1085
1188
  table->const_table= 0;
1086
1189
  table->null_row= false;
1122
1225
 
1123
1226
void Session::close_data_files_and_morph_locks(const identifier::Table &identifier)
1124
1227
{
1125
 
  safe_mutex_assert_owner(table::Cache::mutex().native_handle()); /* Adjust locks at the end of ALTER TABLEL */
 
1228
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle()); /* Adjust locks at the end of ALTER TABLEL */
1126
1229
 
1127
 
  if (open_tables.lock)
 
1230
  if (lock)
1128
1231
  {
1129
1232
    /*
1130
1233
      If we are not under LOCK TABLES we should have only one table
1131
1234
      open and locked so it makes sense to remove the lock at once.
1132
1235
    */
1133
 
    unlockTables(open_tables.lock);
1134
 
    open_tables.lock= 0;
 
1236
    unlockTables(lock);
 
1237
    lock= 0;
1135
1238
  }
1136
1239
 
1137
1240
  /*
1139
1242
    for target table name if we process ALTER Table ... RENAME.
1140
1243
    So loop below makes sense even if we are not under LOCK TABLES.
1141
1244
  */
1142
 
  for (Table *table= open_tables.open_tables_; table ; table=table->getNext())
 
1245
  for (Table *table= open_tables; table ; table=table->getNext())
1143
1246
  {
1144
1247
    if (table->getShare()->getCacheKey() == identifier.getKey())
1145
1248
    {
1165
1268
  combination when one needs tables to be reopened (for
1166
1269
  example see openTablesLock()).
1167
1270
 
1168
 
  @note One should have lock on table::Cache::mutex() when calling this.
 
1271
  @note One should have lock on table::Cache::singleton().mutex() when calling this.
1169
1272
 
1170
1273
  @return false in case of success, true - otherwise.
1171
1274
*/
1180
1283
    DRIZZLE_LOCK_IGNORE_GLOBAL_READ_LOCK |
1181
1284
    DRIZZLE_LOCK_IGNORE_FLUSH;
1182
1285
 
1183
 
  if (open_tables.open_tables_ == NULL)
 
1286
  if (open_tables == NULL)
1184
1287
    return false;
1185
1288
 
1186
 
  safe_mutex_assert_owner(table::Cache::mutex().native_handle());
 
1289
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
1187
1290
  {
1188
1291
    /*
1189
1292
      The ptr is checked later
1191
1294
    */
1192
1295
    uint32_t opens= 0;
1193
1296
 
1194
 
    for (table= open_tables.open_tables_; table ; table=table->getNext())
 
1297
    for (table= open_tables; table ; table=table->getNext())
1195
1298
    {
1196
1299
      opens++;
1197
1300
    }
1200
1303
 
1201
1304
  tables_ptr =tables;
1202
1305
 
1203
 
  prev= &open_tables.open_tables_;
1204
 
  for (table= open_tables.open_tables_; table ; table=next)
 
1306
  prev= &open_tables;
 
1307
  for (table= open_tables; table ; table=next)
1205
1308
  {
1206
1309
    next= table->getNext();
1207
1310
 
1213
1316
 
1214
1317
  if (tables != tables_ptr)                     // Should we get back old locks
1215
1318
  {
 
1319
    DrizzleLock *local_lock;
1216
1320
    /*
1217
1321
      We should always get these locks. Anyway, we must not go into
1218
 
      wait_for_tables() as it tries to acquire table::Cache::mutex(), which is
 
1322
      wait_for_tables() as it tries to acquire table::Cache::singleton().mutex(), which is
1219
1323
      already locked.
1220
1324
    */
 
1325
    some_tables_deleted= false;
1221
1326
 
1222
 
    if (not lockTables(tables, (uint32_t) (tables_ptr - tables), flags))
 
1327
    if ((local_lock= lockTables(tables, (uint32_t) (tables_ptr - tables), flags)))
 
1328
    {
 
1329
      /* unused */
 
1330
    }
 
1331
    else
1223
1332
    {
1224
1333
      /*
1225
1334
        This case should only happen if there is a bug in the reopen logic.
1257
1366
{
1258
1367
  bool found= send_refresh;
1259
1368
 
1260
 
  Table *table= open_tables.open_tables_;
 
1369
  Table *table= open_tables;
1261
1370
 
1262
1371
  for (; table ; table=table->getNext())
1263
1372
  {
1352
1461
Table *drop_locked_tables(Session *session, const drizzled::identifier::Table &identifier)
1353
1462
{
1354
1463
  Table *table,*next,**prev, *found= 0;
1355
 
  prev= &session->open_tables.open_tables_;
 
1464
  prev= &session->open_tables;
1356
1465
 
1357
1466
  /*
1358
 
    Note that we need to hold table::Cache::mutex() while changing the
 
1467
    Note that we need to hold table::Cache::singleton().mutex() while changing the
1359
1468
    open_tables list. Another thread may work on it.
1360
 
    (See: table::Cache::removeTable(), wait_completed_table())
 
1469
    (See: table::Cache::singleton().removeTable(), wait_completed_table())
1361
1470
    Closing a MERGE child before the parent would be fatal if the
1362
1471
    other thread tries to abort the MERGE lock in between.
1363
1472
  */
1364
 
  for (table= session->open_tables.open_tables_; table ; table=next)
 
1473
  for (table= session->open_tables; table ; table=next)
1365
1474
  {
1366
1475
    next=table->getNext();
1367
1476
    if (table->getShare()->getCacheKey() == identifier.getKey())
1408
1517
void abort_locked_tables(Session *session, const drizzled::identifier::Table &identifier)
1409
1518
{
1410
1519
  Table *table;
1411
 
  for (table= session->open_tables.open_tables_; table ; table= table->getNext())
 
1520
  for (table= session->open_tables; table ; table= table->getNext())
1412
1521
  {
1413
1522
    if (table->getShare()->getCacheKey() == identifier.getKey())
1414
1523
    {
1457
1566
  /* Also used for indicating that prelocking is need */
1458
1567
  bool safe_to_ignore_table;
1459
1568
 
1460
 
  open_tables.current_tablenr= 0;
 
1569
  current_tablenr= 0;
1461
1570
restart:
1462
1571
  *counter= 0;
1463
1572
  set_proc_info("Opening tables");
1488
1597
     * table/schema information via error messages
1489
1598
     */
1490
1599
    identifier::Table the_table(tables->getSchemaName(), tables->getTableName());
1491
 
    if (not plugin::Authorization::isAuthorized(*user(), the_table))
 
1600
    if (not plugin::Authorization::isAuthorized(user(), the_table))
1492
1601
    {
1493
1602
      result= -1;                               // Fatal error
1494
1603
      break;
1584
1693
  bool refresh;
1585
1694
 
1586
1695
  set_proc_info("Opening table");
1587
 
  open_tables.current_tablenr= 0;
 
1696
  current_tablenr= 0;
1588
1697
  while (!(table= openTable(table_list, &refresh)) && refresh) ;
1589
1698
 
1590
1699
  if (table)
1592
1701
    table_list->lock_type= lock_type;
1593
1702
    table_list->table=     table;
1594
1703
 
1595
 
    assert(open_tables.lock == 0);      // You must lock everything at once
 
1704
    assert(lock == 0);  // You must lock everything at once
1596
1705
    if ((table->reginfo.lock_type= lock_type) != TL_UNLOCK)
1597
1706
    {
1598
 
      if (not (open_tables.lock= lockTables(&table_list->table, 1, 0)))
 
1707
      if (not (lock= lockTables(&table_list->table, 1, 0)))
1599
1708
        table= NULL;
1600
1709
    }
1601
1710
  }
1647
1756
  if (tables == NULL)
1648
1757
    return 0;
1649
1758
 
1650
 
  assert(session->open_tables.lock == 0);       // You must lock everything at once
 
1759
  assert(session->lock == 0);   // You must lock everything at once
1651
1760
  Table **start,**ptr;
1652
1761
  uint32_t lock_flag= DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN;
1653
1762
 
1654
 
  if (!(ptr=start=(Table**) session->getMemRoot()->allocate(sizeof(Table*)*count)))
 
1763
  if (!(ptr=start=(Table**) session->alloc(sizeof(Table*)*count)))
1655
1764
    return -1;
1656
1765
 
1657
1766
  for (table= tables; table; table= table->next_global)
1660
1769
      *(ptr++)= table->table;
1661
1770
  }
1662
1771
 
1663
 
  if (not (session->open_tables.lock= session->lockTables(start, (uint32_t) (ptr - start), lock_flag)))
 
1772
  if (not (session->lock= session->lockTables(start, (uint32_t) (ptr - start), lock_flag)))
1664
1773
  {
1665
1774
    return -1;
1666
1775
  }
1689
1798
#  Table object
1690
1799
*/
1691
1800
 
1692
 
Table* Session::open_temporary_table(const identifier::Table &identifier, bool link_in_list)
 
1801
Table *Open_tables_state::open_temporary_table(const identifier::Table &identifier,
 
1802
                                               bool link_in_list)
1693
1803
{
1694
1804
  assert(identifier.isTmp());
1695
1805
 
1723
1833
  if (link_in_list)
1724
1834
  {
1725
1835
    /* growing temp list at the head */
1726
 
    new_tmp_table->setNext(open_tables.temporary_tables);
 
1836
    new_tmp_table->setNext(this->temporary_tables);
1727
1837
    if (new_tmp_table->getNext())
1728
1838
    {
1729
1839
      new_tmp_table->getNext()->setPrev(new_tmp_table);
1730
1840
    }
1731
 
    open_tables.temporary_tables= new_tmp_table;
1732
 
    open_tables.temporary_tables->setPrev(0);
 
1841
    this->temporary_tables= new_tmp_table;
 
1842
    this->temporary_tables->setPrev(0);
1733
1843
  }
1734
1844
  new_tmp_table->pos_in_table_list= 0;
1735
1845
 
1818
1928
                           const char *name, uint32_t , Item **,
1819
1929
                           bool, TableList **actual_table)
1820
1930
{
1821
 
  List<Natural_join_column>::iterator
1822
 
    field_it(table_ref->join_columns->begin());
 
1931
  List_iterator_fast<Natural_join_column>
 
1932
    field_it(*(table_ref->join_columns));
1823
1933
  Natural_join_column *nj_col, *curr_nj_col;
1824
1934
  Field *found_field;
1825
1935
 
1833
1943
    {
1834
1944
      if (nj_col)
1835
1945
      {
1836
 
        my_error(ER_NON_UNIQ_ERROR, MYF(0), name, session->where());
 
1946
        my_error(ER_NON_UNIQ_ERROR, MYF(0), name, session->where);
1837
1947
        return NULL;
1838
1948
      }
1839
1949
      nj_col= curr_nj_col;
2034
2144
    */
2035
2145
    if (table_name && table_name[0])
2036
2146
    {
2037
 
      List<TableList>::iterator it(table_list->getNestedJoin()->join_list.begin());
 
2147
      List_iterator<TableList> it(table_list->getNestedJoin()->join_list);
2038
2148
      TableList *table;
2039
2149
      while ((table= it++))
2040
2150
      {
2184
2294
        fields.
2185
2295
      */
2186
2296
      {
2187
 
        Select_Lex *current_sel= session->lex().current_select;
 
2297
        Select_Lex *current_sel= session->lex->current_select;
2188
2298
        Select_Lex *last_select= table_ref->select_lex;
2189
2299
        /*
2190
2300
          If the field was an outer referencee, mark all selects using this
2230
2340
      */
2231
2341
      item->cached_table= found ?  0 : actual_table;
2232
2342
 
2233
 
      assert(session->where());
 
2343
      assert(session->where);
2234
2344
      /*
2235
2345
        If we found a fully qualified field we return it directly as it can't
2236
2346
        have duplicates.
2243
2353
        if (report_error == REPORT_ALL_ERRORS ||
2244
2354
            report_error == IGNORE_EXCEPT_NON_UNIQUE)
2245
2355
          my_error(ER_NON_UNIQ_ERROR, MYF(0),
2246
 
                   table_name ? item->full_name() : name, session->where());
 
2356
                   table_name ? item->full_name() : name, session->where);
2247
2357
        return (Field*) 0;
2248
2358
      }
2249
2359
      found= cur_field;
2276
2386
      strcat(buff, table_name);
2277
2387
      table_name=buff;
2278
2388
    }
2279
 
    my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, session->where());
 
2389
    my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, session->where);
2280
2390
  }
2281
2391
  else
2282
2392
  {
2283
2393
    if (report_error == REPORT_ALL_ERRORS ||
2284
2394
        report_error == REPORT_EXCEPT_NON_UNIQUE)
2285
 
      my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), session->where());
 
2395
      my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), session->where);
2286
2396
    else
2287
2397
      found= not_found_field;
2288
2398
  }
2333
2443
                  find_item_error_report_type report_error,
2334
2444
                  enum_resolution_type *resolution)
2335
2445
{
2336
 
  List<Item>::iterator li(items.begin());
 
2446
  List_iterator<Item> li(items);
2337
2447
  Item **found=0, **found_unaliased= 0, *item;
2338
2448
  const char *db_name=0;
2339
2449
  const char *field_name=0;
2409
2519
            */
2410
2520
            if (report_error != IGNORE_ERRORS)
2411
2521
              my_error(ER_NON_UNIQ_ERROR, MYF(0),
2412
 
                       find->full_name(), session->where());
 
2522
                       find->full_name(), session->where);
2413
2523
            return (Item**) 0;
2414
2524
          }
2415
2525
          found_unaliased= li.ref();
2440
2550
              continue;                           // Same field twice
2441
2551
            if (report_error != IGNORE_ERRORS)
2442
2552
              my_error(ER_NON_UNIQ_ERROR, MYF(0),
2443
 
                       find->full_name(), session->where());
 
2553
                       find->full_name(), session->where);
2444
2554
            return (Item**) 0;
2445
2555
          }
2446
2556
          found= li.ref();
2492
2602
    {
2493
2603
      if (report_error != IGNORE_ERRORS)
2494
2604
        my_error(ER_NON_UNIQ_ERROR, MYF(0),
2495
 
                 find->full_name(), session->where());
 
2605
                 find->full_name(), session->where);
2496
2606
      return (Item **) 0;
2497
2607
    }
2498
2608
    if (found_unaliased)
2508
2618
  {
2509
2619
    if (report_error == REPORT_ALL_ERRORS)
2510
2620
      my_error(ER_BAD_FIELD_ERROR, MYF(0),
2511
 
               find->full_name(), session->where());
 
2621
               find->full_name(), session->where);
2512
2622
    return (Item **) 0;
2513
2623
  }
2514
2624
  else
2536
2646
static bool
2537
2647
test_if_string_in_list(const char *find, List<String> *str_list)
2538
2648
{
2539
 
  List<String>::iterator str_list_it(str_list->begin());
 
2649
  List_iterator<String> str_list_it(*str_list);
2540
2650
  String *curr_str;
2541
2651
  size_t find_length= strlen(find);
2542
2652
  while ((curr_str= str_list_it++))
2679
2789
        if (cur_nj_col_2->is_common ||
2680
2790
            (found && (!using_fields || is_using_column_1)))
2681
2791
        {
2682
 
          my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1, session->where());
 
2792
          my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1, session->where);
2683
2793
          return(result);
2684
2794
        }
2685
2795
        nj_col_2= cur_nj_col_2;
2867
2977
    columns. If this is not the case, report the first one that was
2868
2978
    not found in an error.
2869
2979
  */
2870
 
  if (using_fields && found_using_fields < using_fields->size())
 
2980
  if (using_fields && found_using_fields < using_fields->elements)
2871
2981
  {
2872
2982
    String *using_field_name;
2873
 
    List<String>::iterator using_fields_it(using_fields->begin());
 
2983
    List_iterator_fast<String> using_fields_it(*using_fields);
2874
2984
    while ((using_field_name= using_fields_it++))
2875
2985
    {
2876
2986
      const char *using_field_name_ptr= using_field_name->c_ptr();
2877
 
      List<Natural_join_column>::iterator
2878
 
        it(natural_using_join->join_columns->begin());
 
2987
      List_iterator_fast<Natural_join_column>
 
2988
        it(*(natural_using_join->join_columns));
2879
2989
      Natural_join_column *common_field;
2880
2990
 
2881
2991
      for (;;)
2884
2994
        if (!(common_field= it++))
2885
2995
        {
2886
2996
          my_error(ER_BAD_FIELD_ERROR, MYF(0), using_field_name_ptr,
2887
 
                   session->where());
 
2997
                   session->where);
2888
2998
          return(result);
2889
2999
        }
2890
3000
        if (!my_strcasecmp(system_charset_info,
2907
3017
    }
2908
3018
  }
2909
3019
 
2910
 
  if (non_join_columns->size() > 0)
 
3020
  if (non_join_columns->elements > 0)
2911
3021
    natural_using_join->join_columns->concat(non_join_columns);
2912
3022
  natural_using_join->is_join_columns_complete= true;
2913
3023
 
2957
3067
  /* Call the procedure recursively for each nested table reference. */
2958
3068
  if (table_ref->getNestedJoin())
2959
3069
  {
2960
 
    List<TableList>::iterator nested_it(table_ref->getNestedJoin()->join_list.begin());
 
3070
    List_iterator_fast<TableList> nested_it(table_ref->getNestedJoin()->join_list);
2961
3071
    TableList *same_level_left_neighbor= nested_it++;
2962
3072
    TableList *same_level_right_neighbor= NULL;
2963
3073
    /* Left/right-most neighbors, possibly at higher levels in the join tree. */
2982
3092
          cur_table_ref->outer_join & JOIN_TYPE_RIGHT)
2983
3093
      {
2984
3094
        /* This can happen only for JOIN ... ON. */
2985
 
        assert(table_ref->getNestedJoin()->join_list.size() == 2);
 
3095
        assert(table_ref->getNestedJoin()->join_list.elements == 2);
2986
3096
        std::swap(same_level_left_neighbor, cur_table_ref);
2987
3097
      }
2988
3098
 
3010
3120
  if (table_ref->is_natural_join)
3011
3121
  {
3012
3122
    assert(table_ref->getNestedJoin() &&
3013
 
           table_ref->getNestedJoin()->join_list.size() == 2);
3014
 
    List<TableList>::iterator operand_it(table_ref->getNestedJoin()->join_list.begin());
 
3123
           table_ref->getNestedJoin()->join_list.elements == 2);
 
3124
    List_iterator_fast<TableList> operand_it(table_ref->getNestedJoin()->join_list);
3015
3125
    /*
3016
3126
      Notice that the order of join operands depends on whether table_ref
3017
3127
      represents a LEFT or a RIGHT join. In a RIGHT join, the operands are
3107
3217
                                         List<TableList> *from_clause,
3108
3218
                                         Name_resolution_context *context)
3109
3219
{
3110
 
  session->setWhere("from clause");
3111
 
  if (from_clause->size() == 0)
 
3220
  session->where= "from clause";
 
3221
  if (from_clause->elements == 0)
3112
3222
    return false; /* We come here in the case of UNIONs. */
3113
3223
 
3114
 
  List<TableList>::iterator table_ref_it(from_clause->begin());
 
3224
  List_iterator_fast<TableList> table_ref_it(*from_clause);
3115
3225
  TableList *table_ref; /* Current table reference. */
3116
3226
  /* Table reference to the left of the current. */
3117
3227
  TableList *left_neighbor;
3161
3271
    return 0;
3162
3272
 
3163
3273
  Item *item;
3164
 
  List<Item>::iterator it(fields.begin());
 
3274
  List_iterator<Item> it(fields);
3165
3275
 
3166
 
  session->lex().current_select->cur_pos_in_select_list= 0;
 
3276
  session->lex->current_select->cur_pos_in_select_list= 0;
3167
3277
  while (wild_num && (item= it++))
3168
3278
  {
3169
3279
    if (item->type() == Item::FIELD_ITEM &&
3171
3281
        ((Item_field*) item)->field_name[0] == '*' &&
3172
3282
        !((Item_field*) item)->field)
3173
3283
    {
3174
 
      uint32_t elem= fields.size();
 
3284
      uint32_t elem= fields.elements;
3175
3285
      bool any_privileges= ((Item_field *) item)->any_privileges;
3176
 
      Item_subselect *subsel= session->lex().current_select->master_unit()->item;
 
3286
      Item_subselect *subsel= session->lex->current_select->master_unit()->item;
3177
3287
      if (subsel &&
3178
3288
          subsel->substype() == Item_subselect::EXISTS_SUBS)
3179
3289
      {
3199
3309
          Because of this we have to update the element count also for this
3200
3310
          list after expanding the '*' entry.
3201
3311
        */
3202
 
        sum_func_list->set_size(sum_func_list->size() + fields.size() - elem);
 
3312
        sum_func_list->elements+= fields.elements - elem;
3203
3313
      }
3204
3314
      wild_num--;
3205
3315
    }
3206
3316
    else
3207
 
      session->lex().current_select->cur_pos_in_select_list++;
 
3317
      session->lex->current_select->cur_pos_in_select_list++;
3208
3318
  }
3209
 
  session->lex().current_select->cur_pos_in_select_list= UNDEF_POS;
 
3319
  session->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
3210
3320
 
3211
3321
  return 0;
3212
3322
}
3221
3331
{
3222
3332
  register Item *item;
3223
3333
  enum_mark_columns save_mark_used_columns= session->mark_used_columns;
3224
 
  nesting_map save_allow_sum_func= session->lex().allow_sum_func;
3225
 
  List<Item>::iterator it(fields.begin());
 
3334
  nesting_map save_allow_sum_func= session->lex->allow_sum_func;
 
3335
  List_iterator<Item> it(fields);
3226
3336
  bool save_is_item_list_lookup;
3227
3337
 
3228
3338
  session->mark_used_columns= mark_used_columns;
3229
3339
  if (allow_sum_func)
3230
 
    session->lex().allow_sum_func|= 1 << session->lex().current_select->nest_level;
3231
 
  session->setWhere(Session::DEFAULT_WHERE);
3232
 
  save_is_item_list_lookup= session->lex().current_select->is_item_list_lookup;
3233
 
  session->lex().current_select->is_item_list_lookup= 0;
 
3340
    session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
 
3341
  session->where= Session::DEFAULT_WHERE;
 
3342
  save_is_item_list_lookup= session->lex->current_select->is_item_list_lookup;
 
3343
  session->lex->current_select->is_item_list_lookup= 0;
3234
3344
 
3235
3345
  /*
3236
3346
    To prevent fail on forward lookup we fill it with zerows,
3240
3350
    There is other way to solve problem: fill array with pointers to list,
3241
3351
    but it will be slower.
3242
3352
 
3243
 
    TODO-> remove it when (if) we made one list for allfields and ref_pointer_array
 
3353
TODO: remove it when (if) we made one list for allfields and
 
3354
ref_pointer_array
3244
3355
  */
3245
3356
  if (ref_pointer_array)
3246
 
  {
3247
 
    memset(ref_pointer_array, 0, sizeof(Item *) * fields.size());
3248
 
  }
 
3357
    memset(ref_pointer_array, 0, sizeof(Item *) * fields.elements);
3249
3358
 
3250
3359
  Item **ref= ref_pointer_array;
3251
 
  session->lex().current_select->cur_pos_in_select_list= 0;
 
3360
  session->lex->current_select->cur_pos_in_select_list= 0;
3252
3361
  while ((item= it++))
3253
3362
  {
3254
3363
    if ((!item->fixed && item->fix_fields(session, it.ref())) || (item= *(it.ref()))->check_cols(1))
3255
3364
    {
3256
 
      session->lex().current_select->is_item_list_lookup= save_is_item_list_lookup;
3257
 
      session->lex().allow_sum_func= save_allow_sum_func;
 
3365
      session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
 
3366
      session->lex->allow_sum_func= save_allow_sum_func;
3258
3367
      session->mark_used_columns= save_mark_used_columns;
3259
3368
      return true;
3260
3369
    }
3264
3373
        sum_func_list)
3265
3374
      item->split_sum_func(session, ref_pointer_array, *sum_func_list);
3266
3375
    session->used_tables|= item->used_tables();
3267
 
    session->lex().current_select->cur_pos_in_select_list++;
 
3376
    session->lex->current_select->cur_pos_in_select_list++;
3268
3377
  }
3269
 
  session->lex().current_select->is_item_list_lookup= save_is_item_list_lookup;
3270
 
  session->lex().current_select->cur_pos_in_select_list= UNDEF_POS;
 
3378
  session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
 
3379
  session->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
3271
3380
 
3272
 
  session->lex().allow_sum_func= save_allow_sum_func;
 
3381
  session->lex->allow_sum_func= save_allow_sum_func;
3273
3382
  session->mark_used_columns= save_mark_used_columns;
3274
3383
  return(test(session->is_error()));
3275
3384
}
3438
3547
 
3439
3548
bool
3440
3549
insert_fields(Session *session, Name_resolution_context *context, const char *db_name,
3441
 
              const char *table_name, List<Item>::iterator *it,
 
3550
              const char *table_name, List_iterator<Item> *it,
3442
3551
              bool )
3443
3552
{
3444
3553
  Field_iterator_table_ref field_iterator;
3545
3654
        session->used_tables|= item->used_tables();
3546
3655
      }
3547
3656
 
3548
 
      session->lex().current_select->cur_pos_in_select_list++;
 
3657
      session->lex->current_select->cur_pos_in_select_list++;
3549
3658
    }
3550
3659
    /*
3551
3660
      In case of stored tables, all fields are considered as used,
3598
3707
int Session::setup_conds(TableList *leaves, COND **conds)
3599
3708
{
3600
3709
  Session *session= this;
3601
 
  Select_Lex *select_lex= session->lex().current_select;
 
3710
  Select_Lex *select_lex= session->lex->current_select;
3602
3711
  TableList *table= NULL;       // For HP compilers
3603
3712
  void *save_session_marker= session->session_marker;
3604
3713
  /*
3620
3729
  session->session_marker= (void*)1;
3621
3730
  if (*conds)
3622
3731
  {
3623
 
    session->setWhere("where clause");
 
3732
    session->where="where clause";
3624
3733
    if ((!(*conds)->fixed && (*conds)->fix_fields(session, conds)) ||
3625
3734
        (*conds)->check_cols(1))
3626
3735
      goto err_no_arena;
3642
3751
      {
3643
3752
        /* Make a join an a expression */
3644
3753
        session->session_marker= (void*)embedded;
3645
 
        session->setWhere("on clause");
 
3754
        session->where="on clause";
3646
3755
        if ((!embedded->on_expr->fixed && embedded->on_expr->fix_fields(session, &embedded->on_expr)) ||
3647
3756
            embedded->on_expr->check_cols(1))
3648
3757
          goto err_no_arena;
3651
3760
      embedding= embedded->getEmbedding();
3652
3761
    }
3653
3762
    while (embedding &&
3654
 
           &embedding->getNestedJoin()->join_list.front() == embedded);
 
3763
           embedding->getNestedJoin()->join_list.head() == embedded);
3655
3764
 
3656
3765
  }
3657
3766
  session->session_marker= save_session_marker;
3658
3767
 
3659
 
  session->lex().current_select->is_item_list_lookup= save_is_item_list_lookup;
 
3768
  session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
3660
3769
  return(test(session->is_error()));
3661
3770
 
3662
3771
err_no_arena:
3694
3803
bool
3695
3804
fill_record(Session *session, List<Item> &fields, List<Item> &values, bool ignore_errors)
3696
3805
{
3697
 
  List<Item>::iterator f(fields.begin());
3698
 
  List<Item>::iterator v(values.begin());
 
3806
  List_iterator_fast<Item> f(fields),v(values);
3699
3807
  Item *value;
3700
3808
  Item_field *field;
3701
3809
  Table *table;
3704
3812
    Reset the table->auto_increment_field_not_null as it is valid for
3705
3813
    only one row.
3706
3814
  */
3707
 
  if (fields.size())
 
3815
  if (fields.elements)
3708
3816
  {
3709
3817
    /*
3710
3818
      On INSERT or UPDATE fields are checked to be from the same table,
3713
3821
    field= static_cast<Item_field *>(f++);
3714
3822
    table= field->field->getTable();
3715
3823
    table->auto_increment_field_not_null= false;
3716
 
    f= fields.begin();
 
3824
    f.rewind();
3717
3825
  }
3718
3826
 
3719
3827
  while ((field= static_cast<Item_field *>(f++)))
3760
3868
 
3761
3869
bool fill_record(Session *session, Field **ptr, List<Item> &values, bool)
3762
3870
{
3763
 
  List<Item>::iterator v(values.begin());
 
3871
  List_iterator_fast<Item> v(values);
3764
3872
  Item *value;
3765
3873
  Table *table= 0;
3766
3874
  Field *field;
3800
3908
}
3801
3909
 
3802
3910
 
3803
 
void drizzle_rm_tmp_tables()
 
3911
bool drizzle_rm_tmp_tables()
3804
3912
{
 
3913
 
3805
3914
  assert(drizzle_tmpdir.size());
3806
3915
  Session::shared_ptr session= Session::make_shared(plugin::Listen::getNullClient(), catalog::local());
 
3916
 
 
3917
  if (not session)
 
3918
    return true;
3807
3919
  session->thread_stack= (char*) session.get();
3808
3920
  session->storeGlobals();
 
3921
 
3809
3922
  plugin::StorageEngine::removeLostTemporaryTables(*session, drizzle_tmpdir.c_str());
 
3923
 
 
3924
  return false;
3810
3925
}
3811
3926
 
3812
3927