~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_base.cc

  • Committer: Monty Taylor
  • Date: 2011-02-13 17:26:39 UTC
  • mfrom: (2157.2.2 give-in-to-pkg-config)
  • mto: This revision was merged to the branch mainline in revision 2166.
  • Revision ID: mordred@inaugust.com-20110213172639-nhy7i72sfhoq13ms
Merged in pkg-config fixes.

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