~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_base.cc

  • Committer: Brian Aker
  • Date: 2010-09-20 00:00:20 UTC
  • Revision ID: brian@tangent.org-20100920000020-s6x30brpajr83pkr
Update session/memory to use boost specific.

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
# endif
32
32
#endif
33
33
#include "drizzled/internal/my_pthread.h"
 
34
#include "drizzled/internal/thread_var.h"
34
35
 
35
36
#include <drizzled/sql_select.h>
36
37
#include <drizzled/error.h>
46
47
#include "drizzled/cached_directory.h"
47
48
#include <drizzled/field/timestamp.h>
48
49
#include <drizzled/field/null.h>
49
 
#include "drizzled/memory/multi_malloc.h"
50
50
#include "drizzled/sql_table.h"
51
51
#include "drizzled/global_charset_info.h"
52
52
#include "drizzled/pthread_globals.h"
53
53
#include "drizzled/internal/iocache.h"
 
54
#include "drizzled/drizzled.h"
54
55
#include "drizzled/plugin/authorization.h"
 
56
#include "drizzled/table_placeholder.h"
55
57
 
56
58
using namespace std;
57
59
 
60
62
 
61
63
extern bool volatile shutdown_in_progress;
62
64
 
63
 
bool drizzle_rm_tmp_tables();
64
 
 
65
 
/**
66
 
  @defgroup Data_Dictionary Data Dictionary
67
 
  @{
68
 
*/
69
 
Table *unused_tables;                           /* Used by mysql_test */
70
 
HASH open_cache;                                /* Used by mysql_test */
71
 
static int open_unireg_entry(Session *session, Table *entry, TableList *table_list,
 
65
TableOpenCache &get_open_cache()
 
66
{
 
67
  static TableOpenCache open_cache;                             /* Used by mysql_test */
 
68
 
 
69
  return open_cache;
 
70
}
 
71
 
 
72
static void free_cache_entry(Table *entry);
 
73
 
 
74
void remove_table(Table *arg)
 
75
{
 
76
  TableOpenCacheRange ppp;
 
77
  ppp= get_open_cache().equal_range(arg->getShare()->getCacheKey());
 
78
 
 
79
  for (TableOpenCache::const_iterator iter= ppp.first;
 
80
         iter != ppp.second; ++iter)
 
81
  {
 
82
    Table *found_table= (*iter).second;
 
83
 
 
84
    if (found_table == arg)
 
85
    {
 
86
      free_cache_entry(arg);
 
87
      get_open_cache().erase(iter);
 
88
      return;
 
89
    }
 
90
  }
 
91
}
 
92
 
 
93
static bool add_table(Table *arg)
 
94
{
 
95
  TableOpenCache &open_cache(get_open_cache());
 
96
 
 
97
  TableOpenCache::iterator returnable= open_cache.insert(make_pair(arg->getShare()->getCacheKey(), arg));
 
98
 
 
99
  return not (returnable == open_cache.end());
 
100
}
 
101
 
 
102
class UnusedTables {
 
103
  Table *tables;                                /* Used by mysql_test */
 
104
 
 
105
  Table *getTable() const
 
106
  {
 
107
    return tables;
 
108
  }
 
109
 
 
110
  Table *setTable(Table *arg)
 
111
  {
 
112
    return tables= arg;
 
113
  }
 
114
 
 
115
public:
 
116
 
 
117
  void cull()
 
118
  {
 
119
    /* Free cache if too big */
 
120
    while (cached_open_tables() > table_cache_size && getTable())
 
121
      remove_table(getTable());
 
122
  }
 
123
 
 
124
  void cullByVersion()
 
125
  {
 
126
    while (getTable() && not getTable()->getShare()->getVersion())
 
127
      remove_table(getTable());
 
128
  }
 
129
  
 
130
  void link(Table *table)
 
131
  {
 
132
    if (getTable())
 
133
    {
 
134
      table->setNext(getTable());               /* Link in last */
 
135
      table->setPrev(getTable()->getPrev());
 
136
      getTable()->setPrev(table);
 
137
      table->getPrev()->setNext(table);
 
138
    }
 
139
    else
 
140
    {
 
141
      table->setPrev(setTable(table));
 
142
      table->setNext(table->getPrev());
 
143
      assert(table->getNext() == table && table->getPrev() == table);
 
144
    }
 
145
  }
 
146
 
 
147
 
 
148
  void unlink(Table *table)
 
149
  {
 
150
    table->unlink();
 
151
 
 
152
    /* Unlink the table from "unused_tables" list. */
 
153
    if (table == getTable())
 
154
    {  // First unused
 
155
      setTable(getTable()->getNext()); // Remove from link
 
156
      if (table == getTable())
 
157
        setTable(NULL);
 
158
    }
 
159
  }
 
160
 
 
161
/* move table first in unused links */
 
162
 
 
163
  void relink(Table *table)
 
164
  {
 
165
    if (table != getTable())
 
166
    {
 
167
      table->unlink();
 
168
 
 
169
      table->setNext(getTable());                       /* Link in unused tables */
 
170
      table->setPrev(getTable()->getPrev());
 
171
      getTable()->getPrev()->setNext(table);
 
172
      getTable()->setPrev(table);
 
173
      setTable(table);
 
174
    }
 
175
  }
 
176
 
 
177
 
 
178
  void clear()
 
179
  {
 
180
    while (getTable())
 
181
      remove_table(getTable());
 
182
  }
 
183
 
 
184
  UnusedTables():
 
185
    tables(NULL)
 
186
  { }
 
187
 
 
188
  ~UnusedTables()
 
189
  { 
 
190
  }
 
191
};
 
192
 
 
193
static UnusedTables unused_tables;
 
194
static int open_unireg_entry(Session *session,
 
195
                             Table *entry,
72
196
                             const char *alias,
73
 
                             char *cache_key, uint32_t cache_key_length);
74
 
void free_cache_entry(void *entry);
 
197
                             TableIdentifier &identifier);
 
198
 
75
199
unsigned char *table_cache_key(const unsigned char *record,
76
200
                               size_t *length,
77
201
                               bool );
78
202
 
 
203
#if 0
 
204
static bool reopen_table(Table *table);
 
205
#endif
79
206
 
80
207
unsigned char *table_cache_key(const unsigned char *record,
81
208
                               size_t *length,
82
209
                               bool )
83
210
{
84
211
  Table *entry=(Table*) record;
85
 
  *length= entry->s->table_cache_key.length;
86
 
  return (unsigned char*) entry->s->table_cache_key.str;
87
 
}
88
 
 
89
 
HASH *get_open_cache()
90
 
{
91
 
  return &open_cache;
92
 
}
93
 
 
 
212
  *length= entry->getShare()->getCacheKey().size();
 
213
  return (unsigned char*) &entry->getShare()->getCacheKey()[0];
 
214
}
94
215
 
95
216
bool table_cache_init(void)
96
217
{
97
 
  return hash_init(&open_cache, &my_charset_bin,
98
 
                   (size_t) table_cache_size+16,
99
 
                   0, 0, table_cache_key,
100
 
                   free_cache_entry, 0);
 
218
  return false;
 
219
}
 
220
 
 
221
uint32_t cached_open_tables(void)
 
222
{
 
223
  return get_open_cache().size();
101
224
}
102
225
 
103
226
void table_cache_free(void)
104
227
{
105
228
  refresh_version++;                            // Force close of open tables
106
229
 
107
 
  while (unused_tables)
108
 
    hash_delete(&open_cache, (unsigned char*) unused_tables);
109
 
 
110
 
  if (not open_cache.records)                   // Safety first
111
 
    hash_free(&open_cache);
112
 
}
113
 
 
114
 
uint32_t cached_open_tables(void)
115
 
{
116
 
  return open_cache.records;
117
 
}
118
 
 
 
230
  unused_tables.clear();
 
231
  get_open_cache().clear();
 
232
}
119
233
 
120
234
/*
121
235
  Close cursor handle, but leave the table in the table cache
137
251
 
138
252
void close_handle_and_leave_table_as_lock(Table *table)
139
253
{
140
 
  TableShare *share, *old_share= table->s;
141
 
  char *key_buff;
142
 
  memory::Root *mem_root= &table->mem_root;
143
 
 
 
254
  TableShare *share, *old_share= table->getMutableShare();
144
255
  assert(table->db_stat);
 
256
  assert(table->getShare()->getType() == message::Table::STANDARD);
145
257
 
146
258
  /*
147
259
    Make a local copy of the table share and free the current one.
148
260
    This has to be done to ensure that the table share is removed from
149
261
    the table defintion cache as soon as the last instance is removed
150
262
  */
151
 
  if (multi_alloc_root(mem_root,
152
 
                       &share, sizeof(*share),
153
 
                       &key_buff, old_share->table_cache_key.length,
154
 
                       NULL))
155
 
  {
156
 
    memset(share, 0, sizeof(*share));
157
 
    share->set_table_cache_key(key_buff, old_share->table_cache_key.str,
158
 
                               old_share->table_cache_key.length);
159
 
    share->tmp_table= message::Table::INTERNAL;       // for intern_close_table()
160
 
  }
 
263
  TableIdentifier identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), message::Table::INTERNAL);
 
264
  const TableIdentifier::Key &key(identifier.getKey());
 
265
  share= new TableShare(identifier.getType(),
 
266
                        identifier,
 
267
                        const_cast<char *>(&key[0]),  static_cast<uint32_t>(old_share->getCacheKeySize()));
161
268
 
162
269
  table->cursor->close();
163
270
  table->db_stat= 0;                            // Mark cursor closed
164
 
  TableShare::release(table->s);
165
 
  table->s= share;
166
 
  table->cursor->change_table_ptr(table, table->s);
 
271
  TableShare::release(table->getMutableShare());
 
272
  table->setShare(share);
 
273
  table->cursor->change_table_ptr(table, table->getMutableShare());
167
274
}
168
275
 
169
276
 
176
283
{                                               // Free all structures
177
284
  free_io_cache();
178
285
  if (cursor)                              // Not true if name lock
179
 
    closefrm(true);                     // close cursor
 
286
  {
 
287
    delete_table(true);                 // close cursor
 
288
  }
180
289
}
181
290
 
182
291
/*
190
299
  We need to have a lock on LOCK_open when calling this
191
300
*/
192
301
 
193
 
void free_cache_entry(void *entry)
 
302
void free_cache_entry(Table *table)
194
303
{
195
 
  Table *table= static_cast<Table *>(entry);
196
304
  table->intern_close_table();
197
305
  if (not table->in_use)
198
306
  {
199
 
    table->next->prev=table->prev;              /* remove from used chain */
200
 
    table->prev->next=table->next;
201
 
    if (table == unused_tables)
202
 
    {
203
 
      unused_tables=unused_tables->next;
204
 
      if (table == unused_tables)
205
 
        unused_tables= NULL;
206
 
    }
 
307
    unused_tables.unlink(table);
207
308
  }
208
 
  free(table);
 
309
 
 
310
  delete table;
209
311
}
210
312
 
211
313
/* Free resources allocated by filesort() and read_record() */
241
343
  bool result= false;
