~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-04-20 09:27:49 UTC
  • mto: This revision was merged to the branch mainline in revision 2285.
  • Revision ID: olafvdspek@gmail.com-20110420092749-hw1q9rfj1pumc2no
Session Cache

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/catalog/local.h>
 
64
#include <drizzled/open_tables_state.h>
 
65
#include <drizzled/table/cache.h>
59
66
 
60
67
using namespace std;
61
68
 
62
 
namespace drizzled
63
 
{
 
69
namespace drizzled {
64
70
 
65
71
extern bool volatile shutdown_in_progress;
66
72
 
76
82
 
77
83
void table_cache_free(void)
78
84
{
79
 
  refresh_version++;                            // Force close of open tables
 
85
  g_refresh_version++;                          // Force close of open tables
80
86
 
81
87
  table::getUnused().clear();
82
88
  table::getCache().clear();
110
116
    This has to be done to ensure that the table share is removed from
111
117
    the table defintion cache as soon as the last instance is removed
112
118
  */
113
 
  TableIdentifier identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), message::Table::INTERNAL);
114
 
  const TableIdentifier::Key &key(identifier.getKey());
 
119
  identifier::Table identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), message::Table::INTERNAL);
 
120
  const identifier::Table::Key &key(identifier.getKey());
115
121
  TableShare *share= new TableShare(identifier.getType(),
116
122
                                    identifier,
117
123
                                    const_cast<char *>(key.vector()),  static_cast<uint32_t>(table->getShare()->getCacheKeySize()));
118
124
 
119
125
  table->cursor->close();
120
126
  table->db_stat= 0;                            // Mark cursor closed
121
 
  TableShare::release(table->getMutableShare());
 
127
  table::instance::release(table->getMutableShare());
122
128
  table->setShare(share);
123
129
}
124
130
 
144
150
  if (sort.io_cache)
145
151
  {
146
152
    sort.io_cache->close_cached_file();
147
 
    delete sort.io_cache;
148
 
    sort.io_cache= 0;
 
153
    safe_delete(sort.io_cache);
149
154
  }
150
155
}
151
156
 
155
160
 
156
161
  @param session Thread context (may be NULL)
157
162
  @param tables List of tables to remove from the cache
158
 
  @param have_lock If table::Cache::singleton().mutex() is locked
 
163
  @param have_lock If table::Cache::mutex() is locked
159
164
  @param wait_for_refresh Wait for a impending flush
160
165
  @param wait_for_placeholders Wait for tables being reopened so that the GRL
161
166
  won't proceed while write-locked tables are being reopened by other
171
176
  Session *session= this;
172
177
 
173
178
  {
174
 
    table::Cache::singleton().mutex().lock(); /* Optionally lock for remove tables from open_cahe if not in use */
 
179
    boost::mutex::scoped_lock scopedLock(table::Cache::mutex()); /* Optionally lock for remove tables from open_cahe if not in use */
175
180
 
176
181
    if (tables == NULL)
177
182
    {
178
 
      refresh_version++;                                // Force close of open tables
 
183
      g_refresh_version++;                              // Force close of open tables
179
184
 
180
185
      table::getUnused().clear();
181
186
 
208
213
          again. There they will wait until we update all tables version
209
214
          below.
210
215
 
211
 
          Setting some_tables_deleted is done by table::Cache::singleton().removeTable()
 
216
          Setting some_tables_deleted is done by table::Cache::removeTable()
212
217
          in the other branch.
213
218
 
214
219
          In other words (reviewer suggestion): You need this setting of
218
223
          after the call to Session::close_old_data_files() i.e. after removal of
219
224
          current thread locks.
220
225
        */
221
 
        for (table::CacheMap::const_iterator iter= table::getCache().begin();
222
 
             iter != table::getCache().end();
223
 
             iter++)
 
226
        BOOST_FOREACH(table::CacheMap::const_reference iter, table::getCache())
224
227
        {
225
 
          Table *table= (*iter).second;
226
 
          if (table->in_use)
227
 
            table->in_use->some_tables_deleted= false;
 
228
          if (iter.second->in_use)
 
229
            iter.second->in_use->some_tables_deleted= false;
228
230
        }
229
231
      }
230
232
    }
233
235
      bool found= false;
234
236
      for (TableList *table= tables; table; table= table->next_local)
235
237
      {
236
 
        TableIdentifier identifier(table->getSchemaName(), table->getTableName());
237
 
        if (table::Cache::singleton().removeTable(session, identifier,
238
 
                                    RTFC_OWNED_BY_Session_FLAG))
 
238
        if (table::Cache::removeTable(*session, identifier::Table(table->getSchemaName(), table->getTableName()), RTFC_OWNED_BY_Session_FLAG))
239
239
        {
240
240
          found= true;
241
241
        }
250
250
        If there is any table that has a lower refresh_version, wait until
251
251
        this is closed (or this thread is killed) before returning
252
252
      */
253
 
      session->mysys_var->current_mutex= &table::Cache::singleton().mutex();
 
253
      session->mysys_var->current_mutex= &table::Cache::mutex();
254
254
      session->mysys_var->current_cond= &COND_refresh;
255
255
      session->set_proc_info("Flushing tables");
256
256
 
265
265
             iter != table::getCache().end();
266
266
             iter++)
267
267
        {
268
 
          Table *table= (*iter).second;
 
268
          Table *table= iter->second;
269
269
          /* Avoid a self-deadlock. */
270
270
          if (table->in_use == session)
271
271
            continue;
287
287
                                                     (table->open_placeholder && wait_for_placeholders)))
288
288
          {
289
289
            found= true;
290
 
            boost_unique_lock_t scoped(table::Cache::singleton().mutex(), boost::adopt_lock_t());
291
 
            COND_refresh.wait(scoped);
292
 
            scoped.release();
 
290
            COND_refresh.wait(scopedLock);
293
291
            break;
294
292
          }
295
293
        }
299
297
        old locks. This should always succeed (unless some external process
300
298
        has removed the tables)
301
299
      */
302
 
      result= session->reopen_tables(true, true);
 
300
      result= session->reopen_tables();
303
301
 
304
302
      /* Set version for table */
305
 
      for (Table *table= session->open_tables; table ; table= table->getNext())
 
303
      for (Table *table= session->open_tables.open_tables_; table ; table= table->getNext())
