~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_base.cc

  • Committer: Lee Bieber
  • Date: 2010-10-27 18:28:56 UTC
  • mfrom: (1883.1.3 build)
  • Revision ID: kalebral@gmail.com-20101027182856-q3wqtbv1t4egkjsk
Merge Andrew - fix bug 667360: --defaults-file not processed before paths read           
Merge Andrew - fix bug 656577: Importing SQL script results in silent failure    
Merge Andrew - fix bug 667053: drizzledump minor output cleanup needed

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"
55
55
#include "drizzled/plugin/authorization.h"
56
56
#include "drizzled/table/temporary.h"
57
57
#include "drizzled/table/placeholder.h"
58
 
#include "drizzled/table/unused.h"
59
 
#include "drizzled/plugin/storage_engine.h"
60
 
 
61
 
#include <drizzled/refresh_version.h>
62
58
 
63
59
using namespace std;
64
60
 
67
63
 
68
64
extern bool volatile shutdown_in_progress;
69
65
 
 
66
TableOpenCache &get_open_cache()
 
67
{
 
68
  static TableOpenCache open_cache;                             /* Used by mysql_test */
 
69
 
 
70
  return open_cache;
 
71
}
 
72
 
 
73
static void free_cache_entry(table::Concurrent *entry);
 
74
 
 
75
void remove_table(table::Concurrent *arg)
 
76
{
 
77
  TableOpenCacheRange ppp;
 
78
  ppp= get_open_cache().equal_range(arg->getShare()->getCacheKey());
 
79
 
 
80
  for (TableOpenCache::const_iterator iter= ppp.first;
 
81
         iter != ppp.second; ++iter)
 
82
  {
 
83
    table::Concurrent *found_table= (*iter).second;
 
84
 
 
85
    if (found_table == arg)
 
86
    {
 
87
      free_cache_entry(arg);
 
88
      get_open_cache().erase(iter);
 
89
      return;
 
90
    }
 
91
  }
 
92
}
 
93
 
 
94
static bool add_table(table::Concurrent *arg)
 
95
{
 
96
  TableOpenCache &open_cache(get_open_cache());
 
97
 
 
98
  TableOpenCache::iterator returnable= open_cache.insert(make_pair(arg->getShare()->getCacheKey(), arg));
 
99
 
 
100
  return not (returnable == open_cache.end());
 
101
}
 
102
 
 
103
class UnusedTables {
 
104
  table::Concurrent *tables;                            /* Used by mysql_test */
 
105
 
 
106
  table::Concurrent *getTable() const
 
107
  {
 
108
    return tables;
 
109
  }
 
110
 
 
111
  table::Concurrent *setTable(Table *arg)
 
112
  {
 
113
    return tables= static_cast<table::Concurrent *>(arg);
 
114
  }
 
115
 
 
116
public:
 
117
 
 
118
  void cull()
 
119
  {
 
120
    /* Free cache if too big */
 
121
    while (cached_open_tables() > table_cache_size && getTable())
 
122
      remove_table(getTable());
 
123
  }
 
124
 
 
125
  void cullByVersion()
 
126
  {
 
127
    while (getTable() && not getTable()->getShare()->getVersion())
 
128
      remove_table(getTable());
 
129
  }
 
130
  
 
131
  void link(table::Concurrent *table)
 
132
  {
 
133
    if (getTable())
 
134
    {
 
135
      table->setNext(getTable());               /* Link in last */
 
136
      table->setPrev(getTable()->getPrev());
 
137
      getTable()->setPrev(table);
 
138
      table->getPrev()->setNext(table);
 
139
    }
 
140
    else
 
141
    {
 
142
      table->setPrev(setTable(table));
 
143
      table->setNext(table->getPrev());
 
144
      assert(table->getNext() == table && table->getPrev() == table);
 
145
    }
 
146
  }
 
147
 
 
148
 
 
149
  void unlink(table::Concurrent *table)
 
150
  {
 
151
    table->unlink();
 
152
 
 
153
    /* Unlink the table from "unused_tables" list. */
 
154
    if (table == getTable())
 
155
    {  // First unused
 
156
      setTable(getTable()->getNext()); // Remove from link
 
157
      if (table == getTable())
 
158
        setTable(NULL);
 
159
    }
 
160
  }
 
161
 
 
162
/* move table first in unused links */
 
163
 
 
164
  void relink(table::Concurrent *table)
 
165
  {
 
166
    if (table != getTable())
 
167
    {
 
168
      table->unlink();
 
169
 
 
170
      table->setNext(getTable());                       /* Link in unused tables */
 
171
      table->setPrev(getTable()->getPrev());
 
172
      getTable()->getPrev()->setNext(table);
 
173
      getTable()->setPrev(table);
 
174
      setTable(table);
 
175
    }
 
176
  }
 
177
 
 
178
 
 
179
  void clear()
 
180
  {
 
181
    while (getTable())
 
182
      remove_table(getTable());
 
183
  }
 
184
 
 
185
  UnusedTables():
 
186
    tables(NULL)
 
187
  { }
 
188
 
 
189
  ~UnusedTables()
 
190
  { 
 
191
  }
 
192
};
 
193
 
 
194
static UnusedTables unused_tables;
 
195
 
 
196
unsigned char *table_cache_key(const unsigned char *record,
 
197
                               size_t *length,
 
198
                               bool );
 
199
 
 
200
unsigned char *table_cache_key(const unsigned char *record,
 
201
                               size_t *length,
 
202
                               bool )
 
203
{
 
204
  Table *entry=(Table*) record;
 
205
  *length= entry->getShare()->getCacheKey().size();
 
206
  return (unsigned char*) &entry->getShare()->getCacheKey()[0];
 
207
}
 
208
 
70
209
bool table_cache_init(void)
71
210
{
72
211
  return false;
74
213
 
75
214
uint32_t cached_open_tables(void)
76
215
{
77
 
  return table::getCache().size();
 
216
  return get_open_cache().size();
78
217
}
79
218
 
80
219
void table_cache_free(void)
81
220
{
82
221
  refresh_version++;                            // Force close of open tables
83
222
 
84
 
  table::getUnused().clear();
85
 
  table::getCache().clear();
 
223
  unused_tables.clear();
 
224
  get_open_cache().clear();
86
225
}
87
226
 
88
227
/*
96
235
  By leaving the table in the table cache, it disallows any other thread
97
236
  to open the table
98
237
 
99
 
  session->getKilled() will be set if we run out of memory
 
238
  session->killed will be set if we run out of memory
100
239
 
101
240
  If closing a MERGE child, the calling function has to take care for
102
241
  closing the parent too, if necessary.
113
252
    This has to be done to ensure that the table share is removed from
114
253
    the table defintion cache as soon as the last instance is removed
115
254
  */
116
 
  identifier::Table identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), message::Table::INTERNAL);
117
 
  const identifier::Table::Key &key(identifier.getKey());
 
255
  TableIdentifier identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), message::Table::INTERNAL);
 
256
  const TableIdentifier::Key &key(identifier.getKey());
118
257
  TableShare *share= new TableShare(identifier.getType(),
119
258
                                    identifier,
120
 
                                    const_cast<char *>(key.vector()),  static_cast<uint32_t>(table->getShare()->getCacheKeySize()));
 
259
                                    const_cast<char *>(&key[0]),  static_cast<uint32_t>(table->getShare()->getCacheKeySize()));
121
260
 
122
261
  table->cursor->close();
123
262
  table->db_stat= 0;                            // Mark cursor closed
124
 
  table::instance::release(table->getMutableShare());
 
263
  TableShare::release(table->getMutableShare());
125
264
  table->setShare(share);
126
265
}
127
266
 
140
279
  }
141
280
}
142
281
 
 
282
/*
 
283
  Remove table from the open table cache
 
284
 
 
285
  SYNOPSIS
 
286
  free_cache_entry()
 
287
  entry         Table to remove
 
288
 
 
289
  NOTE
 
290
  We need to have a lock on LOCK_open when calling this
 
291
*/
 
292
 
 
293
void free_cache_entry(table::Concurrent *table)
 
