~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_base.cc

  • Committer: Lee Bieber
  • Date: 2010-11-07 19:34:48 UTC
  • mfrom: (1910.1.2 build)
  • Revision ID: kalebral@gmail.com-20101107193448-64kdu912qej354sh
Merge Stewart - including adapting and expanding the "differences from mysql" page from the wiki.
Merge Stewart - fix bug 668143: drizzleslap with --commit runs second iteration data load in a transaction

Show diffs side-by-side

added added

removed removed

Lines of Context:
45
45
#include <drizzled/lock.h>
46
46
#include <drizzled/plugin/listen.h>
47
47
#include "drizzled/cached_directory.h"
48
 
#include <drizzled/field/epoch.h>
 
48
#include <drizzled/field/timestamp.h>
49
49
#include <drizzled/field/null.h>
50
50
#include "drizzled/sql_table.h"
51
51
#include "drizzled/global_charset_info.h"
56
56
#include "drizzled/table/temporary.h"
57
57
#include "drizzled/table/placeholder.h"
58
58
#include "drizzled/table/unused.h"
59
 
#include "drizzled/plugin/storage_engine.h"
60
 
 
61
 
#include <drizzled/refresh_version.h>
62
59
 
63
60
using namespace std;
64
61
 
96
93
  By leaving the table in the table cache, it disallows any other thread
97
94
  to open the table
98
95
 
99
 
  session->getKilled() will be set if we run out of memory
 
96
  session->killed will be set if we run out of memory
100
97
 
101
98
  If closing a MERGE child, the calling function has to take care for
102
99
  closing the parent too, if necessary.
113
110
    This has to be done to ensure that the table share is removed from
114
111
    the table defintion cache as soon as the last instance is removed
115
112
  */
116
 
  identifier::Table identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), message::Table::INTERNAL);
117
 
  const identifier::Table::Key &key(identifier.getKey());
 
113
  TableIdentifier identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), message::Table::INTERNAL);
 
114
  const TableIdentifier::Key &key(identifier.getKey());
118
115
  TableShare *share= new TableShare(identifier.getType(),
119
116
                                    identifier,
120
117
                                    const_cast<char *>(key.vector()),  static_cast<uint32_t>(table->getShare()->getCacheKeySize()));
121
118
 
122
119
  table->cursor->close();
123
120
  table->db_stat= 0;                            // Mark cursor closed
124
 
  table::instance::release(table->getMutableShare());
 
121
  TableShare::release(table->getMutableShare());
125
122
  table->setShare(share);
126
123
}
127
124
 
158
155
 
159
156
  @param session Thread context (may be NULL)
160
157
  @param tables List of tables to remove from the cache
161
 
  @param have_lock If table::Cache::singleton().mutex() is locked
 
158
  @param have_lock If LOCK_open is locked
162
159
  @param wait_for_refresh Wait for a impending flush
163
160
  @param wait_for_placeholders Wait for tables being reopened so that the GRL
164
161
  won't proceed while write-locked tables are being reopened by other
174
171
  Session *session= this;
175
172
 
176
173
  {
177
 
    boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex()); /* Optionally lock for remove tables from open_cahe if not in use */
 
174
    LOCK_open.lock(); /* Optionally lock for remove tables from open_cahe if not in use */
178
175
 
179
176
    if (tables == NULL)
180
177
    {
236
233
      bool found= false;
237
234
      for (TableList *table= tables; table; table= table->next_local)
238
235
      {
239
 
        identifier::Table identifier(table->getSchemaName(), table->getTableName());
 
236
        TableIdentifier identifier(table->getSchemaName(), table->getTableName());
240
237
        if (table::Cache::singleton().removeTable(session, identifier,
241
238
                                    RTFC_OWNED_BY_Session_FLAG))
242
239
        {
253
250
        If there is any table that has a lower refresh_version, wait until
254
251
        this is closed (or this thread is killed) before returning
255
252
      */
256
 
      session->mysys_var->current_mutex= &table::Cache::singleton().mutex();
 
253
      session->mysys_var->current_mutex= &LOCK_open;
257
254
      session->mysys_var->current_cond= &COND_refresh;
258
255
      session->set_proc_info("Flushing tables");
259
256
 
261
258
 
262
259
      bool found= true;
263
260
      /* Wait until all threads has closed all the tables we had locked */
264
 
      while (found && ! session->getKilled())
 
261
      while (found && ! session->killed)
265
262
      {
266
263
        found= false;
267
264
        for (table::CacheMap::const_iterator iter= table::getCache().begin();
290
287
                                                     (table->open_placeholder && wait_for_placeholders)))
291
288
          {
292
289
            found= true;
293
 
            COND_refresh.wait(scopedLock);
 
290
            boost_unique_lock_t scoped(LOCK_open, boost::adopt_lock_t());
 
291
            COND_refresh.wait(scoped);
 
292
            scoped.release();
294
293
            break;
295
294
          }
296
295
        }
300
299
        old locks. This should always succeed (unless some external process
301
300
        has removed the tables)
302
301
      */
303
 
      result= session->reopen_tables();
 
302
      result= session->reopen_tables(true, true);
304
303
 
305
304
      /* Set version for table */
306
305
      for (Table *table= session->open_tables; table ; table= table->getNext())
313
312
          table->getMutableShare()->refreshVersion();
314
313
      }
315
314
    }
 
315
 
 
316
    LOCK_open.unlock();
316
317
  }
317
318
 
318
319
  if (wait_for_refresh)
331
332
  move one table to free list 
332
333
*/
333
334
 
334
 
bool Session::free_cached_table(boost::mutex::scoped_lock &scopedLock)
 
