~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_base.cc

  • Committer: Monty Taylor
  • Date: 2010-10-30 01:19:00 UTC
  • mto: (1892.1.2 build)
  • mto: This revision was merged to the branch mainline in revision 1893.
  • Revision ID: mordred@inaugust.com-20101030011900-2tdt8w9vt7a6pbk0
Fixed things to make things compile with clang

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/epoch.h>
 
47
#include "drizzled/cached_directory.h"
 
48
#include <drizzled/field/timestamp.h>
49
49
#include <drizzled/field/null.h>
50
 
#include <drizzled/sql_table.h>
51
 
#include <drizzled/global_charset_info.h>
52
 
#include <drizzled/pthread_globals.h>
53
 
#include <drizzled/internal/iocache.h>
54
 
#include <drizzled/drizzled.h>
55
 
#include <drizzled/plugin/authorization.h>
56
 
#include <drizzled/table/temporary.h>
57
 
#include <drizzled/table/placeholder.h>
58
 
#include <drizzled/table/unused.h>
59
 
#include <drizzled/plugin/storage_engine.h>
60
 
#include <drizzled/session.h>
61
 
 
62
 
#include <drizzled/refresh_version.h>
 
50
#include "drizzled/sql_table.h"
 
51
#include "drizzled/global_charset_info.h"
 
52
#include "drizzled/pthread_globals.h"
 
53
#include "drizzled/internal/iocache.h"
 
54
#include "drizzled/drizzled.h"
 
55
#include "drizzled/plugin/authorization.h"
 
56
#include "drizzled/table/temporary.h"
 
57
#include "drizzled/table/placeholder.h"
 
58
#include "drizzled/table/unused.h"
63
59
 
64
60
using namespace std;
65
61
 
68
64
 
69
65
extern bool volatile shutdown_in_progress;
70
66
 
 
67
static bool add_table(table::Concurrent *arg)
 
68
{
 
69
  table::CacheMap &open_cache(table::getCache());
 
70
 
 
71
  table::CacheMap::iterator returnable= open_cache.insert(make_pair(arg->getShare()->getCacheKey(), arg));
 
72
 
 
73
  return not (returnable == open_cache.end());
 
74
}
 
75
 
71
76
bool table_cache_init(void)
72
77
{
73
78
  return false;
97
102
  By leaving the table in the table cache, it disallows any other thread
98
103
  to open the table
99
104
 
100
 
  session->getKilled() will be set if we run out of memory
 
105
  session->killed will be set if we run out of memory
101
106
 
102
107
  If closing a MERGE child, the calling function has to take care for
103
108
  closing the parent too, if necessary.
114
119
    This has to be done to ensure that the table share is removed from
115
120
    the table defintion cache as soon as the last instance is removed
116
121
  */
117
 
  identifier::Table identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), message::Table::INTERNAL);
118
 
  const identifier::Table::Key &key(identifier.getKey());
 
122
  TableIdentifier identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), message::Table::INTERNAL);
 
123
  const TableIdentifier::Key &key(identifier.getKey());
119
124
  TableShare *share= new TableShare(identifier.getType(),
120
125
                                    identifier,
121
126
                                    const_cast<char *>(key.vector()),  static_cast<uint32_t>(table->getShare()->getCacheKeySize()));
122
127
 
123
128
  table->cursor->close();
124
129
  table->db_stat= 0;                            // Mark cursor closed
125
 
  table::instance::release(table->getMutableShare());
 
130
  TableShare::release(table->getMutableShare());
126
131
  table->setShare(share);
127
132
}
128
133
 
147
152
{
148
153
  if (sort.io_cache)
149
154
  {
150
 
    sort.io_cache->close_cached_file();
151
 
    safe_delete(sort.io_cache);
 
155
    close_cached_file(sort.io_cache);
 
156
    delete sort.io_cache;
 
157
    sort.io_cache= 0;
152
158
  }
153
159
}
154
160
 
158
164
 
159
165
  @param session Thread context (may be NULL)
160
166
  @param tables List of tables to remove from the cache
161
 
  @param have_lock If table::Cache::singleton().mutex() is locked
 
167
  @param have_lock If LOCK_open is locked
162
168
  @param wait_for_refresh Wait for a impending flush
163
169
  @param wait_for_placeholders Wait for tables being reopened so that the GRL
164
170
  won't proceed while write-locked tables are being reopened by other
174
180
  Session *session= this;
175
181
 
176
182
  {
177
 
    boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex()); /* Optionally lock for remove tables from open_cahe if not in use */
 
183
    LOCK_open.lock(); /* Optionally lock for remove tables from open_cahe if not in use */
178
184
 
179
185
    if (tables == NULL)
180
186
    {
236
242
      bool found= false;
237
243
      for (TableList *table= tables; table; table= table->next_local)
238
244
      {
239
 
        identifier::Table identifier(table->getSchemaName(), table->getTableName());
 
245
        TableIdentifier identifier(table->getSchemaName(), table->getTableName());
240
246
        if (table::Cache::singleton().removeTable(session, identifier,
241
247
                                    RTFC_OWNED_BY_Session_FLAG))
242
248
        {
253
259
        If there is any table that has a lower refresh_version, wait until
254
260
        this is closed (or this thread is killed) before returning
255
261
      */
256
 
      session->mysys_var->current_mutex= &table::Cache::singleton().mutex();
 
262
      session->mysys_var->current_mutex= &LOCK_open;
257
263
      session->mysys_var->current_cond= &COND_refresh;
258
264
      session->set_proc_info("Flushing tables");
259
265
 
261
267
 
262
268
      bool found= true;
263
269
      /* Wait until all threads has closed all the tables we had locked */
264
 
      while (found && ! session->getKilled())
 
270
      while (found && ! session->killed)
265
271
      {
266
272
        found= false;
267
273
        for (table::CacheMap::const_iterator iter= table::getCache().begin();
290
296
                                                     (table->open_placeholder && wait_for_placeholders)))
291
297
          {
292
298
            found= true;
293
 
            COND_refresh.wait(scopedLock);
 
299
            boost_unique_lock_t scoped(LOCK_open, boost::adopt_lock_t());
 
300
            COND_refresh.wait(scoped);
 
301
            scoped.release();
294
302
            break;
295
303
          }
296
304
        }
300
308
        old locks. This should always succeed (unless some external process
301
309
        has removed the tables)
302
310
      */
303
 
      result= session->reopen_tables();
 
311
      result= session->reopen_tables(true, true);
304
312
 
305
313
      /* Set version for table */
306
314
      for (Table *table= session->open_tables; table ; table= table->getNext())
313
321
          table->getMutableShare()->refreshVersion();
314
322
      }
315
323
    }
 
324
 
 
325
    LOCK_open.unlock();
316
326
  }
317
327
 
318
328
  if (wait_for_refresh)
331
341
  move one table to free list 
332
342
*/
333
343
 
334
 
bool Session::free_cached_table(boost::mutex::scoped_lock &scopedLock)
 