242
344
  Session *session= this;
243
345
 
244
 
  pthread_mutex_lock(&LOCK_open); /* Optionally lock for remove tables from open_cahe if not in use */
 
346
  LOCK_open.lock(); /* Optionally lock for remove tables from open_cahe if not in use */
245
347
 
246
348
  if (tables == NULL)
247
349
  {
248
350
    refresh_version++;                          // Force close of open tables
249
 
    while (unused_tables)
250
 
      hash_delete(&open_cache,(unsigned char*) unused_tables);
 
351
 
 
352
    unused_tables.clear();
251
353
 
252
354
    if (wait_for_refresh)
253
355
    {
288
390
        after the call to Session::close_old_data_files() i.e. after removal of
289
391
        current thread locks.
290
392
      */
291
 
      for (uint32_t idx=0 ; idx < open_cache.records ; idx++)
 
393
      for (TableOpenCache::const_iterator iter= get_open_cache().begin();
 
394
           iter != get_open_cache().end();
 
395
           iter++)
292
396
      {
293
 
        Table *table=(Table*) hash_element(&open_cache,idx);
 
397
        Table *table= (*iter).second;
294
398
        if (table->in_use)
295
399
          table->in_use->some_tables_deleted= false;
296
400
      }
301
405
    bool found= false;
302
406
    for (TableList *table= tables; table; table= table->next_local)
303
407
    {
304
 
      if (remove_table_from_cache(session, table->db, table->table_name,
 
408
      TableIdentifier identifier(table->db, table->table_name);
 
409
      if (remove_table_from_cache(session, identifier,
305
410
                                  RTFC_OWNED_BY_Session_FLAG))
 
411
      {
306
412
        found= true;
 
413
      }
307
414
    }
308
415
    if (!found)
309
416
      wait_for_refresh= false;                  // Nothing to wait for
315
422
      If there is any table that has a lower refresh_version, wait until
316
423
      this is closed (or this thread is killed) before returning
317
424
    */
318
 
    session->mysys_var->current_mutex= &LOCK_open;
319
 
    session->mysys_var->current_cond= &COND_refresh;
 
425
    session->mysys_var->current_mutex= LOCK_open.native_handle();
 
426
    session->mysys_var->current_cond= COND_refresh.native_handle();
320
427
    session->set_proc_info("Flushing tables");
321
428
 
322
429
    session->close_old_data_files();
326
433
    while (found && ! session->killed)
327
434
    {
328
435
      found= false;
329
 
      for (uint32_t idx=0 ; idx < open_cache.records ; idx++)
 
436
      for (TableOpenCache::const_iterator iter= get_open_cache().begin();
 
437
           iter != get_open_cache().end();
 
438
           iter++)
330
439
      {
331
 
        Table *table=(Table*) hash_element(&open_cache,idx);
 
440
        Table *table= (*iter).second;
332
441
        /* Avoid a self-deadlock. */
333
442
        if (table->in_use == session)
334
443
          continue;
337
446
          not for placeholders with Table::open_placeholder set. Waiting for
338
447
          latter will cause deadlock in the following scenario, for example:
339
448
 
340
 
conn1: lock table t1 write;
341
 
conn2: lock table t2 write;
342
 
conn1: flush tables;
343
 
conn2: flush tables;
 
449
          conn1-> lock table t1 write;
 
450
          conn2-> lock table t2 write;
 
451
          conn1-> flush tables;
 
452
          conn2-> flush tables;
344
453
 
345
 
It also does not make sense to wait for those of placeholders that
346
 
are employed by CREATE TABLE as in this case table simply does not
347
 
exist yet.
 
454
          It also does not make sense to wait for those of placeholders that
 
455
          are employed by CREATE TABLE as in this case table simply does not
 
456
          exist yet.
348
457
        */
349
458
        if (table->needs_reopen_or_name_lock() && (table->db_stat ||
350
459
                                                   (table->open_placeholder && wait_for_placeholders)))
351
460
        {
352
461
          found= true;
353
 
          pthread_cond_wait(&COND_refresh,&LOCK_open);
 
462
          pthread_cond_wait(COND_refresh.native_handle(),LOCK_open.native_handle());
354
463
          break;
355
464
        }
356
465
      }
363
472
    result= session->reopen_tables(true, true);
364
473
 
365
474
    /* Set version for table */
366
 
    for (Table *table= session->open_tables; table ; table= table->next)
 
475
    for (Table *table= session->open_tables; table ; table= table->getNext())
367
476
    {
368
477
      /*
369
478
        Preserve the version (0) of write locked tables so that a impending
370
479
        global read lock won't sneak in.
371
480
      */
372
481
      if (table->reginfo.lock_type < TL_WRITE_ALLOW_WRITE)
373
 
        table->s->version= refresh_version;
 
482
        table->getMutableShare()->refreshVersion();
374
483
    }
375
484
  }
376
485
 
377
 
  pthread_mutex_unlock(&LOCK_open);
 
486
  LOCK_open.unlock();
378
487
 
379
488
  if (wait_for_refresh)
380
489
  {
398
507
  bool found_old_table= false;
399
508
  Table *table= open_tables;
400
509
 
401
 
  safe_mutex_assert_owner(&LOCK_open);
 
510
  safe_mutex_assert_owner(LOCK_open.native_handle());
402
511
  assert(table->key_read == 0);
403
512
  assert(!table->cursor || table->cursor->inited == Cursor::NONE);
404
513
 
405
 
  open_tables= table->next;
 
514
  open_tables= table->getNext();
406
515
 
407
516
  if (table->needs_reopen_or_name_lock() ||
408
517
      version != refresh_version || !table->db_stat)
409
518
  {
410
 
    hash_delete(&open_cache,(unsigned char*) table);
 
519
    remove_table(table);
411
520
    found_old_table= true;
412
521
  }
413
522
  else
422
531
    table->cursor->ha_reset();
423
532
    table->in_use= false;
424
533
 
425
 
    if (unused_tables)
426
 
    {
427
 
      table->next= unused_tables;               /* Link in last */
428
 
      table->prev= unused_tables->prev;
429
 
      unused_tables->prev= table;
430
 
      table->prev->next= table;
431
 
    }
432
 
    else
433
 
      unused_tables= table->next=table->prev=table;
 
534
    unused_tables.link(table);
434
535
  }
435
536
 
436
537
  return found_old_table;
449
550
{
450
551
  bool found_old_table= false;
451
552
 
452
 
  safe_mutex_assert_not_owner(&LOCK_open);
 
553
  safe_mutex_assert_not_owner(LOCK_open.native_handle());
453
554
 
454
 
  pthread_mutex_lock(&LOCK_open); /* Close all open tables on Session */
 
555
  boost::mutex::scoped_lock scoped_lock(LOCK_open); /* Close all open tables on Session */
455
556
 
456
557
  while (open_tables)
 
558
  {
457
559
    found_old_table|= free_cached_table();
 
560
  }
458
561
  some_tables_deleted= false;
459
562
 
460
563
  if (found_old_table)
462
565
    /* Tell threads waiting for refresh that something has happened */
463
566
    broadcast_refresh();
464
567
  }
465
 
 
466
 
  pthread_mutex_unlock(&LOCK_open);
467
568
}
468
569
 
469
570
/*
491
592
{
492
593
  for (; table; table= table->*link )
493
594
  {
494
 
    if ((table->table == 0 || table->table->s->tmp_table == message::Table::STANDARD) &&
 
595
    if ((table->table == 0 || table->table->getShare()->getType() == message::Table::STANDARD) &&
495
596
        strcasecmp(table->db, db_name) == 0 &&
496
597
        strcasecmp(table->table_name, table_name) == 0)
497
598
      break;
555
656
  if (table->table)
556
657
  {
557
658
    /* temporary table is always unique */
558
 
    if (table->table && table->table->s->tmp_table != message::Table::STANDARD)
 
659
    if (table->table && table->table->getShare()->getType() != message::Table::STANDARD)
559
660
      return 0;
560
661
    table= table->find_underlying_table(table->table);
561
662
    /*
586
687
}
587
688
 
588
689
 
589
 
void Session::doGetTableNames(SchemaIdentifier &schema_identifier,
 
690
void Session::doGetTableNames(const SchemaIdentifier &schema_identifier,
590
691
                              std::set<std::string>& set_of_names)
591
692
{
592
 
  for (Table *table= temporary_tables ; table ; table= table->next)
 
693
  for (Table *table= temporary_tables ; table ; table= table->getNext())
593
694
  {
594
 
    if (schema_identifier.compare(table->s->getSchemaName()))
 
695
    if (schema_identifier.compare(table->getShare()->getSchemaName()))
595
696
    {
596
 
      set_of_names.insert(table->s->table_name.str);
 
697
      set_of_names.insert(table->getShare()->getTableName());
597
698
    }
598
699
  }
599
700
}
600
701
 
601
702
void Session::doGetTableNames(CachedDirectory &,
602
 
                              SchemaIdentifier &schema_identifier,
 
703
                              const SchemaIdentifier &schema_identifier,
603
704
                              std::set<std::string> &set_of_names)
604
705
{
605
706
  doGetTableNames(schema_identifier, set_of_names);
606
707
}
607
708
 
608
 
bool Session::doDoesTableExist(TableIdentifier &identifier)
609
 
{
610
 
  for (Table *table= temporary_tables ; table ; table= table->next)
611
 
  {
612
 
    if (table->s->tmp_table == message::Table::TEMPORARY)
613
 
    {
614
 
      if (identifier.compare(table->s->getSchemaName(), table->s->table_name.str))
 
709
void Session::doGetTableIdentifiers(const SchemaIdentifier &schema_identifier,
 
710
                                    TableIdentifiers &set_of_identifiers)
 
711
{
 
712
  for (Table *table= temporary_tables ; table ; table= table->getNext())
 
713
  {
 
714
    if (schema_identifier.compare(table->getShare()->getSchemaName()))
 
715
    {
 
716
      set_of_identifiers.push_back(TableIdentifier(table->getShare()->getSchemaName(),
 
717
                                                   table->getShare()->getTableName(),
 
718
                                                   table->getShare()->getPath()));
 
719
    }
 
720
  }
 
721
}
 
722
 
 
723
void Session::doGetTableIdentifiers(CachedDirectory &,
 
724
                                    const SchemaIdentifier &schema_identifier,
 
725
                                    TableIdentifiers &set_of_identifiers)
 
726
{
 
727
  doGetTableIdentifiers(schema_identifier, set_of_identifiers);
 
728
}
 
729
 
 
730
bool Session::doDoesTableExist(const TableIdentifier &identifier)
 
731
{
 
732
  for (Table *table= temporary_tables ; table ; table= table->getNext())
 
733
  {
 
734
    if (table->getShare()->getType() == message::Table::TEMPORARY)
 
735
    {
 
736
      if (identifier.getKey() == table->getShare()->getCacheKey())
615
737
      {
616
738
        return true;
617
739
      }
621
743
  return false;
622
744
}
623
745
 
624
 
int Session::doGetTableDefinition(TableIdentifier &identifier,
 
746
int Session::doGetTableDefinition(const TableIdentifier &identifier,
625
747
                                  message::Table &table_proto)
626
748
{
627
 
  for (Table *table= temporary_tables ; table ; table= table->next)
 
749
  for (Table *table= temporary_tables ; table ; table= table->getNext())
628
750
  {
629
 
    if (table->s->tmp_table == message::Table::TEMPORARY)
 
751
    if (table->getShare()->getType() == message::Table::TEMPORARY)
630
752
    {
631
 
      if (identifier.compare(table->s->getSchemaName(), table->s->table_name.str))
 
753
      if (identifier.getKey() == table->getShare()->getCacheKey())
632
754
      {
633
 
        table_proto.CopyFrom(*(table->s->getTableProto()));
 
755
        table_proto.CopyFrom(*(table->getShare()->getTableProto()));
634
756
 
635
757
        return EEXIST;
636
758
      }
645
767
  char  key[MAX_DBKEY_LENGTH];
646
768
  uint  key_length;
647
769
 
648
 
  key_length= TableShare::createKey(key, new_db, table_name);
 
770
  key_length= TableIdentifier::createKey(key, new_db, table_name);
649
771
 
650
 
  for (Table *table= temporary_tables ; table ; table= table->next)
 
772
  for (Table *table= temporary_tables ; table ; table= table->getNext())
651
773
  {
652
 
    if (table->s->table_cache_key.length == key_length &&
653
 
        not memcmp(table->s->table_cache_key.str, key, key_length))
 
774
    const TableIdentifier::Key &share_key(table->getShare()->getCacheKey());
 
775
    if (share_key.size() == key_length &&
 
776
        not memcmp(&share_key[0], key, key_length))
654
777
    {
655
778
      return table;
656
779
    }
665
788
 
666
789
Table *Session::find_temporary_table(TableIdentifier &identifier)
667
790
{
668
 
  char  key[MAX_DBKEY_LENGTH];
669
 
  uint  key_length;
670
 
 
671
 
  key_length= TableShare::createKey(key, identifier);
672
 
 
673
 
  for (Table *table= temporary_tables ; table ; table= table->next)
 
791
  for (Table *table= temporary_tables ; table ; table= table->getNext())
674
792
  {
675
 
    if (table->s->table_cache_key.length == key_length &&
676
 
        not memcmp(table->s->table_cache_key.str, key, key_length))
677
 
 
 
793
    if (identifier.getKey() == table->getShare()->getCacheKey())
678
794
      return table;
679
795
  }
680
796
 
718
834
  /* Table might be in use by some outer statement. */
719
835
  if (table->query_id && table->query_id != query_id)
720
836
  {
721
 
    my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
 
837
    my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->getAlias());
722
838
    return -1;
723
839
  }
724
840
 
728
844
}
729
845
 
730
846
 
731
 
/* move table first in unused links */
732
 
 
733
 
static void relink_unused(Table *table)
734
 
{
735
 
  if (table != unused_tables)
736
 
  {
737
 
    table->prev->next=table->next;              /* Remove from unused list */
738
 
    table->next->prev=table->prev;
739
 
    table->next=unused_tables;                  /* Link in unused tables */
740
 
    table->prev=unused_tables->prev;
741
 
    unused_tables->prev->next=table;
742
 
    unused_tables->prev=table;
743
 
    unused_tables=table;
744
 
  }
745
 
}
746
 
 
747
 
 
748
847
/**
749
848
  Remove all instances of table from thread's open list and
750
849
  table cache.
756
855
void Session::unlink_open_table(Table *find)
757
856
{
758
857
  char key[MAX_DBKEY_LENGTH];
759
 
  uint32_t key_length= find->s->table_cache_key.length;
 
858
  uint32_t key_length= find->getShare()->getCacheKeySize();
760
859
  Table *list, **prev;
761
 
 
762
 
  safe_mutex_assert_owner(&LOCK_open);
763
 
 
764
 
  memcpy(key, find->s->table_cache_key.str, key_length);
 
860
  safe_mutex_assert_owner(LOCK_open.native_handle());
 
861
 
 
862
  memcpy(key, &find->getMutableShare()->getCacheKey()[0], key_length);
765
863
  /*
766
864
    Note that we need to hold LOCK_open while changing the
767
865
    open_tables list. Another thread may work on it.
773
871
  {
774
872
    list= *prev;
775
873
 
776
 
    if (list->s->table_cache_key.length == key_length &&
777
 
        not memcmp(list->s->table_cache_key.str, key, key_length))
 
874
    if (list->getShare()->getCacheKeySize() == key_length &&
 
875
        not memcmp(&list->getShare()->getCacheKey()[0], key, key_length))
778
876
    {
779
877
      /* Remove table from open_tables list. */
780
 
      *prev= list->next;
 
878
      *prev= list->getNext();
 
879
 
781
880
      /* Close table. */
782
 
      hash_delete(&open_cache,(unsigned char*) list); // Close table
 
881
      remove_table(list);
783
882
    }