306
304
      {
307
305
        /*
308
306
          Preserve the version (0) of write locked tables so that a impending
312
310
          table->getMutableShare()->refreshVersion();
313
311
      }
314
312
    }
315
 
 
316
 
    table::Cache::singleton().mutex().unlock();
317
313
  }
318
314
 
319
315
  if (wait_for_refresh)
320
316
  {
321
 
    boost_unique_lock_t scopedLock(session->mysys_var->mutex);
 
317
    boost::mutex::scoped_lock scopedLock(session->mysys_var->mutex);
322
318
    session->mysys_var->current_mutex= 0;
323
319
    session->mysys_var->current_cond= 0;
324
320
    session->set_proc_info(0);
329
325
 
330
326
 
331
327
/**
332
 
  move one table to free list 
 
328
  move one table to free list
333
329
*/
334
330
 
335
 
bool Session::free_cached_table()
 
331
bool Session::free_cached_table(boost::mutex::scoped_lock &scopedLock)
336
332
{
337
333
  bool found_old_table= false;
338
 
  table::Concurrent *table= static_cast<table::Concurrent *>(open_tables);
339
 
 
340
 
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
 
334
 
 
335
  (void)scopedLock;
 
336
 
 
337
  table::Concurrent *table= static_cast<table::Concurrent *>(open_tables.open_tables_);
 
338
 
 
339
  safe_mutex_assert_owner(table::Cache::mutex().native_handle());
341
340
  assert(table->key_read == 0);
342
341
  assert(!table->cursor || table->cursor->inited == Cursor::NONE);
343
342
 
344
 
  open_tables= table->getNext();
 
343
  open_tables.open_tables_= table->getNext();
345
344
 
346
345
  if (table->needs_reopen_or_name_lock() ||
347
 
      version != refresh_version || !table->db_stat)
 
346
      open_tables.version != g_refresh_version || !table->db_stat)
348
347
  {
349
348
    table::remove_table(table);
350
349
    found_old_table= true;
380
379
{
381
380
  bool found_old_table= false;
382
381
 
383
 
  safe_mutex_assert_not_owner(table::Cache::singleton().mutex().native_handle());
384
 
 
385
 
  boost_unique_lock_t scoped_lock(table::Cache::singleton().mutex()); /* Close all open tables on Session */
386
 
 
387
 
  while (open_tables)
 
382
  safe_mutex_assert_not_owner(table::Cache::mutex().native_handle());
 
383
 
 
384
  boost::mutex::scoped_lock scoped_lock(table::Cache::mutex()); /* Close all open tables on Session */
 
385
 
 
386
  while (open_tables.open_tables_)
388
387
  {
389
 
    found_old_table|= free_cached_table();
 
388
    found_old_table|= free_cached_table(scoped_lock);
390
389
  }
391
390
  some_tables_deleted= false;
392
391
 
422
421
{
423
422
  for (; table; table= table->*link )
424
423
  {
425
 
    if ((table->table == 0 || table->table->getShare()->getType() == message::Table::STANDARD) &&
426
 
        strcasecmp(table->getSchemaName(), db_name) == 0 &&
427
 
        strcasecmp(table->getTableName(), table_name) == 0)
 
424
    if ((table->table == 0 || table->table->getShare()->getType() == message::Table::STANDARD) and
 
425
        my_strcasecmp(system_charset_info, table->getSchemaName(), db_name) == 0 and
 
426
        my_strcasecmp(system_charset_info, table->getTableName(), table_name) == 0)
 
427
    {
428
428
      break;
 
429
    }
429
430
  }
430
431
  return table;
431
432
}
517
518
}
518
519
 
519
520
 
520
 
void Open_tables_state::doGetTableNames(const SchemaIdentifier &schema_identifier,
 
521
void Open_tables_state::doGetTableNames(const identifier::Schema &schema_identifier,
521
522
                                        std::set<std::string>& set_of_names)
522
523
{
523
524
  for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
530
531
}
531
532
 
532
533
void Open_tables_state::doGetTableNames(CachedDirectory &,
533
 
                                        const SchemaIdentifier &schema_identifier,
 
534
                                        const identifier::Schema &schema_identifier,
534
535
                                        std::set<std::string> &set_of_names)
535
536
{
536
537
  doGetTableNames(schema_identifier, set_of_names);
537
538
}
538
539
 
539
 
void Open_tables_state::doGetTableIdentifiers(const SchemaIdentifier &schema_identifier,
540
 
                                              TableIdentifier::vector &set_of_identifiers)
 
540
void Open_tables_state::doGetTableIdentifiers(const identifier::Schema &schema_identifier,
 
541
                                              identifier::table::vector &set_of_identifiers)
541
542
{
542
543
  for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
543
544
  {
544
545
    if (schema_identifier.compare(table->getShare()->getSchemaName()))
545
546
    {
546
 
      set_of_identifiers.push_back(TableIdentifier(table->getShare()->getSchemaName(),
 
547
      set_of_identifiers.push_back(identifier::Table(table->getShare()->getSchemaName(),
547
548
                                                   table->getShare()->getTableName(),
548
549
                                                   table->getShare()->getPath()));
549
550
    }
551
552
}
552
553
 
553
554
void Open_tables_state::doGetTableIdentifiers(CachedDirectory &,
554
 
                                              const SchemaIdentifier &schema_identifier,
555
 
                                              TableIdentifier::vector &set_of_identifiers)
 
555
                                              const identifier::Schema &schema_identifier,
 
556
                                              identifier::table::vector &set_of_identifiers)
556
557
{
557
558
  doGetTableIdentifiers(schema_identifier, set_of_identifiers);
558
559
}
559
560
 
560
 
bool Open_tables_state::doDoesTableExist(const TableIdentifier &identifier)
 
561
bool Open_tables_state::doDoesTableExist(const identifier::Table &identifier)
561
562
{
562
563
  for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
563
564
  {
573
574
  return false;
574
575
}
575
576
 
576
 
int Open_tables_state::doGetTableDefinition(const TableIdentifier &identifier,
577
 
                                  message::Table &table_proto)
 
577
int Open_tables_state::doGetTableDefinition(const identifier::Table &identifier,
 
578
                                            message::Table &table_proto)
578
579
{
579
580
  for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
580
581
  {
582
583
    {
583
584
      if (identifier.getKey() == table->getShare()->getCacheKey())
584
585
      {
585
 
        table_proto.CopyFrom(*(table->getShare()->getTableProto()));
 
586
        table_proto.CopyFrom(*(table->getShare()->getTableMessage()));
586
587
 
587
588
        return EEXIST;
588
589
      }
592
593
  return ENOENT;
593
594
}
594
595
 
595
 
Table *Open_tables_state::find_temporary_table(const TableIdentifier &identifier)
 
596
Table *Open_tables_state::find_temporary_table(const identifier::Table &identifier)
596
597
{
597
598
  for (Table *table= temporary_tables ; table ; table= table->getNext())
598
599
  {
630
631
  @retval -1  the table is in use by a outer query
631
632
*/
632
633
 
633
 
int Open_tables_state::drop_temporary_table(const drizzled::TableIdentifier &identifier)
 
634
int Open_tables_state::drop_temporary_table(const drizzled::identifier::Table &identifier)
634
635
{
635
 
  Table *table;
636
 
 
637
 
  if (not (table= find_temporary_table(identifier)))
 
636
  Table* table= find_temporary_table(identifier);
 
637
  if (not table)
638
638
    return 1;
639
639
 
640
640
  /* Table might be in use by some outer statement. */
641
 
  if (table->query_id && table->query_id != getQueryId())
 
641
  if (table->query_id && table->query_id != session_.getQueryId())
642
642
  {
643
643
    my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->getAlias());
644
644
    return -1;
645
645
  }
646
 
 
647
646
  close_temporary_table(table);
648
 
 
649
647
  return 0;
650
648
}
651
649
 
662
660
 
663
661
void Session::unlink_open_table(Table *find)
664
662
{
665
 
  const TableIdentifier::Key find_key(find->getShare()->getCacheKey());
 
663
  const identifier::Table::Key find_key(find->getShare()->getCacheKey());
666
664
  Table **prev;
667
 
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
 
665
  safe_mutex_assert_owner(table::Cache::mutex().native_handle());
668
666
 
669
667
  /*
670
 
    Note that we need to hold table::Cache::singleton().mutex() while changing the
 
668
    Note that we need to hold table::Cache::mutex() while changing the
671
669
    open_tables list. Another thread may work on it.
672
 
    (See: table::Cache::singleton().removeTable(), mysql_wait_completed_table())
 
670
    (See: table::Cache::removeTable(), wait_completed_table())
673
671
    Closing a MERGE child before the parent would be fatal if the
674
672
    other thread tries to abort the MERGE lock in between.
675
673
  */
676
 
  for (prev= &open_tables; *prev; )
 
674
  for (prev= &open_tables.open_tables_; *prev; )
677
675
  {
678
676
    Table *list= *prev;
679
677
 
716
714
  table that was locked with LOCK TABLES.
717
715
*/
718
716
 
719
 
void Session::drop_open_table(Table *table, const TableIdentifier &identifier)
 
717
void Session::drop_open_table(Table *table, const identifier::Table &identifier)
720
718
{
721
719
  if (table->getShare()->getType())
722
720
  {
723
 
    close_temporary_table(table);
 
721
    open_tables.close_temporary_table(table);
724
722
  }
725
723
  else
726
724
  {
727
 
    boost_unique_lock_t scoped_lock(table::Cache::singleton().mutex()); /* Close and drop a table (AUX routine) */
 
725
    boost::mutex::scoped_lock scoped_lock(table::Cache::mutex()); /* Close and drop a table (AUX routine) */
728
726
    /*
729
727
      unlink_open_table() also tells threads waiting for refresh or close
730
728
      that something has happened.
731
729
    */
732
730
    unlink_open_table(table);
733
 
    plugin::StorageEngine::dropTable(*this, identifier);
 
731
    (void)plugin::StorageEngine::dropTable(*this, identifier);
734
732
  }
735
733
}
736
734
 
765
763
      condition variables that are guranteed to not disapper (freed) even if this
766
764
      mutex is unlocked
767
765
    */
768
 
    boost_unique_lock_t scopedLock(mutex, boost::adopt_lock_t());
 
766
    boost::mutex::scoped_lock scopedLock(mutex, boost::adopt_lock_t());
769
767
    if (not getKilled())
770
768
    {
771
769
      cond.wait(scopedLock);
772
770
    }
773
771
  }
774
 
  boost_unique_lock_t mysys_scopedLock(mysys_var->mutex);
 
772
  boost::mutex::scoped_lock mysys_scopedLock(mysys_var->mutex);
775
773
  mysys_var->current_mutex= 0;
776
774
  mysys_var->current_cond= 0;
777
775
  set_proc_info(saved_proc_info);
791
789
  case of failure.
792
790
*/
793
791
 
794
 
table::Placeholder *Session::table_cache_insert_placeholder(const drizzled::TableIdentifier &arg)
 
792
table::Placeholder& Session::table_cache_insert_placeholder(const drizzled::identifier::Table &arg)
795
793
{
796
 
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
 
794
  safe_mutex_assert_owner(table::Cache::mutex().native_handle());
797
795
 
798
796
  /*
799
797
    Create a table entry with the right key and with an old refresh version
800
798
  */
801
 
  TableIdentifier identifier(arg.getSchemaName(), arg.getTableName(), message::Table::INTERNAL);
802
 
  table::Placeholder *table= new table::Placeholder(this, identifier);
803
 
 
804
 
  if (not table::Cache::singleton().insert(table))
805
 
  {
806
 
    delete table;
807
 
 
808
 
    return NULL;
809
 
  }
810
 
 
811
 
  return table;
 
799
  identifier::Table identifier(arg.getSchemaName(), arg.getTableName(), message::Table::INTERNAL);
 
800
  table::Placeholder* table= new table::Placeholder(this, identifier);
 
801
  table::Cache::insert(table);
 
802
  return *table;
812
803
}
813
804
 
814
805
 
833
824
  @retval  true   Error occured (OOM)
834
825
  @retval  false  Success. 'table' parameter set according to above rules.
835
826
*/
836
 
bool Session::lock_table_name_if_not_cached(const TableIdentifier &identifier, Table **table)
 
827
bool Session::lock_table_name_if_not_cached(const identifier::Table &identifier, Table **table)
837
828
{
838
 
  const TableIdentifier::Key &key(identifier.getKey());
839
 
 
840
 
  boost_unique_lock_t scope_lock(table::Cache::singleton().mutex()); /* Obtain a name lock even though table is not in cache (like for create table)  */
841
 
 
842
 
  table::CacheMap::iterator iter;
843
 
 
844
 
  iter= table::getCache().find(key);
845
 
 
846
 
  if (iter != table::getCache().end())
 
829
  const identifier::Table::Key &key(identifier.getKey());
 
830
 
 
831
  boost::mutex::scoped_lock scope_lock(table::Cache::mutex()); /* Obtain a name lock even though table is not in cache (like for create table)  */
 
832
 
 
833
  if (find_ptr(table::getCache(), key))
847
834
  {
848
835
    *table= 0;
849
836
    return false;
850
837
  }
851
838
 
852
 
  if (not (*table= table_cache_insert_placeholder(identifier)))
853
 
  {
854
 
    return true;
855
 
  }
 
839
  *table= &table_cache_insert_placeholder(identifier);
856
840
  (*table)->open_placeholder= true;
857
 
  (*table)->setNext(open_tables);
858
 
  open_tables= *table;
 
841
  (*table)->setNext(open_tables.open_tables_);
 
842
  open_tables.open_tables_= *table;
859
843
 
860
 
  return false;
 
844
  return false; //return void
861
845
}
862
846
 
863
847
/*
899
883
  const char *alias= table_list->alias;
900
884
 
901
885
  /* Parsing of partitioning information from .frm needs session->lex set up. */
902
 
  assert(lex->is_lex_started);
 
886
  assert(lex().is_lex_started);
903
887
 
904
888
  /* find a unused table in the open table cache */
905
889
  if (refresh)
912
896
  if (getKilled())
913
897
    return NULL;
914
898
 
915
 
  TableIdentifier identifier(table_list->getSchemaName(), table_list->getTableName());
916
 
  const TableIdentifier::Key &key(identifier.getKey());
 
899
  identifier::Table identifier(table_list->getSchemaName(), table_list->getTableName());
 
900
  const identifier::Table::Key &key(identifier.getKey());
917
901
  table::CacheRange ppp;
918
902
 
919
903
  /*
924
908
    TODO -> move this block into a separate function.
925
909
  */
926
910
  bool reset= false;
927
 
  for (table= getTemporaryTables(); table ; table=table->getNext())
 
911
  for (table= open_tables.getTemporaryTables(); table ; table=table->getNext())
928
912
  {
929
913
    if (table->getShare()->getCacheKey() == key)
930
914
    {
949
933
  {
950
934
    if (flags & DRIZZLE_OPEN_TEMPORARY_ONLY)
951
935
    {
952
 
      my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->getSchemaName(), table_list->getTableName());
 
936
      my_error(ER_TABLE_UNKNOWN, identifier);
953
937
      return NULL;
954
938
    }
955
939
 
962
946
 
963
947
      Note-> refresh_version is currently changed only during FLUSH TABLES.
964
948
    */
965
 
    if (!open_tables)
 
949
    if (!open_tables.open_tables_)
966
950
    {
967
 
      version= refresh_version;
 
951
      open_tables.version= g_refresh_version;
968
952
    }
969
 
    else if ((version != refresh_version) &&
 
953
    else if ((open_tables.version != g_refresh_version) &&
970
954
             ! (flags & DRIZZLE_LOCK_IGNORE_FLUSH))
971
955
    {
972
956
      /* Someone did a refresh while thread was opening tables */
977
961
    }
978
962
 
979
963
    /*
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
964
      Non pre-locked/LOCK TABLES mode, and the table is not temporary:
989
965
      this is the normal use case.
990
966
      Now we should:
994
970
      until no one holds a name lock on the table.
995
971
      - if there is no such Table in the name cache, read the table definition
996
972
      and insert it into the cache.
997
 
      We perform all of the above under table::Cache::singleton().mutex() which currently protects
 
973
      We perform all of the above under table::Cache::mutex() which currently protects
998
974
      the open cache (also known as table cache) and table definitions stored
999
975
      on disk.
1000
976
    */
1001
977
 
1002
978
    {
1003
 
      table::Cache::singleton().mutex().lock(); /* Lock for FLUSH TABLES for open table */
 
979
      boost::mutex::scoped_lock scopedLock(table::Cache::mutex());
1004
980
 
1005
981
      /*
1006
982
        Actually try to find the table in the open_cache.
1015
991
      ppp= table::getCache().equal_range(key);
1016
992
 
1017
993
      table= NULL;
1018
 
      for (table::CacheMap::const_iterator iter= ppp.first;
1019
 
           iter != ppp.second; ++iter, table= NULL)
 
994
      for (table::CacheMap::const_iterator iter= ppp.first; iter != ppp.second; ++iter, table= NULL)
1020
995
      {
1021
 
        table= (*iter).second;
 
996
        table= iter->second;
1022
997
 
1023
998
        if (not table->in_use)
1024
999
          break;
1045
1020
          if (flags & DRIZZLE_LOCK_IGNORE_FLUSH)
1046
1021
          {
1047
1022
            /* Force close at once after usage */
1048
 
            version= table->getShare()->getVersion();
 
1023
            open_tables.version= table->getShare()->getVersion();
1049
1024
            continue;
1050
1025
          }
1051
1026
 
1052
1027
          /* Avoid self-deadlocks by detecting self-dependencies. */
1053
1028
          if (table->open_placeholder && table->in_use == this)
1054
1029
          {
1055
 
            table::Cache::singleton().mutex().unlock();
1056
1030
            my_error(ER_UPDATE_TABLE_USED, MYF(0), table->getShare()->getTableName());
1057
1031
            return NULL;
1058
1032
          }
1085
1059
          */
1086
1060
          if (table->in_use != this)
1087
1061
          {
1088
 
            /* wait_for_conditionwill unlock table::Cache::singleton().mutex() for us */
1089
 
            wait_for_condition(table::Cache::singleton().mutex(), COND_refresh);
 
1062
            /* wait_for_conditionwill unlock table::Cache::mutex() for us */
 
1063
            wait_for_condition(table::Cache::mutex(), COND_refresh);
 
1064
            scopedLock.release();
1090
1065
          }
1091
1066
          else
1092
1067
          {
1093
 
            table::Cache::singleton().mutex().unlock();
 
1068
            scopedLock.unlock();
1094
1069
          }
 
1070
 
1095
1071
          /*
1096
1072
            There is a refresh in progress for this table.
1097
1073
            Signal the caller that it has to try again.
1098
1074
          */
1099
1075
          if (refresh)
1100
1076
            *refresh= true;
 
1077
 
1101
1078
          return NULL;
1102
1079
        }
1103
1080
      }
 
1081
 
1104
1082
      if (table)
1105
1083
      {
1106
1084
        table::getUnused().unlink(static_cast<table::Concurrent *>(table));
1109
1087
      else
1110
1088
      {
1111
1089
        /* Insert a new Table instance into the open cache */
1112
 
        int error;
1113
1090
        /* Free cache if too big */
1114
1091
        table::getUnused().cull();
1115
1092
 
1116
1093
        if (table_list->isCreate())
1117
1094
        {
1118
 
          TableIdentifier  lock_table_identifier(table_list->getSchemaName(), table_list->getTableName(), message::Table::STANDARD);
 
1095
          identifier::Table  lock_table_identifier(table_list->getSchemaName(), table_list->getTableName(), message::Table::STANDARD);
1119
1096
 
1120
1097
          if (not plugin::StorageEngine::doesTableExist(*this, lock_table_identifier))
1121
1098
          {
1122
1099
            /*
1123
1100
              Table to be created, so we need to create placeholder in table-cache.
1124
1101
            */
1125
 
            if (!(table= table_cache_insert_placeholder(lock_table_identifier)))
1126
 
            {
1127
 
              table::Cache::singleton().mutex().unlock();
1128
 
              return NULL;
1129
 
            }
 
1102
            table= &table_cache_insert_placeholder(lock_table_identifier);
1130
1103
            /*
1131
1104
              Link placeholder to the open tables list so it will be automatically
1132
1105
              removed once tables are closed. Also mark it so it won't be ignored
1133
1106
              by other trying to take name-lock.
1134
1107
            */
1135
1108
            table->open_placeholder= true;
1136
 
            table->setNext(open_tables);
1137
 
            open_tables= table;
1138
 
            table::Cache::singleton().mutex().unlock();
 
1109
            table->setNext(open_tables.open_tables_);
 
1110
            open_tables.open_tables_= table;
1139
1111
 
1140
1112
            return table ;
1141
1113
          }
1146
1118
        {
1147
1119
          table::Concurrent *new_table= new table::Concurrent;
1148
1120
          table= new_table;
1149
 
          if (new_table == NULL)
1150
 
          {
1151
 
            table::Cache::singleton().mutex().unlock();
1152
 
            return NULL;
1153
 
          }
1154
 
 
1155
 
          error= new_table->open_unireg_entry(this, alias, identifier);
1156
 
          if (error != 0)
 
1121
          if (new_table->open_unireg_entry(this, alias, identifier))
1157
1122
          {
1158
1123
            delete new_table;
1159
 
            table::Cache::singleton().mutex().unlock();
1160
1124
            return NULL;
1161
1125
          }
1162
 
          (void)table::Cache::singleton().insert(new_table);
 
1126
          (void)table::Cache::insert(new_table);
1163
1127
        }
1164
1128
      }
 
1129
    }
1165
1130
 
1166
 
      table::Cache::singleton().mutex().unlock();
1167
 
    }
1168
1131
    if (refresh)
1169
1132
    {
1170
 
      table->setNext(open_tables); /* Link into simple list */
1171
 
      open_tables= table;
 
1133
      table->setNext(open_tables.open_tables_); /* Link into simple list */
 
1134
      open_tables.open_tables_= table;
1172
1135
    }
1173
1136
    table->reginfo.lock_type= TL_READ; /* Assume read */
1174
1137
 
1182
1145
  }
1183
1146
 
1184
1147
  /* These variables are also set in reopen_table() */
1185
 
  table->tablenr= current_tablenr++;
 
1148
  table->tablenr= open_tables.current_tablenr++;
1186
1149
  table->used_fields= 0;
1187
1150
  table->const_table= 0;
1188
1151
  table->null_row= false;
1222
1185
  the strings are used in a loop even after the share may be freed.
1223
1186
*/
1224
1187
 
1225
 
void Session::close_data_files_and_morph_locks(const TableIdentifier &identifier)
 
1188
void Session::close_data_files_and_morph_locks(const identifier::Table &identifier)
1226
1189
{
1227
 
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle()); /* Adjust locks at the end of ALTER TABLEL */
 
1190
  safe_mutex_assert_owner(table::Cache::mutex().native_handle()); /* Adjust locks at the end of ALTER TABLEL */
1228
1191
 
1229
 
  if (lock)
 
1192
  if (open_tables.lock)
1230
1193
  {
1231
1194
    /*
1232
1195
      If we are not under LOCK TABLES we should have only one table
1233
1196
      open and locked so it makes sense to remove the lock at once.
1234
1197
    */
1235
 
    unlockTables(lock);
1236
 
    lock= 0;
 
1198
    unlockTables(open_tables.lock);
 
1199
    open_tables.lock= 0;
1237
1200
  }
1238
1201
 
1239
1202
  /*
1241
1204
    for target table name if we process ALTER Table ... RENAME.
1242
1205
    So loop below makes sense even if we are not under LOCK TABLES.
1243
1206
  */
1244
 
  for (Table *table= open_tables; table ; table=table->getNext())
 
1207
  for (Table *table= open_tables.open_tables_; table ; table=table->getNext())
1245
1208
  {
1246
1209
    if (table->getShare()->getCacheKey() == identifier.getKey())
1247
1210
    {
1267
1230
  combination when one needs tables to be reopened (for
1268
1231
  example see openTablesLock()).
1269
1232
 
1270
 
  @note One should have lock on table::Cache::singleton().mutex() when calling this.
 
1233
  @note One should have lock on table::Cache::mutex() when calling this.
1271
1234
 
1272
1235
  @return false in case of success, true - otherwise.
1273
1236
*/
1274
1237
 
1275
 
bool Session::reopen_tables(bool get_locks, bool)
 
1238
bool Session::reopen_tables()
1276
1239
{
1277
1240
  Table *table,*next,**prev;
1278
 
  Table **tables,**tables_ptr;                  // For locks
1279
 
  bool error=0, not_used;
 
1241
  Table **tables= 0;                    // For locks
 
1242
  Table **tables_ptr= 0;                        // For locks
 
1243
  bool error= false;
1280
1244
  const uint32_t flags= DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN |
1281
1245
    DRIZZLE_LOCK_IGNORE_GLOBAL_READ_LOCK |
1282
1246
    DRIZZLE_LOCK_IGNORE_FLUSH;
1283
1247
 
1284
 
  if (open_tables == NULL)
 
1248
  if (open_tables.open_tables_ == NULL)
1285
1249
    return false;
1286
1250
 
1287
 
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
1288
 
  if (get_locks)
 
1251
  safe_mutex_assert_owner(table::Cache::mutex().native_handle());
1289
1252
  {
1290
1253
    /*
1291
1254
      The ptr is checked later
1293
1256
    */
1294
1257
    uint32_t opens= 0;
1295
1258
 
1296
 
    for (table= open_tables; table ; table=table->getNext())
 
1259
    for (table= open_tables.open_tables_; table ; table=table->getNext())
1297
1260
    {
1298
1261
      opens++;
1299
1262
    }
1300
1263
    tables= new Table *[opens];
1301
1264
  }
1302
 
  else
1303
 
  {
1304
 
    tables= &open_tables;
1305
 
  }
 
1265
 
1306
1266
  tables_ptr =tables;
1307
1267
 
1308
 
  prev= &open_tables;
1309
 
  for (table= open_tables; table ; table=next)
 
1268
  prev= &open_tables.open_tables_;
 
1269
  for (table= open_tables.open_tables_; table ; table=next)
1310
1270
  {
1311
1271
    next= table->getNext();
1312
1272
 
1315
1275
    error= 1;
1316
1276
  }
1317
1277
  *prev=0;
 
1278
 
1318
1279
  if (tables != tables_ptr)                     // Should we get back old locks
1319
1280
  {
1320
1281
    DrizzleLock *local_lock;
1321
1282
    /*
1322
1283
      We should always get these locks. Anyway, we must not go into
1323
 
      wait_for_tables() as it tries to acquire table::Cache::singleton().mutex(), which is
 
1284
      wait_for_tables() as it tries to acquire table::Cache::mutex(), which is
1324
1285
      already locked.
1325
1286
    */
1326
1287
    some_tables_deleted= false;
1327
1288
 
1328
 
    if ((local_lock= lockTables(tables, (uint32_t) (tables_ptr - tables),
1329
 
                                       flags, &not_used)))
 
1289
    if ((local_lock= lockTables(tables, (uint32_t) (tables_ptr - tables), flags)))
1330
1290
    {
1331
1291
      /* unused */
1332
1292
    }
1342
1302
    }
1343
1303
  }
1344
1304
 
1345
 
  if (get_locks && tables)
1346
 
    delete [] tables;
 
1305
  delete [] tables;
1347
1306
 
1348
1307
  locking::broadcast_refresh();
1349
1308
 
1350
 
  return(error);
 
1309
  return error;
1351
1310
}
1352
1311
 
1353
1312
 
1369
1328
{
1370
1329
  bool found= send_refresh;
1371
1330
 
1372
 
  Table *table= open_tables;
 
1331
  Table *table= open_tables.open_tables_;
1373
1332
 
1374
1333
  for (; table ; table=table->getNext())
1375
1334
  {
1378
1337
    */
1379
1338
    if (table->needs_reopen_or_name_lock())
1380
1339
    {
1381
 
      found=1;
 
1340
      found= true;
1382
1341
      if (table->db_stat)
1383
1342
      {
1384
1343
        if (morph_locks)
1437
1396
}
1438
1397
 
1439
1398
 
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
1399
/*
1476
1400
  drop tables from locked list
1477
1401
 
1496
1420
*/
1497
1421
 
1498
1422
 
1499
 
Table *drop_locked_tables(Session *session, const drizzled::TableIdentifier &identifier)
 
1423
Table *drop_locked_tables(Session *session, const drizzled::identifier::Table &identifier)
1500
1424
{
1501
1425
  Table *table,*next,**prev, *found= 0;
1502
 
  prev= &session->open_tables;
 
1426
  prev= &session->open_tables.open_tables_;
1503
1427
 
1504
1428
  /*
1505
 
    Note that we need to hold table::Cache::singleton().mutex() while changing the
 
1429
    Note that we need to hold table::Cache::mutex() while changing the
1506
1430
    open_tables list. Another thread may work on it.
1507
 
    (See: table::Cache::singleton().removeTable(), mysql_wait_completed_table())
 
1431
    (See: table::Cache::removeTable(), wait_completed_table())
1508
1432
    Closing a MERGE child before the parent would be fatal if the
1509
1433
    other thread tries to abort the MERGE lock in between.
1510
1434
  */
1511
 
  for (table= session->open_tables; table ; table=next)
 
1435
  for (table= session->open_tables.open_tables_; table ; table=next)
1512
1436
  {
1513
1437
    next=table->getNext();
1514
1438
    if (table->getShare()->getCacheKey() == identifier.getKey())
1538
1462
    }
1539
1463
  }
1540
1464
  *prev=0;
 
1465
 
1541
1466
  if (found)
1542
1467
    locking::broadcast_refresh();
1543
1468
 
1544
 
  return(found);
 
1469
  return found;
1545
1470
}
1546
1471
 
1547
1472
 
1551
1476
  other threads trying to get the lock.
1552
1477
*/
1553
1478
 
1554
 
void abort_locked_tables(Session *session, const drizzled::TableIdentifier &identifier)
 
1479
void abort_locked_tables(Session *session, const drizzled::identifier::Table &identifier)
1555
1480
{
1556
1481
  Table *table;
1557
 
  for (table= session->open_tables; table ; table= table->getNext())
 
1482
  for (table= session->open_tables.open_tables_; table ; table= table->getNext())
1558
1483
  {
1559
1484
    if (table->getShare()->getCacheKey() == identifier.getKey())
1560
1485
    {
1561
1486
      /* If MERGE child, forward lock handling to parent. */
1562
1487
      session->abortLock(table);
 
1488
      assert(0);
1563
1489
      break;
1564
1490
    }
1565
1491
  }
1602
1528
  /* Also used for indicating that prelocking is need */
1603
1529
  bool safe_to_ignore_table;
1604
1530
 
1605
 
  current_tablenr= 0;
 
1531
  open_tables.current_tablenr= 0;
1606
1532
restart:
1607
1533
  *counter= 0;
1608
1534
  set_proc_info("Opening tables");
1632
1558
     * to see if it exists so that an unauthorized user cannot phish for
1633
1559
     * table/schema information via error messages
1634
1560
     */
1635
 
    TableIdentifier the_table(tables->getSchemaName(), tables->getTableName());
1636
 
    if (not plugin::Authorization::isAuthorized(getSecurityContext(),
1637
 
                                                the_table))
 
1561
    identifier::Table the_table(tables->getSchemaName(), tables->getTableName());
 
1562
    if (not plugin::Authorization::isAuthorized(*user(), the_table))
1638
1563
    {
1639
1564
      result= -1;                               // Fatal error
1640
1565
      break;
1730
1655
  bool refresh;
1731
1656
 
1732
1657
  set_proc_info("Opening table");
1733
 
  current_tablenr= 0;
1734
 
  while (!(table= openTable(table_list, &refresh)) &&
1735
 
         refresh)
1736
 
    ;
 
1658
  open_tables.current_tablenr= 0;
 
1659
  while (!(table= openTable(table_list, &refresh)) && refresh) ;
1737
1660
 
1738
1661
  if (table)
1739
1662
  {
1740
1663
    table_list->lock_type= lock_type;
1741
1664
    table_list->table=     table;
1742
1665
 
1743
 
    assert(lock == 0);  // You must lock everything at once
 
1666
    assert(open_tables.lock == 0);      // You must lock everything at once
1744
1667
    if ((table->reginfo.lock_type= lock_type) != TL_UNLOCK)
1745
 
      if (! (lock= lockTables(&table_list->table, 1, 0, &refresh)))
1746
 
        table= 0;
 
1668
    {
 
1669
      if (not (open_tables.lock= lockTables(&table_list->table, 1, 0)))
 
1670
        table= NULL;
 
1671
    }
1747
1672
  }
1748
1673
 
1749
1674
  set_proc_info(0);
1793
1718
  if (tables == NULL)
1794
1719
    return 0;
1795
1720
 
1796
 
  assert(session->lock == 0);   // You must lock everything at once
 
1721
  assert(session->open_tables.lock == 0);       // You must lock everything at once
1797
1722
  Table **start,**ptr;
1798
1723
  uint32_t lock_flag= DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN;
1799
1724
 
1800
 
  if (!(ptr=start=(Table**) session->alloc(sizeof(Table*)*count)))
 
1725
  if (!(ptr=start=(Table**) session->getMemRoot()->allocate(sizeof(Table*)*count)))
1801
1726
    return -1;
 
1727
 
1802
1728
  for (table= tables; table; table= table->next_global)
1803
1729
  {
1804
1730
    if (!table->placeholder())
1805
1731
      *(ptr++)= table->table;
1806
1732
  }
1807
1733
 
1808
 
  if (!(session->lock= session->lockTables(start, (uint32_t) (ptr - start), lock_flag, need_reopen)))
 
1734
  if (not (session->open_tables.lock= session->lockTables(start, (uint32_t) (ptr - start), lock_flag)))
1809
1735
  {
1810
1736
    return -1;
1811
1737
  }
1834
1760
#  Table object
1835
1761
*/
1836
1762
 
1837
 
Table *Open_tables_state::open_temporary_table(const TableIdentifier &identifier,
1838
 
                                               bool link_in_list)
 
1763
Table* Session::open_temporary_table(const identifier::Table &identifier, bool link_in_list)
1839
1764
{
1840
1765
  assert(identifier.isTmp());
1841
1766
 
1842
1767
 
1843
1768
  table::Temporary *new_tmp_table= new table::Temporary(identifier.getType(),
1844
1769
                                                        identifier,
1845
 
                                                        const_cast<char *>(const_cast<TableIdentifier&>(identifier).getPath().c_str()),
 
1770
                                                        const_cast<char *>(const_cast<identifier::Table&>(identifier).getPath().c_str()),
1846
1771
                                                        static_cast<uint32_t>(identifier.getPath().length()));
1847
1772
  if (not new_tmp_table)
1848
1773
    return NULL;
1869
1794
  if (link_in_list)
1870
1795
  {
1871
1796
    /* growing temp list at the head */
1872
 
    new_tmp_table->setNext(this->temporary_tables);
 
1797
    new_tmp_table->setNext(open_tables.temporary_tables);
1873
1798
    if (new_tmp_table->getNext())
1874
1799
    {
1875
1800
      new_tmp_table->getNext()->setPrev(new_tmp_table);
1876
1801
    }
1877
 
    this->temporary_tables= new_tmp_table;
1878
 
    this->temporary_tables->setPrev(0);
 
1802
    open_tables.temporary_tables= new_tmp_table;
 
1803
    open_tables.temporary_tables->setPrev(0);
1879
1804
  }
1880
1805
  new_tmp_table->pos_in_table_list= 0;
1881
1806
 
1964
1889
                           const char *name, uint32_t , Item **,
1965
1890
                           bool, TableList **actual_table)
1966
1891
{
1967
 
  List_iterator_fast<Natural_join_column>
1968
 
    field_it(*(table_ref->join_columns));
 
1892
  List<Natural_join_column>::iterator
 
1893
    field_it(table_ref->join_columns->begin());
1969
1894
  Natural_join_column *nj_col, *curr_nj_col;
1970
1895
  Field *found_field;
1971
1896
 
1979
1904
    {
1980
1905
      if (nj_col)
1981
1906
      {
1982
 
        my_error(ER_NON_UNIQ_ERROR, MYF(0), name, session->where);
 
1907
        my_error(ER_NON_UNIQ_ERROR, MYF(0), name, session->where());
1983
1908
        return NULL;
1984
1909
      }
1985
1910
      nj_col= curr_nj_col;
2180
2105
    */
2181
2106
    if (table_name && table_name[0])
2182
2107
    {
2183
 
      List_iterator<TableList> it(table_list->getNestedJoin()->join_list);
 
2108
      List<TableList>::iterator it(table_list->getNestedJoin()->join_list.begin());
2184
2109
      TableList *table;
2185
2110
      while ((table= it++))
2186
2111
      {
2330
2255
        fields.
2331
2256
      */
2332
2257
      {
2333
 
        Select_Lex *current_sel= session->lex->current_select;
 
2258
        Select_Lex *current_sel= session->lex().current_select;
2334
2259
        Select_Lex *last_select= table_ref->select_lex;
2335
2260
        /*
2336
2261
          If the field was an outer referencee, mark all selects using this
2376
2301
      */
2377
2302
      item->cached_table= found ?  0 : actual_table;
2378
2303
 
2379
 
      assert(session->where);
 
2304
      assert(session->where());
2380
2305
      /*
2381
2306
        If we found a fully qualified field we return it directly as it can't
2382
2307
        have duplicates.
2389
2314
        if (report_error == REPORT_ALL_ERRORS ||
2390
2315
            report_error == IGNORE_EXCEPT_NON_UNIQUE)
2391
2316
          my_error(ER_NON_UNIQ_ERROR, MYF(0),
2392
 
                   table_name ? item->full_name() : name, session->where);
 
2317
                   table_name ? item->full_name() : name, session->where());
2393
2318
        return (Field*) 0;
2394
2319
      }
2395
2320
      found= cur_field;
2422
2347
      strcat(buff, table_name);
2423
2348
      table_name=buff;
2424
2349
    }
2425
 
    my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, session->where);
 
2350
    my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, session->where());
2426
2351
  }
2427
2352
  else
2428
2353
  {
2429
2354
    if (report_error == REPORT_ALL_ERRORS ||
2430
2355
        report_error == REPORT_EXCEPT_NON_UNIQUE)
2431
 
      my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), session->where);
 
2356
      my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), session->where());
2432
2357
    else
2433
2358
      found= not_found_field;
2434
2359
  }
2479
2404
                  find_item_error_report_type report_error,
2480
2405
                  enum_resolution_type *resolution)
2481
2406
{
2482
 
  List_iterator<Item> li(items);
 
2407
  List<Item>::iterator li(items.begin());
2483
2408
  Item **found=0, **found_unaliased= 0, *item;
2484
2409
  const char *db_name=0;
2485
2410
  const char *field_name=0;
2555
2480
            */
2556
2481
            if (report_error != IGNORE_ERRORS)
2557
2482
              my_error(ER_NON_UNIQ_ERROR, MYF(0),
2558
 
                       find->full_name(), session->where);
 
2483
                       find->full_name(), session->where());
2559
2484
            return (Item**) 0;
2560
2485
          }
2561
2486
          found_unaliased= li.ref();
2586
2511
              continue;                           // Same field twice
2587
2512
            if (report_error != IGNORE_ERRORS)
2588
2513
              my_error(ER_NON_UNIQ_ERROR, MYF(0),
2589
 
                       find->full_name(), session->where);
 
2514
                       find->full_name(), session->where());
2590
2515
            return (Item**) 0;
2591
2516
          }
2592
2517
          found= li.ref();
2638
2563
    {
2639
2564
      if (report_error != IGNORE_ERRORS)
2640
2565
        my_error(ER_NON_UNIQ_ERROR, MYF(0),
2641
 
                 find->full_name(), session->where);
 
2566
                 find->full_name(), session->where());
2642
2567
      return (Item **) 0;
2643
2568
    }
2644
2569
    if (found_unaliased)
2654
2579
  {
2655
2580
    if (report_error == REPORT_ALL_ERRORS)
2656
2581
      my_error(ER_BAD_FIELD_ERROR, MYF(0),
2657
 
               find->full_name(), session->where);
 
2582
               find->full_name(), session->where());
2658
2583
    return (Item **) 0;
2659
2584
  }
2660
2585
  else
2682
2607
static bool
2683
2608
test_if_string_in_list(const char *find, List<String> *str_list)
2684
2609
{
2685
 
  List_iterator<String> str_list_it(*str_list);
 
2610
  List<String>::iterator str_list_it(str_list->begin());
2686
2611
  String *curr_str;
2687
2612
  size_t find_length= strlen(find);
2688
2613
  while ((curr_str= str_list_it++))
2825
2750
        if (cur_nj_col_2->is_common ||
2826
2751
            (found && (!using_fields || is_using_column_1)))
2827
2752
        {
2828
 
          my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1, session->where);
 
2753
          my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1, session->where());
2829
2754
          return(result);
2830
2755
        }
2831
2756
        nj_col_2= cur_nj_col_2;
3013
2938
    columns. If this is not the case, report the first one that was
3014
2939
    not found in an error.
3015
2940
  */
3016
 
  if (using_fields && found_using_fields < using_fields->elements)
 
2941
  if (using_fields && found_using_fields < using_fields->size())
3017
2942
  {
3018
2943
    String *using_field_name;
3019
 
    List_iterator_fast<String> using_fields_it(*using_fields);
 
2944
    List<String>::iterator using_fields_it(using_fields->begin());
3020
2945
    while ((using_field_name= using_fields_it++))
3021
2946
    {
3022
2947
      const char *using_field_name_ptr= using_field_name->c_ptr();
3023
 
      List_iterator_fast<Natural_join_column>
3024
 
        it(*(natural_using_join->join_columns));
 
2948
      List<Natural_join_column>::iterator
 
2949
        it(natural_using_join->join_columns->begin());
3025
2950
      Natural_join_column *common_field;
3026
2951
 
3027
2952
      for (;;)
3030
2955
        if (!(common_field= it++))
3031
2956
        {
3032
2957
          my_error(ER_BAD_FIELD_ERROR, MYF(0), using_field_name_ptr,
3033
 
                   session->where);
 
2958
                   session->where());
3034
2959
          return(result);
3035
2960
        }
3036
2961
        if (!my_strcasecmp(system_charset_info,
3053
2978
    }
3054
2979
  }
3055
2980
 
3056
 
  if (non_join_columns->elements > 0)
 
2981
  if (non_join_columns->size() > 0)
3057
2982
    natural_using_join->join_columns->concat(non_join_columns);
3058
2983
  natural_using_join->is_join_columns_complete= true;
3059
2984
 
3103
3028
  /* Call the procedure recursively for each nested table reference. */
3104
3029
  if (table_ref->getNestedJoin())
3105
3030
  {
3106
 
    List_iterator_fast<TableList> nested_it(table_ref->getNestedJoin()->join_list);
 
3031
    List<TableList>::iterator nested_it(table_ref->getNestedJoin()->join_list.begin());
3107
3032
    TableList *same_level_left_neighbor= nested_it++;
3108
3033
    TableList *same_level_right_neighbor= NULL;
3109
3034
    /* Left/right-most neighbors, possibly at higher levels in the join tree. */
3128
3053
          cur_table_ref->outer_join & JOIN_TYPE_RIGHT)
3129
3054
      {
3130
3055
        /* This can happen only for JOIN ... ON. */
3131
 
        assert(table_ref->getNestedJoin()->join_list.elements == 2);
 
3056
        assert(table_ref->getNestedJoin()->join_list.size() == 2);
3132
3057
        std::swap(same_level_left_neighbor, cur_table_ref);
3133
3058
      }
3134
3059
 
3156
3081
  if (table_ref->is_natural_join)
3157
3082
  {
3158
3083
    assert(table_ref->getNestedJoin() &&
3159
 
           table_ref->getNestedJoin()->join_list.elements == 2);
3160
 
    List_iterator_fast<TableList> operand_it(table_ref->getNestedJoin()->join_list);
 
3084
           table_ref->getNestedJoin()->join_list.size() == 2);
 
3085
    List<TableList>::iterator operand_it(table_ref->getNestedJoin()->join_list.begin());
3161
3086
    /*
3162
3087
      Notice that the order of join operands depends on whether table_ref
3163
3088
      represents a LEFT or a RIGHT join. In a RIGHT join, the operands are
3253
3178
                                         List<TableList> *from_clause,
3254
3179
                                         Name_resolution_context *context)
3255
3180
{
3256
 
  session->where= "from clause";
3257
 
  if (from_clause->elements == 0)
 
3181
  session->setWhere("from clause");
 
3182
  if (from_clause->size() == 0)
3258
3183
    return false; /* We come here in the case of UNIONs. */
3259
3184
 
3260
 
  List_iterator_fast<TableList> table_ref_it(*from_clause);
 
3185
  List<TableList>::iterator table_ref_it(from_clause->begin());
3261
3186
  TableList *table_ref; /* Current table reference. */
3262
3187
  /* Table reference to the left of the current. */
3263
3188
  TableList *left_neighbor;
3307
3232
    return 0;
3308
3233
 
3309
3234
  Item *item;
3310
 
  List_iterator<Item> it(fields);
 
3235
  List<Item>::iterator it(fields.begin());
3311
3236
 
3312
 
  session->lex->current_select->cur_pos_in_select_list= 0;
 
3237
  session->lex().current_select->cur_pos_in_select_list= 0;
3313
3238
  while (wild_num && (item= it++))
3314
3239
  {
3315
3240
    if (item->type() == Item::FIELD_ITEM &&
3317
3242
        ((Item_field*) item)->field_name[0] == '*' &&
3318
3243
        !((Item_field*) item)->field)
3319
3244
    {
3320
 
      uint32_t elem= fields.elements;
 
3245
      uint32_t elem= fields.size();
3321
3246
      bool any_privileges= ((Item_field *) item)->any_privileges;
3322
 
      Item_subselect *subsel= session->lex->current_select->master_unit()->item;
 
3247
      Item_subselect *subsel= session->lex().current_select->master_unit()->item;
3323
3248
      if (subsel &&
3324
3249
          subsel->substype() == Item_subselect::EXISTS_SUBS)
3325
3250
      {
3345
3270
          Because of this we have to update the element count also for this
3346
3271
          list after expanding the '*' entry.
3347
3272
        */
3348
 
        sum_func_list->elements+= fields.elements - elem;
 
3273
        sum_func_list->set_size(sum_func_list->size() + fields.size() - elem);
3349
3274
      }
3350
3275
      wild_num--;
3351
3276
    }
3352
3277
    else
3353
 
      session->lex->current_select->cur_pos_in_select_list++;
 
3278
      session->lex().current_select->cur_pos_in_select_list++;
3354
3279
  }
3355
 
  session->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
 
3280
  session->lex().current_select->cur_pos_in_select_list= UNDEF_POS;
3356
3281
 
3357
3282
  return 0;
3358
3283
}
3367
3292
{
3368
3293
  register Item *item;
3369
3294
  enum_mark_columns save_mark_used_columns= session->mark_used_columns;
3370
 
  nesting_map save_allow_sum_func= session->lex->allow_sum_func;
3371
 
  List_iterator<Item> it(fields);
 
3295
  nesting_map save_allow_sum_func= session->lex().allow_sum_func;
 
3296
  List<Item>::iterator it(fields.begin());
3372
3297
  bool save_is_item_list_lookup;
3373
3298
 
3374
3299
  session->mark_used_columns= mark_used_columns;
3375
3300
  if (allow_sum_func)
3376
 
    session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
3377
 
  session->where= Session::DEFAULT_WHERE;
3378
 
  save_is_item_list_lookup= session->lex->current_select->is_item_list_lookup;
3379
 
  session->lex->current_select->is_item_list_lookup= 0;
 
3301
    session->lex().allow_sum_func|= 1 << session->lex().current_select->nest_level;
 
3302
  session->setWhere(Session::DEFAULT_WHERE);
 
3303
  save_is_item_list_lookup= session->lex().current_select->is_item_list_lookup;
 
3304
  session->lex().current_select->is_item_list_lookup= 0;
3380
3305
 
3381
3306
  /*
3382
3307
    To prevent fail on forward lookup we fill it with zerows,
3386
3311
    There is other way to solve problem: fill array with pointers to list,
3387
3312
    but it will be slower.
3388
3313
 
3389
 
TODO: remove it when (if) we made one list for allfields and
3390
 
ref_pointer_array
 
3314
    TODO-> remove it when (if) we made one list for allfields and ref_pointer_array
3391
3315
  */
3392
3316
  if (ref_pointer_array)
3393
 
    memset(ref_pointer_array, 0, sizeof(Item *) * fields.elements);
 
3317
  {
 
3318
    memset(ref_pointer_array, 0, sizeof(Item *) * fields.size());
 
3319
  }
3394
3320
 
3395
3321
  Item **ref= ref_pointer_array;
3396
 
  session->lex->current_select->cur_pos_in_select_list= 0;
 
3322
  session->lex().current_select->cur_pos_in_select_list= 0;
3397
3323
  while ((item= it++))
3398
3324
  {
3399
3325
    if ((!item->fixed && item->fix_fields(session, it.ref())) || (item= *(it.ref()))->check_cols(1))
3400
3326
    {
3401
 
      session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
3402
 
      session->lex->allow_sum_func= save_allow_sum_func;
 
3327
      session->lex().current_select->is_item_list_lookup= save_is_item_list_lookup;
 
3328
      session->lex().allow_sum_func= save_allow_sum_func;
3403
3329
      session->mark_used_columns= save_mark_used_columns;
3404
3330
      return true;
3405
3331
    }
3409
3335
        sum_func_list)
3410
3336
      item->split_sum_func(session, ref_pointer_array, *sum_func_list);
3411
3337
    session->used_tables|= item->used_tables();
3412
 
    session->lex->current_select->cur_pos_in_select_list++;
 
3338
    session->lex().current_select->cur_pos_in_select_list++;
3413
3339
  }
3414
 
  session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
3415
 
  session->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
 
3340
  session->lex().current_select->is_item_list_lookup= save_is_item_list_lookup;
 
3341
  session->lex().current_select->cur_pos_in_select_list= UNDEF_POS;
3416
3342
 
3417
 
  session->lex->allow_sum_func= save_allow_sum_func;
 
3343
  session->lex().allow_sum_func= save_allow_sum_func;
3418
3344
  session->mark_used_columns= save_mark_used_columns;
3419
3345
  return(test(session->is_error()));
3420
3346
}
3583
3509
 
3584
3510
bool
3585
3511
insert_fields(Session *session, Name_resolution_context *context, const char *db_name,
3586
 
              const char *table_name, List_iterator<Item> *it,
 
3512
              const char *table_name, List<Item>::iterator *it,
3587
3513
              bool )
3588
3514
{
3589
3515
  Field_iterator_table_ref field_iterator;
3622
3548
    assert(tables->is_leaf_for_name_resolution());
3623
3549
 
3624
3550
    if ((table_name && my_strcasecmp(table_alias_charset, table_name, tables->alias)) ||
3625
 
        (db_name && strcasecmp(tables->getSchemaName(),db_name)))
 
3551
        (db_name && my_strcasecmp(system_charset_info, tables->getSchemaName(),db_name)))
3626
3552
      continue;
3627
3553
 
3628
3554
    /*
3686
3612
        }
3687
3613
      }
3688
3614
      else
 
3615
      {
3689
3616
        session->used_tables|= item->used_tables();
3690
 
      session->lex->current_select->cur_pos_in_select_list++;
 
3617
      }
 
3618
 
 
3619
      session->lex().current_select->cur_pos_in_select_list++;
3691
3620
    }
3692
3621
    /*
3693
3622
      In case of stored tables, all fields are considered as used,
3706
3635
    qualified '*', and all columns were coalesced, we have to give a more
3707
3636
    meaningful message than ER_BAD_TABLE_ERROR.
3708
3637
  */
3709
 
  if (!table_name)
 
3638
  if (not table_name)
 
3639
  {
3710
3640
    my_message(ER_NO_TABLES_USED, ER(ER_NO_TABLES_USED), MYF(0));
 
3641
  }
3711
3642
  else
 
3643
  {
3712
3644
    my_error(ER_BAD_TABLE_ERROR, MYF(0), table_name);
 
3645
  }
3713
3646
 
3714
3647
  return true;
3715
3648
}
3736
3669
int Session::setup_conds(TableList *leaves, COND **conds)
3737
3670
{
3738
3671
  Session *session= this;
3739
 
  Select_Lex *select_lex= session->lex->current_select;
 
3672
  Select_Lex *select_lex= session->lex().current_select;
3740
3673
  TableList *table= NULL;       // For HP compilers
3741
3674
  void *save_session_marker= session->session_marker;
3742
3675
  /*
3758
3691
  session->session_marker= (void*)1;
3759
3692
  if (*conds)
3760
3693
  {
3761
 
    session->where="where clause";
 
3694
    session->setWhere("where clause");
3762
3695
    if ((!(*conds)->fixed && (*conds)->fix_fields(session, conds)) ||
3763
3696
        (*conds)->check_cols(1))
3764
3697
      goto err_no_arena;
3780
3713
      {
3781
3714
        /* Make a join an a expression */
3782
3715
        session->session_marker= (void*)embedded;
3783
 
        session->where="on clause";
 
3716
        session->setWhere("on clause");
3784
3717
        if ((!embedded->on_expr->fixed && embedded->on_expr->fix_fields(session, &embedded->on_expr)) ||
3785
3718
            embedded->on_expr->check_cols(1))
3786
3719
          goto err_no_arena;
3789
3722
      embedding= embedded->getEmbedding();
3790
3723
    }
3791
3724
    while (embedding &&
3792
 
           embedding->getNestedJoin()->join_list.head() == embedded);
 
3725
           &embedding->getNestedJoin()->join_list.front() == embedded);
3793
3726
 
3794
3727
  }
3795
3728
  session->session_marker= save_session_marker;
3796
3729
 
3797
 
  session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
 
3730
  session->lex().current_select->is_item_list_lookup= save_is_item_list_lookup;
3798
3731
  return(test(session->is_error()));
3799
3732
 
3800
3733
err_no_arena:
3832
3765
bool
3833
3766
fill_record(Session *session, List<Item> &fields, List<Item> &values, bool ignore_errors)
3834
3767
{
3835
 
  List_iterator_fast<Item> f(fields),v(values);
 
3768
  List<Item>::iterator f(fields.begin());
 
3769
  List<Item>::iterator v(values.begin());
3836
3770
  Item *value;
3837
3771
  Item_field *field;
3838
3772
  Table *table;
3841
3775
    Reset the table->auto_increment_field_not_null as it is valid for
3842
3776
    only one row.
3843
3777
  */
3844
 
  if (fields.elements)
 
3778
  if (fields.size())
3845
3779
  {
3846
3780
    /*
3847
3781
      On INSERT or UPDATE fields are checked to be from the same table,
3850
3784
    field= static_cast<Item_field *>(f++);
3851
3785
    table= field->field->getTable();
3852
3786
    table->auto_increment_field_not_null= false;
3853
 
    f.rewind();
 
3787
    f= fields.begin();
3854
3788
  }
3855
3789
 
3856
3790
  while ((field= static_cast<Item_field *>(f++)))
3897
3831
 
3898
3832
bool fill_record(Session *session, Field **ptr, List<Item> &values, bool)
3899
3833
{
3900
 
  List_iterator_fast<Item> v(values);
 
3834
  List<Item>::iterator v(values.begin());
3901
3835
  Item *value;
3902
3836
  Table *table= 0;
3903
3837
  Field *field;
3915
3849
    table= (*ptr)->getTable();
3916
3850
    table->auto_increment_field_not_null= false;
3917
3851
  }
 
3852
 
3918
3853
  while ((field = *ptr++) && ! session->is_error())
3919
3854
  {
3920
3855
    value=v++;
3921
3856
    table= field->getTable();
 
3857
 
3922
3858
    if (field == table->next_number_field)
3923
3859
      table->auto_increment_field_not_null= true;
 
3860
 
3924
3861
    if (value->save_in_field(field, 0) < 0)
3925
3862
    {
3926
3863
      if (table)
3936
3873
 
3937
3874
bool drizzle_rm_tmp_tables()
3938
3875
{
3939
 
  Session *session;
3940
3876
 
3941
3877
  assert(drizzle_tmpdir.size());
 
3878
  Session::shared_ptr session= Session::make_shared(plugin::Listen::getNullClient(), catalog::local());
3942
3879
 
3943
 
  if (!(session= new Session(plugin::Listen::getNullClient())))
 
3880
  if (not session)
3944
3881
    return true;
3945
 
  session->thread_stack= (char*) &session;
 
3882
  session->thread_stack= (char*) session.get();
3946
3883
  session->storeGlobals();
3947
3884
 
3948
3885
  plugin::StorageEngine::removeLostTemporaryTables(*session, drizzle_tmpdir.c_str());
3949
3886
 
3950
 
  delete session;
3951
 
 
3952
3887
  return false;
3953
3888
}
3954
3889