344
bool Session::free_cached_table()
335
345
{
336
346
  bool found_old_table= false;
337
 
 
338
 
  (void)scopedLock;
339
 
 
340
347
  table::Concurrent *table= static_cast<table::Concurrent *>(open_tables);
341
348
 
342
 
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
 
349
  safe_mutex_assert_owner(LOCK_open.native_handle());
343
350
  assert(table->key_read == 0);
344
351
  assert(!table->cursor || table->cursor->inited == Cursor::NONE);
345
352
 
382
389
{
383
390
  bool found_old_table= false;
384
391
 
385
 
  safe_mutex_assert_not_owner(table::Cache::singleton().mutex().native_handle());
 
392
  safe_mutex_assert_not_owner(LOCK_open.native_handle());
386
393
 
387
 
  boost_unique_lock_t scoped_lock(table::Cache::singleton().mutex()); /* Close all open tables on Session */
 
394
  boost_unique_lock_t scoped_lock(LOCK_open); /* Close all open tables on Session */
388
395
 
389
396
  while (open_tables)
390
397
  {
391
 
    found_old_table|= free_cached_table(scoped_lock);
 
398
    found_old_table|= free_cached_table();
392
399
  }
393
400
  some_tables_deleted= false;
394
401
 
395
402
  if (found_old_table)
396
403
  {
397
404
    /* Tell threads waiting for refresh that something has happened */
398
 
    locking::broadcast_refresh();
 
405
    broadcast_refresh();
399
406
  }
400
407
}
401
408
 
424
431
{
425
432
  for (; table; table= table->*link )
426
433
  {
427
 
    if ((table->table == 0 || table->table->getShare()->getType() == message::Table::STANDARD) and
428
 
        my_strcasecmp(system_charset_info, table->getSchemaName(), db_name) == 0 and
429
 
        my_strcasecmp(system_charset_info, table->getTableName(), table_name) == 0)
430
 
    {
 
434
    if ((table->table == 0 || table->table->getShare()->getType() == message::Table::STANDARD) &&
 
435
        strcasecmp(table->getSchemaName(), db_name) == 0 &&
 
436
        strcasecmp(table->getTableName(), table_name) == 0)
431
437
      break;
432
 
    }
433
438
  }
434
439
  return table;
435
440
}
521
526
}
522
527
 
523
528
 
524
 
void Open_tables_state::doGetTableNames(const identifier::Schema &schema_identifier,
525
 
                                        std::set<std::string>& set_of_names)
 
529
void Session::doGetTableNames(const SchemaIdentifier &schema_identifier,
 
530
                              std::set<std::string>& set_of_names)