784
883
    else
785
884
    {
786
885
      /* Step to next entry in open_tables list. */
787
 
      prev= &list->next;
 
886
      prev= list->getNextPtr();
788
887
    }
789
888
  }
790
889
 
814
913
 
815
914
void Session::drop_open_table(Table *table, TableIdentifier &identifier)
816
915
{
817
 
  if (table->s->tmp_table)
 
916
  if (table->getShare()->getType())
818
917
  {
819
918
    close_temporary_table(table);
820
919
  }
821
920
  else
822
921
  {
823
 
    pthread_mutex_lock(&LOCK_open); /* Close and drop a table (AUX routine) */
 
922
    boost::mutex::scoped_lock scoped_lock(LOCK_open); /* Close and drop a table (AUX routine) */
824
923
    /*
825
924
      unlink_open_table() also tells threads waiting for refresh or close
826
925
      that something has happened.
827
926
    */
828
927
    unlink_open_table(table);
829
928
    quick_rm_table(*this, identifier);
830
 
    pthread_mutex_unlock(&LOCK_open);
831
929
  }
832
930
}
833
931
 
843
941
  cond  Condition to wait for
844
942
*/
845
943
 
846
 
void Session::wait_for_condition(pthread_mutex_t *mutex, pthread_cond_t *cond)
 
