~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_base.cc

  • Committer: Brian Aker
  • Date: 2010-11-06 15:43:10 UTC
  • mfrom: (1908.1.1 merge)
  • Revision ID: brian@tangent.org-20101106154310-g1jpjzwbc53pfc4f
Filesort encapsulation, plus modification to copy contructor

Show diffs side-by-side

added added

removed removed

Lines of Context:
93
93
  By leaving the table in the table cache, it disallows any other thread
94
94
  to open the table
95
95
 
96
 
  session->getKilled() will be set if we run out of memory
 
96
  session->killed will be set if we run out of memory
97
97
 
98
98
  If closing a MERGE child, the calling function has to take care for
99
99
  closing the parent too, if necessary.
143
143
{
144
144
  if (sort.io_cache)
145
145
  {
146
 
    sort.io_cache->close_cached_file();
 
146
    close_cached_file(sort.io_cache);
147
147
    delete sort.io_cache;
148
148
    sort.io_cache= 0;
149
149
  }
155
155
 
156
156
  @param session Thread context (may be NULL)
157
157
  @param tables List of tables to remove from the cache
158
 
  @param have_lock If table::Cache::singleton().mutex() is locked
 
158
  @param have_lock If LOCK_open is locked
159
159
  @param wait_for_refresh Wait for a impending flush
160
160
  @param wait_for_placeholders Wait for tables being reopened so that the GRL
161
161
  won't proceed while write-locked tables are being reopened by other
171
171
  Session *session= this;
172
172
 
173
173
  {
174
 
    table::Cache::singleton().mutex().lock(); /* 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 */
175
175
 
176
176
    if (tables == NULL)
177
177
    {
250
250
        If there is any table that has a lower refresh_version, wait until
251
251
        this is closed (or this thread is killed) before returning
252
252
      */
253
 
      session->mysys_var->current_mutex= &table::Cache::singleton().mutex();
 
253
      session->mysys_var->current_mutex= &LOCK_open;
254
254
      session->mysys_var->current_cond= &COND_refresh;
255
255
      session->set_proc_info("Flushing tables");
256
256
 
258
258
 
259
259
      bool found= true;
260
260
      /* Wait until all threads has closed all the tables we had locked */
261
 
      while (found && ! session->getKilled())
 
261
      while (found && ! session->killed)
262
262
      {
263
263
        found= false;
264
264
        for (table::CacheMap::const_iterator iter= table::getCache().begin();
287
287
                                                     (table->open_placeholder && wait_for_placeholders)))
288
288
          {
289
289
            found= true;
290
 
            boost_unique_lock_t scoped(table::Cache::singleton().mutex(), boost::adopt_lock_t());
 
290
            boost_unique_lock_t scoped(LOCK_open, boost::adopt_lock_t());
291
291
            COND_refresh.wait(scoped);
292
292
            scoped.release();
293
293
            break;
313
313
      }
314
314
    }
315
315
 
316
 
    table::Cache::singleton().mutex().unlock();
 
316
    LOCK_open.unlock();
317
317
  }
318
318
 
319
319
  if (wait_for_refresh)
337
337
  bool found_old_table= false;
338
338
  table::Concurrent *table= static_cast<table::Concurrent *>(open_tables);
339
339
 
340
 
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
 
340
  safe_mutex_assert_owner(LOCK_open.native_handle());
341
341
  assert(table->key_read == 0);
342
342
  assert(!table->cursor || table->cursor->inited == Cursor::NONE);
343
343
 
380
380
{
381
381
  bool found_old_table= false;
382
382
 
383
 
  safe_mutex_assert_not_owner(table::Cache::singleton().mutex().native_handle());
 
383
  safe_mutex_assert_not_owner(LOCK_open.native_handle());
384
384
 
385
 
  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 */
386
386
 
387
387
  while (open_tables)
388
388
  {
393
393
  if (found_old_table)
394
394
  {
395
395
    /* Tell threads waiting for refresh that something has happened */
396
 
    locking::broadcast_refresh();
 
396
    broadcast_refresh();
397
397
  }
398
398
}
399
399
 
517
517
}
518
518
 
519
519
 
520
 
void Open_tables_state::doGetTableNames(const SchemaIdentifier &schema_identifier,
521
 
                                        std::set<std::string>& set_of_names)
 
520
void Session::doGetTableNames(const SchemaIdentifier &schema_identifier,
 
521
                              std::set<std::string>& set_of_names)
522
522
{
523
 
  for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
 
523
  for (Table *table= temporary_tables ; table ; table= table->getNext())
524
524
  {
525
525
    if (schema_identifier.compare(table->getShare()->getSchemaName()))
526
526
    {
529
529
  }
530
530
}
531
531
 
532
 
void Open_tables_state::doGetTableNames(CachedDirectory &,
533
 
                                        const SchemaIdentifier &schema_identifier,
534
 
                                        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)
535
535
{
536
536
  doGetTableNames(schema_identifier, set_of_names);
537
537
}
538
538
 
539
 
void Open_tables_state::doGetTableIdentifiers(const SchemaIdentifier &schema_identifier,
540
 
                                              TableIdentifier::vector &set_of_identifiers)
 
539
void Session::doGetTableIdentifiers(const SchemaIdentifier &schema_identifier,
 
540
                                    TableIdentifiers &set_of_identifiers)
541
541
{
542
 
  for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
 
542
  for (Table *table= temporary_tables ; table ; table= table->getNext())
543
543
  {
544
544
    if (schema_identifier.compare(table->getShare()->getSchemaName()))
545
545
    {
550
550
  }
551
551
}
552
552
 
553
 
void Open_tables_state::doGetTableIdentifiers(CachedDirectory &,
554
 
                                              const SchemaIdentifier &schema_identifier,
555
 
                                              TableIdentifier::vector &set_of_identifiers)
 
553
void Session::doGetTableIdentifiers(CachedDirectory &,
 
554
                                    const SchemaIdentifier &schema_identifier,
 
555
                                    TableIdentifiers &set_of_identifiers)
556
556
{
557
557
  doGetTableIdentifiers(schema_identifier, set_of_identifiers);
558
558
}
559
559
 
560
 
bool Open_tables_state::doDoesTableExist(const TableIdentifier &identifier)
 
560
bool Session::doDoesTableExist(const TableIdentifier &identifier)
561
561
{
562
 
  for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
 
562
  for (Table *table= temporary_tables ; table ; table= table->getNext())
563
563
  {
564
564
    if (table->getShare()->getType() == message::Table::TEMPORARY)
565
565
    {
573
573
  return false;
574
574
}
575
575
 
576
 
int Open_tables_state::doGetTableDefinition(const TableIdentifier &identifier,
 
576
int Session::doGetTableDefinition(const TableIdentifier &identifier,
577
577
                                  message::Table &table_proto)
578
578
{
579
 
  for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
 
579
  for (Table *table= temporary_tables ; table ; table= table->getNext())
580
580
  {
581
581
    if (table->getShare()->getType() == message::Table::TEMPORARY)
582
582
    {
592
592
  return ENOENT;
593
593
}
594
594
 
595
 
Table *Open_tables_state::find_temporary_table(const TableIdentifier &identifier)
 
595
Table *Session::find_temporary_table(const TableIdentifier &identifier)
596
596
{
597
597
  for (Table *table= temporary_tables ; table ; table= table->getNext())
598
598
  {
630
630
  @retval -1  the table is in use by a outer query
631
631
*/
632
632
 
633
 
int Open_tables_state::drop_temporary_table(const drizzled::TableIdentifier &identifier)
 
633
int Session::drop_temporary_table(const drizzled::TableIdentifier &identifier)
634
634
{
635
635
  Table *table;
636
636
 
638
638
    return 1;
639
639
 
640
640
  /* Table might be in use by some outer statement. */
641
 
  if (table->query_id && table->query_id != getQueryId())
 
641
  if (table->query_id && table->query_id != query_id)
642
642
  {
643
643
    my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->getAlias());
644
644
    return -1;
657
657
  @param  session     Thread context
658
658
  @param  find    Table to remove
659
659
 
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 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.
661
661
*/
662
662
 
663
663
void Session::unlink_open_table(Table *find)
664
664
{
665
665
  const TableIdentifier::Key find_key(find->getShare()->getCacheKey());
666
666
  Table **prev;
667
 
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
 
667
  safe_mutex_assert_owner(LOCK_open.native_handle());
668
668
 
669
669
  /*
670
 
    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
671
671
    open_tables list. Another thread may work on it.
672
672
    (See: table::Cache::singleton().removeTable(), mysql_wait_completed_table())
673
673
    Closing a MERGE child before the parent would be fatal if the
693
693
  }
694
694
 
695
695
  // Notify any 'refresh' threads
696
 
  locking::broadcast_refresh();
 
696
  broadcast_refresh();
697
697
}
698
698
 
699
699
 
716
716
  table that was locked with LOCK TABLES.
717
717
*/
718
718
 
719
 
void Session::drop_open_table(Table *table, const TableIdentifier &identifier)
 
719
void Session::drop_open_table(Table *table, TableIdentifier &identifier)
720
720
{
721
721
  if (table->getShare()->getType())
722
722
  {
724
724
  }
725
725
  else
726
726
  {
727
 
    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) */
728
728
    /*
729
729
      unlink_open_table() also tells threads waiting for refresh or close
730
730
      that something has happened.
731
731
    */
732
732
    unlink_open_table(table);
733
 
    plugin::StorageEngine::dropTable(*this, identifier);
 
733
    quick_rm_table(*this, identifier);
734
734
  }
735
735
}
736
736
 
766
766
      mutex is unlocked
767
767
    */
768
768
    boost_unique_lock_t scopedLock(mutex, boost::adopt_lock_t());
769
 
    if (not getKilled())
 
769
    if (not killed)
770
770
    {
771
771
      cond.wait(scopedLock);
772
772
    }
793
793
 
794
794
table::Placeholder *Session::table_cache_insert_placeholder(const drizzled::TableIdentifier &arg)
795
795
{
796
 
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
 
796
  safe_mutex_assert_owner(LOCK_open.native_handle());
797
797
 
798
798
  /*
799
799
    Create a table entry with the right key and with an old refresh version
833
833
  @retval  true   Error occured (OOM)
834
834
  @retval  false  Success. 'table' parameter set according to above rules.
835
835
*/
836
 
bool Session::lock_table_name_if_not_cached(const TableIdentifier &identifier, Table **table)
 
836
bool Session::lock_table_name_if_not_cached(TableIdentifier &identifier, Table **table)
837
837
{
838
838
  const TableIdentifier::Key &key(identifier.getKey());
839
839
 
840
 
  boost_unique_lock_t scope_lock(table::Cache::singleton().mutex()); /* Obtain a name lock even though table is not in cache (like for create table)  */
 
840
  boost_unique_lock_t scope_lock(LOCK_open); /* Obtain a name lock even though table is not in cache (like for create table)  */
841
841
 
842
842
  table::CacheMap::iterator iter;
843
843
 
909
909
  if (check_stack_overrun(this, STACK_MIN_SIZE_FOR_OPEN, (unsigned char *)&alias))
910
910
    return NULL;
911
911
 
912
 
  if (getKilled())
 
912
  if (killed)
913
913
    return NULL;
914
914
 
915
915
  TableIdentifier identifier(table_list->getSchemaName(), table_list->getTableName());
924
924
    TODO -> move this block into a separate function.
925
925
  */
926
926
  bool reset= false;
927
 
  for (table= getTemporaryTables(); table ; table=table->getNext())
 
927
  for (table= temporary_tables; table ; table=table->getNext())
928
928
  {
929
929
    if (table->getShare()->getCacheKey() == key)
930
930
    {
994
994
      until no one holds a name lock on the table.
995
995
      - if there is no such Table in the name cache, read the table definition
996
996
      and insert it into the cache.
997
 
      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
998
998
      the open cache (also known as table cache) and table definitions stored
999
999
      on disk.
1000
1000
    */
1001
1001
 
1002
1002
    {
1003
 
      table::Cache::singleton().mutex().lock(); /* Lock for FLUSH TABLES for open table */
 
1003
      LOCK_open.lock(); /* Lock for FLUSH TABLES for open table */
1004
1004
 
1005
1005
      /*
1006
1006
        Actually try to find the table in the open_cache.
1052
1052
          /* Avoid self-deadlocks by detecting self-dependencies. */
1053
1053
          if (table->open_placeholder && table->in_use == this)
1054
1054
          {
1055
 
            table::Cache::singleton().mutex().unlock();
 
1055
            LOCK_open.unlock();
1056
1056
            my_error(ER_UPDATE_TABLE_USED, MYF(0), table->getShare()->getTableName());
1057
1057
            return NULL;
1058
1058
          }
1085
1085
          */
1086
1086
          if (table->in_use != this)
1087
1087
          {
1088
 
            /* wait_for_conditionwill unlock table::Cache::singleton().mutex() for us */
1089
 
            wait_for_condition(table::Cache::singleton().mutex(), COND_refresh);
 
1088
            /* wait_for_conditionwill unlock LOCK_open for us */
 
1089
            wait_for_condition(LOCK_open, COND_refresh);
1090
1090
          }
1091
1091
          else
1092
1092
          {
1093
 
            table::Cache::singleton().mutex().unlock();
 
1093
            LOCK_open.unlock();
1094
1094
          }
1095
1095
          /*
1096
1096
            There is a refresh in progress for this table.
1124
1124
            */
1125
1125
            if (!(table= table_cache_insert_placeholder(lock_table_identifier)))
1126
1126
            {
1127
 
              table::Cache::singleton().mutex().unlock();
 
1127
              LOCK_open.unlock();
1128
1128
              return NULL;
1129
1129
            }
1130
1130
            /*
1135
1135
            table->open_placeholder= true;
1136
1136
            table->setNext(open_tables);
1137
1137
            open_tables= table;
1138
 
            table::Cache::singleton().mutex().unlock();
 
1138
            LOCK_open.unlock();
1139
1139
 
1140
1140
            return table ;
1141
1141
          }
1148
1148
          table= new_table;
1149
1149
          if (new_table == NULL)
1150
1150
          {
1151
 
            table::Cache::singleton().mutex().unlock();
 
1151
            LOCK_open.unlock();
1152
1152
            return NULL;
1153
1153
          }
1154
1154
 
1156
1156
          if (error != 0)
1157
1157
          {
1158
1158
            delete new_table;
1159
 
            table::Cache::singleton().mutex().unlock();
 
1159
            LOCK_open.unlock();
1160
1160
            return NULL;
1161
1161
          }
1162
1162
          (void)table::Cache::singleton().insert(new_table);
1163
1163
        }
1164
1164
      }
1165
1165
 
1166
 
      table::Cache::singleton().mutex().unlock();
 
1166
      LOCK_open.unlock();
1167
1167
    }
1168
1168
    if (refresh)
1169
1169
    {
1222
1222
  the strings are used in a loop even after the share may be freed.
1223
1223
*/
1224
1224
 
1225
 
void Session::close_data_files_and_morph_locks(const TableIdentifier &identifier)
 
1225
void Session::close_data_files_and_morph_locks(TableIdentifier &identifier)
1226
1226
{
1227
 
  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 */
1228
1228
 
1229
1229
  if (lock)
1230
1230
  {
1232
1232
      If we are not under LOCK TABLES we should have only one table
1233
1233
      open and locked so it makes sense to remove the lock at once.
1234
1234
    */
1235
 
    unlockTables(lock);
 
1235
    mysql_unlock_tables(this, lock);
1236
1236
    lock= 0;
1237
1237
  }
1238
1238
 
1267
1267
  combination when one needs tables to be reopened (for
1268
1268
  example see openTablesLock()).
1269
1269
 
1270
 
  @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.
1271
1271
 
1272
1272
  @return false in case of success, true - otherwise.
1273
1273
*/
1284
1284
  if (open_tables == NULL)
1285
1285
    return false;
1286
1286
 
1287
 
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
 
1287
  safe_mutex_assert_owner(LOCK_open.native_handle());
1288
1288
  if (get_locks)
1289
1289
  {
1290
1290
    /*
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),
1329
 
                                       flags, &not_used)))
 
1328
    if ((local_lock= mysql_lock_tables(this, tables, (uint32_t) (tables_ptr - tables),
 
1329
                                 flags, &not_used)))
1330
1330
    {
1331
1331
      /* unused */
1332
1332
    }
1345
1345
  if (get_locks && tables)
1346
1346
    delete [] tables;
1347
1347
 
1348
 
  locking::broadcast_refresh();
 
1348
  broadcast_refresh();
1349
1349
 
1350
1350
  return(error);
1351
1351
}
1392
1392
              lock on it. This will also give them a chance to close their
1393
1393
              instances of this table.
1394
1394
            */
1395
 
            abortLock(ulcktbl);
1396
 
            removeLock(ulcktbl);
 
1395
            mysql_lock_abort(this, ulcktbl);
 
1396
            mysql_lock_remove(this, ulcktbl);
1397
1397
            ulcktbl->lock_count= 0;
1398
1398
          }
1399
1399
          if ((ulcktbl != table) && ulcktbl->db_stat)
1433
1433
    }
1434
1434
  }
1435
1435
  if (found)
1436
 
    locking::broadcast_refresh();
 
1436
    broadcast_refresh();
1437
1437
}
1438
1438
 
1439
1439
 
1445
1445
 
1446
1446
  session->set_proc_info("Waiting for tables");
1447
1447
  {
1448
 
    boost_unique_lock_t lock(table::Cache::singleton().mutex());
1449
 
    while (not session->getKilled())
 
1448
    boost_unique_lock_t lock(LOCK_open);
 
1449
    while (!session->killed)
1450
1450
    {
1451
1451
      session->some_tables_deleted= false;
1452
1452
      session->close_old_data_files(false, dropping_tables != 0);
1456
1456
      }
1457
1457
      COND_refresh.wait(lock);
1458
1458
    }
1459
 
    if (session->getKilled())
 
1459
    if (session->killed)
1460
1460
      result= true;                                     // aborted
1461
1461
    else
1462
1462
    {
1502
1502
  prev= &session->open_tables;
1503
1503
 
1504
1504
  /*
1505
 
    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
1506
1506
    open_tables list. Another thread may work on it.
1507
1507
    (See: table::Cache::singleton().removeTable(), mysql_wait_completed_table())
1508
1508
    Closing a MERGE child before the parent would be fatal if the
1513
1513
    next=table->getNext();
1514
1514
    if (table->getShare()->getCacheKey() == identifier.getKey())
1515
1515
    {
1516
 
      session->removeLock(table);
 
1516
      mysql_lock_remove(session, table);
1517
1517
 
1518
1518
      if (!found)
1519
1519
      {
1539
1539
  }
1540
1540
  *prev=0;
1541
1541
  if (found)
1542
 
    locking::broadcast_refresh();
 
1542
    broadcast_refresh();
1543
1543
 
1544
1544
  return(found);
1545
1545
}
1559
1559
    if (table->getShare()->getCacheKey() == identifier.getKey())
1560
1560
    {
1561
1561
      /* If MERGE child, forward lock handling to parent. */
1562
 
      session->abortLock(table);
 
1562
      mysql_lock_abort(session, table);
1563
1563
      break;
1564
1564
    }
1565
1565
  }
1742
1742
 
1743
1743
    assert(lock == 0);  // You must lock everything at once
1744
1744
    if ((table->reginfo.lock_type= lock_type) != TL_UNLOCK)
1745
 
      if (! (lock= lockTables(&table_list->table, 1, 0, &refresh)))
 
1745
      if (! (lock= mysql_lock_tables(this, &table_list->table, 1, 0, &refresh)))
1746
1746
        table= 0;
1747
1747
  }
1748
1748
 
1805
1805
      *(ptr++)= table->table;
1806
1806
  }
1807
1807
 
1808
 
  if (!(session->lock= session->lockTables(start, (uint32_t) (ptr - start), lock_flag, need_reopen)))
 
1808
  if (!(session->lock= mysql_lock_tables(session, start, (uint32_t) (ptr - start),
 
1809
                                         lock_flag, need_reopen)))
1809
1810
  {
1810
1811
    return -1;
1811
1812
  }
1834
1835
#  Table object
1835
1836
*/
1836
1837
 
1837
 
Table *Open_tables_state::open_temporary_table(const TableIdentifier &identifier,
1838
 
                                               bool link_in_list)
 
1838
Table *Session::open_temporary_table(TableIdentifier &identifier,
 
1839
                                     bool link_in_list)
1839
1840
{
1840
1841
  assert(identifier.isTmp());
1841
1842
 
1842
1843
 
1843
1844
  table::Temporary *new_tmp_table= new table::Temporary(identifier.getType(),
1844
1845
                                                        identifier,
1845
 
                                                        const_cast<char *>(const_cast<TableIdentifier&>(identifier).getPath().c_str()),
 
1846
                                                        const_cast<char *>(identifier.getPath().c_str()),
1846
1847
                                                        static_cast<uint32_t>(identifier.getPath().length()));
1847
1848
  if (not new_tmp_table)
1848
1849
    return NULL;
1850
1851
  /*
1851
1852
    First open the share, and then open the table from the share we just opened.
1852
1853
  */
1853
 
  if (new_tmp_table->getMutableShare()->open_table_def(*static_cast<Session *>(this), identifier) ||
1854
 
      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(),
1855
1856
                                                              (uint32_t) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
1856
1857
                                                                          HA_GET_INDEX),
1857
1858
                                                              ha_open_options,
1919
1920
      current_bitmap= table->write_set;
1920
1921
    }
1921
1922
 
1922
 
    //if (current_bitmap->testAndSet(field->position()))
1923
 
    if (current_bitmap->test(field->position()))
 
1923
    //if (current_bitmap->testAndSet(field->field_index))
 
1924
    if (current_bitmap->test(field->field_index))
1924
1925
    {
1925
1926
      if (session->mark_used_columns == MARK_COLUMNS_WRITE)
1926
1927
        session->dup_field= field;
2230
2231
      {
2231
2232
        Table *table= field_to_set->getTable();
2232
2233
        if (session->mark_used_columns == MARK_COLUMNS_READ)
2233
 
          table->setReadSet(field_to_set->position());
 
2234
          table->setReadSet(field_to_set->field_index);
2234
2235
        else
2235
 
          table->setWriteSet(field_to_set->position());
 
2236
          table->setWriteSet(field_to_set->field_index);
2236
2237
      }
2237
2238
    }
2238
2239
  }
2904
2905
      {
2905
2906
        Table *table_1= nj_col_1->table_ref->table;
2906
2907
        /* Mark field_1 used for table cache. */
2907
 
        table_1->setReadSet(field_1->position());
 
2908
        table_1->setReadSet(field_1->field_index);
2908
2909
        table_1->covering_keys&= field_1->part_of_key;
2909
2910
        table_1->merge_keys|= field_1->part_of_key;
2910
2911
      }
2912
2913
      {
2913
2914
        Table *table_2= nj_col_2->table_ref->table;
2914
2915
        /* Mark field_2 used for table cache. */
2915
 
        table_2->setReadSet(field_2->position());
 
2916
        table_2->setReadSet(field_2->field_index);
2916
2917
        table_2->covering_keys&= field_2->part_of_key;
2917
2918
        table_2->merge_keys|= field_2->part_of_key;
2918
2919
      }
3658
3659
      if ((field= field_iterator.field()))
3659
3660
      {
3660
3661
        /* Mark fields as used to allow storage engine to optimze access */
3661
 
        field->getTable()->setReadSet(field->position());
 
3662
        field->getTable()->setReadSet(field->field_index);
3662
3663
        if (table)
3663
3664
        {
3664
3665
          table->covering_keys&= field->part_of_key;
3947
3948
 
3948
3949
  plugin::StorageEngine::removeLostTemporaryTables(*session, drizzle_tmpdir.c_str());
3949
3950
 
 
3951
  session->lockForDelete();
3950
3952
  delete session;
3951
3953
 
3952
3954
  return false;