335
bool Session::free_cached_table()
335
336
{
336
337
  bool found_old_table= false;
337
 
 
338
 
  (void)scopedLock;
339
 
 
340
338
  table::Concurrent *table= static_cast<table::Concurrent *>(open_tables);
341
339
 
342
 
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
 
340
  safe_mutex_assert_owner(LOCK_open.native_handle());
343
341
  assert(table->key_read == 0);
344
342
  assert(!table->cursor || table->cursor->inited == Cursor::NONE);
345
343
 
382
380
{
383
381
  bool found_old_table= false;
384
382
 
385
 
  safe_mutex_assert_not_owner(table::Cache::singleton().mutex().native_handle());
 
383
  safe_mutex_assert_not_owner(LOCK_open.native_handle());
386
384
 
387
 
  boost_unique_lock_t scoped_lock(table::Cache::singleton().mutex()); /* Close all open tables on Session */
 
385
  boost_unique_lock_t scoped_lock(LOCK_open); /* Close all open tables on Session */
388
386
 
389
387
  while (open_tables)
390
388
  {
391
 
    found_old_table|= free_cached_table(scoped_lock);
 
389
    found_old_table|= free_cached_table();
392
390
  }
393
391
  some_tables_deleted= false;
394
392
 
395
393
  if (found_old_table)
396
394
  {
397
395
    /* Tell threads waiting for refresh that something has happened */
398
 
    locking::broadcast_refresh();
 
396
    broadcast_refresh();
399
397
  }
400
398
}
401
399
 
424
422
{
425
423
  for (; table; table= table->*link )
426
424
  {
427
 
    if ((table->table == 0 || table->table->getShare()->getType() == message::Table::STANDARD) and
428
 
        my_strcasecmp(system_charset_info, table->getSchemaName(), db_name) == 0 and
429
 
        my_strcasecmp(system_charset_info, table->getTableName(), table_name) == 0)
430
 
    {
 
425
    if ((table->table == 0 || table->table->getShare()->getType() == message::Table::STANDARD) &&
 
426
        strcasecmp(table->getSchemaName(), db_name) == 0 &&
 
427
        strcasecmp(table->getTableName(), table_name) == 0)
431
428
      break;
432
 
    }
433
429
  }
434
430
  return table;
435
431
}
521
517
}
522
518
 
523
519
 
524
 
void Open_tables_state::doGetTableNames(const identifier::Schema &schema_identifier,
525
 
                                        std::set<std::string>& set_of_names)
 
520
void Session::doGetTableNames(const SchemaIdentifier &schema_identifier,
 
521
                              std::set<std::string>& set_of_names)