944
void Session::wait_for_condition(boost::mutex &mutex, boost::condition_variable &cond)
847
945
{
848
946
  /* Wait until the current table is up to date */
849
947
  const char *saved_proc_info;
850
 
  mysys_var->current_mutex= mutex;
851
 
  mysys_var->current_cond= cond;
 
948
  mysys_var->current_mutex= mutex.native_handle();
 
949
  mysys_var->current_cond= cond.native_handle();
852
950
  saved_proc_info= get_proc_info();
853
951
  set_proc_info("Waiting for table");
854
952
  if (!killed)
855
 
    (void) pthread_cond_wait(cond, mutex);
 
953
    (void) pthread_cond_wait(cond.native_handle(), mutex.native_handle());
856
954
 
857
955
  /*
858
956
    We must unlock mutex first to avoid deadlock becasue conditions are
865
963
    mutex is unlocked
866
964
  */
867
965
 
868
 
  pthread_mutex_unlock(mutex);
 
966
  pthread_mutex_unlock(mutex.native_handle());
869
967
  pthread_mutex_lock(&mysys_var->mutex);
870
968
  mysys_var->current_mutex= 0;
871
969
  mysys_var->current_cond= 0;
904
1002
  char *table_name= table_list->table_name;
905
1003
  Table orig_table;
906
1004
 
907
 
  safe_mutex_assert_owner(&LOCK_open);
 
1005
  safe_mutex_assert_owner(LOCK_open.native_handle());
908
1006
 
909
1007
  if (killed || !table)
910
1008
    return true;
911
1009
 
912
1010
  orig_table= *table;
913
1011
 
914
 
  if (open_unireg_entry(this, table, table_list, table_name,
915
 
                        table->s->table_cache_key.str,
916
 
                        table->s->table_cache_key.length))
 
1012
  TableIdentifier identifier(table_list->db, table_list->table_name);
 
1013
  if (open_unireg_entry(this, table, table_name, identifier))
917
1014
  {
918
1015
    table->intern_close_table();
919
1016
    /*
926
1023
    return true;
927
1024
  }
928
1025
 
929
 
  share= table->s;
 
1026
  share= table->getMutableShare();
930
1027
  /*
931
1028
    We want to prevent other connections from opening this table until end
932
1029
    of statement as it is likely that modifications of table's metadata are
935
1032
    This also allows us to assume that no other connection will sneak in
936
1033
    before we will get table-level lock on this table.
937
1034
  */
938
 
  share->version=0;
 
1035
  share->resetVersion();
939
1036
  table->in_use = this;
940
1037
 
941
1038
  if (link_in)
942
1039
  {
943
 
    table->next= open_tables;
 
1040
    table->setNext(open_tables);
944
1041
    open_tables= table;
945
1042
  }
946
1043
  else
949
1046
      Table object should be already in Session::open_tables list so we just
950
1047
      need to set Table::next correctly.
951
1048
    */
952
 
    table->next= orig_table.next;
 
1049
    table->setNext(orig_table.getNext());
953
1050
  }
954
1051
 
955
1052
  table->tablenr= current_tablenr++;
977
1074
  case of failure.
978
1075
*/
979
1076
 
980
 
Table *Session::table_cache_insert_placeholder(const char *key, uint32_t key_length)
 
1077
Table *Session::table_cache_insert_placeholder(const char *db_name, const char *table_name)
981
1078
{
982
 
  Table *table;
983
 
  TableShare *share;
984
 
  char *key_buff;
985
 
 
986
 
  safe_mutex_assert_owner(&LOCK_open);
 
1079
  safe_mutex_assert_owner(LOCK_open.native_handle());
987
1080
 
988
1081
  /*
989
1082
    Create a table entry with the right key and with an old refresh version
990
 
    Note that we must use multi_malloc() here as this is freed by the
991
 
    table cache
992
1083
  */
993
 
  if (! memory::multi_malloc(true,
994
 
                             &table, sizeof(*table),
995
 
                             &share, sizeof(*share),
996
 
                             &key_buff, key_length,
997
 
                             NULL))
998
 
    return NULL;
999
 
 
1000
 
  table->s= share;
1001
 
  share->set_table_cache_key(key_buff, key, key_length);
1002
 
  share->tmp_table= message::Table::INTERNAL;  // for intern_close_table
1003
 
  table->in_use= this;
1004
 
  table->locked_by_name=1;
1005
 
 
1006
 
  if (my_hash_insert(&open_cache, (unsigned char*)table))
 
1084
  TableIdentifier identifier(db_name, table_name, message::Table::INTERNAL);
 
1085
  TablePlaceholder *table= new TablePlaceholder(this, identifier);
 
1086
 
 
1087
  if (not add_table(table))
1007
1088
  {
1008
 
    free((unsigned char*) table);
 
1089
    delete table;
 
1090
 
1009
1091
    return NULL;
1010
1092
  }
1011
1093
 
1036
1118
*/
1037
1119
bool Session::lock_table_name_if_not_cached(TableIdentifier &identifier, Table **table)
1038
1120
{
1039
 
  return lock_table_name_if_not_cached(identifier.getSchemaName().c_str(), identifier.getTableName().c_str(), table);
1040
 
}
1041
 
 
1042
 
bool Session::lock_table_name_if_not_cached(const char *new_db,
1043
 
                                            const char *table_name, Table **table)
1044
 
{
1045
 
  char key[MAX_DBKEY_LENGTH];
1046
 
  char *key_pos= key;
1047
 
  uint32_t key_length;
1048
 
 
1049
 
  key_pos= strcpy(key_pos, new_db) + strlen(new_db);
1050
 
  key_pos= strcpy(key_pos+1, table_name) + strlen(table_name);
1051
 
  key_length= (uint32_t) (key_pos-key)+1;
1052
 
 
1053
 
  pthread_mutex_lock(&LOCK_open); /* Obtain a name lock even though table is not in cache (like for create table)  */
1054
 
 
1055
 
  if (hash_search(&open_cache, (unsigned char *)key, key_length))
 
1121
  const TableIdentifier::Key &key(identifier.getKey());
 
1122
 
 
1123
  boost::mutex::scoped_lock scope_lock(LOCK_open); /* Obtain a name lock even though table is not in cache (like for create table)  */
 
1124
 
 
1125
  TableOpenCache::iterator iter;
 
1126
 
 
1127
  iter= get_open_cache().find(key);
 
1128
 
 
1129
  if (iter != get_open_cache().end())
1056
1130
  {
1057
 
    pthread_mutex_unlock(&LOCK_open);
1058
1131
    *table= 0;
1059
1132
    return false;
1060
1133
  }
1061
 
  if (not (*table= table_cache_insert_placeholder(key, key_length)))
 
1134
 
 
1135
  if (not (*table= table_cache_insert_placeholder(identifier.getSchemaName().c_str(), identifier.getTableName().c_str())))
1062
1136
  {
1063
 
    pthread_mutex_unlock(&LOCK_open);
1064
1137
    return true;
1065
1138
  }
1066
1139
  (*table)->open_placeholder= true;
1067
 
  (*table)->next= open_tables;
 
1140
  (*table)->setNext(open_tables);
1068
1141
  open_tables= *table;
1069
 
  pthread_mutex_unlock(&LOCK_open);
1070
1142
 
1071
1143
  return false;
1072
1144
}
1107
1179
Table *Session::openTable(TableList *table_list, bool *refresh, uint32_t flags)
1108
1180
{
1109
1181
  Table *table;
1110
 
  char key[MAX_DBKEY_LENGTH];
1111
 
  unsigned int key_length;
1112
1182
  const char *alias= table_list->alias;
1113
 
  HASH_SEARCH_STATE state;
1114
1183
 
1115
1184
  /* Parsing of partitioning information from .frm needs session->lex set up. */
1116
1185
  assert(lex->is_lex_started);
1126
1195
  if (killed)
1127
1196
    return NULL;
1128
1197
 
1129
 
  key_length= table_list->create_table_def_key(key);
 
1198
  TableIdentifier identifier(table_list->db, table_list->table_name);
 
1199
  const TableIdentifier::Key &key(identifier.getKey());
 
1200
  TableOpenCacheRange ppp;
1130
1201
 
1131
1202
  /*
1132
1203
    Unless requested otherwise, try to resolve this table in the list
1135
1206
    same name. This block implements the behaviour.
1136
1207
    TODO -> move this block into a separate function.
1137
1208
  */
1138
 
  for (table= temporary_tables; table ; table=table->next)
 
1209
  for (table= temporary_tables; table ; table=table->getNext())
1139
1210
  {
1140
 
    if (table->s->table_cache_key.length == key_length && !memcmp(table->s->table_cache_key.str, key, key_length))
 
1211
    if (table->getShare()->getCacheKey() == key)
1141
1212
    {
1142
1213
      /*
1143
1214
        We're trying to use the same temporary table twice in a query.
1147
1218
      */
1148
1219
      if (table->query_id)
1149
1220
      {
1150
 
        my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
 
1221
        my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->getAlias());
1151
1222
        return NULL;
1152
1223
      }
1153
1224
      table->query_id= getQueryId();
1171
1242
    Note-> refresh_version is currently changed only during FLUSH TABLES.
1172
1243
  */
1173
1244
  if (!open_tables)
 
1245
  {
1174
1246
    version= refresh_version;
 
1247
  }
1175
1248
  else if ((version != refresh_version) &&
1176
1249
           ! (flags & DRIZZLE_LOCK_IGNORE_FLUSH))
1177
1250
  {
1196
1269
    Now we should:
1197
1270
    - try to find the table in the table cache.
1198
1271
    - if one of the discovered Table instances is name-locked
1199
 
    (table->s->version == 0) back off -- we have to wait
 
1272
    (table->getShare()->version == 0) back off -- we have to wait
1200
1273
    until no one holds a name lock on the table.
1201
1274
    - if there is no such Table in the name cache, read the table definition
1202
1275
    and insert it into the cache.
1205
1278
    on disk.
1206
1279
  */
1207
1280
 
1208
 
  pthread_mutex_lock(&LOCK_open); /* Lock for FLUSH TABLES for open table */
 
1281
  LOCK_open.lock(); /* Lock for FLUSH TABLES for open table */
1209
1282
 
1210
1283
  /*
1211
1284
    Actually try to find the table in the open_cache.
1217
1290
    an implicit "pending locks queue" - see
1218
1291
    wait_for_locked_table_names for details.
1219
1292
  */
1220
 
  for (table= (Table*) hash_first(&open_cache, (unsigned char*) key, key_length,
1221
 
                                  &state);
1222
 
       table && table->in_use ;
1223
 
       table= (Table*) hash_next(&open_cache, (unsigned char*) key, key_length,
1224
 
                                 &state))
 
1293
  ppp= get_open_cache().equal_range(key);
 
1294
 
 
1295
  table= NULL;
 
1296
  for (TableOpenCache::const_iterator iter= ppp.first;
 
1297
       iter != ppp.second; ++iter, table= NULL)
1225
1298
  {
 
1299
    table= (*iter).second;
 
1300
 
 
1301
    if (not table->in_use)
 
1302
      break;
1226
1303
    /*
1227
1304
      Here we flush tables marked for flush.
1228
 
      Normally, table->s->version contains the value of
 
1305
      Normally, table->getShare()->version contains the value of
1229
1306
      refresh_version from the moment when this table was
1230
1307
      (re-)opened and added to the cache.
1231
1308
      If since then we did (or just started) FLUSH TABLES
1232
1309
      statement, refresh_version has been increased.
1233
 
      For "name-locked" Table instances, table->s->version is set
 
1310
      For "name-locked" Table instances, table->getShare()->version is set
1234
1311
      to 0 (see lock_table_name for details).
1235
1312
      In case there is a pending FLUSH TABLES or a name lock, we
1236
1313
      need to back off and re-start opening tables.
1237
1314
      If we do not back off now, we may dead lock in case of lock
1238
1315
      order mismatch with some other thread:
1239
 
c1: name lock t1; -- sort of exclusive lock
1240
 
c2: open t2;      -- sort of shared lock
1241
 
c1: name lock t2; -- blocks
1242
 
c2: open t1; -- blocks
 
1316
      c1-> name lock t1; -- sort of exclusive lock
 
1317
      c2-> open t2;      -- sort of shared lock
 
1318
      c1-> name lock t2; -- blocks
 
1319
      c2-> open t1; -- blocks
1243
1320
    */
1244
1321
    if (table->needs_reopen_or_name_lock())
1245
1322
    {
1246
1323
      if (flags & DRIZZLE_LOCK_IGNORE_FLUSH)
1247
1324
      {
1248
1325
        /* Force close at once after usage */
1249
 
        version= table->s->version;
 
1326
        version= table->getShare()->getVersion();
1250
1327
        continue;
1251
1328
      }
1252
1329
 
1253
1330
      /* Avoid self-deadlocks by detecting self-dependencies. */
1254
1331
      if (table->open_placeholder && table->in_use == this)
1255
1332
      {
1256
 
        pthread_mutex_unlock(&LOCK_open);
1257
 
        my_error(ER_UPDATE_TABLE_USED, MYF(0), table->s->table_name.str);
 
1333
        LOCK_open.unlock();
 
1334
        my_error(ER_UPDATE_TABLE_USED, MYF(0), table->getMutableShare()->getTableName());
1258
1335
        return NULL;
1259
1336
      }
1260
1337
 
1262
1339
        Back off, part 1: mark the table as "unused" for the
1263
1340
        purpose of name-locking by setting table->db_stat to 0. Do
1264
1341
        that only for the tables in this thread that have an old
1265
 
        table->s->version (this is an optimization (?)).
 
1342
        table->getShare()->version (this is an optimization (?)).
1266
1343
        table->db_stat == 0 signals wait_for_locked_table_names
1267
1344
        that the tables in question are not used any more. See
1268
1345
        table_is_used call for details.
1273
1350
        Back-off part 2: try to avoid "busy waiting" on the table:
1274
1351
        if the table is in use by some other thread, we suspend
1275
1352
        and wait till the operation is complete: when any
1276
 
        operation that juggles with table->s->version completes,
 
1353
        operation that juggles with table->getShare()->version completes,
1277
1354
        it broadcasts COND_refresh condition variable.
1278
1355
        If 'old' table we met is in use by current thread we return
1279
1356
        without waiting since in this situation it's this thread
1287
1364
      if (table->in_use != this)
1288
1365
      {
1289
1366
        /* wait_for_conditionwill unlock LOCK_open for us */
1290
 
        wait_for_condition(&LOCK_open, &COND_refresh);
 
1367
        wait_for_condition(LOCK_open, COND_refresh);
1291
1368
      }
1292
1369
      else
1293
1370
      {
1294
 
        pthread_mutex_unlock(&LOCK_open);
 
1371
        LOCK_open.unlock();
1295
1372
      }
1296
1373
      /*
1297
1374
        There is a refresh in progress for this table.
1304
1381
  }
1305
1382
  if (table)
1306
1383
  {
1307
 
    /* Unlink the table from "unused_tables" list. */
1308
 
    if (table == unused_tables)
1309
 
    {  // First unused
1310
 
      unused_tables=unused_tables->next; // Remove from link
1311
 
      if (table == unused_tables)
1312
 
        unused_tables= NULL;
1313
 
    }
1314
 
    table->prev->next=table->next; /* Remove from unused list */
1315
 
    table->next->prev=table->prev;
 
1384
    unused_tables.unlink(table);
1316
1385
    table->in_use= this;
1317
1386
  }
1318
1387
  else
1320
1389
    /* Insert a new Table instance into the open cache */
1321
1390
    int error;
1322
1391
    /* Free cache if too big */
1323
 
    while (open_cache.records > table_cache_size && unused_tables)
1324
 
      hash_delete(&open_cache,(unsigned char*) unused_tables);
 
1392
    unused_tables.cull();
1325
1393
 
1326
 
    if (table_list->create)
 
1394
    if (table_list->isCreate())
1327
1395
    {
1328
1396
      TableIdentifier  lock_table_identifier(table_list->db, table_list->table_name, message::Table::STANDARD);
1329
1397
 
1332
1400
        /*
1333
1401
          Table to be created, so we need to create placeholder in table-cache.
1334
1402
        */
1335
 
        if (!(table= table_cache_insert_placeholder(key, key_length)))
 
1403
        if (!(table= table_cache_insert_placeholder(table_list->db, table_list->table_name)))
1336
1404
        {
1337
 
          pthread_mutex_unlock(&LOCK_open);
 
1405
          LOCK_open.unlock();
1338
1406
          return NULL;
1339
1407
        }
1340
1408
        /*
1343
1411
          by other trying to take name-lock.
1344
1412
        */
1345
1413
        table->open_placeholder= true;
1346
 
        table->next= open_tables;
 
1414
        table->setNext(open_tables);
1347
1415
        open_tables= table;
1348
 
        pthread_mutex_unlock(&LOCK_open);
 
1416
        LOCK_open.unlock();
1349
1417
 
1350
1418
        return table ;
1351
1419
      }
1353
1421
    }
1354
1422
 
1355
1423
    /* make a new table */
1356
 
    table= (Table *)malloc(sizeof(Table));
 
1424
    table= new Table;
1357
1425
    if (table == NULL)
1358
1426
    {
1359
 
      pthread_mutex_unlock(&LOCK_open);
 
1427
      LOCK_open.unlock();
1360
1428
      return NULL;
1361
1429
    }
1362
1430
 
1363
 
    error= open_unireg_entry(this, table, table_list, alias, key, key_length);
 
1431
    error= open_unireg_entry(this, table, alias, identifier);
1364
1432
    if (error != 0)
1365
1433
    {
1366
 
      free(table);
1367
 
      pthread_mutex_unlock(&LOCK_open);
 
1434
      delete table;
 
1435
      LOCK_open.unlock();
1368
1436
      return NULL;
1369
1437
    }
1370
 
    my_hash_insert(&open_cache, (unsigned char*) table);
 
1438
    (void)add_table(table);
1371
1439
  }
1372
1440
 
1373
 
  pthread_mutex_unlock(&LOCK_open);
 
1441
  LOCK_open.unlock();
1374
1442
  if (refresh)
1375
1443
  {
1376
 
    table->next= open_tables; /* Link into simple list */
1377
 
    open_tables=table;
 
1444
    table->setNext(open_tables); /* Link into simple list */
 
1445
    open_tables= table;
1378
1446
  }
1379
1447
  table->reginfo.lock_type= TL_READ; /* Assume read */
1380
1448
 
1381
1449
reset:
1382
 
  assert(table->s->ref_count > 0 || table->s->tmp_table != message::Table::STANDARD);
 
1450
  assert(table->getShare()->getTableCount() > 0 || table->getShare()->getType() != message::Table::STANDARD);
1383
1451
 
1384
1452
  if (lex->need_correct_ident())
1385
1453
    table->alias_name_used= my_strcasecmp(table_alias_charset,
1386
 
                                          table->s->table_name.str, alias);
 
1454
                                          table->getMutableShare()->getTableName(), alias);
1387
1455
  /* Fix alias if table name changes */
1388
 
  if (strcmp(table->alias, alias))
 
1456
  if (strcmp(table->getAlias(), alias))
1389
1457
  {
1390
1458
    uint32_t length=(uint32_t) strlen(alias)+1;
1391
1459
    table->alias= (char*) realloc((char*) table->alias, length);
1400
1468
  table->maybe_null= false;
1401
1469
  table->force_index= false;
1402
1470
  table->status=STATUS_NO_RECORD;
1403
 
  table->insert_values= 0;
 
1471
  table->insert_values.clear();
1404
1472
  /* Catch wrong handling of the auto_increment_field_not_null. */
1405
1473
  assert(!table->auto_increment_field_not_null);
1406
1474
  table->auto_increment_field_not_null= false;
1407
1475
  if (table->timestamp_field)
 
1476
  {
1408
1477
    table->timestamp_field_type= table->timestamp_field->get_auto_set_type();
 
1478
  }
1409
1479
  table->pos_in_table_list= table_list;
1410
1480
  table->clear_column_bitmaps();
1411
1481
  assert(table->key_read == 0);
1414
1484
}
1415
1485
 
1416
1486
 
 
1487
#if 0
1417
1488
/*
1418
1489
  Reopen an table because the definition has changed.
1419
1490
 
1439
1510
  TableList table_list;
1440
1511
  Session *session= table->in_use;
1441
1512
 
1442
 
  assert(table->s->ref_count == 0);
 
1513
  assert(table->getShare()->ref_count == 0);
1443
1514
  assert(!table->sort.io_cache);
1444
1515
 
1445
1516
#ifdef EXTRA_DEBUG
1447
1518
    errmsg_printf(ERRMSG_LVL_ERROR, _("Table %s had a open data Cursor in reopen_table"),
1448
1519
                  table->alias);
1449
1520
#endif
1450
 
  table_list.db=         const_cast<char *>(table->s->getSchemaName());
1451
 
  table_list.table_name= table->s->table_name.str;
 
1521
  table_list.db=         const_cast<char *>(table->getShare()->getSchemaName());
 
1522
  table_list.table_name= table->getShare()->getTableName();
1452
1523
  table_list.table=      table;
1453
1524
 
1454
1525
  if (wait_for_locked_table_names(session, &table_list))
1456
1527
 
1457
1528
  if (open_unireg_entry(session, &tmp, &table_list,
1458
1529
                        table->alias,
1459
 
                        table->s->table_cache_key.str,
1460
 
                        table->s->table_cache_key.length))
 
1530
                        table->getShare()->getCacheKey(),
 
1531
                        table->getShare()->getCacheKeySize()))
1461
1532
    goto end;
1462
1533
 
1463
1534
  /* This list copies variables set by open_table */
1477
1548
  tmp.prev=             table->prev;
1478
1549
 
1479
1550
  if (table->cursor)
1480
 
    table->closefrm(true);              // close cursor, free everything
 
1551
    table->delete_table(true);          // close cursor, free everything
1481
1552
 
1482
1553
  *table= tmp;
1483
1554
  table->default_column_bitmaps();
1489
1560
    (*field)->table= (*field)->orig_table= table;
1490
1561
    (*field)->table_name= &table->alias;
1491
1562
  }
1492
 
  for (key=0 ; key < table->s->keys ; key++)
 
1563
  for (key=0 ; key < table->getShare()->keys ; key++)
1493
1564
  {
1494
1565
    for (part=0 ; part < table->key_info[key].usable_key_parts ; part++)
1495
1566
      table->key_info[key].key_part[part].field->table= table;
1501
1572
end:
1502
1573
  return(error);
1503
1574
}
 
1575
#endif
1504
1576
 
1505
1577
 
1506
1578
/**
1522
1594
 
1523
1595
void Session::close_data_files_and_morph_locks(TableIdentifier &identifier)
1524
1596
{
1525
 
  close_data_files_and_morph_locks(identifier.getSchemaName().c_str(), identifier.getTableName().c_str());
1526
 
}
1527
 
 
1528
 
void Session::close_data_files_and_morph_locks(const char *new_db, const char *new_table_name)
1529
 
{
1530
 
  Table *table;
1531
 
 
1532
 
  safe_mutex_assert_owner(&LOCK_open); /* Adjust locks at the end of ALTER TABLEL */
 
1597
  safe_mutex_assert_owner(LOCK_open.native_handle()); /* Adjust locks at the end of ALTER TABLEL */
1533
1598
 
1534
1599
  if (lock)
1535
1600
  {
1546
1611
    for target table name if we process ALTER Table ... RENAME.
1547
1612
    So loop below makes sense even if we are not under LOCK TABLES.
1548
1613
  */
1549
 
  for (table= open_tables; table ; table=table->next)
 
1614
  for (Table *table= open_tables; table ; table=table->getNext())
1550
1615
  {
1551
 
    if (!strcmp(table->s->table_name.str, new_table_name) &&
1552
 
        !strcasecmp(table->s->getSchemaName(), new_db))
 
1616
    if (table->getShare()->getCacheKey() == identifier.getKey())
1553
1617
    {
1554
1618
      table->open_placeholder= true;
1555
1619
      close_handle_and_leave_table_as_lock(table);
1578
1642
  @return false in case of success, true - otherwise.
1579
1643
*/
1580
1644
 
1581
 
bool Session::reopen_tables(bool get_locks, bool mark_share_as_old)
 
1645
bool Session::reopen_tables(bool get_locks, bool)
1582
1646
{
1583
1647
  Table *table,*next,**prev;
1584
1648
  Table **tables,**tables_ptr;                  // For locks
1590
1654
  if (open_tables == NULL)
1591
1655
    return false;
1592
1656
 
1593
 
  safe_mutex_assert_owner(&LOCK_open);
 
1657
  safe_mutex_assert_owner(LOCK_open.native_handle());
1594
1658
  if (get_locks)
1595
1659
  {
1596
1660
    /*
1599
1663
    */
1600
1664
    uint32_t opens= 0;
1601
1665
 
1602
 
    for (table= open_tables; table ; table=table->next)
 
1666
    for (table= open_tables; table ; table=table->getNext())
 
1667
    {
1603
1668
      opens++;
 
1669
    }
1604
1670
    tables= new Table *[opens];
1605
1671
  }
1606
1672
  else
 
1673
  {
1607
1674
    tables= &open_tables;
 
1675
  }
1608
1676
  tables_ptr =tables;
1609
1677
 
1610
1678
  prev= &open_tables;
1611
1679
  for (table= open_tables; table ; table=next)
1612
1680
  {
1613
 
    uint32_t db_stat= table->db_stat;
1614
 
    next= table->next;
1615
 
    if (!tables || (!db_stat && reopen_table(table)))
1616
 
    {
1617
 
      my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
1618
 
      hash_delete(&open_cache,(unsigned char*) table);
1619
 
      error= 1;
1620
 
    }
1621
 
    else
1622
 
    {
1623
 
      *prev= table;
1624
 
      prev= &table->next;
1625
 
      /* Do not handle locks of MERGE children. */
1626
 
      if (get_locks && !db_stat)
1627
 
        *tables_ptr++= table;                   // need new lock on this
1628
 
      if (mark_share_as_old)
1629
 
      {
1630
 
        table->s->version= 0;
1631
 
        table->open_placeholder= false;
1632
 
      }
1633
 
    }
 
1681
    next= table->getNext();
 
1682
 
 
1683
    my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->getAlias());
 
1684
    remove_table(table);
 
1685
    error= 1;
1634
1686
  }
1635
1687
  *prev=0;
1636
1688
  if (tables != tables_ptr)                     // Should we get back old locks
1637
1689
  {
1638
 
    DRIZZLE_LOCK *local_lock;
 
1690
    DrizzleLock *local_lock;
1639
1691
    /*
1640
1692
      We should always get these locks. Anyway, we must not go into
1641
1693
      wait_for_tables() as it tries to acquire LOCK_open, which is
1689
1741
 
1690
1742
  Table *table= open_tables;
1691
1743
 
1692
 
  for (; table ; table=table->next)
 
1744
  for (; table ; table=table->getNext())
1693
1745
  {
1694
1746
    /*
1695
1747
      Reopen marked for flush.
1765
1817
{
1766
1818
  do
1767
1819
  {
1768
 
    char *key= table->s->table_cache_key.str;
1769
 
    uint32_t key_length= table->s->table_cache_key.length;
1770
 
 
1771
 
    HASH_SEARCH_STATE state;
1772
 
    for (Table *search= (Table*) hash_first(&open_cache, (unsigned char*) key,
1773
 
                                            key_length, &state);
1774
 
         search ;
1775
 
         search= (Table*) hash_next(&open_cache, (unsigned char*) key,
1776
 
                                    key_length, &state))
 
1820
    const TableIdentifier::Key &key(table->getShare()->getCacheKey());
 
1821
 
 
1822
    TableOpenCacheRange ppp;
 
1823
    ppp= get_open_cache().equal_range(key);
 
1824
 
 
1825
    for (TableOpenCache::const_iterator iter= ppp.first;
 
1826
         iter != ppp.second; ++iter)
1777
1827
    {
 
1828
      Table *search= (*iter).second;
1778
1829
      if (search->in_use == table->in_use)
1779
1830
        continue;                               // Name locked by this thread
1780
1831
      /*
1788
1839
           (search->is_name_opened() && search->needs_reopen_or_name_lock()))
1789
1840
        return 1;
1790
1841
    }
1791
 
  } while ((table=table->next));
 
1842
  } while ((table=table->getNext()));
1792
1843
  return 0;
1793
1844
}
1794
1845
 
1800
1851
  bool result;
1801
1852
 
1802
1853
  session->set_proc_info("Waiting for tables");
1803
 
  pthread_mutex_lock(&LOCK_open); /* Lock for all tables to be refreshed */
1804
 
  while (!session->killed)
1805
 
  {
1806
 
    session->some_tables_deleted= false;
1807
 
    session->close_old_data_files(false, dropping_tables != 0);
1808
 
    if (!table_is_used(session->open_tables, 1))
1809
 
      break;
1810
 
    (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
1811
 
  }
1812
 
  if (session->killed)
1813
 
    result= true;                                       // aborted
1814
 
  else
1815
 
  {
1816
 
    /* Now we can open all tables without any interference */
1817
 
    session->set_proc_info("Reopen tables");
1818
 
    session->version= refresh_version;
1819
 
    result= session->reopen_tables(false, false);
1820
 
  }
1821
 
  pthread_mutex_unlock(&LOCK_open);
 
1854
  {
 
1855
    boost::mutex::scoped_lock lock(LOCK_open);
 
1856
    while (!session->killed)
 
1857
    {
 
1858
      session->some_tables_deleted= false;
 
1859
      session->close_old_data_files(false, dropping_tables != 0);
 
1860
      if (!table_is_used(session->open_tables, 1))
 
1861
        break;
 
1862
      COND_refresh.wait(lock);
 
1863
    }
 
1864
    if (session->killed)
 
1865
      result= true;                                     // aborted
 
1866
    else
 
1867
    {
 
1868
      /* Now we can open all tables without any interference */
 
1869
      session->set_proc_info("Reopen tables");
 
1870
      session->version= refresh_version;
 
1871
      result= session->reopen_tables(false, false);
 
1872
    }
 
1873
  }
1822
1874
  session->set_proc_info(0);
1823
1875
 
1824
1876
  return result;
1849
1901
*/
1850
1902
 
1851
1903
 
1852
 
Table *drop_locked_tables(Session *session,const char *db, const char *table_name)
 
1904
Table *drop_locked_tables(Session *session, const drizzled::TableIdentifier &identifier)
1853
1905
{
1854
1906
  Table *table,*next,**prev, *found= 0;
1855
1907
  prev= &session->open_tables;
1863
1915
  */
1864
1916
  for (table= session->open_tables; table ; table=next)
1865
1917
  {
1866
 
    next=table->next;
1867
 
    if (!strcmp(table->s->table_name.str, table_name) &&
1868
 
        !strcasecmp(table->s->getSchemaName(), db))
 
1918
    next=table->getNext();
 
1919
    if (table->getShare()->getCacheKey() == identifier.getKey())
1869
1920
    {
1870
1921
      mysql_lock_remove(session, table);
1871
1922
 
1882
1933
      else
1883
1934
      {
1884
1935
        /* We already have a name lock, remove copy */
1885
 
        hash_delete(&open_cache,(unsigned char*) table);
 
1936
        remove_table(table);
1886
1937
      }
1887
1938
    }
1888
1939
    else
1889
1940
    {
1890
1941
      *prev=table;
1891
 
      prev= &table->next;
 
1942
      prev= table->getNextPtr();
1892
1943
    }
1893
1944
  }
1894
1945
  *prev=0;
1905
1956
  other threads trying to get the lock.
1906
1957
*/
1907
1958
 
1908
 
void abort_locked_tables(Session *session,const char *db, const char *table_name)
 
1959
void abort_locked_tables(Session *session, const drizzled::TableIdentifier &identifier)
1909
1960
{
1910
1961
  Table *table;
1911
 
  for (table= session->open_tables; table ; table= table->next)
 
1962
  for (table= session->open_tables; table ; table= table->getNext())
1912
1963
  {
1913
 
    if (!strcmp(table->s->table_name.str, table_name) &&
1914
 
        !strcmp(table->s->getSchemaName(), db))
 
1964
    if (table->getShare()->getCacheKey() == identifier.getKey())
1915
1965
    {
1916
1966
      /* If MERGE child, forward lock handling to parent. */
1917
1967
      mysql_lock_abort(session, table);
1941
1991
#       Error
1942
1992
*/
1943
1993
 
1944
 
static int open_unireg_entry(Session *session, Table *entry, TableList *table_list,
 
1994
static int open_unireg_entry(Session *session,
 
1995
                             Table *entry,
1945
1996
                             const char *alias,
1946
 
                             char *cache_key, uint32_t cache_key_length)
 
1997
                             TableIdentifier &identifier)
1947
1998
{
1948
1999
  int error;
1949
2000
  TableShare *share;
1950
2001
  uint32_t discover_retry_count= 0;
1951
2002
 
1952
 
  safe_mutex_assert_owner(&LOCK_open);
 
2003
  safe_mutex_assert_owner(LOCK_open.native_handle());
1953
2004
retry:
1954
 
  if (not (share= TableShare::getShare(session, table_list, cache_key,
1955
 
                                       cache_key_length,
1956
 
                                       table_list->i_s_requested_object,
1957
 
                                       &error)))
 
2005
  if (not (share= TableShare::getShareCreate(session,
 
2006
                                             identifier,
 
2007
                                             &error)))
1958
2008
    return 1;
1959
2009
 
1960
 
  while ((error= open_table_from_share(session, share, alias,
1961
 
                                       (uint32_t) (HA_OPEN_KEYFILE |
1962
 
                                                   HA_OPEN_RNDFILE |
1963
 
                                                   HA_GET_INDEX |
1964
 
                                                   HA_TRY_READ_ONLY),
1965
 
                                       session->open_options, entry)))
 
2010
  while ((error= share->open_table_from_share(session,
 
2011
                                              identifier,
 
2012
                                              alias,
 
2013
                                              (uint32_t) (HA_OPEN_KEYFILE |
 
2014
                                                          HA_OPEN_RNDFILE |
 
2015
                                                          HA_GET_INDEX |
 
2016
                                                          HA_TRY_READ_ONLY),
 
2017
                                              session->open_options, *entry)))
1966
2018
  {
1967
2019
    if (error == 7)                             // Table def changed
1968
2020
    {
1969
 
      share->version= 0;                        // Mark share as old
 
2021
      share->resetVersion();                        // Mark share as old
1970
2022
      if (discover_retry_count++)               // Retry once
1971
2023
        goto err;
1972
2024
 
1989
2041
        To avoid deadlock, only wait for release if no one else is
1990
2042
        using the share.
1991
2043
      */
1992
 
      if (share->ref_count != 1)
 
2044
      if (share->getTableCount() != 1)
1993
2045
        goto err;
1994
2046
      /* Free share and wait until it's released by all threads */
1995
2047
      TableShare::release(share);
2081
2133
     * to see if it exists so that an unauthorized user cannot phish for
2082
2134
     * table/schema information via error messages
2083
2135
     */
 
2136
    TableIdentifier the_table(tables->db, tables->table_name);
2084
2137
    if (not plugin::Authorization::isAuthorized(getSecurityContext(),
2085
 
                                                string(tables->db),
2086
 
                                                string(tables->table_name)))
 
2138
                                                the_table))
2087
2139
    {
2088
2140
      result= -1;                               // Fatal error
2089
2141
      break;
2129
2181
    {
2130
2182
      if (tables->lock_type == TL_WRITE_DEFAULT)
2131
2183
        tables->table->reginfo.lock_type= update_lock_default;
2132
 
      else if (tables->table->s->tmp_table == message::Table::STANDARD)
 
2184
      else if (tables->table->getShare()->getType() == message::Table::STANDARD)
2133
2185
        tables->table->reginfo.lock_type= tables->lock_type;
2134
2186
    }
2135
2187
  }
2287
2339
Table *Session::open_temporary_table(TableIdentifier &identifier,
2288
2340
                                     bool link_in_list)
2289
2341
{
2290
 
  Table *new_tmp_table;
2291
2342
  TableShare *share;
2292
 
  char cache_key[MAX_DBKEY_LENGTH], *saved_cache_key, *tmp_path;
2293
 
  uint32_t key_length, path_length;
2294
 
  TableList table_list;
2295
 
 
2296
 
  table_list.db=         (char*) identifier.getSchemaName().c_str();
2297
 
  table_list.table_name= (char*) identifier.getTableName().c_str();
2298
 
  /* Create the cache_key for temporary tables */
2299
 
  key_length= table_list.create_table_def_key(cache_key);
2300
 
  path_length= identifier.getPath().length();
2301
 
 
2302
 
  if (!(new_tmp_table= (Table*) malloc(sizeof(*new_tmp_table) + sizeof(*share) +
2303
 
                                       path_length + 1 + key_length)))
 
2343
 
 
2344
  assert(identifier.isTmp());
 
2345
  share= new TableShare(identifier.getType(),
 
2346
                        identifier,
 
2347
                        const_cast<char *>(identifier.getPath().c_str()), static_cast<uint32_t>(identifier.getPath().length()));
 
2348
 
 
2349
 
 
2350
  Table *new_tmp_table= new Table;
 
2351
  if (not new_tmp_table)
2304
2352
    return NULL;
2305
2353
 
2306
 
  share= (TableShare*) (new_tmp_table+1);
2307
 
  tmp_path= (char*) (share+1);
2308
 
  saved_cache_key= strcpy(tmp_path, identifier.getPath().c_str())+path_length+1;
2309
 
  memcpy(saved_cache_key, cache_key, key_length);
2310
 
 
2311
 
  share->init(saved_cache_key, key_length, strchr(saved_cache_key, '\0')+1, tmp_path);
2312
 
 
2313
2354
  /*
2314
2355
    First open the share, and then open the table from the share we just opened.
2315
2356
  */
2316
 
  if (open_table_def(*this, identifier, share) ||
2317
 
      open_table_from_share(this, share, identifier.getTableName().c_str(),
 
2357
  if (share->open_table_def(*this, identifier) ||
 
2358
      share->open_table_from_share(this, identifier, identifier.getTableName().c_str(),
2318
2359
                            (uint32_t) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
2319
2360
                                        HA_GET_INDEX),
2320
2361
                            ha_open_options,
2321
 
                            new_tmp_table))
 
2362
                            *new_tmp_table))
2322
2363
  {
2323
2364
    /* No need to lock share->mutex as this is not needed for tmp tables */
2324
 
    share->free_table_share();
2325
 
    free((char*) new_tmp_table);
 
2365
    delete share;
 
2366
    delete new_tmp_table;
 
2367
 
2326
2368
    return 0;
2327
2369
  }
2328
2370
 
2329
2371
  new_tmp_table->reginfo.lock_type= TL_WRITE;    // Simulate locked
2330
 
  share->tmp_table= message::Table::TEMPORARY;
2331
2372
 
2332
2373
  if (link_in_list)
2333
2374
  {
2334
2375
    /* growing temp list at the head */
2335
 
    new_tmp_table->next= this->temporary_tables;
2336
 
    if (new_tmp_table->next)
2337
 
      new_tmp_table->next->prev= new_tmp_table;
 
2376
    new_tmp_table->setNext(this->temporary_tables);
 
2377
    if (new_tmp_table->getNext())
 
2378
    {
 
2379
      new_tmp_table->getNext()->setPrev(new_tmp_table);
 
2380
    }
2338
2381
    this->temporary_tables= new_tmp_table;
2339
 
    this->temporary_tables->prev= 0;
 
2382
    this->temporary_tables->setPrev(0);
2340
2383
  }
2341
2384
  new_tmp_table->pos_in_table_list= 0;
2342
2385
 
2451
2494
    return NULL;
2452
2495
  {
2453
2496
    /* This is a base table. */
2454
 
    assert(nj_col->table_ref->table == nj_col->table_field->table);
 
2497
    assert(nj_col->table_ref->table == nj_col->table_field->getTable());
2455
2498
    found_field= nj_col->table_field;
2456
2499
    update_field_dependencies(session, found_field, nj_col->table_ref->table);
2457
2500
  }
2488
2531
  uint32_t cached_field_index= *cached_field_index_ptr;
2489
2532
 
2490
2533
  /* We assume here that table->field < NO_CACHED_FIELD_INDEX = UINT_MAX */
2491
 
  if (cached_field_index < table->s->fields &&
 
2534
  if (cached_field_index < table->getShare()->sizeFields() &&
2492
2535
      !my_strcasecmp(system_charset_info,
2493
 
                     table->field[cached_field_index]->field_name, name))
2494
 
    field_ptr= table->field + cached_field_index;
2495
 
  else if (table->s->name_hash.records)
2496
 
  {
2497
 
    field_ptr= (Field**) hash_search(&table->s->name_hash, (unsigned char*) name,
2498
 
                                     length);
 
2536
                     table->getField(cached_field_index)->field_name, name))
 
2537
  {
 
2538
    field_ptr= table->getFields() + cached_field_index;
 
2539
  }
 
2540
  else if (table->getShare()->getNamedFieldSize())
 
2541
  {
 
2542
    field_ptr= table->getMutableShare()->getNamedField(std::string(name, length));
2499
2543
    if (field_ptr)
2500
2544
    {
2501
2545
      /*
2502
2546
        field_ptr points to field in TableShare. Convert it to the matching
2503
2547
        field in table
2504
2548
      */
2505
 
      field_ptr= (table->field + (field_ptr - table->s->field));
 
2549
      field_ptr= (table->getFields() + table->getShare()->positionFields(field_ptr));
2506
2550
    }
2507
2551
  }
2508
2552
  else
2509
2553
  {
2510
 
    if (!(field_ptr= table->field))
 
2554
    if (!(field_ptr= table->getFields()))
2511
2555
      return((Field *)0);
2512
2556
    for (; *field_ptr; ++field_ptr)
2513
2557
      if (!my_strcasecmp(system_charset_info, (*field_ptr)->field_name, name))
2516
2560
 
2517
2561
  if (field_ptr && *field_ptr)
2518
2562
  {
2519
 
    *cached_field_index_ptr= field_ptr - table->field;
 
2563
    *cached_field_index_ptr= field_ptr - table->getFields();
2520
2564
    field= *field_ptr;
2521
2565
  }
2522
2566
  else
2523
2567
  {
2524
2568
    if (!allow_rowid ||
2525
2569
        my_strcasecmp(system_charset_info, name, "_rowid") ||
2526
 
        table->s->rowid_field_offset == 0)
 
2570
        table->getShare()->rowid_field_offset == 0)
2527
2571
      return((Field*) 0);
2528
 
    field= table->field[table->s->rowid_field_offset-1];
 
2572
    field= table->getField(table->getShare()->rowid_field_offset-1);
2529
2573
  }
2530
2574
 
2531
2575
  update_field_dependencies(session, field, table);
2604
2648
    inside the view, but we want to search directly in the view columns
2605
2649
    which are represented as a 'field_translation'.
2606
2650
 
2607
 
TODO: Ensure that table_name, db_name and tables->db always points to
2608
 
something !
 
2651
    TODO-> Ensure that table_name, db_name and tables->db always points to something !
2609
2652
  */
2610
2653
  if (/* Exclude nested joins. */
2611
 
      (!table_list->nested_join) &&
 
2654
      (!table_list->getNestedJoin()) &&
2612
2655
      /* Include merge views and information schema tables. */
2613
2656
      /*
2614
2657
        Test if the field qualifiers match the table reference we plan
2622
2665
 
2623
2666
  *actual_table= NULL;
2624
2667
 
2625
 
  if (!table_list->nested_join)
 
2668
  if (!table_list->getNestedJoin())
2626
2669
  {
2627
2670
    /* 'table_list' is a stored table. */
2628
2671
    assert(table_list->table);
2642
2685
    */
2643
2686
    if (table_name && table_name[0])
2644
2687
    {
2645
 
      List_iterator<TableList> it(table_list->nested_join->join_list);
 
2688
      List_iterator<TableList> it(table_list->getNestedJoin()->join_list);
2646
2689
      TableList *table;
2647
2690
      while ((table= it++))
2648
2691
      {
2690
2733
        field_to_set= fld;
2691
2734
      if (field_to_set)
2692
2735
      {
2693
 
        Table *table= field_to_set->table;
 
2736
        Table *table= field_to_set->getTable();
2694
2737
        if (session->mark_used_columns == MARK_COLUMNS_READ)
2695
2738
          table->setReadSet(field_to_set->field_index);
2696
2739
        else
2936
2979
 
2937
2980
 
2938
2981
Item **
2939
 
find_item_in_list(Item *find, List<Item> &items, uint32_t *counter,
 
2982
find_item_in_list(Session *session,
 
2983
                  Item *find, List<Item> &items, uint32_t *counter,
2940
2984
                  find_item_error_report_type report_error,
2941
2985
                  enum_resolution_type *resolution)
2942
2986
{
3016
3060
            */
3017
3061
            if (report_error != IGNORE_ERRORS)
3018
3062
              my_error(ER_NON_UNIQ_ERROR, MYF(0),
3019
 
                       find->full_name(), current_session->where);
 
3063
                       find->full_name(), session->where);
3020
3064
            return (Item**) 0;
3021
3065
          }
3022
3066
          found_unaliased= li.ref();
3047
3091
              continue;                           // Same field twice
3048
3092
            if (report_error != IGNORE_ERRORS)
3049
3093
              my_error(ER_NON_UNIQ_ERROR, MYF(0),
3050
 
                       find->full_name(), current_session->where);
 
3094
                       find->full_name(), session->where);
3051
3095
            return (Item**) 0;
3052
3096
          }
3053
3097
          found= li.ref();
3099
3143
    {
3100
3144
      if (report_error != IGNORE_ERRORS)
3101
3145
        my_error(ER_NON_UNIQ_ERROR, MYF(0),
3102
 
                 find->full_name(), current_session->where);
 
3146
                 find->full_name(), session->where);
3103
3147
      return (Item **) 0;
3104
3148
    }
3105
3149
    if (found_unaliased)
3115
3159
  {
3116
3160
    if (report_error == REPORT_ALL_ERRORS)
3117
3161
      my_error(ER_BAD_FIELD_ERROR, MYF(0),
3118
 
               find->full_name(), current_session->where);
 
3162
               find->full_name(), session->where);
3119
3163
    return (Item **) 0;
3120
3164
  }
3121
3165
  else
3233
3277
    Leaf table references to which new natural join columns are added
3234
3278
    if the leaves are != NULL.
3235
3279
  */
3236
 
  TableList *leaf_1= (table_ref_1->nested_join &&
3237
 
                      !table_ref_1->is_natural_join) ?
 
3280
  TableList *leaf_1= (table_ref_1->getNestedJoin() &&
 
3281
                      ! table_ref_1->is_natural_join) ?
3238
3282
    NULL : table_ref_1;
3239
 
  TableList *leaf_2= (table_ref_2->nested_join &&
3240
 
                      !table_ref_2->is_natural_join) ?
 
3283
  TableList *leaf_2= (table_ref_2->getNestedJoin() &&
 
3284
                      ! table_ref_2->is_natural_join) ?
3241
3285
    NULL : table_ref_2;
3242
3286
 
3243
3287
  *found_using_fields= 0;
3436
3480
*/
3437
3481
 
3438
3482
static bool
3439
 
store_natural_using_join_columns(Session *,
 
3483
store_natural_using_join_columns(Session *session,
3440
3484
                                 TableList *natural_using_join,
3441
3485
                                 TableList *table_ref_1,
3442
3486
                                 TableList *table_ref_2,
3490
3534
        if (!(common_field= it++))
3491
3535
        {
3492
3536
          my_error(ER_BAD_FIELD_ERROR, MYF(0), using_field_name_ptr,
3493
 
                   current_session->where);
 
3537
                   session->where);
3494
3538
          goto err;
3495
3539
        }
3496
3540
        if (!my_strcasecmp(system_charset_info,
3562
3606
  bool result= true;
3563
3607
 
3564
3608
  /* Call the procedure recursively for each nested table reference. */
3565
 
  if (table_ref->nested_join)
 
3609
  if (table_ref->getNestedJoin())
3566
3610
  {
3567
 
    List_iterator_fast<TableList> nested_it(table_ref->nested_join->join_list);
 
3611
    List_iterator_fast<TableList> nested_it(table_ref->getNestedJoin()->join_list);
3568
3612
    TableList *same_level_left_neighbor= nested_it++;
3569
3613
    TableList *same_level_right_neighbor= NULL;
3570
3614
    /* Left/right-most neighbors, possibly at higher levels in the join tree. */
3589
3633
          cur_table_ref->outer_join & JOIN_TYPE_RIGHT)
3590
3634
      {
3591
3635
        /* This can happen only for JOIN ... ON. */
3592
 
        assert(table_ref->nested_join->join_list.elements == 2);
 
3636
        assert(table_ref->getNestedJoin()->join_list.elements == 2);
3593
3637
        std::swap(same_level_left_neighbor, cur_table_ref);
3594
3638
      }
3595
3639
 
3602
3646
      real_right_neighbor= (same_level_right_neighbor) ?
3603
3647
        same_level_right_neighbor : right_neighbor;
3604
3648
 
3605
 
      if (cur_table_ref->nested_join &&
 
3649
      if (cur_table_ref->getNestedJoin() &&
3606
3650
          store_top_level_join_columns(session, cur_table_ref,
3607
3651
                                       real_left_neighbor, real_right_neighbor))
3608
3652
        goto err;
3616
3660
  */
3617
3661
  if (table_ref->is_natural_join)
3618
3662
  {
3619
 
    assert(table_ref->nested_join &&
3620
 
           table_ref->nested_join->join_list.elements == 2);
3621
 
    List_iterator_fast<TableList> operand_it(table_ref->nested_join->join_list);
 
3663
    assert(table_ref->getNestedJoin() &&
 
3664
           table_ref->getNestedJoin()->join_list.elements == 2);
 
3665
    List_iterator_fast<TableList> operand_it(table_ref->getNestedJoin()->join_list);
3622
3666
    /*
3623
3667
      Notice that the order of join operands depends on whether table_ref
3624
3668
      represents a LEFT or a RIGHT join. In a RIGHT join, the operands are
4120
4164
      if ((field= field_iterator.field()))
4121
4165
      {
4122
4166
        /* Mark fields as used to allow storage engine to optimze access */
4123
 
        field->table->setReadSet(field->field_index);
 
4167
        field->getTable()->setReadSet(field->field_index);
4124
4168
        if (table)
4125
4169
        {
4126
4170
          table->covering_keys&= field->part_of_key;
4158
4202
      For NATURAL joins, used_tables is updated in the IF above.
4159
4203
    */
4160
4204
    if (table)
4161
 
      table->used_fields= table->s->fields;
 
4205
      table->used_fields= table->getShare()->sizeFields();
4162
4206
  }
4163
4207
  if (found)
4164
4208
    return false;
4248
4292
          goto err_no_arena;
4249
4293
        select_lex->cond_count++;
4250
4294
      }
4251
 
      embedding= embedded->embedding;
 
4295
      embedding= embedded->getEmbedding();
4252
4296
    }
4253
4297
    while (embedding &&
4254
 
           embedding->nested_join->join_list.head() == embedded);
 
4298
           embedding->getNestedJoin()->join_list.head() == embedded);
4255
4299
 
4256
4300
  }
4257
4301
  session->session_marker= save_session_marker;
4310
4354
      thus we safely can take table from the first field.
4311
4355
    */
4312
4356
    field= static_cast<Item_field *>(f++);
4313
 
    table= field->field->table;
 
4357
    table= field->field->getTable();
4314
4358
    table->auto_increment_field_not_null= false;
4315
4359
    f.rewind();
4316
4360
  }
4320
4364
    value= v++;
4321
4365
 
4322
4366
    Field *rfield= field->field;
4323
 
    table= rfield->table;
 
4367
    table= rfield->getTable();
4324
4368
 
4325
4369
    if (rfield == table->next_number_field)
4326
4370
      table->auto_increment_field_not_null= true;
4377
4421
      On INSERT or UPDATE fields are checked to be from the same table,
4378
4422
      thus we safely can take table from the first field.
4379
4423
    */
4380
 
    table= (*ptr)->table;
 
4424
    table= (*ptr)->getTable();
4381
4425
    table->auto_increment_field_not_null= false;
4382
4426
  }
4383
4427
  while ((field = *ptr++) && ! session->is_error())
4384
4428
  {
4385
4429
    value=v++;
4386
 
    table= field->table;
 
4430
    table= field->getTable();
4387
4431
    if (field == table->next_number_field)
4388
4432
      table->auto_increment_field_not_null= true;
4389
4433
    if (value->save_in_field(field, 0) < 0)
4404
4448
{
4405
4449
  Session *session;
4406
4450
 
4407
 
  assert(drizzle_tmpdir);
 
4451
  assert(drizzle_tmpdir.size());
4408
4452
 
4409
4453
  if (!(session= new Session(plugin::Listen::getNullClient())))
4410
4454
    return true;
4411
4455
  session->thread_stack= (char*) &session;
4412
4456
  session->storeGlobals();
4413
4457
 
4414
 
  plugin::StorageEngine::removeLostTemporaryTables(*session, drizzle_tmpdir);
 
4458
  plugin::StorageEngine::removeLostTemporaryTables(*session, drizzle_tmpdir.c_str());
4415
4459
 
 
4460
  session->lockForDelete();
4416
4461
  delete session;
4417
4462
 
4418
4463
  return false;
4437
4482
and afterwards delete those marked unused.
4438
4483
*/
4439
4484
 
4440
 
void remove_db_from_cache(SchemaIdentifier &schema_identifier)
 
4485
void remove_db_from_cache(const SchemaIdentifier &schema_identifier)
4441
4486
{
4442
 
  safe_mutex_assert_owner(&LOCK_open);
 
4487
  safe_mutex_assert_owner(LOCK_open.native_handle());
4443
4488
 
4444
 
  for (uint32_t idx=0 ; idx < open_cache.records ; idx++)
 
4489
  for (TableOpenCache::const_iterator iter= get_open_cache().begin();
 
4490
       iter != get_open_cache().end();
 
4491
       iter++)
4445
4492
  {
4446
 
    Table *table=(Table*) hash_element(&open_cache,idx);
4447
 
    if (not schema_identifier.getPath().compare(table->s->getSchemaName()))
 
4493
    Table *table= (*iter).second;
 
4494
 
 
4495
    if (not schema_identifier.getPath().compare(table->getMutableShare()->getSchemaName()))
4448
4496
    {
4449
 
      table->s->version= 0L;                    /* Free when thread is ready */
 
4497
      table->getMutableShare()->resetVersion();                 /* Free when thread is ready */
4450
4498
      if (not table->in_use)
4451
 
        relink_unused(table);
 
4499
        unused_tables.relink(table);
4452
4500
    }
4453
4501
  }
4454
 
  while (unused_tables && !unused_tables->s->version)
4455
 
    hash_delete(&open_cache,(unsigned char*) unused_tables);
 
4502
 
 
4503
  unused_tables.cullByVersion();
4456
4504
}
4457
4505
 
4458
4506
 
4471
4519
  1  Table is in use by another thread
4472
4520
*/
4473
4521
 
4474
 
bool remove_table_from_cache(Session *session, const char *db, const char *table_name,
4475
 
                             uint32_t flags)
 
4522
bool remove_table_from_cache(Session *session, TableIdentifier &identifier, uint32_t flags)
4476
4523
{
4477
 
  char key[MAX_DBKEY_LENGTH];
4478
 
  char *key_pos= key;
4479
 
  uint32_t key_length;
4480
 
  Table *table;
 
4524
  const TableIdentifier::Key &key(identifier.getKey());
4481
4525
  bool result= false; 
4482
4526
  bool signalled= false;
4483
4527
 
4484
 
  key_pos= strcpy(key_pos, db) + strlen(db);
4485
 
  key_pos= strcpy(key_pos+1, table_name) + strlen(table_name);
4486
 
  key_length= (uint32_t) (key_pos-key)+1;
4487
 
 
4488
4528
  for (;;)
4489
4529
  {
4490
 
    HASH_SEARCH_STATE state;
4491
4530
    result= signalled= false;
4492
4531
 
4493
 
    for (table= (Table*) hash_first(&open_cache, (unsigned char*) key, key_length,
4494
 
                                    &state);
4495
 
         table;
4496
 
         table= (Table*) hash_next(&open_cache, (unsigned char*) key, key_length,
4497
 
                                   &state))
 
4532
    TableOpenCacheRange ppp;
 
4533
    ppp= get_open_cache().equal_range(key);
 
4534
 
 
4535
    for (TableOpenCache::const_iterator iter= ppp.first;
 
4536
         iter != ppp.second; ++iter)
4498
4537
    {
 
4538
      Table *table= (*iter).second;
4499
4539
      Session *in_use;
4500
4540
 
4501
 
      table->s->version=0L;             /* Free when thread is ready */
 
4541
      table->getMutableShare()->resetVersion();         /* Free when thread is ready */
4502
4542
      if (!(in_use=table->in_use))
4503
4543
      {
4504
 
        relink_unused(table);
 
4544
        unused_tables.relink(table);
4505
4545
      }
4506
4546
      else if (in_use != session)
4507
4547
      {
4526
4566
        */
4527
4567
        for (Table *session_table= in_use->open_tables;
4528
4568
             session_table ;
4529
 
             session_table= session_table->next)
 
4569
             session_table= session_table->getNext())
4530
4570
        {
4531
4571
          /* Do not handle locks of MERGE children. */
4532
4572
          if (session_table->db_stat)   // If table is open
4536
4576
      else
4537
4577
        result= result || (flags & RTFC_OWNED_BY_Session_FLAG);
4538
4578
    }
4539
 
    while (unused_tables && !unused_tables->s->version)
4540
 
      hash_delete(&open_cache,(unsigned char*) unused_tables);
 
4579
 
 
4580
    unused_tables.cullByVersion();
4541
4581
 
4542
4582
    /* Remove table from table definition cache if it's not in use */
4543
 
    TableShare::release(key, key_length);
 
4583
    TableShare::release(identifier);
4544
4584
 
4545
4585
    if (result && (flags & RTFC_WAIT_OTHER_THREAD_FLAG))
4546
4586
    {
4553
4593
      {
4554
4594
        dropping_tables++;
4555
4595
        if (likely(signalled))
4556
 
          (void) pthread_cond_wait(&COND_refresh, &LOCK_open);
 
4596
          (void) pthread_cond_wait(COND_refresh.native_handle(), LOCK_open.native_handle());
4557
4597
        else
4558
4598
        {
4559
4599
          struct timespec abstime;
4568
4608
            remove_table_from_cache routine.
4569
4609
          */
4570
4610
          set_timespec(abstime, 10);
4571
 
          pthread_cond_timedwait(&COND_refresh, &LOCK_open, &abstime);
 
4611
          pthread_cond_timedwait(COND_refresh.native_handle(), LOCK_open.native_handle(), &abstime);
4572
4612
        }
4573
4613
        dropping_tables--;
4574
4614
        continue;
4576
4616
    }
4577
4617
    break;
4578
4618
  }
 
4619
 
4579
4620
  return result;
4580
4621
}
4581
4622