526
531
{
527
 
  for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
 
532
  for (Table *table= temporary_tables ; table ; table= table->getNext())
528
533
  {
529
534
    if (schema_identifier.compare(table->getShare()->getSchemaName()))
530
535
    {
533
538
  }
534
539
}
535
540
 
536
 
void Open_tables_state::doGetTableNames(CachedDirectory &,
537
 
                                        const identifier::Schema &schema_identifier,
538
 
                                        std::set<std::string> &set_of_names)
 
541
void Session::doGetTableNames(CachedDirectory &,
 
542
                              const SchemaIdentifier &schema_identifier,
 
543
                              std::set<std::string> &set_of_names)
539
544
{
540
545
  doGetTableNames(schema_identifier, set_of_names);
541
546
}
542
547
 
543
 
void Open_tables_state::doGetTableIdentifiers(const identifier::Schema &schema_identifier,
544
 
                                              identifier::Table::vector &set_of_identifiers)
 
548
void Session::doGetTableIdentifiers(const SchemaIdentifier &schema_identifier,
 
549
                                    TableIdentifiers &set_of_identifiers)
545
550
{
546
 
  for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
 
551
  for (Table *table= temporary_tables ; table ; table= table->getNext())
547
552
  {
548
553
    if (schema_identifier.compare(table->getShare()->getSchemaName()))
549
554
    {
550
 
      set_of_identifiers.push_back(identifier::Table(table->getShare()->getSchemaName(),
 
555
      set_of_identifiers.push_back(TableIdentifier(table->getShare()->getSchemaName(),
551
556
                                                   table->getShare()->getTableName(),
552
557
                                                   table->getShare()->getPath()));
553
558
    }
554
559
  }
555
560
}
556
561
 
557
 
void Open_tables_state::doGetTableIdentifiers(CachedDirectory &,
558
 
                                              const identifier::Schema &schema_identifier,
559
 
                                              identifier::Table::vector &set_of_identifiers)
 
562
void Session::doGetTableIdentifiers(CachedDirectory &,
 
563
                                    const SchemaIdentifier &schema_identifier,
 
564
                                    TableIdentifiers &set_of_identifiers)
560
565
{
561
566
  doGetTableIdentifiers(schema_identifier, set_of_identifiers);
562
567
}
563
568
 
564
 
bool Open_tables_state::doDoesTableExist(const identifier::Table &identifier)
 
569
bool Session::doDoesTableExist(const TableIdentifier &identifier)
565
570
{
566
 
  for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
 
571
  for (Table *table= temporary_tables ; table ; table= table->getNext())
567
572
  {
568
573
    if (table->getShare()->getType() == message::Table::TEMPORARY)
569
574
    {
577
582
  return false;
578
583
}
579
584
 
580
 
int Open_tables_state::doGetTableDefinition(const identifier::Table &identifier,
581
 
                                            message::Table &table_proto)
 
585
int Session::doGetTableDefinition(const TableIdentifier &identifier,
 
586
                                  message::Table &table_proto)
582
587
{
583
 
  for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
 
588
  for (Table *table= temporary_tables ; table ; table= table->getNext())
584
589
  {
585
590
    if (table->getShare()->getType() == message::Table::TEMPORARY)
586
591
    {
587
592
      if (identifier.getKey() == table->getShare()->getCacheKey())
588
593
      {
589
 
        table_proto.CopyFrom(*(table->getShare()->getTableMessage()));
 
594
        table_proto.CopyFrom(*(table->getShare()->getTableProto()));
590
595
 
591
596
        return EEXIST;
592
597
      }
596
601
  return ENOENT;
597
602
}
598
603
 
599
 
Table *Open_tables_state::find_temporary_table(const identifier::Table &identifier)
 
604
Table *Session::find_temporary_table(const TableIdentifier &identifier)
600
605
{
601
606
  for (Table *table= temporary_tables ; table ; table= table->getNext())
602
607
  {
634
639
  @retval -1  the table is in use by a outer query
635
640
*/
636
641
 
637
 
int Open_tables_state::drop_temporary_table(const drizzled::identifier::Table &identifier)
 
642
int Session::drop_temporary_table(const drizzled::TableIdentifier &identifier)
638
643
{
639
644
  Table *table;
640
645
 
642
647
    return 1;
643
648
 
644
649
  /* Table might be in use by some outer statement. */
645
 
  if (table->query_id && table->query_id != getQueryId())
 
650
  if (table->query_id && table->query_id != query_id)
646
651
  {
647
652
    my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->getAlias());
648
653
    return -1;
661
666
  @param  session     Thread context
662
667
  @param  find    Table to remove
663
668
 
664
 
  @note because we risk the chance of deleting the share, we can't assume that it will exist past, this should be modified once we can use a TableShare::shared_ptr here.
 
669
  @note because we risk the chance of deleting the share, we can't assume that it will exist past, this should be modified once we can use a TableSharePtr here.
665
670
*/
666
671
 
667
672
void Session::unlink_open_table(Table *find)
668
673
{
669
 
  const identifier::Table::Key find_key(find->getShare()->getCacheKey());
 
674
  const TableIdentifier::Key find_key(find->getShare()->getCacheKey());
670
675
  Table **prev;
671
 
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
 
676
  safe_mutex_assert_owner(LOCK_open.native_handle());
672
677
 
673
678
  /*
674
 
    Note that we need to hold table::Cache::singleton().mutex() while changing the
 
679
    Note that we need to hold LOCK_open while changing the
675
680
    open_tables list. Another thread may work on it.
676
 
    (See: table::Cache::singleton().removeTable(), wait_completed_table())
 
681
    (See: table::Cache::singleton().removeTable(), mysql_wait_completed_table())
677
682
    Closing a MERGE child before the parent would be fatal if the
678
683
    other thread tries to abort the MERGE lock in between.
679
684
  */
697
702
  }
698
703
 
699
704
  // Notify any 'refresh' threads
700
 
  locking::broadcast_refresh();
 
705
  broadcast_refresh();
701
706
}
702
707
 
703
708
 
720
725
  table that was locked with LOCK TABLES.
721
726
*/
722
727
 
723
 
void Session::drop_open_table(Table *table, const identifier::Table &identifier)
 
728
void Session::drop_open_table(Table *table, TableIdentifier &identifier)
724
729
{
725
730
  if (table->getShare()->getType())
726
731
  {
728
733
  }
729
734
  else
730
735
  {
731
 
    boost_unique_lock_t scoped_lock(table::Cache::singleton().mutex()); /* Close and drop a table (AUX routine) */
 
736
    boost_unique_lock_t scoped_lock(LOCK_open); /* Close and drop a table (AUX routine) */
732
737
    /*
733
738
      unlink_open_table() also tells threads waiting for refresh or close
734
739
      that something has happened.
735
740
    */
736
741
    unlink_open_table(table);
737
 
    (void)plugin::StorageEngine::dropTable(*this, identifier);
 
742
    quick_rm_table(*this, identifier);
738
743
  }
739
744
}
740
745
 
770
775
      mutex is unlocked
771
776
    */
772
777
    boost_unique_lock_t scopedLock(mutex, boost::adopt_lock_t());
773
 
    if (not getKilled())
 
778
    if (not killed)
774
779
    {
775
780
      cond.wait(scopedLock);
776
781
    }
795
800
  case of failure.
796
801
*/
797
802
 
798
 
table::Placeholder *Session::table_cache_insert_placeholder(const drizzled::identifier::Table &arg)
 
803
table::Placeholder *Session::table_cache_insert_placeholder(const drizzled::TableIdentifier &arg)
799
804
{
800
 
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
 
805
  safe_mutex_assert_owner(LOCK_open.native_handle());
801
806
 
802
807
  /*
803
808
    Create a table entry with the right key and with an old refresh version
804
809
  */
805
 
  identifier::Table identifier(arg.getSchemaName(), arg.getTableName(), message::Table::INTERNAL);
 
810
  TableIdentifier identifier(arg.getSchemaName(), arg.getTableName(), message::Table::INTERNAL);
806
811
  table::Placeholder *table= new table::Placeholder(this, identifier);
807
812
 
808
 
  if (not table::Cache::singleton().insert(table))
 
813
  if (not add_table(table))
809
814
  {
810
 
    safe_delete(table);
 
815
    delete table;
811
816
 
812
817
    return NULL;
813
818
  }
837
842
  @retval  true   Error occured (OOM)
838
843
  @retval  false  Success. 'table' parameter set according to above rules.
839
844
*/
840
 
bool Session::lock_table_name_if_not_cached(const identifier::Table &identifier, Table **table)
 
845
bool Session::lock_table_name_if_not_cached(TableIdentifier &identifier, Table **table)
841
846
{
842
 
  const identifier::Table::Key &key(identifier.getKey());
 
847
  const TableIdentifier::Key &key(identifier.getKey());
843
848
 
844
 
  boost_unique_lock_t scope_lock(table::Cache::singleton().mutex()); /* Obtain a name lock even though table is not in cache (like for create table)  */
 
849
  boost_unique_lock_t scope_lock(LOCK_open); /* Obtain a name lock even though table is not in cache (like for create table)  */
845
850
 
846
851
  table::CacheMap::iterator iter;
847
852
 
913
918
  if (check_stack_overrun(this, STACK_MIN_SIZE_FOR_OPEN, (unsigned char *)&alias))
914
919
    return NULL;
915
920
 
916
 
  if (getKilled())
 
921
  if (killed)
917
922
    return NULL;
918
923
 
919
 
  identifier::Table identifier(table_list->getSchemaName(), table_list->getTableName());
920
 
  const identifier::Table::Key &key(identifier.getKey());
 
924
  TableIdentifier identifier(table_list->getSchemaName(), table_list->getTableName());
 
925
  const TableIdentifier::Key &key(identifier.getKey());
921
926
  table::CacheRange ppp;
922
927
 
923
928
  /*
928
933
    TODO -> move this block into a separate function.
929
934
  */
930
935
  bool reset= false;
931
 
  for (table= getTemporaryTables(); table ; table=table->getNext())
 
936
  for (table= temporary_tables; table ; table=table->getNext())
932
937
  {
933
938
    if (table->getShare()->getCacheKey() == key)
934
939
    {
953
958
  {
954
959
    if (flags & DRIZZLE_OPEN_TEMPORARY_ONLY)
955
960
    {
956
 
      my_error(ER_TABLE_UNKNOWN, identifier);
 
961
      my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->getSchemaName(), table_list->getTableName());
957
962
      return NULL;
958
963
    }
959
964
 
998
1003
      until no one holds a name lock on the table.
999
1004
      - if there is no such Table in the name cache, read the table definition
1000
1005
      and insert it into the cache.
1001
 
      We perform all of the above under table::Cache::singleton().mutex() which currently protects
 
1006
      We perform all of the above under LOCK_open which currently protects
1002
1007
      the open cache (also known as table cache) and table definitions stored
1003
1008
      on disk.
1004
1009
    */
1005
1010
 
1006
1011
    {
1007
 
      boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex());
 
1012
      LOCK_open.lock(); /* Lock for FLUSH TABLES for open table */
1008
1013
 
1009
1014
      /*
1010
1015
        Actually try to find the table in the open_cache.
1056
1061
          /* Avoid self-deadlocks by detecting self-dependencies. */
1057
1062
          if (table->open_placeholder && table->in_use == this)
1058
1063
          {
 
1064
            LOCK_open.unlock();
1059
1065
            my_error(ER_UPDATE_TABLE_USED, MYF(0), table->getShare()->getTableName());
1060
1066
            return NULL;
1061
1067
          }
1088
1094
          */
1089
1095
          if (table->in_use != this)
1090
1096
          {
1091
 
            /* wait_for_conditionwill unlock table::Cache::singleton().mutex() for us */
1092
 
            wait_for_condition(table::Cache::singleton().mutex(), COND_refresh);
1093
 
            scopedLock.release();
 
1097
            /* wait_for_conditionwill unlock LOCK_open for us */
 
1098
            wait_for_condition(LOCK_open, COND_refresh);
1094
1099
          }
1095
1100
          else
1096
1101
          {
1097
 
            scopedLock.unlock();
 
1102
            LOCK_open.unlock();
1098
1103
          }
1099
 
 
1100
1104
          /*
1101
1105
            There is a refresh in progress for this table.
1102
1106
            Signal the caller that it has to try again.
1103
1107
          */
1104
1108
          if (refresh)
1105
1109
            *refresh= true;
1106
 
 
1107
1110
          return NULL;
1108
1111
        }
1109
1112
      }
1110
 
 
1111
1113
      if (table)
1112
1114
      {
1113
1115
        table::getUnused().unlink(static_cast<table::Concurrent *>(table));
1122
1124
 
1123
1125
        if (table_list->isCreate())
1124
1126
        {
1125
 
          identifier::Table  lock_table_identifier(table_list->getSchemaName(), table_list->getTableName(), message::Table::STANDARD);
 
1127
          TableIdentifier  lock_table_identifier(table_list->getSchemaName(), table_list->getTableName(), message::Table::STANDARD);
1126
1128
 
1127
1129
          if (not plugin::StorageEngine::doesTableExist(*this, lock_table_identifier))
1128
1130
          {
1131
1133
            */
1132
1134
            if (!(table= table_cache_insert_placeholder(lock_table_identifier)))
1133
1135
            {
 
1136
              LOCK_open.unlock();
1134
1137
              return NULL;
1135
1138
            }
1136
1139
            /*
1141
1144
            table->open_placeholder= true;
1142
1145
            table->setNext(open_tables);
1143
1146
            open_tables= table;
 
1147
            LOCK_open.unlock();
1144
1148
 
1145
1149
            return table ;
1146
1150
          }
1153
1157
          table= new_table;
1154
1158
          if (new_table == NULL)
1155
1159
          {
 
1160
            LOCK_open.unlock();
1156
1161
            return NULL;
1157
1162
          }
1158
1163
 
1160
1165
          if (error != 0)
1161
1166
          {
1162
1167
            delete new_table;
 
1168
            LOCK_open.unlock();
1163
1169
            return NULL;
1164
1170
          }
1165
 
          (void)table::Cache::singleton().insert(new_table);
 
1171
          (void)add_table(new_table);
1166
1172
        }
1167
1173
      }
 
1174
 
 
1175
      LOCK_open.unlock();
1168
1176
    }
1169
 
 
1170
1177
    if (refresh)
1171
1178
    {
1172
1179
      table->setNext(open_tables); /* Link into simple list */
1224
1231
  the strings are used in a loop even after the share may be freed.
1225
1232
*/
1226
1233
 
1227
 
void Session::close_data_files_and_morph_locks(const identifier::Table &identifier)
 
1234
void Session::close_data_files_and_morph_locks(TableIdentifier &identifier)
1228
1235
{
1229
 
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle()); /* Adjust locks at the end of ALTER TABLEL */
 
1236
  safe_mutex_assert_owner(LOCK_open.native_handle()); /* Adjust locks at the end of ALTER TABLEL */
1230
1237
 
1231
1238
  if (lock)
1232
1239
  {
1234
1241
      If we are not under LOCK TABLES we should have only one table
1235
1242
      open and locked so it makes sense to remove the lock at once.
1236
1243
    */
1237
 
    unlockTables(lock);
 
1244
    mysql_unlock_tables(this, lock);
1238
1245
    lock= 0;
1239
1246
  }
1240
1247
 
1269
1276
  combination when one needs tables to be reopened (for
1270
1277
  example see openTablesLock()).
1271
1278
 
1272
 
  @note One should have lock on table::Cache::singleton().mutex() when calling this.
 
1279
  @note One should have lock on LOCK_open when calling this.
1273
1280
 
1274
1281
  @return false in case of success, true - otherwise.
1275
1282
*/
1276
1283
 
1277
 
bool Session::reopen_tables()
 
1284
bool Session::reopen_tables(bool get_locks, bool)
1278
1285
{
1279
1286
  Table *table,*next,**prev;
1280
 
  Table **tables= 0;                    // For locks
1281
 
  Table **tables_ptr= 0;                        // For locks
1282
 
  bool error= false;
 
1287
  Table **tables,**tables_ptr;                  // For locks
 
1288
  bool error=0, not_used;
1283
1289
  const uint32_t flags= DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN |
1284
1290
    DRIZZLE_LOCK_IGNORE_GLOBAL_READ_LOCK |
1285
1291
    DRIZZLE_LOCK_IGNORE_FLUSH;
1287
1293
  if (open_tables == NULL)
1288
1294
    return false;
1289
1295
 
1290
 
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
 
1296
  safe_mutex_assert_owner(LOCK_open.native_handle());
 
1297
  if (get_locks)
1291
1298
  {
1292
1299
    /*
1293
1300
      The ptr is checked later
1301
1308
    }
1302
1309
    tables= new Table *[opens];
1303
1310
  }
1304
 
 
 
1311
  else
 
1312
  {
 
1313
    tables= &open_tables;
 
1314
  }
1305
1315
  tables_ptr =tables;
1306
1316
 
1307
1317
  prev= &open_tables;
1314
1324
    error= 1;
1315
1325
  }
1316
1326
  *prev=0;
1317
 
 
1318
1327
  if (tables != tables_ptr)                     // Should we get back old locks
1319
1328
  {
1320
1329
    DrizzleLock *local_lock;
1321
1330
    /*
1322
1331
      We should always get these locks. Anyway, we must not go into
1323
 
      wait_for_tables() as it tries to acquire table::Cache::singleton().mutex(), which is
 
1332
      wait_for_tables() as it tries to acquire LOCK_open, which is
1324
1333
      already locked.
1325
1334
    */
1326
1335
    some_tables_deleted= false;
1327
1336
 
1328
 
    if ((local_lock= lockTables(tables, (uint32_t) (tables_ptr - tables), flags)))
 
1337
    if ((local_lock= mysql_lock_tables(this, tables, (uint32_t) (tables_ptr - tables),
 
1338
                                 flags, &not_used)))
1329
1339
    {
1330
1340
      /* unused */
1331
1341
    }
1341
1351
    }
1342
1352
  }
1343
1353
 
1344
 
  delete [] tables;
1345
 
 
1346
 
  locking::broadcast_refresh();
1347
 
 
1348
 
  return error;
 
1354
  if (get_locks && tables)
 
1355
    delete [] tables;
 
1356
 
 
1357
  broadcast_refresh();
 
1358
 
 
1359
  return(error);
1349
1360
}
1350
1361
 
1351
1362
 
1376
1387
    */
1377
1388
    if (table->needs_reopen_or_name_lock())
1378
1389
    {
1379
 
      found= true;
 
1390
      found=1;
1380
1391
      if (table->db_stat)
1381
1392
      {
1382
1393
        if (morph_locks)
1390
1401
              lock on it. This will also give them a chance to close their
1391
1402
              instances of this table.
1392
1403
            */
1393
 
            abortLock(ulcktbl);
1394
 
            removeLock(ulcktbl);
 
1404
            mysql_lock_abort(this, ulcktbl);
 
1405
            mysql_lock_remove(this, ulcktbl);
1395
1406
            ulcktbl->lock_count= 0;
1396
1407
          }
1397
1408
          if ((ulcktbl != table) && ulcktbl->db_stat)
1431
1442
    }
1432
1443
  }
1433
1444
  if (found)
1434
 
    locking::broadcast_refresh();
 
1445
    broadcast_refresh();
 
1446
}
 
1447
 
 
1448
 
 
1449
/* Wait until all used tables are refreshed */
 
1450
 
 
1451
bool wait_for_tables(Session *session)
 
1452
{
 
1453
  bool result;
 
1454
 
 
1455
  session->set_proc_info("Waiting for tables");
 
1456
  {
 
1457
    boost_unique_lock_t lock(LOCK_open);
 
1458
    while (!session->killed)
 
1459
    {
 
1460
      session->some_tables_deleted= false;
 
1461
      session->close_old_data_files(false, dropping_tables != 0);
 
1462
      if (not table::Cache::singleton().areTablesUsed(session->open_tables, 1))
 
1463
      {
 
1464
        break;
 
1465
      }
 
1466
      COND_refresh.wait(lock);
 
1467
    }
 
1468
    if (session->killed)
 
1469
      result= true;                                     // aborted
 
1470
    else
 
1471
    {
 
1472
      /* Now we can open all tables without any interference */
 
1473
      session->set_proc_info("Reopen tables");
 
1474
      session->version= refresh_version;
 
1475
      result= session->reopen_tables(false, false);
 
1476
    }
 
1477
  }
 
1478
  session->set_proc_info(0);
 
1479
 
 
1480
  return result;
1435
1481
}
1436
1482
 
1437
1483
 
1459
1505
*/
1460
1506
 
1461
1507
 
1462
 
Table *drop_locked_tables(Session *session, const drizzled::identifier::Table &identifier)
 
1508
Table *drop_locked_tables(Session *session, const drizzled::TableIdentifier &identifier)
1463
1509
{
1464
1510
  Table *table,*next,**prev, *found= 0;
1465
1511
  prev= &session->open_tables;
1466
1512
 
1467
1513
  /*
1468
 
    Note that we need to hold table::Cache::singleton().mutex() while changing the
 
1514
    Note that we need to hold LOCK_open while changing the
1469
1515
    open_tables list. Another thread may work on it.
1470
 
    (See: table::Cache::singleton().removeTable(), wait_completed_table())
 
1516
    (See: table::Cache::singleton().removeTable(), mysql_wait_completed_table())
1471
1517
    Closing a MERGE child before the parent would be fatal if the
1472
1518
    other thread tries to abort the MERGE lock in between.
1473
1519
  */
1476
1522
    next=table->getNext();
1477
1523
    if (table->getShare()->getCacheKey() == identifier.getKey())
1478
1524
    {
1479
 
      session->removeLock(table);
 
1525
      mysql_lock_remove(session, table);
1480
1526
 
1481
1527
      if (!found)
1482
1528
      {
1501
1547
    }
1502
1548
  }
1503
1549
  *prev=0;
1504
 
 
1505
1550
  if (found)
1506
 
    locking::broadcast_refresh();
 
1551
    broadcast_refresh();
1507
1552
 
1508
 
  return found;
 
1553
  return(found);
1509
1554
}
1510
1555
 
1511
1556
 
1515
1560
  other threads trying to get the lock.
1516
1561
*/
1517
1562
 
1518
 
void abort_locked_tables(Session *session, const drizzled::identifier::Table &identifier)
 
1563
void abort_locked_tables(Session *session, const drizzled::TableIdentifier &identifier)
1519
1564
{
1520
1565
  Table *table;
1521
1566
  for (table= session->open_tables; table ; table= table->getNext())
1523
1568
    if (table->getShare()->getCacheKey() == identifier.getKey())
1524
1569
    {
1525
1570
      /* If MERGE child, forward lock handling to parent. */
1526
 
      session->abortLock(table);
1527
 
      assert(0);
 
1571
      mysql_lock_abort(session, table);
1528
1572
      break;
1529
1573
    }
1530
1574
  }
1597
1641
     * to see if it exists so that an unauthorized user cannot phish for
1598
1642
     * table/schema information via error messages
1599
1643
     */
1600
 
    identifier::Table the_table(tables->getSchemaName(), tables->getTableName());
1601
 
    if (not plugin::Authorization::isAuthorized(*user(), the_table))
 
1644
    TableIdentifier the_table(tables->getSchemaName(), tables->getTableName());
 
1645
    if (not plugin::Authorization::isAuthorized(getSecurityContext(),
 
1646
                                                the_table))
1602
1647
    {
1603
1648
      result= -1;                               // Fatal error
1604
1649
      break;
1695
1740
 
1696
1741
  set_proc_info("Opening table");
1697
1742
  current_tablenr= 0;
1698
 
  while (!(table= openTable(table_list, &refresh)) && refresh) ;
 
1743
  while (!(table= openTable(table_list, &refresh)) &&
 
1744
         refresh)
 
1745
    ;
1699
1746
 
1700
1747
  if (table)
1701
1748
  {
1704
1751
 
1705
1752
    assert(lock == 0);  // You must lock everything at once
1706
1753
    if ((table->reginfo.lock_type= lock_type) != TL_UNLOCK)
1707
 
    {
1708
 
      if (not (lock= lockTables(&table_list->table, 1, 0)))
1709
 
        table= NULL;
1710
 
    }
 
1754
      if (! (lock= mysql_lock_tables(this, &table_list->table, 1, 0, &refresh)))
 
1755
        table= 0;
1711
1756
  }
1712
1757
 
1713
1758
  set_proc_info(0);
1761
1806
  Table **start,**ptr;
1762
1807
  uint32_t lock_flag= DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN;
1763
1808
 
1764
 
  if (!(ptr=start=(Table**) session->getMemRoot()->allocate(sizeof(Table*)*count)))
 
1809
  if (!(ptr=start=(Table**) session->alloc(sizeof(Table*)*count)))
1765
1810
    return -1;
1766
 
 
1767
1811
  for (table= tables; table; table= table->next_global)
1768
1812
  {
1769
1813
    if (!table->placeholder())
1770
1814
      *(ptr++)= table->table;
1771
1815
  }
1772
1816
 
1773
 
  if (not (session->lock= session->lockTables(start, (uint32_t) (ptr - start), lock_flag)))
 
1817
  if (!(session->lock= mysql_lock_tables(session, start, (uint32_t) (ptr - start),
 
1818
                                         lock_flag, need_reopen)))
1774
1819
  {
1775
1820
    return -1;
1776
1821
  }
1799
1844
#  Table object
1800
1845
*/
1801
1846
 
1802
 
Table *Open_tables_state::open_temporary_table(const identifier::Table &identifier,
1803
 
                                               bool link_in_list)
 
1847
Table *Session::open_temporary_table(TableIdentifier &identifier,
 
1848
                                     bool link_in_list)
1804
1849
{
1805
1850
  assert(identifier.isTmp());
1806
1851
 
1807
1852
 
1808
1853
  table::Temporary *new_tmp_table= new table::Temporary(identifier.getType(),
1809
1854
                                                        identifier,
1810
 
                                                        const_cast<char *>(const_cast<identifier::Table&>(identifier).getPath().c_str()),
 
1855
                                                        const_cast<char *>(identifier.getPath().c_str()),
1811
1856
                                                        static_cast<uint32_t>(identifier.getPath().length()));
1812
1857
  if (not new_tmp_table)
1813
1858
    return NULL;
1815
1860
  /*
1816
1861
    First open the share, and then open the table from the share we just opened.
1817
1862
  */
1818
 
  if (new_tmp_table->getMutableShare()->open_table_def(*static_cast<Session *>(this), identifier) ||
1819
 
      new_tmp_table->getMutableShare()->open_table_from_share(static_cast<Session *>(this), identifier, identifier.getTableName().c_str(),
 
1863
  if (new_tmp_table->getMutableShare()->open_table_def(*this, identifier) ||
 
1864
      new_tmp_table->getMutableShare()->open_table_from_share(this, identifier, identifier.getTableName().c_str(),
1820
1865
                                                              (uint32_t) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
1821
1866
                                                                          HA_GET_INDEX),
1822
1867
                                                              ha_open_options,
1884
1929
      current_bitmap= table->write_set;
1885
1930
    }
1886
1931
 
1887
 
    //if (current_bitmap->testAndSet(field->position()))
1888
 
    if (current_bitmap->test(field->position()))
 
1932
    //if (current_bitmap->testAndSet(field->field_index))
 
1933
    if (current_bitmap->test(field->field_index))
1889
1934
    {
1890
1935
      if (session->mark_used_columns == MARK_COLUMNS_WRITE)
1891
1936
        session->dup_field= field;
1929
1974
                           const char *name, uint32_t , Item **,
1930
1975
                           bool, TableList **actual_table)
1931
1976
{
1932
 
  List<Natural_join_column>::iterator
1933
 
    field_it(table_ref->join_columns->begin());
 
1977
  List_iterator_fast<Natural_join_column>
 
1978
    field_it(*(table_ref->join_columns));
1934
1979
  Natural_join_column *nj_col, *curr_nj_col;
1935
1980
  Field *found_field;
1936
1981
 
1944
1989
    {
1945
1990
      if (nj_col)
1946
1991
      {
1947
 
        my_error(ER_NON_UNIQ_ERROR, MYF(0), name, session->where());
 
1992
        my_error(ER_NON_UNIQ_ERROR, MYF(0), name, session->where);
1948
1993
        return NULL;
1949
1994
      }
1950
1995
      nj_col= curr_nj_col;
2145
2190
    */
2146
2191
    if (table_name && table_name[0])
2147
2192
    {
2148
 
      List<TableList>::iterator it(table_list->getNestedJoin()->join_list.begin());
 
2193
      List_iterator<TableList> it(table_list->getNestedJoin()->join_list);
2149
2194
      TableList *table;
2150
2195
      while ((table= it++))
2151
2196
      {
2195
2240
      {
2196
2241
        Table *table= field_to_set->getTable();
2197
2242
        if (session->mark_used_columns == MARK_COLUMNS_READ)
2198
 
          table->setReadSet(field_to_set->position());
 
2243
          table->setReadSet(field_to_set->field_index);
2199
2244
        else
2200
 
          table->setWriteSet(field_to_set->position());
 
2245
          table->setWriteSet(field_to_set->field_index);
2201
2246
      }
2202
2247
    }
2203
2248
  }
2295
2340
        fields.
2296
2341
      */
2297
2342
      {
2298
 
        Select_Lex *current_sel= session->getLex()->current_select;
 
2343
        Select_Lex *current_sel= session->lex->current_select;
2299
2344
        Select_Lex *last_select= table_ref->select_lex;
2300
2345
        /*
2301
2346
          If the field was an outer referencee, mark all selects using this
2341
2386
      */
2342
2387
      item->cached_table= found ?  0 : actual_table;
2343
2388
 
2344
 
      assert(session->where());
 
2389
      assert(session->where);
2345
2390
      /*
2346
2391
        If we found a fully qualified field we return it directly as it can't
2347
2392
        have duplicates.
2354
2399
        if (report_error == REPORT_ALL_ERRORS ||
2355
2400
            report_error == IGNORE_EXCEPT_NON_UNIQUE)
2356
2401
          my_error(ER_NON_UNIQ_ERROR, MYF(0),
2357
 
                   table_name ? item->full_name() : name, session->where());
 
2402
                   table_name ? item->full_name() : name, session->where);
2358
2403
        return (Field*) 0;
2359
2404
      }
2360
2405
      found= cur_field;
2387
2432
      strcat(buff, table_name);
2388
2433
      table_name=buff;
2389
2434
    }
2390
 
    my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, session->where());
 
2435
    my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, session->where);
2391
2436
  }
2392
2437
  else
2393
2438
  {
2394
2439
    if (report_error == REPORT_ALL_ERRORS ||
2395
2440
        report_error == REPORT_EXCEPT_NON_UNIQUE)
2396
 
      my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), session->where());
 
2441
      my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), session->where);
2397
2442
    else
2398
2443
      found= not_found_field;
2399
2444
  }
2444
2489
                  find_item_error_report_type report_error,
2445
2490
                  enum_resolution_type *resolution)
2446
2491
{
2447
 
  List<Item>::iterator li(items.begin());
 
2492
  List_iterator<Item> li(items);
2448
2493
  Item **found=0, **found_unaliased= 0, *item;
2449
2494
  const char *db_name=0;
2450
2495
  const char *field_name=0;
2520
2565
            */
2521
2566
            if (report_error != IGNORE_ERRORS)
2522
2567
              my_error(ER_NON_UNIQ_ERROR, MYF(0),
2523
 
                       find->full_name(), session->where());
 
2568
                       find->full_name(), session->where);
2524
2569
            return (Item**) 0;
2525
2570
          }
2526
2571
          found_unaliased= li.ref();
2551
2596
              continue;                           // Same field twice
2552
2597
            if (report_error != IGNORE_ERRORS)
2553
2598
              my_error(ER_NON_UNIQ_ERROR, MYF(0),
2554
 
                       find->full_name(), session->where());
 
2599
                       find->full_name(), session->where);
2555
2600
            return (Item**) 0;
2556
2601
          }
2557
2602
          found= li.ref();
2603
2648
    {
2604
2649
      if (report_error != IGNORE_ERRORS)
2605
2650
        my_error(ER_NON_UNIQ_ERROR, MYF(0),
2606
 
                 find->full_name(), session->where());
 
2651
                 find->full_name(), session->where);
2607
2652
      return (Item **) 0;
2608
2653
    }
2609
2654
    if (found_unaliased)
2619
2664
  {
2620
2665
    if (report_error == REPORT_ALL_ERRORS)
2621
2666
      my_error(ER_BAD_FIELD_ERROR, MYF(0),
2622
 
               find->full_name(), session->where());
 
2667
               find->full_name(), session->where);
2623
2668
    return (Item **) 0;
2624
2669
  }
2625
2670
  else
2647
2692
static bool
2648
2693
test_if_string_in_list(const char *find, List<String> *str_list)
2649
2694
{
2650
 
  List<String>::iterator str_list_it(str_list->begin());
 
2695
  List_iterator<String> str_list_it(*str_list);
2651
2696
  String *curr_str;
2652
2697
  size_t find_length= strlen(find);
2653
2698
  while ((curr_str= str_list_it++))
2790
2835
        if (cur_nj_col_2->is_common ||
2791
2836
            (found && (!using_fields || is_using_column_1)))
2792
2837
        {
2793
 
          my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1, session->where());
 
2838
          my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1, session->where);
2794
2839
          return(result);
2795
2840
        }
2796
2841
        nj_col_2= cur_nj_col_2;
2869
2914
      {
2870
2915
        Table *table_1= nj_col_1->table_ref->table;
2871
2916
        /* Mark field_1 used for table cache. */
2872
 
        table_1->setReadSet(field_1->position());
 
2917
        table_1->setReadSet(field_1->field_index);
2873
2918
        table_1->covering_keys&= field_1->part_of_key;
2874
2919
        table_1->merge_keys|= field_1->part_of_key;
2875
2920
      }
2877
2922
      {
2878
2923
        Table *table_2= nj_col_2->table_ref->table;
2879
2924
        /* Mark field_2 used for table cache. */
2880
 
        table_2->setReadSet(field_2->position());
 
2925
        table_2->setReadSet(field_2->field_index);
2881
2926
        table_2->covering_keys&= field_2->part_of_key;
2882
2927
        table_2->merge_keys|= field_2->part_of_key;
2883
2928
      }
2981
3026
  if (using_fields && found_using_fields < using_fields->elements)
2982
3027
  {
2983
3028
    String *using_field_name;
2984
 
    List<String>::iterator using_fields_it(using_fields->begin());
 
3029
    List_iterator_fast<String> using_fields_it(*using_fields);
2985
3030
    while ((using_field_name= using_fields_it++))
2986
3031
    {
2987
3032
      const char *using_field_name_ptr= using_field_name->c_ptr();
2988
 
      List<Natural_join_column>::iterator
2989
 
        it(natural_using_join->join_columns->begin());
 
3033
      List_iterator_fast<Natural_join_column>
 
3034
        it(*(natural_using_join->join_columns));
2990
3035
      Natural_join_column *common_field;
2991
3036
 
2992
3037
      for (;;)
2995
3040
        if (!(common_field= it++))
2996
3041
        {
2997
3042
          my_error(ER_BAD_FIELD_ERROR, MYF(0), using_field_name_ptr,
2998
 
                   session->where());
 
3043
                   session->where);
2999
3044
          return(result);
3000
3045
        }
3001
3046
        if (!my_strcasecmp(system_charset_info,
3068
3113
  /* Call the procedure recursively for each nested table reference. */
3069
3114
  if (table_ref->getNestedJoin())
3070
3115
  {
3071
 
    List<TableList>::iterator nested_it(table_ref->getNestedJoin()->join_list.begin());
 
3116
    List_iterator_fast<TableList> nested_it(table_ref->getNestedJoin()->join_list);
3072
3117
    TableList *same_level_left_neighbor= nested_it++;
3073
3118
    TableList *same_level_right_neighbor= NULL;
3074
3119
    /* Left/right-most neighbors, possibly at higher levels in the join tree. */
3122
3167
  {
3123
3168
    assert(table_ref->getNestedJoin() &&
3124
3169
           table_ref->getNestedJoin()->join_list.elements == 2);
3125
 
    List<TableList>::iterator operand_it(table_ref->getNestedJoin()->join_list.begin());
 
3170
    List_iterator_fast<TableList> operand_it(table_ref->getNestedJoin()->join_list);
3126
3171
    /*
3127
3172
      Notice that the order of join operands depends on whether table_ref
3128
3173
      represents a LEFT or a RIGHT join. In a RIGHT join, the operands are
3218
3263
                                         List<TableList> *from_clause,
3219
3264
                                         Name_resolution_context *context)
3220
3265
{
3221
 
  session->setWhere("from clause");
 
3266
  session->where= "from clause";
3222
3267
  if (from_clause->elements == 0)
3223
3268
    return false; /* We come here in the case of UNIONs. */
3224
3269
 
3225
 
  List<TableList>::iterator table_ref_it(from_clause->begin());
 
3270
  List_iterator_fast<TableList> table_ref_it(*from_clause);
3226
3271
  TableList *table_ref; /* Current table reference. */
3227
3272
  /* Table reference to the left of the current. */
3228
3273
  TableList *left_neighbor;
3272
3317
    return 0;
3273
3318
 
3274
3319
  Item *item;
3275
 
  List<Item>::iterator it(fields.begin());
 
3320
  List_iterator<Item> it(fields);
3276
3321
 
3277
 
  session->getLex()->current_select->cur_pos_in_select_list= 0;
 
3322
  session->lex->current_select->cur_pos_in_select_list= 0;
3278
3323
  while (wild_num && (item= it++))
3279
3324
  {
3280
3325
    if (item->type() == Item::FIELD_ITEM &&
3284
3329
    {
3285
3330
      uint32_t elem= fields.elements;
3286
3331
      bool any_privileges= ((Item_field *) item)->any_privileges;
3287
 
      Item_subselect *subsel= session->getLex()->current_select->master_unit()->item;
 
3332
      Item_subselect *subsel= session->lex->current_select->master_unit()->item;
3288
3333
      if (subsel &&
3289
3334
          subsel->substype() == Item_subselect::EXISTS_SUBS)
3290
3335
      {
3315
3360
      wild_num--;
3316
3361
    }
3317
3362
    else
3318
 
      session->getLex()->current_select->cur_pos_in_select_list++;
 
3363
      session->lex->current_select->cur_pos_in_select_list++;
3319
3364
  }
3320
 
  session->getLex()->current_select->cur_pos_in_select_list= UNDEF_POS;
 
3365
  session->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
3321
3366
 
3322
3367
  return 0;
3323
3368
}
3332
3377
{
3333
3378
  register Item *item;
3334
3379
  enum_mark_columns save_mark_used_columns= session->mark_used_columns;
3335
 
  nesting_map save_allow_sum_func= session->getLex()->allow_sum_func;
3336
 
  List<Item>::iterator it(fields.begin());
 
3380
  nesting_map save_allow_sum_func= session->lex->allow_sum_func;
 
3381
  List_iterator<Item> it(fields);
3337
3382
  bool save_is_item_list_lookup;
3338
3383
 
3339
3384
  session->mark_used_columns= mark_used_columns;
3340
3385
  if (allow_sum_func)
3341
 
    session->getLex()->allow_sum_func|= 1 << session->getLex()->current_select->nest_level;
3342
 
  session->setWhere(Session::DEFAULT_WHERE);
3343
 
  save_is_item_list_lookup= session->getLex()->current_select->is_item_list_lookup;
3344
 
  session->getLex()->current_select->is_item_list_lookup= 0;
 
3386
    session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
 
3387
  session->where= Session::DEFAULT_WHERE;
 
3388
  save_is_item_list_lookup= session->lex->current_select->is_item_list_lookup;
 
3389
  session->lex->current_select->is_item_list_lookup= 0;
3345
3390
 
3346
3391
  /*
3347
3392
    To prevent fail on forward lookup we fill it with zerows,
3351
3396
    There is other way to solve problem: fill array with pointers to list,
3352
3397
    but it will be slower.
3353
3398
 
3354
 
    TODO-> remove it when (if) we made one list for allfields and ref_pointer_array
 
3399
TODO: remove it when (if) we made one list for allfields and
 
3400
ref_pointer_array
3355
3401
  */
3356
3402
  if (ref_pointer_array)
3357
 
  {
3358
3403
    memset(ref_pointer_array, 0, sizeof(Item *) * fields.elements);
3359
 
  }
3360
3404
 
3361
3405
  Item **ref= ref_pointer_array;
3362
 
  session->getLex()->current_select->cur_pos_in_select_list= 0;
 
3406
  session->lex->current_select->cur_pos_in_select_list= 0;
3363
3407
  while ((item= it++))
3364
3408
  {
3365
3409
    if ((!item->fixed && item->fix_fields(session, it.ref())) || (item= *(it.ref()))->check_cols(1))
3366
3410
    {
3367
 
      session->getLex()->current_select->is_item_list_lookup= save_is_item_list_lookup;
3368
 
      session->getLex()->allow_sum_func= save_allow_sum_func;
 
3411
      session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
 
3412
      session->lex->allow_sum_func= save_allow_sum_func;
3369
3413
      session->mark_used_columns= save_mark_used_columns;
3370
3414
      return true;
3371
3415
    }
3375
3419
        sum_func_list)
3376
3420
      item->split_sum_func(session, ref_pointer_array, *sum_func_list);
3377
3421
    session->used_tables|= item->used_tables();
3378
 
    session->getLex()->current_select->cur_pos_in_select_list++;
 
3422
    session->lex->current_select->cur_pos_in_select_list++;
3379
3423
  }
3380
 
  session->getLex()->current_select->is_item_list_lookup= save_is_item_list_lookup;
3381
 
  session->getLex()->current_select->cur_pos_in_select_list= UNDEF_POS;
 
3424
  session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
 
3425
  session->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
3382
3426
 
3383
 
  session->getLex()->allow_sum_func= save_allow_sum_func;
 
3427
  session->lex->allow_sum_func= save_allow_sum_func;
3384
3428
  session->mark_used_columns= save_mark_used_columns;
3385
3429
  return(test(session->is_error()));
3386
3430
}
3549
3593
 
3550
3594
bool
3551
3595
insert_fields(Session *session, Name_resolution_context *context, const char *db_name,
3552
 
              const char *table_name, List<Item>::iterator *it,
 
3596
              const char *table_name, List_iterator<Item> *it,
3553
3597
              bool )
3554
3598
{
3555
3599
  Field_iterator_table_ref field_iterator;
3588
3632
    assert(tables->is_leaf_for_name_resolution());
3589
3633
 
3590
3634
    if ((table_name && my_strcasecmp(table_alias_charset, table_name, tables->alias)) ||
3591
 
        (db_name && my_strcasecmp(system_charset_info, tables->getSchemaName(),db_name)))
 
3635
        (db_name && strcasecmp(tables->getSchemaName(),db_name)))
3592
3636
      continue;
3593
3637
 
3594
3638
    /*
3624
3668
      if ((field= field_iterator.field()))
3625
3669
      {
3626
3670
        /* Mark fields as used to allow storage engine to optimze access */
3627
 
        field->getTable()->setReadSet(field->position());
 
3671
        field->getTable()->setReadSet(field->field_index);
3628
3672
        if (table)
3629
3673
        {
3630
3674
          table->covering_keys&= field->part_of_key;
3652
3696
        }
3653
3697
      }
3654
3698
      else
3655
 
      {
3656
3699
        session->used_tables|= item->used_tables();
3657
 
      }
3658
 
 
3659
 
      session->getLex()->current_select->cur_pos_in_select_list++;
 
3700
      session->lex->current_select->cur_pos_in_select_list++;
3660
3701
    }
3661
3702
    /*
3662
3703
      In case of stored tables, all fields are considered as used,
3675
3716
    qualified '*', and all columns were coalesced, we have to give a more
3676
3717
    meaningful message than ER_BAD_TABLE_ERROR.
3677
3718
  */
3678
 
  if (not table_name)
3679
 
  {
 
3719
  if (!table_name)
3680
3720
    my_message(ER_NO_TABLES_USED, ER(ER_NO_TABLES_USED), MYF(0));
3681
 
  }
3682
3721
  else
3683
 
  {
3684
3722
    my_error(ER_BAD_TABLE_ERROR, MYF(0), table_name);
3685
 
  }
3686
3723
 
3687
3724
  return true;
3688
3725
}
3709
3746
int Session::setup_conds(TableList *leaves, COND **conds)
3710
3747
{
3711
3748
  Session *session= this;
3712
 
  Select_Lex *select_lex= session->getLex()->current_select;
 
3749
  Select_Lex *select_lex= session->lex->current_select;
3713
3750
  TableList *table= NULL;       // For HP compilers
3714
3751
  void *save_session_marker= session->session_marker;
3715
3752
  /*
3731
3768
  session->session_marker= (void*)1;
3732
3769
  if (*conds)
3733
3770
  {
3734
 
    session->setWhere("where clause");
 
3771
    session->where="where clause";
3735
3772
    if ((!(*conds)->fixed && (*conds)->fix_fields(session, conds)) ||
3736
3773
        (*conds)->check_cols(1))
3737
3774
      goto err_no_arena;
3753
3790
      {
3754
3791
        /* Make a join an a expression */
3755
3792
        session->session_marker= (void*)embedded;
3756
 
        session->setWhere("on clause");
 
3793
        session->where="on clause";
3757
3794
        if ((!embedded->on_expr->fixed && embedded->on_expr->fix_fields(session, &embedded->on_expr)) ||
3758
3795
            embedded->on_expr->check_cols(1))
3759
3796
          goto err_no_arena;
3767
3804
  }
3768
3805
  session->session_marker= save_session_marker;
3769
3806
 
3770
 
  session->getLex()->current_select->is_item_list_lookup= save_is_item_list_lookup;
 
3807
  session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
3771
3808
  return(test(session->is_error()));
3772
3809
 
3773
3810
err_no_arena:
3805
3842
bool
3806
3843
fill_record(Session *session, List<Item> &fields, List<Item> &values, bool ignore_errors)
3807
3844
{
3808
 
  List<Item>::iterator f(fields.begin());
3809
 
  List<Item>::iterator v(values.begin());
 
3845
  List_iterator_fast<Item> f(fields),v(values);
3810
3846
  Item *value;
3811
3847
  Item_field *field;
3812
3848
  Table *table;
3824
3860
    field= static_cast<Item_field *>(f++);
3825
3861
    table= field->field->getTable();
3826
3862
    table->auto_increment_field_not_null= false;
3827
 
    f= fields.begin();
 
3863
    f.rewind();
3828
3864
  }
3829
3865
 
3830
3866
  while ((field= static_cast<Item_field *>(f++)))
3871
3907
 
3872
3908
bool fill_record(Session *session, Field **ptr, List<Item> &values, bool)
3873
3909
{
3874
 
  List<Item>::iterator v(values.begin());
 
3910
  List_iterator_fast<Item> v(values);
3875
3911
  Item *value;
3876
3912
  Table *table= 0;
3877
3913
  Field *field;
3889
3925
    table= (*ptr)->getTable();
3890
3926
    table->auto_increment_field_not_null= false;
3891
3927
  }
3892
 
 
3893
3928
  while ((field = *ptr++) && ! session->is_error())
3894
3929
  {
3895
3930
    value=v++;
3896
3931
    table= field->getTable();
3897
 
 
3898
3932
    if (field == table->next_number_field)
3899
3933
      table->auto_increment_field_not_null= true;
3900
 
 
3901
3934
    if (value->save_in_field(field, 0) < 0)
3902
3935
    {
3903
3936
      if (table)
3913
3946
 
3914
3947
bool drizzle_rm_tmp_tables()
3915
3948
{
 
3949
  Session *session;
3916
3950
 
3917
3951
  assert(drizzle_tmpdir.size());
3918
 
  Session::shared_ptr session= Session::make_shared(plugin::Listen::getNullClient(), catalog::local());
3919
3952
 
3920
 
  if (not session)
 
3953
  if (!(session= new Session(plugin::Listen::getNullClient())))
3921
3954
    return true;
3922
 
  session->thread_stack= (char*) session.get();
 
3955
  session->thread_stack= (char*) &session;
3923
3956
  session->storeGlobals();
3924
3957
 
3925
3958
  plugin::StorageEngine::removeLostTemporaryTables(*session, drizzle_tmpdir.c_str());
3926
3959
 
 
3960
  session->lockForDelete();
 
3961
  delete session;
 
3962
 
3927
3963
  return false;
3928
3964
}
3929
3965