294
{
 
295
  table->intern_close_table();
 
296
  if (not table->in_use)
 
297
  {
 
298
    unused_tables.unlink(table);
 
299
  }
 
300
 
 
301
  delete table;
 
302
}
 
303
 
143
304
/* Free resources allocated by filesort() and read_record() */
144
305
 
145
306
void Table::free_io_cache()
146
307
{
147
308
  if (sort.io_cache)
148
309
  {
149
 
    sort.io_cache->close_cached_file();
 
310
    close_cached_file(sort.io_cache);
150
311
    delete sort.io_cache;
151
312
    sort.io_cache= 0;
152
313
  }
158
319
 
159
320
  @param session Thread context (may be NULL)
160
321
  @param tables List of tables to remove from the cache
161
 
  @param have_lock If table::Cache::singleton().mutex() is locked
 
322
  @param have_lock If LOCK_open is locked
162
323
  @param wait_for_refresh Wait for a impending flush
163
324
  @param wait_for_placeholders Wait for tables being reopened so that the GRL
164
325
  won't proceed while write-locked tables are being reopened by other
174
335
  Session *session= this;
175
336
 
176
337
  {
177
 
    boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex()); /* Optionally lock for remove tables from open_cahe if not in use */
 
338
    LOCK_open.lock(); /* Optionally lock for remove tables from open_cahe if not in use */
178
339
 
179
340
    if (tables == NULL)
180
341
    {
181
342
      refresh_version++;                                // Force close of open tables
182
343
 
183
 
      table::getUnused().clear();
 
344
      unused_tables.clear();
184
345
 
185
346
      if (wait_for_refresh)
186
347
      {
211
372
          again. There they will wait until we update all tables version
212
373
          below.
213
374
 
214
 
          Setting some_tables_deleted is done by table::Cache::singleton().removeTable()
 
375
          Setting some_tables_deleted is done by remove_table_from_cache()
215
376
          in the other branch.
216
377
 
217
378
          In other words (reviewer suggestion): You need this setting of
221
382
          after the call to Session::close_old_data_files() i.e. after removal of
222
383
          current thread locks.
223
384
        */
224
 
        for (table::CacheMap::const_iterator iter= table::getCache().begin();
225
 
             iter != table::getCache().end();
 
385
        for (TableOpenCache::const_iterator iter= get_open_cache().begin();
 
386
             iter != get_open_cache().end();
226
387
             iter++)
227
388
        {
228
389
          Table *table= (*iter).second;
236
397
      bool found= false;
237
398
      for (TableList *table= tables; table; table= table->next_local)
238
399
      {
239
 
        identifier::Table identifier(table->getSchemaName(), table->getTableName());
240
 
        if (table::Cache::singleton().removeTable(session, identifier,
 
400
        TableIdentifier identifier(table->getSchemaName(), table->getTableName());
 
401
        if (remove_table_from_cache(session, identifier,
241
402
                                    RTFC_OWNED_BY_Session_FLAG))
242
403
        {
243
404
          found= true;
253
414
        If there is any table that has a lower refresh_version, wait until
254
415
        this is closed (or this thread is killed) before returning
255
416
      */
256
 
      session->mysys_var->current_mutex= &table::Cache::singleton().mutex();
 
417
      session->mysys_var->current_mutex= &LOCK_open;
257
418
      session->mysys_var->current_cond= &COND_refresh;
258
419
      session->set_proc_info("Flushing tables");
259
420
 
261
422
 
262
423
      bool found= true;
263
424
      /* Wait until all threads has closed all the tables we had locked */
264
 
      while (found && ! session->getKilled())
 
425
      while (found && ! session->killed)
265
426
      {
266
427
        found= false;
267
 
        for (table::CacheMap::const_iterator iter= table::getCache().begin();
268
 
             iter != table::getCache().end();
 
428
        for (TableOpenCache::const_iterator iter= get_open_cache().begin();
 
429
             iter != get_open_cache().end();
269
430
             iter++)
270
431
        {
271
432
          Table *table= (*iter).second;
290
451
                                                     (table->open_placeholder && wait_for_placeholders)))
291
452
          {
292
453
            found= true;
293
 
            COND_refresh.wait(scopedLock);
 
454
            boost_unique_lock_t scoped(LOCK_open, boost::adopt_lock_t());
 
455
            COND_refresh.wait(scoped);
 
456
            scoped.release();
294
457
            break;
295
458
          }
296
459
        }
300
463
        old locks. This should always succeed (unless some external process
301
464
        has removed the tables)
302
465
      */
303
 
      result= session->reopen_tables();
 
466
      result= session->reopen_tables(true, true);
304
467
 
305
468
      /* Set version for table */
306
469
      for (Table *table= session->open_tables; table ; table= table->getNext())
313
476
          table->getMutableShare()->refreshVersion();
314
477
      }
315
478
    }
 
479
 
 
480
    LOCK_open.unlock();
316
481
  }
317
482
 
318
483
  if (wait_for_refresh)
331
496
  move one table to free list 
332
497
*/
333
498
 
334
 
bool Session::free_cached_table(boost::mutex::scoped_lock &scopedLock)
 
499
bool Session::free_cached_table()
335
500
{
336
501
  bool found_old_table= false;
337
 
 
338
 
  (void)scopedLock;
339
 
 
340
502
  table::Concurrent *table= static_cast<table::Concurrent *>(open_tables);
341
503
 
342
 
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
 
504
  safe_mutex_assert_owner(LOCK_open.native_handle());
343
505
  assert(table->key_read == 0);
344
506
  assert(!table->cursor || table->cursor->inited == Cursor::NONE);
345
507
 
348
510
  if (table->needs_reopen_or_name_lock() ||
349
511
      version != refresh_version || !table->db_stat)
350
512
  {
351
 
    table::remove_table(table);
 
513
    remove_table(table);
352
514
    found_old_table= true;
353
515
  }
354
516
  else
361
523
 
362
524
    /* Free memory and reset for next loop */
363
525
    table->cursor->ha_reset();
364
 
    table->in_use= NULL;
 
526
    table->in_use= false;
365
527
 
366
 
    table::getUnused().link(table);
 
528
    unused_tables.link(table);
367
529
  }
368
530
 
369
531
  return found_old_table;
382
544
{
383
545
  bool found_old_table= false;
384
546
 
385
 
  safe_mutex_assert_not_owner(table::Cache::singleton().mutex().native_handle());
 
547
  safe_mutex_assert_not_owner(LOCK_open.native_handle());
386
548
 
387
 
  boost_unique_lock_t scoped_lock(table::Cache::singleton().mutex()); /* Close all open tables on Session */
 
549
  boost_unique_lock_t scoped_lock(LOCK_open); /* Close all open tables on Session */
388
550
 
389
551
  while (open_tables)
390
552
  {
391
 
    found_old_table|= free_cached_table(scoped_lock);
 
553
    found_old_table|= free_cached_table();
392
554
  }
393
555
  some_tables_deleted= false;
394
556
 
395
557
  if (found_old_table)
396
558
  {
397
559
    /* Tell threads waiting for refresh that something has happened */
398
 
    locking::broadcast_refresh();
 
560
    broadcast_refresh();
399
561
  }
400
562
}
401
563
 
424
586
{
425
587
  for (; table; table= table->*link )
426
588
  {
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
 
    {
 
589
    if ((table->table == 0 || table->table->getShare()->getType() == message::Table::STANDARD) &&
 
590
        strcasecmp(table->getSchemaName(), db_name) == 0 &&
 
591
        strcasecmp(table->getTableName(), table_name) == 0)
431
592
      break;
432
 
    }
433
593
  }
434
594
  return table;
435
595
}
521
681
}
522
682
 
523
683
 
524
 
void Open_tables_state::doGetTableNames(const identifier::Schema &schema_identifier,
525
 
                                        std::set<std::string>& set_of_names)
 
684
void Session::doGetTableNames(const SchemaIdentifier &schema_identifier,
 
685
                              std::set<std::string>& set_of_names)
526
686
{
527
 
  for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
 
687
  for (Table *table= temporary_tables ; table ; table= table->getNext())
528
688
  {
529
689
    if (schema_identifier.compare(table->getShare()->getSchemaName()))
530
690
    {
533
693
  }
534
694
}
535
695
 
536
 
void Open_tables_state::doGetTableNames(CachedDirectory &,
537
 
                                        const identifier::Schema &schema_identifier,
538
 
                                        std::set<std::string> &set_of_names)
 
696
void Session::doGetTableNames(CachedDirectory &,
 
697
                              const SchemaIdentifier &schema_identifier,
 
698
                              std::set<std::string> &set_of_names)
539
699
{
540
700
  doGetTableNames(schema_identifier, set_of_names);
541
701
}
542
702
 
543
 
void Open_tables_state::doGetTableIdentifiers(const identifier::Schema &schema_identifier,
544
 
                                              identifier::Table::vector &set_of_identifiers)
 
703
void Session::doGetTableIdentifiers(const SchemaIdentifier &schema_identifier,
 
704
                                    TableIdentifiers &set_of_identifiers)
545
705
{
546
 
  for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
 
706
  for (Table *table= temporary_tables ; table ; table= table->getNext())
547
707
  {
548
708
    if (schema_identifier.compare(table->getShare()->getSchemaName()))
549
709
    {
550
 
      set_of_identifiers.push_back(identifier::Table(table->getShare()->getSchemaName(),
 
710
      set_of_identifiers.push_back(TableIdentifier(table->getShare()->getSchemaName(),
551
711
                                                   table->getShare()->getTableName(),
552
712
                                                   table->getShare()->getPath()));
553
713
    }
554
714
  }
555
715
}
556
716
 
557
 
void Open_tables_state::doGetTableIdentifiers(CachedDirectory &,
558
 
                                              const identifier::Schema &schema_identifier,
559
 
                                              identifier::Table::vector &set_of_identifiers)
 
717
void Session::doGetTableIdentifiers(CachedDirectory &,
 
718
                                    const SchemaIdentifier &schema_identifier,
 
719
                                    TableIdentifiers &set_of_identifiers)
560
720
{
561
721
  doGetTableIdentifiers(schema_identifier, set_of_identifiers);
562
722
}
563
723
 
564
 
bool Open_tables_state::doDoesTableExist(const identifier::Table &identifier)
 
724
bool Session::doDoesTableExist(const TableIdentifier &identifier)
565
725
{
566
 
  for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
 
726
  for (Table *table= temporary_tables ; table ; table= table->getNext())
567
727
  {
568
728
    if (table->getShare()->getType() == message::Table::TEMPORARY)
569
729
    {
577
737
  return false;
578
738
}
579
739
 
580
 
int Open_tables_state::doGetTableDefinition(const identifier::Table &identifier,
581
 
                                            message::Table &table_proto)
 
740
int Session::doGetTableDefinition(const TableIdentifier &identifier,
 
741
                                  message::Table &table_proto)
582
742
{
583
 
  for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
 
743
  for (Table *table= temporary_tables ; table ; table= table->getNext())
584
744
  {
585
745
    if (table->getShare()->getType() == message::Table::TEMPORARY)
586
746
    {
587
747
      if (identifier.getKey() == table->getShare()->getCacheKey())
588
748
      {
589
 
        table_proto.CopyFrom(*(table->getShare()->getTableMessage()));
 
749
        table_proto.CopyFrom(*(table->getShare()->getTableProto()));
590
750
 
591
751
        return EEXIST;
592
752
      }
596
756
  return ENOENT;
597
757
}
598
758
 
599
 
Table *Open_tables_state::find_temporary_table(const identifier::Table &identifier)
 
759
Table *Session::find_temporary_table(const TableIdentifier &identifier)
600
760
{
601
761
  for (Table *table= temporary_tables ; table ; table= table->getNext())
602
762
  {
634
794
  @retval -1  the table is in use by a outer query
635
795
*/
636
796
 
637
 
int Open_tables_state::drop_temporary_table(const drizzled::identifier::Table &identifier)
 
797
int Session::drop_temporary_table(const drizzled::TableIdentifier &identifier)
638
798
{
639
799
  Table *table;
640
800
 
642
802
    return 1;
643
803
 
644
804
  /* Table might be in use by some outer statement. */
645
 
  if (table->query_id && table->query_id != getQueryId())
 
805
  if (table->query_id && table->query_id != query_id)
646
806
  {
647
807
    my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->getAlias());
648
808
    return -1;
661
821
  @param  session     Thread context
662
822
  @param  find    Table to remove
663
823
 
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.
 
824
  @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
825
*/
666
826
 
667
827
void Session::unlink_open_table(Table *find)
668
828
{
669
 
  const identifier::Table::Key find_key(find->getShare()->getCacheKey());
 
829
  const TableIdentifier::Key find_key(find->getShare()->getCacheKey());
670
830
  Table **prev;
671
 
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
 
831
  safe_mutex_assert_owner(LOCK_open.native_handle());
672
832
 
673
833
  /*
674
 
    Note that we need to hold table::Cache::singleton().mutex() while changing the
 
834
    Note that we need to hold LOCK_open while changing the
675
835
    open_tables list. Another thread may work on it.
676
 
    (See: table::Cache::singleton().removeTable(), wait_completed_table())
 
836
    (See: remove_table_from_cache(), mysql_wait_completed_table())
677
837
    Closing a MERGE child before the parent would be fatal if the
678
838
    other thread tries to abort the MERGE lock in between.
679
839
  */
687
847
      *prev= list->getNext();
688
848
 
689
849
      /* Close table. */
690
 
      table::remove_table(static_cast<table::Concurrent *>(list));
 
850
      remove_table(static_cast<table::Concurrent *>(list));
691
851
    }
692
852
    else
693
853
    {
697
857
  }
698
858
 
699
859
  // Notify any 'refresh' threads
700
 
  locking::broadcast_refresh();
 
860
  broadcast_refresh();
701
861
}
702
862
 
703
863
 
720
880
  table that was locked with LOCK TABLES.
721
881
*/
722
882
 
723
 
void Session::drop_open_table(Table *table, const identifier::Table &identifier)
 
883
void Session::drop_open_table(Table *table, TableIdentifier &identifier)
724
884
{
725
885
  if (table->getShare()->getType())
726
886
  {
728
888
  }
729
889
  else
730
890
  {
731
 
    boost_unique_lock_t scoped_lock(table::Cache::singleton().mutex()); /* Close and drop a table (AUX routine) */
 
891
    boost_unique_lock_t scoped_lock(LOCK_open); /* Close and drop a table (AUX routine) */
732
892
    /*
733
893
      unlink_open_table() also tells threads waiting for refresh or close
734
894
      that something has happened.
735
895
    */
736
896
    unlink_open_table(table);
737
 
    (void)plugin::StorageEngine::dropTable(*this, identifier);
 
897
    quick_rm_table(*this, identifier);
738
898
  }
739
899
}
740
900
 
770
930
      mutex is unlocked
771
931
    */
772
932
    boost_unique_lock_t scopedLock(mutex, boost::adopt_lock_t());
773
 
    if (not getKilled())
 
933
    if (not killed)
774
934
    {
775
935
      cond.wait(scopedLock);
776
936
    }
795
955
  case of failure.
796
956
*/
797
957
 
798
 
table::Placeholder *Session::table_cache_insert_placeholder(const drizzled::identifier::Table &arg)
 
958
Table *Session::table_cache_insert_placeholder(const drizzled::TableIdentifier &arg)
799
959
{
800
 
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
 
960
  safe_mutex_assert_owner(LOCK_open.native_handle());
801
961
 
802
962
  /*
803
963
    Create a table entry with the right key and with an old refresh version
804
964
  */
805
 
  identifier::Table identifier(arg.getSchemaName(), arg.getTableName(), message::Table::INTERNAL);
 
965
  TableIdentifier identifier(arg.getSchemaName(), arg.getTableName(), message::Table::INTERNAL);
806
966
  table::Placeholder *table= new table::Placeholder(this, identifier);
807
967
 
808
 
  if (not table::Cache::singleton().insert(table))
 
968
  if (not add_table(table))
809
969
  {
810
970
    delete table;
811
971
 
837
997
  @retval  true   Error occured (OOM)
838
998
  @retval  false  Success. 'table' parameter set according to above rules.
839
999
*/
840
 
bool Session::lock_table_name_if_not_cached(const identifier::Table &identifier, Table **table)
 
1000
bool Session::lock_table_name_if_not_cached(TableIdentifier &identifier, Table **table)
841
1001
{
842
 
  const identifier::Table::Key &key(identifier.getKey());
843
 
 
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)  */
845
 
 
846
 
  table::CacheMap::iterator iter;
847
 
 
848
 
  iter= table::getCache().find(key);
849
 
 
850
 
  if (iter != table::getCache().end())
 
1002
  const TableIdentifier::Key &key(identifier.getKey());
 
1003
 
 
1004
  boost_unique_lock_t scope_lock(LOCK_open); /* Obtain a name lock even though table is not in cache (like for create table)  */
 
1005
 
 
1006
  TableOpenCache::iterator iter;
 
1007
 
 
1008
  iter= get_open_cache().find(key);
 
1009
 
 
1010
  if (iter != get_open_cache().end())
851
1011
  {
852
1012
    *table= 0;
853
1013
    return false;
913
1073
  if (check_stack_overrun(this, STACK_MIN_SIZE_FOR_OPEN, (unsigned char *)&alias))
914
1074
    return NULL;
915
1075
 
916
 
  if (getKilled())
 
1076
  if (killed)
917
1077
    return NULL;
918
1078
 
919
 
  identifier::Table identifier(table_list->getSchemaName(), table_list->getTableName());
920
 
  const identifier::Table::Key &key(identifier.getKey());
921
 
  table::CacheRange ppp;
 
1079
  TableIdentifier identifier(table_list->getSchemaName(), table_list->getTableName());
 
1080
  const TableIdentifier::Key &key(identifier.getKey());
 
1081
  TableOpenCacheRange ppp;
922
1082
 
923
1083
  /*
924
1084
    Unless requested otherwise, try to resolve this table in the list
928
1088
    TODO -> move this block into a separate function.
929
1089
  */
930
1090
  bool reset= false;
931
 
  for (table= getTemporaryTables(); table ; table=table->getNext())
 
1091
  for (table= temporary_tables; table ; table=table->getNext())
932
1092
  {
933
1093
    if (table->getShare()->getCacheKey() == key)
934
1094
    {
953
1113
  {
954
1114
    if (flags & DRIZZLE_OPEN_TEMPORARY_ONLY)
955
1115
    {
956
 
      my_error(ER_TABLE_UNKNOWN, identifier);
 
1116
      my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->getSchemaName(), table_list->getTableName());
957
1117
      return NULL;
958
1118
    }
959
1119
 
998
1158
      until no one holds a name lock on the table.
999
1159
      - if there is no such Table in the name cache, read the table definition
1000
1160
      and insert it into the cache.
1001
 
      We perform all of the above under table::Cache::singleton().mutex() which currently protects
 
1161
      We perform all of the above under LOCK_open which currently protects
1002
1162
      the open cache (also known as table cache) and table definitions stored
1003
1163
      on disk.
1004
1164
    */
1005
1165
 
1006
1166
    {
1007
 
      boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex());
 
1167
      LOCK_open.lock(); /* Lock for FLUSH TABLES for open table */
1008
1168
 
1009
1169
      /*
1010
1170
        Actually try to find the table in the open_cache.
1016
1176
        an implicit "pending locks queue" - see
1017
1177
        wait_for_locked_table_names for details.
1018
1178
      */
1019
 
      ppp= table::getCache().equal_range(key);
 
1179
      ppp= get_open_cache().equal_range(key);
1020
1180
 
1021
1181
      table= NULL;
1022
 
      for (table::CacheMap::const_iterator iter= ppp.first;
 
1182
      for (TableOpenCache::const_iterator iter= ppp.first;
1023
1183
           iter != ppp.second; ++iter, table= NULL)
1024
1184
      {
1025
1185
        table= (*iter).second;
1056
1216
          /* Avoid self-deadlocks by detecting self-dependencies. */
1057
1217
          if (table->open_placeholder && table->in_use == this)
1058
1218
          {
 
1219
            LOCK_open.unlock();
1059
1220
            my_error(ER_UPDATE_TABLE_USED, MYF(0), table->getShare()->getTableName());
1060
1221
            return NULL;
1061
1222
          }
1088
1249
          */
1089
1250
          if (table->in_use != this)
1090
1251
          {
1091
 
            /* wait_for_conditionwill unlock table::Cache::singleton().mutex() for us */
1092
 
            wait_for_condition(table::Cache::singleton().mutex(), COND_refresh);
1093
 
            scopedLock.release();
 
1252
            /* wait_for_conditionwill unlock LOCK_open for us */
 
1253
            wait_for_condition(LOCK_open, COND_refresh);
1094
1254
          }
1095
1255
          else
1096
1256
          {
1097
 
            scopedLock.unlock();
 
1257
            LOCK_open.unlock();
1098
1258
          }
1099
 
 
1100
1259
          /*
1101
1260
            There is a refresh in progress for this table.
1102
1261
            Signal the caller that it has to try again.
1103
1262
          */
1104
1263
          if (refresh)
1105
1264
            *refresh= true;
1106
 
 
1107
1265
          return NULL;
1108
1266
        }
1109
1267
      }
1110
 
 
1111
1268
      if (table)
1112
1269
      {
1113
 
        table::getUnused().unlink(static_cast<table::Concurrent *>(table));
 
1270
        unused_tables.unlink(static_cast<table::Concurrent *>(table));
1114
1271
        table->in_use= this;
1115
1272
      }
1116
1273
      else
1118
1275
        /* Insert a new Table instance into the open cache */
1119
1276
        int error;
1120
1277
        /* Free cache if too big */
1121
 
        table::getUnused().cull();
 
1278
        unused_tables.cull();
1122
1279
 
1123
1280
        if (table_list->isCreate())
1124
1281
        {
1125
 
          identifier::Table  lock_table_identifier(table_list->getSchemaName(), table_list->getTableName(), message::Table::STANDARD);
 
1282
          TableIdentifier  lock_table_identifier(table_list->getSchemaName(), table_list->getTableName(), message::Table::STANDARD);
1126
1283
 
1127
1284
          if (not plugin::StorageEngine::doesTableExist(*this, lock_table_identifier))
1128
1285
          {
1131
1288
            */
1132
1289
            if (!(table= table_cache_insert_placeholder(lock_table_identifier)))
1133
1290
            {
 
1291
              LOCK_open.unlock();
1134
1292
              return NULL;
1135
1293
            }
1136
1294
            /*
1141
1299
            table->open_placeholder= true;
1142
1300
            table->setNext(open_tables);
1143
1301
            open_tables= table;
 
1302
            LOCK_open.unlock();
1144
1303
 
1145
1304
            return table ;
1146
1305
          }
1153
1312
          table= new_table;
1154
1313
          if (new_table == NULL)
1155
1314
          {
 
1315
            LOCK_open.unlock();
1156
1316
            return NULL;
1157
1317
          }
1158
1318
 
1160
1320
          if (error != 0)
1161
1321
          {
1162
1322
            delete new_table;
 
1323
            LOCK_open.unlock();
1163
1324
            return NULL;
1164
1325
          }
1165
 
          (void)table::Cache::singleton().insert(new_table);
 
1326
          (void)add_table(new_table);
1166
1327
        }
1167
1328
      }
 
1329
 
 
1330
      LOCK_open.unlock();
1168
1331
    }
1169
 
 
1170
1332
    if (refresh)
1171
1333
    {
1172
1334
      table->setNext(open_tables); /* Link into simple list */
1224
1386
  the strings are used in a loop even after the share may be freed.
1225
1387
*/
1226
1388
 
1227
 
void Session::close_data_files_and_morph_locks(const identifier::Table &identifier)
 
1389
void Session::close_data_files_and_morph_locks(TableIdentifier &identifier)
1228
1390
{
1229
 
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle()); /* Adjust locks at the end of ALTER TABLEL */
 
1391
  safe_mutex_assert_owner(LOCK_open.native_handle()); /* Adjust locks at the end of ALTER TABLEL */
1230
1392
 
1231
1393
  if (lock)
1232
1394
  {
1234
1396
      If we are not under LOCK TABLES we should have only one table
1235
1397
      open and locked so it makes sense to remove the lock at once.
1236
1398
    */
1237
 
    unlockTables(lock);
 
1399
    mysql_unlock_tables(this, lock);
1238
1400
    lock= 0;
1239
1401
  }
1240
1402
 
1269
1431
  combination when one needs tables to be reopened (for
1270
1432
  example see openTablesLock()).
1271
1433
 
1272
 
  @note One should have lock on table::Cache::singleton().mutex() when calling this.
 
1434
  @note One should have lock on LOCK_open when calling this.
1273
1435
 
1274
1436
  @return false in case of success, true - otherwise.
1275
1437
*/
1276
1438
 
1277
 
bool Session::reopen_tables()
 
1439
bool Session::reopen_tables(bool get_locks, bool)
1278
1440
{
1279
1441
  Table *table,*next,**prev;
1280
 
  Table **tables= 0;                    // For locks
1281
 
  Table **tables_ptr= 0;                        // For locks
1282
 
  bool error= false;
 
1442
  Table **tables,**tables_ptr;                  // For locks
 
1443
  bool error=0, not_used;
1283
1444
  const uint32_t flags= DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN |
1284
1445
    DRIZZLE_LOCK_IGNORE_GLOBAL_READ_LOCK |
1285
1446
    DRIZZLE_LOCK_IGNORE_FLUSH;
1287
1448
  if (open_tables == NULL)
1288
1449
    return false;
1289
1450
 
1290
 
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
 
1451
  safe_mutex_assert_owner(LOCK_open.native_handle());
 
1452
  if (get_locks)
1291
1453
  {
1292
1454
    /*
1293
1455
      The ptr is checked later
1301
1463
    }
1302
1464
    tables= new Table *[opens];
1303
1465
  }
1304
 
 
 
1466
  else
 
1467
  {
 
1468
    tables= &open_tables;
 
1469
  }
1305
1470
  tables_ptr =tables;
1306
1471
 
1307
1472
  prev= &open_tables;
1310
1475
    next= table->getNext();
1311
1476
 
1312
1477
    my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->getAlias());
1313
 
    table::remove_table(static_cast<table::Concurrent *>(table));
 
1478
    remove_table(static_cast<table::Concurrent *>(table));
1314
1479
    error= 1;
1315
1480
  }
1316
1481
  *prev=0;
1317
 
 
1318
1482
  if (tables != tables_ptr)                     // Should we get back old locks
1319
1483
  {
1320
1484
    DrizzleLock *local_lock;
1321
1485
    /*
1322
1486
      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
 
1487
      wait_for_tables() as it tries to acquire LOCK_open, which is
1324
1488
      already locked.
1325
1489
    */
1326
1490
    some_tables_deleted= false;
1327
1491
 
1328
 
    if ((local_lock= lockTables(tables, (uint32_t) (tables_ptr - tables), flags)))
 
1492
    if ((local_lock= mysql_lock_tables(this, tables, (uint32_t) (tables_ptr - tables),
 
1493
                                 flags, &not_used)))
1329
1494
    {
1330
1495
      /* unused */
1331
1496
    }
1341
1506
    }
1342
1507
  }
1343
1508
 
1344
 
  delete [] tables;
1345
 
 
1346
 
  locking::broadcast_refresh();
1347
 
 
1348
 
  return error;
 
1509
  if (get_locks && tables)
 
1510
    delete [] tables;
 
1511
 
 
1512
  broadcast_refresh();
 
1513
 
 
1514
  return(error);
1349
1515
}
1350
1516
 
1351
1517
 
1376
1542
    */
1377
1543
    if (table->needs_reopen_or_name_lock())
1378
1544
    {
1379
 
      found= true;
 
1545
      found=1;
1380
1546
      if (table->db_stat)
1381
1547
      {
1382
1548
        if (morph_locks)
1390
1556
              lock on it. This will also give them a chance to close their
1391
1557
              instances of this table.
1392
1558
            */
1393
 
            abortLock(ulcktbl);
1394
 
            removeLock(ulcktbl);
 
1559
            mysql_lock_abort(this, ulcktbl);
 
1560
            mysql_lock_remove(this, ulcktbl);
1395
1561
            ulcktbl->lock_count= 0;
1396
1562
          }
1397
1563
          if ((ulcktbl != table) && ulcktbl->db_stat)
1431
1597
    }
1432
1598
  }
1433
1599
  if (found)
1434
 
    locking::broadcast_refresh();
 
1600
    broadcast_refresh();
 
1601
}
 
1602
 
 
1603
 
 
1604
/*
 
1605
  Wait until all threads has closed the tables in the list
 
1606
  We have also to wait if there is thread that has a lock on this table even
 
1607
  if the table is closed
 
1608
*/
 
1609
 
 
1610
bool table_is_used(Table *table, bool wait_for_name_lock)
 
1611
{
 
1612
  do
 
1613
  {
 
1614
    const TableIdentifier::Key &key(table->getShare()->getCacheKey());
 
1615
 
 
1616
    TableOpenCacheRange ppp;
 
1617
    ppp= get_open_cache().equal_range(key);
 
1618
 
 
1619
    for (TableOpenCache::const_iterator iter= ppp.first;
 
1620
         iter != ppp.second; ++iter)
 
1621
    {
 
1622
      Table *search= (*iter).second;
 
1623
      if (search->in_use == table->in_use)
 
1624
        continue;                               // Name locked by this thread
 
1625
      /*
 
1626
        We can't use the table under any of the following conditions:
 
1627
        - There is an name lock on it (Table is to be deleted or altered)
 
1628
        - If we are in flush table and we didn't execute the flush
 
1629
        - If the table engine is open and it's an old version
 
1630
        (We must wait until all engines are shut down to use the table)
 
1631
      */
 
1632
      if ( (search->locked_by_name && wait_for_name_lock) ||
 
1633
           (search->is_name_opened() && search->needs_reopen_or_name_lock()))
 
1634
        return 1;
 
1635
    }
 
1636
  } while ((table=table->getNext()));
 
1637
  return 0;
 
1638
}
 
1639
 
 
1640
 
 
1641
/* Wait until all used tables are refreshed */
 
1642
 
 
1643
bool wait_for_tables(Session *session)
 
1644
{
 
1645
  bool result;
 
1646
 
 
1647
  session->set_proc_info("Waiting for tables");
 
1648
  {
 
1649
    boost_unique_lock_t lock(LOCK_open);
 
1650
    while (!session->killed)
 
1651
    {
 
1652
      session->some_tables_deleted= false;
 
1653
      session->close_old_data_files(false, dropping_tables != 0);
 
1654
      if (!table_is_used(session->open_tables, 1))
 
1655
        break;
 
1656
      COND_refresh.wait(lock);
 
1657
    }
 
1658
    if (session->killed)
 
1659
      result= true;                                     // aborted
 
1660
    else
 
1661
    {
 
1662
      /* Now we can open all tables without any interference */
 
1663
      session->set_proc_info("Reopen tables");
 
1664
      session->version= refresh_version;
 
1665
      result= session->reopen_tables(false, false);
 
1666
    }
 
1667
  }
 
1668
  session->set_proc_info(0);
 
1669
 
 
1670
  return result;
1435
1671
}
1436
1672
 
1437
1673
 
1459
1695
*/
1460
1696
 
1461
1697
 
1462
 
Table *drop_locked_tables(Session *session, const drizzled::identifier::Table &identifier)
 
1698
Table *drop_locked_tables(Session *session, const drizzled::TableIdentifier &identifier)
1463
1699
{
1464
1700
  Table *table,*next,**prev, *found= 0;
1465
1701
  prev= &session->open_tables;
1466
1702
 
1467
1703
  /*
1468
 
    Note that we need to hold table::Cache::singleton().mutex() while changing the
 
1704
    Note that we need to hold LOCK_open while changing the
1469
1705
    open_tables list. Another thread may work on it.
1470
 
    (See: table::Cache::singleton().removeTable(), wait_completed_table())
 
1706
    (See: remove_table_from_cache(), mysql_wait_completed_table())
1471
1707
    Closing a MERGE child before the parent would be fatal if the
1472
1708
    other thread tries to abort the MERGE lock in between.
1473
1709
  */
1476
1712
    next=table->getNext();
1477
1713
    if (table->getShare()->getCacheKey() == identifier.getKey())
1478
1714
    {
1479
 
      session->removeLock(table);
 
1715
      mysql_lock_remove(session, table);
1480
1716
 
1481
1717
      if (!found)
1482
1718
      {
1491
1727
      else
1492
1728
      {
1493
1729
        /* We already have a name lock, remove copy */
1494
 
        table::remove_table(static_cast<table::Concurrent *>(table));
 
1730
        remove_table(static_cast<table::Concurrent *>(table));
1495
1731
      }
1496
1732
    }
1497
1733
    else
1501
1737
    }
1502
1738
  }
1503
1739
  *prev=0;
1504
 
 
1505
1740
  if (found)
1506
 
    locking::broadcast_refresh();
 
1741
    broadcast_refresh();
1507
1742
 
1508
 
  return found;
 
1743
  return(found);
1509
1744
}
1510
1745
 
1511
1746
 
1515
1750
  other threads trying to get the lock.
1516
1751
*/
1517
1752
 
1518
 
void abort_locked_tables(Session *session, const drizzled::identifier::Table &identifier)
 
1753
void abort_locked_tables(Session *session, const drizzled::TableIdentifier &identifier)
1519
1754
{
1520
1755
  Table *table;
1521
1756
  for (table= session->open_tables; table ; table= table->getNext())
1523
1758
    if (table->getShare()->getCacheKey() == identifier.getKey())
1524
1759
    {
1525
1760
      /* If MERGE child, forward lock handling to parent. */
1526
 
      session->abortLock(table);
1527
 
      assert(0);
 
1761
      mysql_lock_abort(session, table);
1528
1762
      break;
1529
1763
    }
1530
1764
  }
1597
1831
     * to see if it exists so that an unauthorized user cannot phish for
1598
1832
     * table/schema information via error messages
1599
1833
     */
1600
 
    identifier::Table the_table(tables->getSchemaName(), tables->getTableName());
1601
 
    if (not plugin::Authorization::isAuthorized(user(), the_table))
 
1834
    TableIdentifier the_table(tables->getSchemaName(), tables->getTableName());
 
1835
    if (not plugin::Authorization::isAuthorized(getSecurityContext(),
 
1836
                                                the_table))
1602
1837
    {
1603
1838
      result= -1;                               // Fatal error
1604
1839
      break;
1695
1930
 
1696
1931
  set_proc_info("Opening table");
1697
1932
  current_tablenr= 0;
1698
 
  while (!(table= openTable(table_list, &refresh)) && refresh) ;
 
1933
  while (!(table= openTable(table_list, &refresh)) &&
 
1934
         refresh)
 
1935
    ;
1699
1936
 
1700
1937
  if (table)
1701
1938
  {
1704
1941
 
1705
1942
    assert(lock == 0);  // You must lock everything at once
1706
1943
    if ((table->reginfo.lock_type= lock_type) != TL_UNLOCK)
1707
 
    {
1708
 
      if (not (lock= lockTables(&table_list->table, 1, 0)))
1709
 
        table= NULL;
1710
 
    }
 
1944
      if (! (lock= mysql_lock_tables(this, &table_list->table, 1, 0, &refresh)))
 
1945
        table= 0;
1711
1946
  }
1712
1947
 
1713
1948
  set_proc_info(0);
1761
1996
  Table **start,**ptr;
1762
1997
  uint32_t lock_flag= DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN;
1763
1998
 
1764
 
  if (!(ptr=start=(Table**) session->getMemRoot()->allocate(sizeof(Table*)*count)))
 
1999
  if (!(ptr=start=(Table**) session->alloc(sizeof(Table*)*count)))
1765
2000
    return -1;
1766
 
 
1767
2001
  for (table= tables; table; table= table->next_global)
1768
2002
  {
1769
2003
    if (!table->placeholder())
1770
2004
      *(ptr++)= table->table;
1771
2005
  }
1772
2006
 
1773
 
  if (not (session->lock= session->lockTables(start, (uint32_t) (ptr - start), lock_flag)))
 
2007
  if (!(session->lock= mysql_lock_tables(session, start, (uint32_t) (ptr - start),
 
2008
                                         lock_flag, need_reopen)))
1774
2009
  {
1775
2010
    return -1;
1776
2011
  }
1799
2034
#  Table object
1800
2035
*/
1801
2036
 
1802
 
Table *Open_tables_state::open_temporary_table(const identifier::Table &identifier,
1803
 
                                               bool link_in_list)
 
2037
Table *Session::open_temporary_table(TableIdentifier &identifier,
 
2038
                                     bool link_in_list)
1804
2039
{
1805
2040
  assert(identifier.isTmp());
1806
2041
 
1807
2042
 
1808
2043
  table::Temporary *new_tmp_table= new table::Temporary(identifier.getType(),
1809
2044
                                                        identifier,
1810
 
                                                        const_cast<char *>(const_cast<identifier::Table&>(identifier).getPath().c_str()),
 
2045
                                                        const_cast<char *>(identifier.getPath().c_str()),
1811
2046
                                                        static_cast<uint32_t>(identifier.getPath().length()));
1812
2047
  if (not new_tmp_table)
1813
2048
    return NULL;
1815
2050
  /*
1816
2051
    First open the share, and then open the table from the share we just opened.
1817
2052
  */
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(),
 
2053
  if (new_tmp_table->getMutableShare()->open_table_def(*this, identifier) ||
 
2054
      new_tmp_table->getMutableShare()->open_table_from_share(this, identifier, identifier.getTableName().c_str(),
1820
2055
                                                              (uint32_t) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
1821
2056
                                                                          HA_GET_INDEX),
1822
2057
                                                              ha_open_options,
1884
2119
      current_bitmap= table->write_set;
1885
2120
    }
1886
2121
 
1887
 
    //if (current_bitmap->testAndSet(field->position()))
1888
 
    if (current_bitmap->test(field->position()))
 
2122
    //if (current_bitmap->testAndSet(field->field_index))
 
2123
    if (current_bitmap->test(field->field_index))
1889
2124
    {
1890
2125
      if (session->mark_used_columns == MARK_COLUMNS_WRITE)
1891
2126
        session->dup_field= field;
1944
2179
    {
1945
2180
      if (nj_col)
1946
2181
      {
1947
 
        my_error(ER_NON_UNIQ_ERROR, MYF(0), name, session->where());
 
2182
        my_error(ER_NON_UNIQ_ERROR, MYF(0), name, session->where);
1948
2183
        return NULL;
1949
2184
      }
1950
2185
      nj_col= curr_nj_col;
2195
2430
      {
2196
2431
        Table *table= field_to_set->getTable();
2197
2432
        if (session->mark_used_columns == MARK_COLUMNS_READ)
2198
 
          table->setReadSet(field_to_set->position());
 
2433
          table->setReadSet(field_to_set->field_index);
2199
2434
        else
2200
 
          table->setWriteSet(field_to_set->position());
 
2435
          table->setWriteSet(field_to_set->field_index);
2201
2436
      }
2202
2437
    }
2203
2438
  }
2341
2576
      */
2342
2577
      item->cached_table= found ?  0 : actual_table;
2343
2578
 
2344
 
      assert(session->where());
 
2579
      assert(session->where);
2345
2580
      /*
2346
2581
        If we found a fully qualified field we return it directly as it can't
2347
2582
        have duplicates.
2354
2589
        if (report_error == REPORT_ALL_ERRORS ||
2355
2590
            report_error == IGNORE_EXCEPT_NON_UNIQUE)
2356
2591
          my_error(ER_NON_UNIQ_ERROR, MYF(0),
2357
 
                   table_name ? item->full_name() : name, session->where());
 
2592
                   table_name ? item->full_name() : name, session->where);
2358
2593
        return (Field*) 0;
2359
2594
      }
2360
2595
      found= cur_field;
2387
2622
      strcat(buff, table_name);
2388
2623
      table_name=buff;
2389
2624
    }
2390
 
    my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, session->where());
 
2625
    my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, session->where);
2391
2626
  }
2392
2627
  else
2393
2628
  {
2394
2629
    if (report_error == REPORT_ALL_ERRORS ||
2395
2630
        report_error == REPORT_EXCEPT_NON_UNIQUE)
2396
 
      my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), session->where());
 
2631
      my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), session->where);
2397
2632
    else
2398
2633
      found= not_found_field;
2399
2634
  }
2520
2755
            */
2521
2756
            if (report_error != IGNORE_ERRORS)
2522
2757
              my_error(ER_NON_UNIQ_ERROR, MYF(0),
2523
 
                       find->full_name(), session->where());
 
2758
                       find->full_name(), session->where);
2524
2759
            return (Item**) 0;
2525
2760
          }
2526
2761
          found_unaliased= li.ref();
2551
2786
              continue;                           // Same field twice
2552
2787
            if (report_error != IGNORE_ERRORS)
2553
2788
              my_error(ER_NON_UNIQ_ERROR, MYF(0),
2554
 
                       find->full_name(), session->where());
 
2789
                       find->full_name(), session->where);
2555
2790
            return (Item**) 0;
2556
2791
          }
2557
2792
          found= li.ref();
2603
2838
    {
2604
2839
      if (report_error != IGNORE_ERRORS)
2605
2840
        my_error(ER_NON_UNIQ_ERROR, MYF(0),
2606
 
                 find->full_name(), session->where());
 
2841
                 find->full_name(), session->where);
2607
2842
      return (Item **) 0;
2608
2843
    }
2609
2844
    if (found_unaliased)
2619
2854
  {
2620
2855
    if (report_error == REPORT_ALL_ERRORS)
2621
2856
      my_error(ER_BAD_FIELD_ERROR, MYF(0),
2622
 
               find->full_name(), session->where());
 
2857
               find->full_name(), session->where);
2623
2858
    return (Item **) 0;
2624
2859
  }
2625
2860
  else
2790
3025
        if (cur_nj_col_2->is_common ||
2791
3026
            (found && (!using_fields || is_using_column_1)))
2792
3027
        {
2793
 
          my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1, session->where());
 
3028
          my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1, session->where);
2794
3029
          return(result);
2795
3030
        }
2796
3031
        nj_col_2= cur_nj_col_2;
2869
3104
      {
2870
3105
        Table *table_1= nj_col_1->table_ref->table;
2871
3106
        /* Mark field_1 used for table cache. */
2872
 
        table_1->setReadSet(field_1->position());
 
3107
        table_1->setReadSet(field_1->field_index);
2873
3108
        table_1->covering_keys&= field_1->part_of_key;
2874
3109
        table_1->merge_keys|= field_1->part_of_key;
2875
3110
      }
2877
3112
      {
2878
3113
        Table *table_2= nj_col_2->table_ref->table;
2879
3114
        /* Mark field_2 used for table cache. */
2880
 
        table_2->setReadSet(field_2->position());
 
3115
        table_2->setReadSet(field_2->field_index);
2881
3116
        table_2->covering_keys&= field_2->part_of_key;
2882
3117
        table_2->merge_keys|= field_2->part_of_key;
2883
3118
      }
2995
3230
        if (!(common_field= it++))
2996
3231
        {
2997
3232
          my_error(ER_BAD_FIELD_ERROR, MYF(0), using_field_name_ptr,
2998
 
                   session->where());
 
3233
                   session->where);
2999
3234
          return(result);
3000
3235
        }
3001
3236
        if (!my_strcasecmp(system_charset_info,
3218
3453
                                         List<TableList> *from_clause,
3219
3454
                                         Name_resolution_context *context)
3220
3455
{
3221
 
  session->setWhere("from clause");
 
3456
  session->where= "from clause";
3222
3457
  if (from_clause->elements == 0)
3223
3458
    return false; /* We come here in the case of UNIONs. */
3224
3459
 
3339
3574
  session->mark_used_columns= mark_used_columns;
3340
3575
  if (allow_sum_func)
3341
3576
    session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
3342
 
  session->setWhere(Session::DEFAULT_WHERE);
 
3577
  session->where= Session::DEFAULT_WHERE;
3343
3578
  save_is_item_list_lookup= session->lex->current_select->is_item_list_lookup;
3344
3579
  session->lex->current_select->is_item_list_lookup= 0;
3345
3580
 
3351
3586
    There is other way to solve problem: fill array with pointers to list,
3352
3587
    but it will be slower.
3353
3588
 
3354
 
    TODO-> remove it when (if) we made one list for allfields and ref_pointer_array
 
3589
TODO: remove it when (if) we made one list for allfields and
 
3590
ref_pointer_array
3355
3591
  */
3356
3592
  if (ref_pointer_array)
3357
 
  {
3358
3593
    memset(ref_pointer_array, 0, sizeof(Item *) * fields.elements);
3359
 
  }
3360
3594
 
3361
3595
  Item **ref= ref_pointer_array;
3362
3596
  session->lex->current_select->cur_pos_in_select_list= 0;
3588
3822
    assert(tables->is_leaf_for_name_resolution());
3589
3823
 
3590
3824
    if ((table_name && my_strcasecmp(table_alias_charset, table_name, tables->alias)) ||
3591
 
        (db_name && my_strcasecmp(system_charset_info, tables->getSchemaName(),db_name)))
 
3825
        (db_name && strcasecmp(tables->getSchemaName(),db_name)))
3592
3826
      continue;
3593
3827
 
3594
3828
    /*
3624
3858
      if ((field= field_iterator.field()))
3625
3859
      {
3626
3860
        /* Mark fields as used to allow storage engine to optimze access */
3627
 
        field->getTable()->setReadSet(field->position());
 
3861
        field->getTable()->setReadSet(field->field_index);
3628
3862
        if (table)
3629
3863
        {
3630
3864
          table->covering_keys&= field->part_of_key;
3652
3886
        }
3653
3887
      }
3654
3888
      else
3655
 
      {
3656
3889
        session->used_tables|= item->used_tables();
3657
 
      }
3658
 
 
3659
3890
      session->lex->current_select->cur_pos_in_select_list++;
3660
3891
    }
3661
3892
    /*
3675
3906
    qualified '*', and all columns were coalesced, we have to give a more
3676
3907
    meaningful message than ER_BAD_TABLE_ERROR.
3677
3908
  */
3678
 
  if (not table_name)
3679
 
  {
 
3909
  if (!table_name)
3680
3910
    my_message(ER_NO_TABLES_USED, ER(ER_NO_TABLES_USED), MYF(0));
3681
 
  }
3682
3911
  else
3683
 
  {
3684
3912
    my_error(ER_BAD_TABLE_ERROR, MYF(0), table_name);
3685
 
  }
3686
3913
 
3687
3914
  return true;
3688
3915
}
3731
3958
  session->session_marker= (void*)1;
3732
3959
  if (*conds)
3733
3960
  {
3734
 
    session->setWhere("where clause");
 
3961
    session->where="where clause";
3735
3962
    if ((!(*conds)->fixed && (*conds)->fix_fields(session, conds)) ||
3736
3963
        (*conds)->check_cols(1))
3737
3964
      goto err_no_arena;
3753
3980
      {
3754
3981
        /* Make a join an a expression */
3755
3982
        session->session_marker= (void*)embedded;
3756
 
        session->setWhere("on clause");
 
3983
        session->where="on clause";
3757
3984
        if ((!embedded->on_expr->fixed && embedded->on_expr->fix_fields(session, &embedded->on_expr)) ||
3758
3985
            embedded->on_expr->check_cols(1))
3759
3986
          goto err_no_arena;
3888
4115
    table= (*ptr)->getTable();
3889
4116
    table->auto_increment_field_not_null= false;
3890
4117
  }
3891
 
 
3892
4118
  while ((field = *ptr++) && ! session->is_error())
3893
4119
  {
3894
4120
    value=v++;
3895
4121
    table= field->getTable();
3896
 
 
3897
4122
    if (field == table->next_number_field)
3898
4123
      table->auto_increment_field_not_null= true;
3899
 
 
3900
4124
    if (value->save_in_field(field, 0) < 0)
3901
4125
    {
3902
4126
      if (table)
3912
4136
 
3913
4137
bool drizzle_rm_tmp_tables()
3914
4138
{
 
4139
  Session *session;
3915
4140
 
3916
4141
  assert(drizzle_tmpdir.size());
3917
 
  Session::shared_ptr session= Session::make_shared(plugin::Listen::getNullClient(), catalog::local());
3918
4142
 
3919
 
  if (not session)
 
4143
  if (!(session= new Session(plugin::Listen::getNullClient())))
3920
4144
    return true;
3921
 
  session->thread_stack= (char*) session.get();
 
4145
  session->thread_stack= (char*) &session;
3922
4146
  session->storeGlobals();
3923
4147
 
3924
4148
  plugin::StorageEngine::removeLostTemporaryTables(*session, drizzle_tmpdir.c_str());
3925
4149
 
 
4150
  session->lockForDelete();
 
4151
  delete session;
 
4152
 
3926
4153
  return false;
3927
4154
}
3928
4155
 
3932
4159
  unireg support functions
3933
4160
 *****************************************************************************/
3934
4161
 
3935
 
 
 
4162
/*
 
4163
  Invalidate any cache entries that are for some DB
 
4164
 
 
4165
  SYNOPSIS
 
4166
  remove_db_from_cache()
 
4167
  db            Database name. This will be in lower case if
 
4168
  lower_case_table_name is set
 
4169
 
 
4170
NOTE:
 
4171
We can't use hash_delete when looping hash_elements. We mark them first
 
4172
and afterwards delete those marked unused.
 
4173
*/
 
4174
 
 
4175
void remove_db_from_cache(const SchemaIdentifier &schema_identifier)
 
4176
{
 
4177
  safe_mutex_assert_owner(LOCK_open.native_handle());
 
4178
 
 
4179
  for (TableOpenCache::const_iterator iter= get_open_cache().begin();
 
4180
       iter != get_open_cache().end();
 
4181
       iter++)
 
4182
  {
 
4183
    table::Concurrent *table= (*iter).second;
 
4184
 
 
4185
    if (not schema_identifier.getPath().compare(table->getShare()->getSchemaName()))
 
4186
    {
 
4187
      table->getMutableShare()->resetVersion();                 /* Free when thread is ready */
 
4188
      if (not table->in_use)
 
4189
        unused_tables.relink(table);
 
4190
    }
 
4191
  }
 
4192
 
 
4193
  unused_tables.cullByVersion();
 
4194
}
 
4195
 
 
4196
 
 
4197
/*
 
4198
  Mark all entries with the table as deleted to force an reopen of the table
 
4199
 
 
4200
  The table will be closed (not stored in cache) by the current thread when
 
4201
  close_thread_tables() is called.
 
4202
 
 
4203
  PREREQUISITES
 
4204
  Lock on LOCK_open()
 
4205
 
 
4206
  RETURN
 
4207
  0  This thread now have exclusive access to this table and no other thread
 
4208
  can access the table until close_thread_tables() is called.
 
4209
  1  Table is in use by another thread
 
4210
*/
 
4211
 
 
4212
bool remove_table_from_cache(Session *session, TableIdentifier &identifier, uint32_t flags)
 
4213
{
 
4214
  const TableIdentifier::Key &key(identifier.getKey());
 
4215
  bool result= false; 
 
4216
  bool signalled= false;
 
4217
 
 
4218
  for (;;)
 
4219
  {
 
4220
    result= signalled= false;
 
4221
 
 
4222
    TableOpenCacheRange ppp;
 
4223
    ppp= get_open_cache().equal_range(key);
 
4224
 
 
4225
    for (TableOpenCache::const_iterator iter= ppp.first;
 
4226
         iter != ppp.second; ++iter)
 
4227
    {
 
4228
      table::Concurrent *table= (*iter).second;
 
4229
      Session *in_use;
 
4230
 
 
4231
      table->getMutableShare()->resetVersion();         /* Free when thread is ready */
 
4232
      if (not (in_use= table->in_use))
 
4233
      {
 
4234
        unused_tables.relink(table);
 
4235
      }
 
4236
      else if (in_use != session)
 
4237
      {
 
4238
        /*
 
4239
          Mark that table is going to be deleted from cache. This will
 
4240
          force threads that are in mysql_lock_tables() (but not yet
 
4241
          in thr_multi_lock()) to abort it's locks, close all tables and retry
 
4242
        */
 
4243
        in_use->some_tables_deleted= true;
 
4244
        if (table->is_name_opened())
 
4245
        {
 
4246
          result= true;
 
4247
        }
 
4248
        /*
 
4249
          Now we must abort all tables locks used by this thread
 
4250
          as the thread may be waiting to get a lock for another table.
 
4251
          Note that we need to hold LOCK_open while going through the
 
4252
          list. So that the other thread cannot change it. The other
 
4253
          thread must also hold LOCK_open whenever changing the
 
4254
          open_tables list. Aborting the MERGE lock after a child was
 
4255
          closed and before the parent is closed would be fatal.
 
4256
        */
 
4257
        for (Table *session_table= in_use->open_tables;
 
4258
             session_table ;
 
4259
             session_table= session_table->getNext())
 
4260
        {
 
4261
          /* Do not handle locks of MERGE children. */
 
4262
          if (session_table->db_stat)   // If table is open
 
4263
            signalled|= mysql_lock_abort_for_thread(session, session_table);
 
4264
        }
 
4265
      }
 
4266
      else
 
4267
      {
 
4268
        result= result || (flags & RTFC_OWNED_BY_Session_FLAG);
 
4269
      }
 
4270
    }
 
4271
 
 
4272
    unused_tables.cullByVersion();
 
4273
 
 
4274
    /* Remove table from table definition cache if it's not in use */
 
4275
    TableShare::release(identifier);
 
4276
 
 
4277
    if (result && (flags & RTFC_WAIT_OTHER_THREAD_FLAG))
 
4278
    {
 
4279
      /*
 
4280
        Signal any thread waiting for tables to be freed to
 
4281
        reopen their tables
 
4282
      */
 
4283
      broadcast_refresh();
 
4284
      if (!(flags & RTFC_CHECK_KILLED_FLAG) || !session->killed)
 
4285
      {
 
4286
        dropping_tables++;
 
4287
        if (likely(signalled))
 
4288
        {
 
4289
          boost_unique_lock_t scoped(LOCK_open, boost::adopt_lock_t());
 
4290
          COND_refresh.wait(scoped);
 
4291
          scoped.release();
 
4292
        }
 
4293
        else
 
4294
        {
 
4295
          /*
 
4296
            It can happen that another thread has opened the
 
4297
            table but has not yet locked any table at all. Since
 
4298
            it can be locked waiting for a table that our thread
 
4299
            has done LOCK Table x WRITE on previously, we need to
 
4300
            ensure that the thread actually hears our signal
 
4301
            before we go to sleep. Thus we wait for a short time
 
4302
            and then we retry another loop in the
 
4303
            remove_table_from_cache routine.
 
4304
          */
 
4305
          boost::xtime xt; 
 
4306
          xtime_get(&xt, boost::TIME_UTC); 
 
4307
          xt.sec += 10; 
 
4308
          boost_unique_lock_t scoped(LOCK_open, boost::adopt_lock_t());
 
4309
          COND_refresh.timed_wait(scoped, xt);
 
4310
          scoped.release();
 
4311
        }
 
4312
        dropping_tables--;
 
4313
        continue;
 
4314
      }
 
4315
    }
 
4316
    break;
 
4317
  }
 
4318
 
 
4319
  return result;
 
4320
}
3936
4321
 
3937
4322
 
3938
4323
/**