526
522
{
527
 
  for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
 
523
  for (Table *table= temporary_tables ; table ; table= table->getNext())
528
524
  {
529
525
    if (schema_identifier.compare(table->getShare()->getSchemaName()))
530
526
    {
533
529
  }
534
530
}
535
531
 
536
 
void Open_tables_state::doGetTableNames(CachedDirectory &,
537
 
                                        const identifier::Schema &schema_identifier,
538
 
                                        std::set<std::string> &set_of_names)
 
532
void Session::doGetTableNames(CachedDirectory &,
 
533
                              const SchemaIdentifier &schema_identifier,
 
534
                              std::set<std::string> &set_of_names)
539
535
{
540
536
  doGetTableNames(schema_identifier, set_of_names);
541
537
}
542
538
 
543
 
void Open_tables_state::doGetTableIdentifiers(const identifier::Schema &schema_identifier,
544
 
                                              identifier::Table::vector &set_of_identifiers)
 
539
void Session::doGetTableIdentifiers(const SchemaIdentifier &schema_identifier,
 
540
                                    TableIdentifiers &set_of_identifiers)
545
541
{
546
 
  for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
 
542
  for (Table *table= temporary_tables ; table ; table= table->getNext())
547
543
  {
548
544
    if (schema_identifier.compare(table->getShare()->getSchemaName()))
549
545
    {
550
 
      set_of_identifiers.push_back(identifier::Table(table->getShare()->getSchemaName(),
 
546
      set_of_identifiers.push_back(TableIdentifier(table->getShare()->getSchemaName(),
551
547
                                                   table->getShare()->getTableName(),
552
548
                                                   table->getShare()->getPath()));
553
549
    }
554
550
  }
555
551
}
556
552
 
557
 
void Open_tables_state::doGetTableIdentifiers(CachedDirectory &,
558
 
                                              const identifier::Schema &schema_identifier,
559
 
                                              identifier::Table::vector &set_of_identifiers)
 
553
void Session::doGetTableIdentifiers(CachedDirectory &,
 
554
                                    const SchemaIdentifier &schema_identifier,
 
555
                                    TableIdentifiers &set_of_identifiers)
560
556
{
561
557
  doGetTableIdentifiers(schema_identifier, set_of_identifiers);
562
558
}
563
559
 
564
 
bool Open_tables_state::doDoesTableExist(const identifier::Table &identifier)
 
560
bool Session::doDoesTableExist(const TableIdentifier &identifier)
565
561
{
566
 
  for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
 
562
  for (Table *table= temporary_tables ; table ; table= table->getNext())
567
563
  {
568
564
    if (table->getShare()->getType() == message::Table::TEMPORARY)
569
565
    {
577
573
  return false;
578
574
}
579
575
 
580
 
int Open_tables_state::doGetTableDefinition(const identifier::Table &identifier,
581
 
                                            message::Table &table_proto)
 
576
int Session::doGetTableDefinition(const TableIdentifier &identifier,
 
577
                                  message::Table &table_proto)
582
578
{
583
 
  for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
 
579
  for (Table *table= temporary_tables ; table ; table= table->getNext())
584
580
  {
585
581
    if (table->getShare()->getType() == message::Table::TEMPORARY)
586
582
    {
587
583
      if (identifier.getKey() == table->getShare()->getCacheKey())
588
584
      {
589
 
        table_proto.CopyFrom(*(table->getShare()->getTableMessage()));
 
585
        table_proto.CopyFrom(*(table->getShare()->getTableProto()));
590
586
 
591
587
        return EEXIST;
592
588
      }
596
592
  return ENOENT;
597
593
}
598
594
 
599
 
Table *Open_tables_state::find_temporary_table(const identifier::Table &identifier)
 
595
Table *Session::find_temporary_table(const TableIdentifier &identifier)
600
596
{
601
597
  for (Table *table= temporary_tables ; table ; table= table->getNext())
602
598
  {
634
630
  @retval -1  the table is in use by a outer query
635
631
*/
636
632
 
637
 
int Open_tables_state::drop_temporary_table(const drizzled::identifier::Table &identifier)
 
633
int Session::drop_temporary_table(const drizzled::TableIdentifier &identifier)
638
634
{
639
635
  Table *table;
640
636
 
642
638
    return 1;
643
639
 
644
640
  /* Table might be in use by some outer statement. */
645
 
  if (table->query_id && table->query_id != getQueryId())
 
641
  if (table->query_id && table->query_id != query_id)
646
642
  {
647
643
    my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->getAlias());
648
644
    return -1;
661
657
  @param  session     Thread context
662
658
  @param  find    Table to remove
663
659
 
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.
 
660
  @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
661
*/
666
662
 
667
663
void Session::unlink_open_table(Table *find)
668
664
{
669
 
  const identifier::Table::Key find_key(find->getShare()->getCacheKey());
 
665
  const TableIdentifier::Key find_key(find->getShare()->getCacheKey());
670
666
  Table **prev;
671
 
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
 
667
  safe_mutex_assert_owner(LOCK_open.native_handle());
672
668
 
673
669
  /*
674
 
    Note that we need to hold table::Cache::singleton().mutex() while changing the
 
670
    Note that we need to hold LOCK_open while changing the
675
671
    open_tables list. Another thread may work on it.
676
 
    (See: table::Cache::singleton().removeTable(), wait_completed_table())
 
672
    (See: table::Cache::singleton().removeTable(), mysql_wait_completed_table())
677
673
    Closing a MERGE child before the parent would be fatal if the
678
674
    other thread tries to abort the MERGE lock in between.
679
675
  */
697
693
  }
698
694
 
699
695
  // Notify any 'refresh' threads
700
 
  locking::broadcast_refresh();
 
696
  broadcast_refresh();
701
697
}
702
698
 
703
699
 
720
716
  table that was locked with LOCK TABLES.
721
717
*/
722
718
 
723
 
void Session::drop_open_table(Table *table, const identifier::Table &identifier)
 
719
void Session::drop_open_table(Table *table, TableIdentifier &identifier)
724
720
{
725
721
  if (table->getShare()->getType())
726
722
  {
728
724
  }
729
725
  else
730
726
  {
731
 
    boost_unique_lock_t scoped_lock(table::Cache::singleton().mutex()); /* Close and drop a table (AUX routine) */
 
727
    boost_unique_lock_t scoped_lock(LOCK_open); /* Close and drop a table (AUX routine) */
732
728
    /*
733
729
      unlink_open_table() also tells threads waiting for refresh or close
734
730
      that something has happened.
735
731
    */
736
732
    unlink_open_table(table);
737
 
    (void)plugin::StorageEngine::dropTable(*this, identifier);
 
733
    quick_rm_table(*this, identifier);
738
734
  }
739
735
}
740
736
 
770
766
      mutex is unlocked
771
767
    */
772
768
    boost_unique_lock_t scopedLock(mutex, boost::adopt_lock_t());
773
 
    if (not getKilled())
 
769
    if (not killed)
774
770
    {
775
771
      cond.wait(scopedLock);
776
772
    }
795
791
  case of failure.
796
792
*/
797
793
 
798
 
table::Placeholder *Session::table_cache_insert_placeholder(const drizzled::identifier::Table &arg)
 
794
table::Placeholder *Session::table_cache_insert_placeholder(const drizzled::TableIdentifier &arg)
799
795
{
800
 
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
 
796
  safe_mutex_assert_owner(LOCK_open.native_handle());
801
797
 
802
798
  /*
803
799
    Create a table entry with the right key and with an old refresh version
804
800
  */
805
 
  identifier::Table identifier(arg.getSchemaName(), arg.getTableName(), message::Table::INTERNAL);
 
801
  TableIdentifier identifier(arg.getSchemaName(), arg.getTableName(), message::Table::INTERNAL);
806
802
  table::Placeholder *table= new table::Placeholder(this, identifier);
807
803
 
808
804
  if (not table::Cache::singleton().insert(table))
837
833
  @retval  true   Error occured (OOM)
838
834
  @retval  false  Success. 'table' parameter set according to above rules.
839
835
*/
840
 
bool Session::lock_table_name_if_not_cached(const identifier::Table &identifier, Table **table)
 
836
bool Session::lock_table_name_if_not_cached(TableIdentifier &identifier, Table **table)
841
837
{
842
 
  const identifier::Table::Key &key(identifier.getKey());
 
838
  const TableIdentifier::Key &key(identifier.getKey());
843
839
 
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)  */
 
840
  boost_unique_lock_t scope_lock(LOCK_open); /* Obtain a name lock even though table is not in cache (like for create table)  */
845
841
 
846
842
  table::CacheMap::iterator iter;
847
843
 
913
909
  if (check_stack_overrun(this, STACK_MIN_SIZE_FOR_OPEN, (unsigned char *)&alias))
914
910
    return NULL;
915
911
 
916
 
  if (getKilled())
 
912
  if (killed)
917
913
    return NULL;
918
914
 
919
 
  identifier::Table identifier(table_list->getSchemaName(), table_list->getTableName());
920
 
  const identifier::Table::Key &key(identifier.getKey());
 
915
  TableIdentifier identifier(table_list->getSchemaName(), table_list->getTableName());
 
916
  const TableIdentifier::Key &key(identifier.getKey());
921
917
  table::CacheRange ppp;
922
918
 
923
919
  /*
928
924
    TODO -> move this block into a separate function.
929
925
  */
930
926
  bool reset= false;
931
 
  for (table= getTemporaryTables(); table ; table=table->getNext())
 
927
  for (table= temporary_tables; table ; table=table->getNext())
932
928
  {
933
929
    if (table->getShare()->getCacheKey() == key)
934
930
    {
953
949
  {
954
950
    if (flags & DRIZZLE_OPEN_TEMPORARY_ONLY)
955
951
    {
956
 
      my_error(ER_TABLE_UNKNOWN, identifier);
 
952
      my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->getSchemaName(), table_list->getTableName());
957
953
      return NULL;
958
954
    }
959
955
 
998
994
      until no one holds a name lock on the table.
999
995
      - if there is no such Table in the name cache, read the table definition
1000
996
      and insert it into the cache.
1001
 
      We perform all of the above under table::Cache::singleton().mutex() which currently protects
 
997
      We perform all of the above under LOCK_open which currently protects
1002
998
      the open cache (also known as table cache) and table definitions stored
1003
999
      on disk.
1004
1000
    */
1005
1001
 
1006
1002
    {
1007
 
      boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex());
 
1003
      LOCK_open.lock(); /* Lock for FLUSH TABLES for open table */
1008
1004
 
1009
1005
      /*
1010
1006
        Actually try to find the table in the open_cache.
1056
1052
          /* Avoid self-deadlocks by detecting self-dependencies. */
1057
1053
          if (table->open_placeholder && table->in_use == this)
1058
1054
          {
 
1055
            LOCK_open.unlock();
1059
1056
            my_error(ER_UPDATE_TABLE_USED, MYF(0), table->getShare()->getTableName());
1060
1057
            return NULL;
1061
1058
          }
1088
1085
          */
1089
1086
          if (table->in_use != this)
1090
1087
          {
1091
 
            /* wait_for_conditionwill unlock table::Cache::singleton().mutex() for us */
1092
 
            wait_for_condition(table::Cache::singleton().mutex(), COND_refresh);
1093
 
            scopedLock.release();
 
1088
            /* wait_for_conditionwill unlock LOCK_open for us */
 
1089
            wait_for_condition(LOCK_open, COND_refresh);
1094
1090
          }
1095
1091
          else
1096
1092
          {
1097
 
            scopedLock.unlock();
 
1093
            LOCK_open.unlock();
1098
1094
          }
1099
 
 
1100
1095
          /*
1101
1096
            There is a refresh in progress for this table.
1102
1097
            Signal the caller that it has to try again.
1103
1098
          */
1104
1099
          if (refresh)
1105
1100
            *refresh= true;
1106
 
 
1107
1101
          return NULL;
1108
1102
        }
1109
1103
      }
1110
 
 
1111
1104
      if (table)
1112
1105
      {
1113
1106
        table::getUnused().unlink(static_cast<table::Concurrent *>(table));
1122
1115
 
1123
1116
        if (table_list->isCreate())
1124
1117
        {
1125
 
          identifier::Table  lock_table_identifier(table_list->getSchemaName(), table_list->getTableName(), message::Table::STANDARD);
 
1118
          TableIdentifier  lock_table_identifier(table_list->getSchemaName(), table_list->getTableName(), message::Table::STANDARD);
1126
1119
 
1127
1120
          if (not plugin::StorageEngine::doesTableExist(*this, lock_table_identifier))
1128
1121
          {
1131
1124
            */
1132
1125
            if (!(table= table_cache_insert_placeholder(lock_table_identifier)))
1133
1126
            {
 
1127
              LOCK_open.unlock();
1134
1128
              return NULL;
1135
1129
            }
1136
1130
            /*
1141
1135
            table->open_placeholder= true;
1142
1136
            table->setNext(open_tables);
1143
1137
            open_tables= table;
 
1138
            LOCK_open.unlock();
1144
1139
 
1145
1140
            return table ;
1146
1141
          }
1153
1148
          table= new_table;
1154
1149
          if (new_table == NULL)
1155
1150
          {
 
1151
            LOCK_open.unlock();
1156
1152
            return NULL;
1157
1153
          }
1158
1154
 
1160
1156
          if (error != 0)
1161
1157
          {
1162
1158
            delete new_table;
 
1159
            LOCK_open.unlock();
1163
1160
            return NULL;
1164
1161
          }
1165
1162
          (void)table::Cache::singleton().insert(new_table);
1166
1163
        }
1167
1164
      }
 
1165
 
 
1166
      LOCK_open.unlock();
1168
1167
    }
1169
 
 
1170
1168
    if (refresh)
1171
1169
    {
1172
1170
      table->setNext(open_tables); /* Link into simple list */
1224
1222
  the strings are used in a loop even after the share may be freed.
1225
1223
*/
1226
1224
 
1227
 
void Session::close_data_files_and_morph_locks(const identifier::Table &identifier)
 
1225
void Session::close_data_files_and_morph_locks(TableIdentifier &identifier)
1228
1226
{
1229
 
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle()); /* Adjust locks at the end of ALTER TABLEL */
 
1227
  safe_mutex_assert_owner(LOCK_open.native_handle()); /* Adjust locks at the end of ALTER TABLEL */
1230
1228
 
1231
1229
  if (lock)
1232
1230
  {
1234
1232
      If we are not under LOCK TABLES we should have only one table
1235
1233
      open and locked so it makes sense to remove the lock at once.
1236
1234
    */
1237
 
    unlockTables(lock);
 
1235
    mysql_unlock_tables(this, lock);
1238
1236
    lock= 0;
1239
1237
  }
1240
1238
 
1269
1267
  combination when one needs tables to be reopened (for
1270
1268
  example see openTablesLock()).
1271
1269
 
1272
 
  @note One should have lock on table::Cache::singleton().mutex() when calling this.
 
1270
  @note One should have lock on LOCK_open when calling this.
1273
1271
 
1274
1272
  @return false in case of success, true - otherwise.
1275
1273
*/
1276
1274
 
1277
 
bool Session::reopen_tables()
 
1275
bool Session::reopen_tables(bool get_locks, bool)
1278
1276
{
1279
1277
  Table *table,*next,**prev;
1280
 
  Table **tables= 0;                    // For locks
1281
 
  Table **tables_ptr= 0;                        // For locks
1282
 
  bool error= false;
 
1278
  Table **tables,**tables_ptr;                  // For locks
 
1279
  bool error=0, not_used;
1283
1280
  const uint32_t flags= DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN |
1284
1281
    DRIZZLE_LOCK_IGNORE_GLOBAL_READ_LOCK |
1285
1282
    DRIZZLE_LOCK_IGNORE_FLUSH;
1287
1284
  if (open_tables == NULL)
1288
1285
    return false;
1289
1286
 
1290
 
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
 
1287
  safe_mutex_assert_owner(LOCK_open.native_handle());
 
1288
  if (get_locks)
1291
1289
  {
1292
1290
    /*
1293
1291
      The ptr is checked later
1301
1299
    }
1302
1300
    tables= new Table *[opens];
1303
1301
  }
1304
 
 
 
1302
  else
 
1303
  {
 
1304
    tables= &open_tables;
 
1305
  }
1305
1306
  tables_ptr =tables;
1306
1307
 
1307
1308
  prev= &open_tables;
1314
1315
    error= 1;
1315
1316
  }
1316
1317
  *prev=0;
1317
 
 
1318
1318
  if (tables != tables_ptr)                     // Should we get back old locks
1319
1319
  {
1320
1320
    DrizzleLock *local_lock;
1321
1321
    /*
1322
1322
      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
 
1323
      wait_for_tables() as it tries to acquire LOCK_open, which is
1324
1324
      already locked.
1325
1325
    */
1326
1326
    some_tables_deleted= false;
1327
1327
 
1328
 
    if ((local_lock= lockTables(tables, (uint32_t) (tables_ptr - tables), flags)))
 
1328
    if ((local_lock= mysql_lock_tables(this, tables, (uint32_t) (tables_ptr - tables),
 
1329
                                 flags, &not_used)))
1329
1330
    {
1330
1331
      /* unused */
1331
1332
    }
1341
1342
    }
1342
1343
  }
1343
1344
 
1344
 
  delete [] tables;
1345
 
 
1346
 
  locking::broadcast_refresh();
1347
 
 
1348
 
  return error;
 
1345
  if (get_locks && tables)
 
1346
    delete [] tables;
 
1347
 
 
1348
  broadcast_refresh();
 
1349
 
 
1350
  return(error);
1349
1351
}
1350
1352
 
1351
1353
 
1376
1378
    */
1377
1379
    if (table->needs_reopen_or_name_lock())
1378
1380
    {
1379
 
      found= true;
 
1381
      found=1;
1380
1382
      if (table->db_stat)
1381
1383
      {
1382
1384
        if (morph_locks)
1390
1392
              lock on it. This will also give them a chance to close their
1391
1393
              instances of this table.
1392
1394
            */
1393
 
            abortLock(ulcktbl);
1394
 
            removeLock(ulcktbl);
 
1395
            mysql_lock_abort(this, ulcktbl);
 
1396
            mysql_lock_remove(this, ulcktbl);
1395
1397
            ulcktbl->lock_count= 0;
1396
1398
          }
1397
1399
          if ((ulcktbl != table) && ulcktbl->db_stat)
1431
1433
    }
1432
1434
  }
1433
1435
  if (found)
1434
 
    locking::broadcast_refresh();
 
1436
    broadcast_refresh();
 
1437
}
 
1438
 
 
1439
 
 
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(LOCK_open);
 
1449
    while (!session->killed)
 
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->killed)
 
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;
1435
1472
}
1436
1473
 
1437
1474
 
1459
1496
*/
1460
1497
 
1461
1498
 
1462
 
Table *drop_locked_tables(Session *session, const drizzled::identifier::Table &identifier)
 
1499
Table *drop_locked_tables(Session *session, const drizzled::TableIdentifier &identifier)
1463
1500
{
1464
1501
  Table *table,*next,**prev, *found= 0;
1465
1502
  prev= &session->open_tables;
1466
1503
 
1467
1504
  /*
1468
 
    Note that we need to hold table::Cache::singleton().mutex() while changing the
 
1505
    Note that we need to hold LOCK_open while changing the
1469
1506
    open_tables list. Another thread may work on it.
1470
 
    (See: table::Cache::singleton().removeTable(), wait_completed_table())
 
1507
    (See: table::Cache::singleton().removeTable(), mysql_wait_completed_table())
1471
1508
    Closing a MERGE child before the parent would be fatal if the
1472
1509
    other thread tries to abort the MERGE lock in between.
1473
1510
  */
1476
1513
    next=table->getNext();
1477
1514
    if (table->getShare()->getCacheKey() == identifier.getKey())
1478
1515
    {
1479
 
      session->removeLock(table);
 
1516
      mysql_lock_remove(session, table);
1480
1517
 
1481
1518
      if (!found)
1482
1519
      {
1501
1538
    }
1502
1539
  }
1503
1540
  *prev=0;
1504
 
 
1505
1541
  if (found)
1506
 
    locking::broadcast_refresh();
 
1542
    broadcast_refresh();
1507
1543
 
1508
 
  return found;
 
1544
  return(found);
1509
1545
}
1510
1546
 
1511
1547
 
1515
1551
  other threads trying to get the lock.
1516
1552
*/
1517
1553
 
1518
 
void abort_locked_tables(Session *session, const drizzled::identifier::Table &identifier)
 
1554
void abort_locked_tables(Session *session, const drizzled::TableIdentifier &identifier)
1519
1555
{
1520
1556
  Table *table;
1521
1557
  for (table= session->open_tables; table ; table= table->getNext())
1523
1559
    if (table->getShare()->getCacheKey() == identifier.getKey())
1524
1560
    {
1525
1561
      /* If MERGE child, forward lock handling to parent. */
1526
 
      session->abortLock(table);
1527
 
      assert(0);
 
1562
      mysql_lock_abort(session, table);
1528
1563
      break;
1529
1564
    }
1530
1565
  }
1597
1632
     * to see if it exists so that an unauthorized user cannot phish for
1598
1633
     * table/schema information via error messages
1599
1634
     */
1600
 
    identifier::Table the_table(tables->getSchemaName(), tables->getTableName());
1601
 
    if (not plugin::Authorization::isAuthorized(user(), the_table))
 
1635
    TableIdentifier the_table(tables->getSchemaName(), tables->getTableName());
 
1636
    if (not plugin::Authorization::isAuthorized(getSecurityContext(),
 
1637
                                                the_table))
1602
1638
    {
1603
1639
      result= -1;                               // Fatal error
1604
1640
      break;
1695
1731
 
1696
1732
  set_proc_info("Opening table");
1697
1733
  current_tablenr= 0;
1698
 
  while (!(table= openTable(table_list, &refresh)) && refresh) ;
 
1734
  while (!(table= openTable(table_list, &refresh)) &&
 
1735
         refresh)
 
1736
    ;
1699
1737
 
1700
1738
  if (table)
1701
1739
  {
1704
1742
 
1705
1743
    assert(lock == 0);  // You must lock everything at once
1706
1744
    if ((table->reginfo.lock_type= lock_type) != TL_UNLOCK)
1707
 
    {
1708
 
      if (not (lock= lockTables(&table_list->table, 1, 0)))
1709
 
        table= NULL;
1710
 
    }
 
1745
      if (! (lock= mysql_lock_tables(this, &table_list->table, 1, 0, &refresh)))
 
1746
        table= 0;
1711
1747
  }
1712
1748
 
1713
1749
  set_proc_info(0);
1761
1797
  Table **start,**ptr;
1762
1798
  uint32_t lock_flag= DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN;
1763
1799
 
1764
 
  if (!(ptr=start=(Table**) session->getMemRoot()->allocate(sizeof(Table*)*count)))
 
1800
  if (!(ptr=start=(Table**) session->alloc(sizeof(Table*)*count)))
1765
1801
    return -1;
1766
 
 
1767
1802
  for (table= tables; table; table= table->next_global)
1768
1803
  {
1769
1804
    if (!table->placeholder())
1770
1805
      *(ptr++)= table->table;
1771
1806
  }
1772
1807
 
1773
 
  if (not (session->lock= session->lockTables(start, (uint32_t) (ptr - start), lock_flag)))
 
1808
  if (!(session->lock= mysql_lock_tables(session, start, (uint32_t) (ptr - start),
 
1809
                                         lock_flag, need_reopen)))
1774
1810
  {
1775
1811
    return -1;
1776
1812
  }
1799
1835
#  Table object
1800
1836
*/
1801
1837
 
1802
 
Table *Open_tables_state::open_temporary_table(const identifier::Table &identifier,
1803
 
                                               bool link_in_list)
 
1838
Table *Session::open_temporary_table(TableIdentifier &identifier,
 
1839
                                     bool link_in_list)
1804
1840
{
1805
1841
  assert(identifier.isTmp());
1806
1842
 
1807
1843
 
1808
1844
  table::Temporary *new_tmp_table= new table::Temporary(identifier.getType(),
1809
1845
                                                        identifier,
1810
 
                                                        const_cast<char *>(const_cast<identifier::Table&>(identifier).getPath().c_str()),
 
1846
                                                        const_cast<char *>(identifier.getPath().c_str()),
1811
1847
                                                        static_cast<uint32_t>(identifier.getPath().length()));
1812
1848
  if (not new_tmp_table)
1813
1849
    return NULL;
1815
1851
  /*
1816
1852
    First open the share, and then open the table from the share we just opened.
1817
1853
  */
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(),
 
1854
  if (new_tmp_table->getMutableShare()->open_table_def(*this, identifier) ||
 
1855
      new_tmp_table->getMutableShare()->open_table_from_share(this, identifier, identifier.getTableName().c_str(),
1820
1856
                                                              (uint32_t) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
1821
1857
                                                                          HA_GET_INDEX),
1822
1858
                                                              ha_open_options,
1884
1920
      current_bitmap= table->write_set;
1885
1921
    }
1886
1922
 
1887
 
    //if (current_bitmap->testAndSet(field->position()))
1888
 
    if (current_bitmap->test(field->position()))
 
1923
    //if (current_bitmap->testAndSet(field->field_index))
 
1924
    if (current_bitmap->test(field->field_index))
1889
1925
    {
1890
1926
      if (session->mark_used_columns == MARK_COLUMNS_WRITE)
1891
1927
        session->dup_field= field;
1944
1980
    {
1945
1981
      if (nj_col)
1946
1982
      {
1947
 
        my_error(ER_NON_UNIQ_ERROR, MYF(0), name, session->where());
 
1983
        my_error(ER_NON_UNIQ_ERROR, MYF(0), name, session->where);
1948
1984
        return NULL;
1949
1985
      }
1950
1986
      nj_col= curr_nj_col;
2195
2231
      {
2196
2232
        Table *table= field_to_set->getTable();
2197
2233
        if (session->mark_used_columns == MARK_COLUMNS_READ)
2198
 
          table->setReadSet(field_to_set->position());
 
2234
          table->setReadSet(field_to_set->field_index);
2199
2235
        else
2200
 
          table->setWriteSet(field_to_set->position());
 
2236
          table->setWriteSet(field_to_set->field_index);
2201
2237
      }
2202
2238
    }
2203
2239
  }
2341
2377
      */
2342
2378
      item->cached_table= found ?  0 : actual_table;
2343
2379
 
2344
 
      assert(session->where());
 
2380
      assert(session->where);
2345
2381
      /*
2346
2382
        If we found a fully qualified field we return it directly as it can't
2347
2383
        have duplicates.
2354
2390
        if (report_error == REPORT_ALL_ERRORS ||
2355
2391
            report_error == IGNORE_EXCEPT_NON_UNIQUE)
2356
2392
          my_error(ER_NON_UNIQ_ERROR, MYF(0),
2357
 
                   table_name ? item->full_name() : name, session->where());
 
2393
                   table_name ? item->full_name() : name, session->where);
2358
2394
        return (Field*) 0;
2359
2395
      }
2360
2396
      found= cur_field;
2387
2423
      strcat(buff, table_name);
2388
2424
      table_name=buff;
2389
2425
    }
2390
 
    my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, session->where());
 
2426
    my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, session->where);
2391
2427
  }
2392
2428
  else
2393
2429
  {
2394
2430
    if (report_error == REPORT_ALL_ERRORS ||
2395
2431
        report_error == REPORT_EXCEPT_NON_UNIQUE)
2396
 
      my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), session->where());
 
2432
      my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), session->where);
2397
2433
    else
2398
2434
      found= not_found_field;
2399
2435
  }
2520
2556
            */
2521
2557
            if (report_error != IGNORE_ERRORS)
2522
2558
              my_error(ER_NON_UNIQ_ERROR, MYF(0),
2523
 
                       find->full_name(), session->where());
 
2559
                       find->full_name(), session->where);
2524
2560
            return (Item**) 0;
2525
2561
          }
2526
2562
          found_unaliased= li.ref();
2551
2587
              continue;                           // Same field twice
2552
2588
            if (report_error != IGNORE_ERRORS)
2553
2589
              my_error(ER_NON_UNIQ_ERROR, MYF(0),
2554
 
                       find->full_name(), session->where());
 
2590
                       find->full_name(), session->where);
2555
2591
            return (Item**) 0;
2556
2592
          }
2557
2593
          found= li.ref();
2603
2639
    {
2604
2640
      if (report_error != IGNORE_ERRORS)
2605
2641
        my_error(ER_NON_UNIQ_ERROR, MYF(0),
2606
 
                 find->full_name(), session->where());
 
2642
                 find->full_name(), session->where);
2607
2643
      return (Item **) 0;
2608
2644
    }
2609
2645
    if (found_unaliased)
2619
2655
  {
2620
2656
    if (report_error == REPORT_ALL_ERRORS)
2621
2657
      my_error(ER_BAD_FIELD_ERROR, MYF(0),
2622
 
               find->full_name(), session->where());
 
2658
               find->full_name(), session->where);
2623
2659
    return (Item **) 0;
2624
2660
  }
2625
2661
  else
2790
2826
        if (cur_nj_col_2->is_common ||
2791
2827
            (found && (!using_fields || is_using_column_1)))
2792
2828
        {
2793
 
          my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1, session->where());
 
2829
          my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1, session->where);
2794
2830
          return(result);
2795
2831
        }
2796
2832
        nj_col_2= cur_nj_col_2;
2869
2905
      {
2870
2906
        Table *table_1= nj_col_1->table_ref->table;
2871
2907
        /* Mark field_1 used for table cache. */
2872
 
        table_1->setReadSet(field_1->position());
 
2908
        table_1->setReadSet(field_1->field_index);
2873
2909
        table_1->covering_keys&= field_1->part_of_key;
2874
2910
        table_1->merge_keys|= field_1->part_of_key;
2875
2911
      }
2877
2913
      {
2878
2914
        Table *table_2= nj_col_2->table_ref->table;
2879
2915
        /* Mark field_2 used for table cache. */
2880
 
        table_2->setReadSet(field_2->position());
 
2916
        table_2->setReadSet(field_2->field_index);
2881
2917
        table_2->covering_keys&= field_2->part_of_key;
2882
2918
        table_2->merge_keys|= field_2->part_of_key;
2883
2919
      }
2995
3031
        if (!(common_field= it++))
2996
3032
        {
2997
3033
          my_error(ER_BAD_FIELD_ERROR, MYF(0), using_field_name_ptr,
2998
 
                   session->where());
 
3034
                   session->where);
2999
3035
          return(result);
3000
3036
        }
3001
3037
        if (!my_strcasecmp(system_charset_info,
3218
3254
                                         List<TableList> *from_clause,
3219
3255
                                         Name_resolution_context *context)
3220
3256
{
3221
 
  session->setWhere("from clause");
 
3257
  session->where= "from clause";
3222
3258
  if (from_clause->elements == 0)
3223
3259
    return false; /* We come here in the case of UNIONs. */
3224
3260
 
3339
3375
  session->mark_used_columns= mark_used_columns;
3340
3376
  if (allow_sum_func)
3341
3377
    session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
3342
 
  session->setWhere(Session::DEFAULT_WHERE);
 
3378
  session->where= Session::DEFAULT_WHERE;
3343
3379
  save_is_item_list_lookup= session->lex->current_select->is_item_list_lookup;
3344
3380
  session->lex->current_select->is_item_list_lookup= 0;
3345
3381
 
3351
3387
    There is other way to solve problem: fill array with pointers to list,
3352
3388
    but it will be slower.
3353
3389
 
3354
 
    TODO-> remove it when (if) we made one list for allfields and ref_pointer_array
 
3390
TODO: remove it when (if) we made one list for allfields and
 
3391
ref_pointer_array
3355
3392
  */
3356
3393
  if (ref_pointer_array)
3357
 
  {
3358
3394
    memset(ref_pointer_array, 0, sizeof(Item *) * fields.elements);
3359
 
  }
3360
3395
 
3361
3396
  Item **ref= ref_pointer_array;
3362
3397
  session->lex->current_select->cur_pos_in_select_list= 0;
3588
3623
    assert(tables->is_leaf_for_name_resolution());
3589
3624
 
3590
3625
    if ((table_name && my_strcasecmp(table_alias_charset, table_name, tables->alias)) ||
3591
 
        (db_name && my_strcasecmp(system_charset_info, tables->getSchemaName(),db_name)))
 
3626
        (db_name && strcasecmp(tables->getSchemaName(),db_name)))
3592
3627
      continue;
3593
3628
 
3594
3629
    /*
3624
3659
      if ((field= field_iterator.field()))
3625
3660
      {
3626
3661
        /* Mark fields as used to allow storage engine to optimze access */
3627
 
        field->getTable()->setReadSet(field->position());
 
3662
        field->getTable()->setReadSet(field->field_index);
3628
3663
        if (table)
3629
3664
        {
3630
3665
          table->covering_keys&= field->part_of_key;
3652
3687
        }
3653
3688
      }
3654
3689
      else
3655
 
      {
3656
3690
        session->used_tables|= item->used_tables();
3657
 
      }
3658
 
 
3659
3691
      session->lex->current_select->cur_pos_in_select_list++;
3660
3692
    }
3661
3693
    /*
3675
3707
    qualified '*', and all columns were coalesced, we have to give a more
3676
3708
    meaningful message than ER_BAD_TABLE_ERROR.
3677
3709
  */
3678
 
  if (not table_name)
3679
 
  {
 
3710
  if (!table_name)
3680
3711
    my_message(ER_NO_TABLES_USED, ER(ER_NO_TABLES_USED), MYF(0));
3681
 
  }
3682
3712
  else
3683
 
  {
3684
3713
    my_error(ER_BAD_TABLE_ERROR, MYF(0), table_name);
3685
 
  }
3686
3714
 
3687
3715
  return true;
3688
3716
}
3731
3759
  session->session_marker= (void*)1;
3732
3760
  if (*conds)
3733
3761
  {
3734
 
    session->setWhere("where clause");
 
3762
    session->where="where clause";
3735
3763
    if ((!(*conds)->fixed && (*conds)->fix_fields(session, conds)) ||
3736
3764
        (*conds)->check_cols(1))
3737
3765
      goto err_no_arena;
3753
3781
      {
3754
3782
        /* Make a join an a expression */
3755
3783
        session->session_marker= (void*)embedded;
3756
 
        session->setWhere("on clause");
 
3784
        session->where="on clause";
3757
3785
        if ((!embedded->on_expr->fixed && embedded->on_expr->fix_fields(session, &embedded->on_expr)) ||
3758
3786
            embedded->on_expr->check_cols(1))
3759
3787
          goto err_no_arena;
3888
3916
    table= (*ptr)->getTable();
3889
3917
    table->auto_increment_field_not_null= false;
3890
3918
  }
3891
 
 
3892
3919
  while ((field = *ptr++) && ! session->is_error())
3893
3920
  {
3894
3921
    value=v++;
3895
3922
    table= field->getTable();
3896
 
 
3897
3923
    if (field == table->next_number_field)
3898
3924
      table->auto_increment_field_not_null= true;
3899
 
 
3900
3925
    if (value->save_in_field(field, 0) < 0)
3901
3926
    {
3902
3927
      if (table)
3912
3937
 
3913
3938
bool drizzle_rm_tmp_tables()
3914
3939
{
 
3940
  Session *session;
3915
3941
 
3916
3942
  assert(drizzle_tmpdir.size());
3917
 
  Session::shared_ptr session= Session::make_shared(plugin::Listen::getNullClient(), catalog::local());
3918
3943
 
3919
 
  if (not session)
 
3944
  if (!(session= new Session(plugin::Listen::getNullClient())))
3920
3945
    return true;
3921
 
  session->thread_stack= (char*) session.get();
 
3946
  session->thread_stack= (char*) &session;
3922
3947
  session->storeGlobals();
3923
3948
 
3924
3949
  plugin::StorageEngine::removeLostTemporaryTables(*session, drizzle_tmpdir.c_str());
3925
3950
 
 
3951
  session->lockForDelete();
 
3952
  delete session;
 
3953
 
3926
3954
  return false;
3927
3955
}
3928
3956