~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/sql_base.cc

  • Committer: Brian Aker
  • Date: 2008-07-15 06:45:16 UTC
  • Revision ID: brian@tangent.org-20080715064516-fnbq7kowh7w57bxj
Merge Monty's code.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 
16
16
 
17
17
/* Basic functions needed by many modules */
18
 
#include <drizzled/server_includes.h>
19
 
#include <drizzled/sql_select.h>
20
 
#include <mysys/my_dir.h>
21
 
#include <drizzled/drizzled_error_messages.h>
22
 
#include <libdrizzle/gettext.h>
23
18
 
24
 
#if TIME_WITH_SYS_TIME
25
 
# include <sys/time.h>
26
 
# include <time.h>
27
 
#else
28
 
# if HAVE_SYS_TIME_H
29
 
#  include <sys/time.h>
30
 
# else
31
 
#  include <time.h>
32
 
# endif
33
 
#endif
 
19
#include "mysql_priv.h"
 
20
#include "sql_select.h"
 
21
#include <m_ctype.h>
 
22
#include <my_dir.h>
 
23
#include <hash.h>
34
24
 
35
25
#define FLAGSTR(S,F) ((S) & (F) ? #F " " : "")
36
26
 
37
27
/**
38
 
  return true if the table was created explicitly.
39
 
*/
40
 
inline bool is_user_table(Table * table)
41
 
{
42
 
  const char *name= table->s->table_name.str;
43
 
  return strncmp(name, tmp_file_prefix, tmp_file_prefix_length);
44
 
}
45
 
 
46
 
 
47
 
/**
48
28
  @defgroup Data_Dictionary Data Dictionary
49
29
  @{
50
30
*/
51
 
Table *unused_tables;                           /* Used by mysql_test */
 
31
TABLE *unused_tables;                           /* Used by mysql_test */
52
32
HASH open_cache;                                /* Used by mysql_test */
53
33
static HASH table_def_cache;
54
34
static TABLE_SHARE *oldest_unused_share, end_of_unused_share;
55
35
static pthread_mutex_t LOCK_table_share;
56
36
static bool table_def_inited= 0;
57
37
 
58
 
static int open_unireg_entry(THD *thd, Table *entry, TableList *table_list,
59
 
                             const char *alias,
60
 
                             char *cache_key, uint32_t cache_key_length);
61
 
static void free_cache_entry(Table *entry);
62
 
static void close_old_data_files(THD *thd, Table *table, bool morph_locks,
 
38
static int open_unireg_entry(THD *thd, TABLE *entry, TABLE_LIST *table_list,
 
39
                             const char *alias,
 
40
                             char *cache_key, uint cache_key_length,
 
41
                             MEM_ROOT *mem_root, uint flags);
 
42
static void free_cache_entry(TABLE *entry);
 
43
static void close_old_data_files(THD *thd, TABLE *table, bool morph_locks,
63
44
                                 bool send_refresh);
64
45
 
65
46
 
66
 
extern "C" unsigned char *table_cache_key(const unsigned char *record, size_t *length,
 
47
extern "C" uchar *table_cache_key(const uchar *record, size_t *length,
67
48
                                  bool not_used __attribute__((unused)))
68
49
{
69
 
  Table *entry=(Table*) record;
 
50
  TABLE *entry=(TABLE*) record;
70
51
  *length= entry->s->table_cache_key.length;
71
 
  return (unsigned char*) entry->s->table_cache_key.str;
 
52
  return (uchar*) entry->s->table_cache_key.str;
72
53
}
73
54
 
74
55
 
76
57
{
77
58
  return hash_init(&open_cache, &my_charset_bin, table_cache_size+16,
78
59
                   0, 0, table_cache_key,
79
 
                   (hash_free_key) free_cache_entry, 0);
 
60
                   (hash_free_key) free_cache_entry, 0) != 0;
80
61
}
81
62
 
82
63
void table_cache_free(void)
90
71
  return;
91
72
}
92
73
 
93
 
uint32_t cached_open_tables(void)
 
74
uint cached_open_tables(void)
94
75
{
95
76
  return open_cache.records;
96
77
}
120
101
    Length of key
121
102
*/
122
103
 
123
 
uint32_t create_table_def_key(THD *thd, char *key, TableList *table_list,
 
104
uint create_table_def_key(THD *thd, char *key, TABLE_LIST *table_list,
124
105
                          bool tmp_table)
125
106
{
126
 
  uint32_t key_length= (uint) (my_stpcpy(my_stpcpy(key, table_list->db)+1,
 
107
  uint key_length= (uint) (strmov(strmov(key, table_list->db)+1,
127
108
                                  table_list->table_name)-key)+1;
128
109
  if (tmp_table)
129
110
  {
140
121
  Functions to handle table definition cach (TABLE_SHARE)
141
122
*****************************************************************************/
142
123
 
143
 
extern "C" unsigned char *table_def_key(const unsigned char *record, size_t *length,
 
124
extern "C" uchar *table_def_key(const uchar *record, size_t *length,
144
125
                                bool not_used __attribute__((unused)))
145
126
{
146
127
  TABLE_SHARE *entry=(TABLE_SHARE*) record;
147
128
  *length= entry->table_cache_key.length;
148
 
  return (unsigned char*) entry->table_cache_key.str;
 
129
  return (uchar*) entry->table_cache_key.str;
149
130
}
150
131
 
151
132
 
173
154
 
174
155
  return hash_init(&table_def_cache, &my_charset_bin, table_def_size,
175
156
                   0, 0, table_def_key,
176
 
                   (hash_free_key) table_def_free_entry, 0);
 
157
                   (hash_free_key) table_def_free_entry, 0) != 0;
177
158
}
178
159
 
179
160
 
189
170
}
190
171
 
191
172
 
192
 
uint32_t cached_table_definitions(void)
 
173
uint cached_table_definitions(void)
193
174
{
194
175
  return table_def_cache.records;
195
176
}
220
201
   #  Share for table
221
202
*/
222
203
 
223
 
TABLE_SHARE *get_table_share(THD *thd, TableList *table_list, char *key,
224
 
                             uint32_t key_length, uint32_t db_flags, int *error)
 
204
TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key,
 
205
                             uint key_length, uint db_flags, int *error)
225
206
{
226
207
  TABLE_SHARE *share;
227
208
 
228
209
  *error= 0;
229
210
 
230
211
  /* Read table definition from cache */
231
 
  if ((share= (TABLE_SHARE*) hash_search(&table_def_cache,(unsigned char*) key,
 
212
  if ((share= (TABLE_SHARE*) hash_search(&table_def_cache,(uchar*) key,
232
213
                                         key_length)))
233
214
    goto found;
234
215
 
258
239
   */
259
240
  assign_new_table_id(share);
260
241
 
261
 
  if (my_hash_insert(&table_def_cache, (unsigned char*) share))
 
242
  if (my_hash_insert(&table_def_cache, (uchar*) share))
262
243
  {
263
244
    free_table_share(share);
264
245
    return(0);                          // return error
266
247
  if (open_table_def(thd, share, db_flags))
267
248
  {
268
249
    *error= share->error;
269
 
    (void) hash_delete(&table_def_cache, (unsigned char*) share);
 
250
    (void) hash_delete(&table_def_cache, (uchar*) share);
270
251
    return(0);
271
252
  }
272
253
  share->ref_count++;                           // Mark in use
309
290
         oldest_unused_share->next)
310
291
  {
311
292
    pthread_mutex_lock(&oldest_unused_share->mutex);
312
 
    hash_delete(&table_def_cache, (unsigned char*) oldest_unused_share);
 
293
    VOID(hash_delete(&table_def_cache, (uchar*) oldest_unused_share));
313
294
  }
314
295
 
315
296
  return(share);
323
304
*/
324
305
 
325
306
static TABLE_SHARE
326
 
*get_table_share_with_create(THD *thd, TableList *table_list,
327
 
                             char *key, uint32_t key_length,
328
 
                             uint32_t db_flags, int *error)
 
307
*get_table_share_with_create(THD *thd, TABLE_LIST *table_list,
 
308
                             char *key, uint key_length,
 
309
                             uint db_flags, int *error)
329
310
{
330
311
  TABLE_SHARE *share;
331
312
  int tmp;
348
329
    Finally, if share is still NULL, it's a real error and we need
349
330
    to abort.
350
331
 
351
 
    @todo Rework alternative ways to deal with ER_NO_SUCH Table.
 
332
    @todo Rework alternative ways to deal with ER_NO_SUCH TABLE.
352
333
  */
353
334
  if (share || (thd->is_error() && (thd->main_da.sql_errno() != ER_NO_SUCH_TABLE)))
354
335
 
357
338
  /* Table didn't exist. Check if some engine can provide it */
358
339
  if ((tmp= ha_create_table_from_engine(thd, table_list->db,
359
340
                                        table_list->table_name)) < 0)
 
341
  {
 
342
    /*
 
343
      No such table in any engine.
 
344
      Hide "Table doesn't exist" errors if the table belongs to a view.
 
345
      The check for thd->is_error() is necessary to not push an
 
346
      unwanted error in case of pre-locking, which silences
 
347
      "no such table" errors.
 
348
      @todo Rework the alternative ways to deal with ER_NO_SUCH TABLE.
 
349
    */
 
350
    if (thd->is_error() && table_list->belong_to_view)
 
351
    {
 
352
      thd->clear_error();
 
353
      my_error(ER_VIEW_INVALID, MYF(0), "", "");
 
354
    }
360
355
    return(0);
361
 
 
 
356
  }
362
357
  if (tmp)
363
358
  {
364
359
    /* Give right error message */
370
365
    return(0);
371
366
  }
372
367
  /* Table existed in engine. Let's open it */
373
 
  drizzle_reset_errors(thd, 1);                   // Clear warnings
 
368
  mysql_reset_errors(thd, 1);                   // Clear warnings
374
369
  thd->clear_error();                           // Clear error message
375
370
  return(get_table_share(thd, table_list, key, key_length,
376
371
                              db_flags, error));
399
394
*/
400
395
 
401
396
void release_table_share(TABLE_SHARE *share,
402
 
                         enum release_type type __attribute__((unused)))
 
397
                         enum release_type type __attribute__((__unused__)))
403
398
{
404
399
  bool to_be_deleted= 0;
405
400
 
427
422
 
428
423
  if (to_be_deleted)
429
424
  {
430
 
    hash_delete(&table_def_cache, (unsigned char*) share);
 
425
    hash_delete(&table_def_cache, (uchar*) share);
431
426
    return;
432
427
  }
433
428
  pthread_mutex_unlock(&share->mutex);
451
446
TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name)
452
447
{
453
448
  char key[NAME_LEN*2+2];
454
 
  TableList table_list;
455
 
  uint32_t key_length;
 
449
  TABLE_LIST table_list;
 
450
  uint key_length;
456
451
  safe_mutex_assert_owner(&LOCK_open);
457
452
 
458
453
  table_list.db= (char*) db;
459
454
  table_list.table_name= (char*) table_name;
460
455
  key_length= create_table_def_key((THD*) 0, key, &table_list, 0);
461
 
  return (TABLE_SHARE*) hash_search(&table_def_cache,(unsigned char*) key, key_length);
 
456
  return (TABLE_SHARE*) hash_search(&table_def_cache,(uchar*) key, key_length);
462
457
}  
463
458
 
464
459
 
480
475
*/
481
476
 
482
477
 
483
 
void close_handle_and_leave_table_as_lock(Table *table)
 
478
void close_handle_and_leave_table_as_lock(TABLE *table)
484
479
{
485
480
  TABLE_SHARE *share, *old_share= table->s;
486
481
  char *key_buff;
498
493
                       &key_buff, old_share->table_cache_key.length,
499
494
                       NULL))
500
495
  {
501
 
    memset(share, 0, sizeof(*share));
 
496
    bzero((char*) share, sizeof(*share));
502
497
    share->set_table_cache_key(key_buff, old_share->table_cache_key.str,
503
498
                               old_share->table_cache_key.length);
504
499
    share->tmp_table= INTERNAL_TMP_TABLE;       // for intern_close_table()
533
528
    #           Pointer to list of names of open tables.
534
529
*/
535
530
 
536
 
OPEN_TableList *list_open_tables(THD *thd __attribute__((unused)),
 
531
OPEN_TABLE_LIST *list_open_tables(THD *thd __attribute__((__unused__)),
537
532
                                  const char *db, const char *wild)
538
533
{
539
534
  int result = 0;
540
 
  OPEN_TableList **start_list, *open_list;
541
 
  TableList table_list;
 
535
  OPEN_TABLE_LIST **start_list, *open_list;
 
536
  TABLE_LIST table_list;
542
537
 
543
 
  pthread_mutex_lock(&LOCK_open);
544
 
  memset(&table_list, 0, sizeof(table_list));
 
538
  VOID(pthread_mutex_lock(&LOCK_open));
 
539
  bzero((char*) &table_list,sizeof(table_list));
545
540
  start_list= &open_list;
546
541
  open_list=0;
547
542
 
548
 
  for (uint32_t idx=0 ; result == 0 && idx < open_cache.records; idx++)
 
543
  for (uint idx=0 ; result == 0 && idx < open_cache.records; idx++)
549
544
  {
550
 
    OPEN_TableList *table;
551
 
    Table *entry=(Table*) hash_element(&open_cache,idx);
 
545
    OPEN_TABLE_LIST *table;
 
546
    TABLE *entry=(TABLE*) hash_element(&open_cache,idx);
552
547
    TABLE_SHARE *share= entry->s;
553
548
 
554
549
    if (db && my_strcasecmp(system_charset_info, db, share->db.str))
575
570
    }
576
571
    if (table)
577
572
      continue;
578
 
    if (!(*start_list = (OPEN_TableList *)
 
573
    if (!(*start_list = (OPEN_TABLE_LIST *)
579
574
          sql_alloc(sizeof(**start_list)+share->table_cache_key.length)))
580
575
    {
581
576
      open_list=0;                              // Out of memory
582
577
      break;
583
578
    }
584
 
    my_stpcpy((*start_list)->table=
585
 
           my_stpcpy(((*start_list)->db= (char*) ((*start_list)+1)),
 
579
    strmov((*start_list)->table=
 
580
           strmov(((*start_list)->db= (char*) ((*start_list)+1)),
586
581
                  share->db.str)+1,
587
582
           share->table_name.str);
588
583
    (*start_list)->in_use= entry->in_use ? 1 : 0;
590
585
    start_list= &(*start_list)->next;
591
586
    *start_list=0;
592
587
  }
593
 
  pthread_mutex_unlock(&LOCK_open);
 
588
  VOID(pthread_mutex_unlock(&LOCK_open));
594
589
  return(open_list);
595
590
}
596
591
 
599
594
 ****************************************************************************/
600
595
 
601
596
 
602
 
void intern_close_table(Table *table)
 
597
void intern_close_table(TABLE *table)
603
598
{                                               // Free all structures
604
599
  free_io_cache(table);
605
600
  if (table->file)                              // Not true if name lock
606
 
    closefrm(table, 1);                 // close file
 
601
    VOID(closefrm(table, 1));                   // close file
607
602
  return;
608
603
}
609
604
 
618
613
    We need to have a lock on LOCK_open when calling this
619
614
*/
620
615
 
621
 
static void free_cache_entry(Table *table)
 
616
static void free_cache_entry(TABLE *table)
622
617
{
623
618
  intern_close_table(table);
624
619
  if (!table->in_use)
632
627
        unused_tables=0;
633
628
    }
634
629
  }
635
 
  free((unsigned char*) table);
 
630
  my_free((uchar*) table,MYF(0));
636
631
  return;
637
632
}
638
633
 
639
634
/* Free resources allocated by filesort() and read_record() */
640
635
 
641
 
void free_io_cache(Table *table)
 
636
void free_io_cache(TABLE *table)
642
637
{
643
638
  if (table->sort.io_cache)
644
639
  {
645
640
    close_cached_file(table->sort.io_cache);
646
 
    free((unsigned char*) table->sort.io_cache);
 
641
    my_free((uchar*) table->sort.io_cache,MYF(0));
647
642
    table->sort.io_cache=0;
648
643
  }
649
644
  return;
665
660
          and tables must be NULL.
666
661
*/
667
662
 
668
 
bool close_cached_tables(THD *thd, TableList *tables, bool have_lock,
 
663
bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock,
669
664
                         bool wait_for_refresh, bool wait_for_placeholders)
670
665
{
671
666
  bool result=0;
672
667
  assert(thd || (!wait_for_refresh && !tables));
673
668
 
674
669
  if (!have_lock)
675
 
    pthread_mutex_lock(&LOCK_open);
 
670
    VOID(pthread_mutex_lock(&LOCK_open));
676
671
  if (!tables)
677
672
  {
678
673
    refresh_version++;                          // Force close of open tables
679
674
    while (unused_tables)
680
675
    {
681
676
#ifdef EXTRA_DEBUG
682
 
      if (hash_delete(&open_cache,(unsigned char*) unused_tables))
 
677
      if (hash_delete(&open_cache,(uchar*) unused_tables))
683
678
        printf("Warning: Couldn't delete open table from hash\n");
684
679
#else
685
 
      hash_delete(&open_cache,(unsigned char*) unused_tables);
 
680
      VOID(hash_delete(&open_cache,(uchar*) unused_tables));
686
681
#endif
687
682
    }
688
683
    /* Free table shares */
689
684
    while (oldest_unused_share->next)
690
685
    {
691
686
      pthread_mutex_lock(&oldest_unused_share->mutex);
692
 
      hash_delete(&table_def_cache, (unsigned char*) oldest_unused_share);
 
687
      VOID(hash_delete(&table_def_cache, (uchar*) oldest_unused_share));
693
688
    }
694
689
    if (wait_for_refresh)
695
690
    {
730
725
        after the call to close_old_data_files() i.e. after removal of
731
726
        current thread locks.
732
727
      */
733
 
      for (uint32_t idx=0 ; idx < open_cache.records ; idx++)
 
728
      for (uint idx=0 ; idx < open_cache.records ; idx++)
734
729
      {
735
 
        Table *table=(Table*) hash_element(&open_cache,idx);
 
730
        TABLE *table=(TABLE*) hash_element(&open_cache,idx);
736
731
        if (table->in_use)
737
732
          table->in_use->some_tables_deleted= 1;
738
733
      }
741
736
  else
742
737
  {
743
738
    bool found=0;
744
 
    for (TableList *table= tables; table; table= table->next_local)
 
739
    for (TABLE_LIST *table= tables; table; table= table->next_local)
745
740
    {
746
741
      if (remove_table_from_cache(thd, table->db, table->table_name,
747
742
                                  RTFC_OWNED_BY_THD_FLAG))
759
754
    */
760
755
    thd->mysys_var->current_mutex= &LOCK_open;
761
756
    thd->mysys_var->current_cond= &COND_refresh;
762
 
    thd->set_proc_info("Flushing tables");
 
757
    thd_proc_info(thd, "Flushing tables");
763
758
 
764
759
    close_old_data_files(thd,thd->open_tables,1,1);
765
760
    mysql_ha_flush(thd);
769
764
    while (found && ! thd->killed)
770
765
    {
771
766
      found=0;
772
 
      for (uint32_t idx=0 ; idx < open_cache.records ; idx++)
 
767
      for (uint idx=0 ; idx < open_cache.records ; idx++)
773
768
      {
774
 
        Table *table=(Table*) hash_element(&open_cache,idx);
 
769
        TABLE *table=(TABLE*) hash_element(&open_cache,idx);
775
770
        /* Avoid a self-deadlock. */
776
771
        if (table->in_use == thd)
777
772
          continue;
778
773
        /*
779
774
          Note that we wait here only for tables which are actually open, and
780
 
          not for placeholders with Table::open_placeholder set. Waiting for
 
775
          not for placeholders with TABLE::open_placeholder set. Waiting for
781
776
          latter will cause deadlock in the following scenario, for example:
782
777
 
783
778
          conn1: lock table t1 write;
807
802
    result=reopen_tables(thd,1,1);
808
803
    thd->in_lock_tables=0;
809
804
    /* Set version for table */
810
 
    for (Table *table=thd->open_tables; table ; table= table->next)
 
805
    for (TABLE *table=thd->open_tables; table ; table= table->next)
811
806
    {
812
807
      /*
813
808
        Preserve the version (0) of write locked tables so that a impending
818
813
    }
819
814
  }
820
815
  if (!have_lock)
821
 
    pthread_mutex_unlock(&LOCK_open);
 
816
    VOID(pthread_mutex_unlock(&LOCK_open));
822
817
  if (wait_for_refresh)
823
818
  {
824
819
    pthread_mutex_lock(&thd->mysys_var->mutex);
825
820
    thd->mysys_var->current_mutex= 0;
826
821
    thd->mysys_var->current_cond= 0;
827
 
    thd->set_proc_info(0);
 
822
    thd_proc_info(thd, 0);
828
823
    pthread_mutex_unlock(&thd->mysys_var->mutex);
829
824
  }
830
825
  return(result);
839
834
bool close_cached_connection_tables(THD *thd, bool if_wait_for_refresh,
840
835
                                    LEX_STRING *connection, bool have_lock)
841
836
{
842
 
  uint32_t idx;
843
 
  TableList tmp, *tables= NULL;
 
837
  uint idx;
 
838
  TABLE_LIST tmp, *tables= NULL;
844
839
  bool result= false;
845
840
  assert(thd);
846
841
 
847
 
  memset(&tmp, 0, sizeof(TableList));
 
842
  bzero(&tmp, sizeof(TABLE_LIST));
848
843
 
849
844
  if (!have_lock)
850
 
    pthread_mutex_lock(&LOCK_open);
 
845
    VOID(pthread_mutex_lock(&LOCK_open));
851
846
 
852
847
  for (idx= 0; idx < table_def_cache.records; idx++)
853
848
  {
872
867
    tmp.table_name= share->table_name.str;
873
868
    tmp.next_local= tables;
874
869
 
875
 
    tables= (TableList *) memdup_root(thd->mem_root, (char*)&tmp, 
876
 
                                       sizeof(TableList));
 
870
    tables= (TABLE_LIST *) memdup_root(thd->mem_root, (char*)&tmp, 
 
871
                                       sizeof(TABLE_LIST));
877
872
  }
878
873
 
879
874
  if (tables)
880
875
    result= close_cached_tables(thd, tables, true, false, false);
881
876
 
882
877
  if (!have_lock)
883
 
    pthread_mutex_unlock(&LOCK_open);
 
878
    VOID(pthread_mutex_unlock(&LOCK_open));
884
879
 
885
880
  if (if_wait_for_refresh)
886
881
  {
887
882
    pthread_mutex_lock(&thd->mysys_var->mutex);
888
883
    thd->mysys_var->current_mutex= 0;
889
884
    thd->mysys_var->current_cond= 0;
890
 
    thd->set_proc_info(0);
 
885
    thd->proc_info=0;
891
886
    pthread_mutex_unlock(&thd->mysys_var->mutex);
892
887
  }
893
888
 
907
902
 
908
903
static void mark_temp_tables_as_free_for_reuse(THD *thd)
909
904
{
910
 
  for (Table *table= thd->temporary_tables ; table ; table= table->next)
 
905
  for (TABLE *table= thd->temporary_tables ; table ; table= table->next)
911
906
  {
912
907
    if ((table->query_id == thd->query_id) && ! table->open_by_handler)
913
908
    {
941
936
    set to query_id of original query.
942
937
*/
943
938
 
944
 
static void mark_used_tables_as_free_for_reuse(THD *thd, Table *table)
 
939
static void mark_used_tables_as_free_for_reuse(THD *thd, TABLE *table)
945
940
{
946
941
  for (; table ; table= table->next)
947
942
  {
968
963
 
969
964
  safe_mutex_assert_not_owner(&LOCK_open);
970
965
 
971
 
  pthread_mutex_lock(&LOCK_open);
 
966
  VOID(pthread_mutex_lock(&LOCK_open));
972
967
 
973
968
  while (thd->open_tables)
974
969
    found_old_table|= close_thread_table(thd, &thd->open_tables);
976
971
 
977
972
  /* Free tables to hold down open files */
978
973
  while (open_cache.records > table_cache_size && unused_tables)
979
 
    hash_delete(&open_cache,(unsigned char*) unused_tables); /* purecov: tested */
 
974
    VOID(hash_delete(&open_cache,(uchar*) unused_tables)); /* purecov: tested */
980
975
  if (found_old_table)
981
976
  {
982
977
    /* Tell threads waiting for refresh that something has happened */
983
978
    broadcast_refresh();
984
979
  }
985
980
 
986
 
  pthread_mutex_unlock(&LOCK_open);
 
981
  VOID(pthread_mutex_unlock(&LOCK_open));
987
982
}
988
983
 
989
984
 
1007
1002
 
1008
1003
void close_thread_tables(THD *thd)
1009
1004
{
1010
 
  Table *table;
 
1005
  TABLE *table;
1011
1006
 
1012
1007
  /*
1013
1008
    We are assuming here that thd->derived_tables contains ONLY derived
1022
1017
  */
1023
1018
  if (thd->derived_tables)
1024
1019
  {
1025
 
    Table *next;
 
1020
    TABLE *next;
1026
1021
    /*
1027
1022
      Close all derived tables generated in queries like
1028
1023
      SELECT * FROM (SELECT * FROM t1)
1030
1025
    for (table= thd->derived_tables ; table ; table= next)
1031
1026
    {
1032
1027
      next= table->next;
1033
 
      table->free_tmp_table(thd);
 
1028
      free_tmp_table(thd, table);
1034
1029
    }
1035
1030
    thd->derived_tables= 0;
1036
1031
  }
1098
1093
 
1099
1094
/* move one table to free list */
1100
1095
 
1101
 
bool close_thread_table(THD *thd, Table **table_ptr)
 
1096
bool close_thread_table(THD *thd, TABLE **table_ptr)
1102
1097
{
1103
1098
  bool found_old_table= 0;
1104
 
  Table *table= *table_ptr;
 
1099
  TABLE *table= *table_ptr;
1105
1100
 
1106
1101
  assert(table->key_read == 0);
1107
1102
  assert(!table->file || table->file->inited == handler::NONE);
1111
1106
  if (table->needs_reopen_or_name_lock() ||
1112
1107
      thd->version != refresh_version || !table->db_stat)
1113
1108
  {
1114
 
    hash_delete(&open_cache,(unsigned char*) table);
 
1109
    VOID(hash_delete(&open_cache,(uchar*) table));
1115
1110
    found_old_table=1;
1116
1111
  }
1117
1112
  else
1118
1113
  {
1119
1114
    /*
1120
 
      Open placeholders have Table::db_stat set to 0, so they should be
 
1115
      Open placeholders have TABLE::db_stat set to 0, so they should be
1121
1116
      handled by the first alternative.
1122
1117
    */
1123
1118
    assert(!table->open_placeholder);
1140
1135
 
1141
1136
 
1142
1137
/* close_temporary_tables' internal, 4 is due to uint4korr definition */
1143
 
static inline uint32_t  tmpkeyval(THD *thd __attribute__((unused)),
1144
 
                              Table *table)
 
1138
static inline uint  tmpkeyval(THD *thd __attribute__((__unused__)),
 
1139
                              TABLE *table)
1145
1140
{
1146
1141
  return uint4korr(table->s->table_cache_key.str + table->s->table_cache_key.length - 4);
1147
1142
}
1149
1144
 
1150
1145
/*
1151
1146
  Close all temporary tables created by 'CREATE TEMPORARY TABLE' for thread
1152
 
  creates one DROP TEMPORARY Table binlog event for each pseudo-thread 
 
1147
  creates one DROP TEMPORARY TABLE binlog event for each pseudo-thread 
1153
1148
*/
1154
1149
 
1155
1150
void close_temporary_tables(THD *thd)
1156
1151
{
1157
 
  Table *table;
1158
 
  Table *next= NULL;
1159
 
  Table *prev_table;
 
1152
  TABLE *table;
 
1153
  TABLE *next= NULL;
 
1154
  TABLE *prev_table;
1160
1155
  /* Assume thd->options has OPTION_QUOTE_SHOW_CREATE */
1161
1156
  bool was_quote_show= true;
1162
1157
 
1165
1160
 
1166
1161
  if (!mysql_bin_log.is_open() || thd->current_stmt_binlog_row_based)
1167
1162
  {
1168
 
    Table *tmp_next;
 
1163
    TABLE *tmp_next;
1169
1164
    for (table= thd->temporary_tables; table; table= tmp_next)
1170
1165
    {
1171
1166
      tmp_next= table->next;
1176
1171
  }
1177
1172
 
1178
1173
  /* Better add "if exists", in case a RESET MASTER has been done */
1179
 
  const char stub[]= "DROP /*!40005 TEMPORARY */ Table IF EXISTS ";
1180
 
  uint32_t stub_len= sizeof(stub) - 1;
 
1174
  const char stub[]= "DROP /*!40005 TEMPORARY */ TABLE IF EXISTS ";
 
1175
  uint stub_len= sizeof(stub) - 1;
1181
1176
  char buf[256];
1182
1177
  String s_query= String(buf, sizeof(buf), system_charset_info);
1183
1178
  bool found_user_tables= false;
1193
1188
       table;
1194
1189
       prev_table= table, table= table->next)
1195
1190
  {
1196
 
    Table *prev_sorted /* same as for prev_table */, *sorted;
 
1191
    TABLE *prev_sorted /* same as for prev_table */, *sorted;
1197
1192
    if (is_user_table(table))
1198
1193
    {
1199
1194
      if (!found_user_tables)
1259
1254
        close_temporary(table, 1, 1);
1260
1255
      }
1261
1256
      thd->clear_error();
1262
 
      const CHARSET_INFO * const cs_save= thd->variables.character_set_client;
 
1257
      CHARSET_INFO *cs_save= thd->variables.character_set_client;
1263
1258
      thd->variables.character_set_client= system_charset_info;
1264
1259
      Query_log_event qinfo(thd, s_query.ptr(),
1265
1260
                            s_query.length() - 1 /* to remove trailing ',' */,
1309
1304
    #           Pointer to found table.
1310
1305
*/
1311
1306
 
1312
 
TableList *find_table_in_list(TableList *table,
1313
 
                               TableList *TableList::*link,
 
1307
TABLE_LIST *find_table_in_list(TABLE_LIST *table,
 
1308
                               TABLE_LIST *TABLE_LIST::*link,
1314
1309
                               const char *db_name,
1315
1310
                               const char *table_name)
1316
1311
{
1349
1344
    Also SELECT::exclude_from_table_unique_test used to exclude from check
1350
1345
    tables of main SELECT of multi-delete and multi-update
1351
1346
 
1352
 
    We also skip tables with TableList::prelocking_placeholder set,
 
1347
    We also skip tables with TABLE_LIST::prelocking_placeholder set,
1353
1348
    because we want to allow SELECTs from them, and their modification
1354
1349
    will rise the error anyway.
1355
1350
 
1361
1356
    0 if table is unique
1362
1357
*/
1363
1358
 
1364
 
TableList* unique_table(THD *thd, TableList *table, TableList *table_list,
 
1359
TABLE_LIST* unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
1365
1360
                         bool check_alias)
1366
1361
{
1367
 
  TableList *res;
 
1362
  TABLE_LIST *res;
1368
1363
  const char *d_name, *t_name, *t_alias;
1369
1364
 
1370
1365
  /*
1371
1366
    If this function called for query which update table (INSERT/UPDATE/...)
1372
 
    then we have in table->table pointer to Table object which we are
1373
 
    updating even if it is VIEW so we need TableList of this Table object
 
1367
    then we have in table->table pointer to TABLE object which we are
 
1368
    updating even if it is VIEW so we need TABLE_LIST of this TABLE object
1374
1369
    to get right names (even if lower_case_table_names used).
1375
1370
 
1376
1371
    If this function called for CREATE command that we have not opened table
1377
 
    (table->table equal to 0) and right names is in current TableList
 
1372
    (table->table equal to 0) and right names is in current TABLE_LIST
1378
1373
    object.
1379
1374
  */
1380
1375
  if (table->table)
1384
1379
      return(0);
1385
1380
    table= table->find_underlying_table(table->table);
1386
1381
    /*
1387
 
      as far as we have table->table we have to find real TableList of
 
1382
      as far as we have table->table we have to find real TABLE_LIST of
1388
1383
      it in underlying tables
1389
1384
    */
1390
1385
    assert(table);
1428
1423
    here we hide view underlying tables if we have them
1429
1424
*/
1430
1425
 
1431
 
void update_non_unique_table_error(TableList *update,
1432
 
                                   const char *operation __attribute__((unused)),
1433
 
                                   TableList *duplicate __attribute__((unused)))
 
1426
void update_non_unique_table_error(TABLE_LIST *update,
 
1427
                                   const char *operation __attribute__((__unused__)),
 
1428
                                   TABLE_LIST *duplicate __attribute__((__unused__)))
1434
1429
{
1435
1430
  my_error(ER_UPDATE_TABLE_USED, MYF(0), update->alias);
1436
1431
}
1437
1432
 
1438
1433
 
1439
 
Table *find_temporary_table(THD *thd, const char *db, const char *table_name)
 
1434
TABLE *find_temporary_table(THD *thd, const char *db, const char *table_name)
1440
1435
{
1441
 
  TableList table_list;
 
1436
  TABLE_LIST table_list;
1442
1437
 
1443
1438
  table_list.db= (char*) db;
1444
1439
  table_list.table_name= (char*) table_name;
1446
1441
}
1447
1442
 
1448
1443
 
1449
 
Table *find_temporary_table(THD *thd, TableList *table_list)
 
1444
TABLE *find_temporary_table(THD *thd, TABLE_LIST *table_list)
1450
1445
{
1451
1446
  char  key[MAX_DBKEY_LENGTH];
1452
1447
  uint  key_length;
1453
 
  Table *table;
 
1448
  TABLE *table;
1454
1449
 
1455
1450
  key_length= create_table_def_key(thd, key, table_list, 1);
1456
1451
  for (table=thd->temporary_tables ; table ; table= table->next)
1477
1472
 
1478
1473
  This function is used to drop user temporary tables, as well as
1479
1474
  internal tables created in CREATE TEMPORARY TABLE ... SELECT
1480
 
  or ALTER Table. Even though part of the work done by this function
 
1475
  or ALTER TABLE. Even though part of the work done by this function
1481
1476
  is redundant when the table is internal, as long as we
1482
1477
  link both internal and user temporary tables into the same
1483
1478
  thd->temporary_tables list, it's impossible to tell here whether
1489
1484
  @retval -1  the table is in use by a outer query
1490
1485
*/
1491
1486
 
1492
 
int drop_temporary_table(THD *thd, TableList *table_list)
 
1487
int drop_temporary_table(THD *thd, TABLE_LIST *table_list)
1493
1488
{
1494
 
  Table *table;
 
1489
  TABLE *table;
1495
1490
 
1496
1491
  if (!(table= find_temporary_table(thd, table_list)))
1497
1492
    return(1);
1516
1511
  unlink from thd->temporary tables and close temporary table
1517
1512
*/
1518
1513
 
1519
 
void close_temporary_table(THD *thd, Table *table,
 
1514
void close_temporary_table(THD *thd, TABLE *table,
1520
1515
                           bool free_share, bool delete_table)
1521
1516
{
1522
1517
  if (table->prev)
1557
1552
    If this is needed, use close_temporary_table()
1558
1553
*/
1559
1554
 
1560
 
void close_temporary(Table *table, bool free_share, bool delete_table)
 
1555
void close_temporary(TABLE *table, bool free_share, bool delete_table)
1561
1556
{
1562
1557
  handlerton *table_type= table->s->db_type();
1563
1558
 
1573
1568
  if (free_share)
1574
1569
  {
1575
1570
    free_table_share(table->s);
1576
 
    free((char*) table);
 
1571
    my_free((char*) table,MYF(0));
1577
1572
  }
1578
1573
  return;
1579
1574
}
1580
1575
 
1581
1576
 
1582
1577
/*
1583
 
  Used by ALTER Table when the table is a temporary one. It changes something
 
1578
  Used by ALTER TABLE when the table is a temporary one. It changes something
1584
1579
  only if the ALTER contained a RENAME clause (otherwise, table_name is the old
1585
1580
  name).
1586
1581
  Prepares a table cache key, which is the concatenation of db, table_name and
1587
1582
  thd->slave_proxy_id, separated by '\0'.
1588
1583
*/
1589
1584
 
1590
 
bool rename_temporary_table(THD* thd, Table *table, const char *db,
 
1585
bool rename_temporary_table(THD* thd, TABLE *table, const char *db,
1591
1586
                            const char *table_name)
1592
1587
{
1593
1588
  char *key;
1594
 
  uint32_t key_length;
 
1589
  uint key_length;
1595
1590
  TABLE_SHARE *share= table->s;
1596
 
  TableList table_list;
 
1591
  TABLE_LIST table_list;
1597
1592
 
1598
1593
  if (!(key=(char*) alloc_root(&share->mem_root, MAX_DBKEY_LENGTH)))
1599
1594
    return(1);                          /* purecov: inspected */
1608
1603
 
1609
1604
        /* move table first in unused links */
1610
1605
 
1611
 
static void relink_unused(Table *table)
 
1606
static void relink_unused(TABLE *table)
1612
1607
{
1613
1608
  if (table != unused_tables)
1614
1609
  {
1638
1633
          not locked (for example already unlocked).
1639
1634
*/
1640
1635
 
1641
 
void unlink_open_table(THD *thd, Table *find, bool unlock)
 
1636
void unlink_open_table(THD *thd, TABLE *find, bool unlock)
1642
1637
{
1643
1638
  char key[MAX_DBKEY_LENGTH];
1644
 
  uint32_t key_length= find->s->table_cache_key.length;
1645
 
  Table *list, **prev;
 
1639
  uint key_length= find->s->table_cache_key.length;
 
1640
  TABLE *list, **prev;
1646
1641
 
1647
1642
  safe_mutex_assert_owner(&LOCK_open);
1648
1643
 
1667
1662
      /* Remove table from open_tables list. */
1668
1663
      *prev= list->next;
1669
1664
      /* Close table. */
1670
 
      hash_delete(&open_cache,(unsigned char*) list); // Close table
 
1665
      VOID(hash_delete(&open_cache,(uchar*) list)); // Close table
1671
1666
    }
1672
1667
    else
1673
1668
    {
1686
1681
    Auxiliary routine which closes and drops open table.
1687
1682
 
1688
1683
    @param  thd         Thread handle
1689
 
    @param  table       Table object for table to be dropped
 
1684
    @param  table       TABLE object for table to be dropped
1690
1685
    @param  db_name     Name of database for this table
1691
1686
    @param  table_name  Name of this table
1692
1687
 
1701
1696
          table that was locked with LOCK TABLES.
1702
1697
*/
1703
1698
 
1704
 
void drop_open_table(THD *thd, Table *table, const char *db_name,
 
1699
void drop_open_table(THD *thd, TABLE *table, const char *db_name,
1705
1700
                     const char *table_name)
1706
1701
{
1707
1702
  if (table->s->tmp_table)
1709
1704
  else
1710
1705
  {
1711
1706
    handlerton *table_type= table->s->db_type();
1712
 
    pthread_mutex_lock(&LOCK_open);
 
1707
    VOID(pthread_mutex_lock(&LOCK_open));
1713
1708
    /*
1714
1709
      unlink_open_table() also tells threads waiting for refresh or close
1715
1710
      that something has happened.
1716
1711
    */
1717
1712
    unlink_open_table(thd, table, false);
1718
1713
    quick_rm_table(table_type, db_name, table_name, 0);
1719
 
    pthread_mutex_unlock(&LOCK_open);
 
1714
    VOID(pthread_mutex_unlock(&LOCK_open));
1720
1715
  }
1721
1716
}
1722
1717
 
1738
1733
  const char *proc_info;
1739
1734
  thd->mysys_var->current_mutex= mutex;
1740
1735
  thd->mysys_var->current_cond= cond;
1741
 
  proc_info=thd->get_proc_info();
1742
 
  thd->set_proc_info("Waiting for table");
 
1736
  proc_info=thd->proc_info;
 
1737
  thd_proc_info(thd, "Waiting for table");
1743
1738
  if (!thd->killed)
1744
1739
    (void) pthread_cond_wait(cond, mutex);
1745
1740
 
1758
1753
  pthread_mutex_lock(&thd->mysys_var->mutex);
1759
1754
  thd->mysys_var->current_mutex= 0;
1760
1755
  thd->mysys_var->current_cond= 0;
1761
 
  thd->set_proc_info(proc_info);
 
1756
  thd_proc_info(thd, proc_info);
1762
1757
  pthread_mutex_unlock(&thd->mysys_var->mutex);
1763
1758
  return;
1764
1759
}
1774
1769
  @return false on success, true otherwise.
1775
1770
*/
1776
1771
 
1777
 
bool name_lock_locked_table(THD *thd, TableList *tables)
 
1772
bool name_lock_locked_table(THD *thd, TABLE_LIST *tables)
1778
1773
{
1779
1774
  /* Under LOCK TABLES we must only accept write locked tables. */
1780
1775
  tables->table= find_locked_table(thd, tables->db, tables->table_name);
1803
1798
  SYNOPSIS
1804
1799
    reopen_name_locked_table()
1805
1800
      thd         Thread handle
1806
 
      table_list  TableList object for table to be open, TableList::table
1807
 
                  member should point to Table object which was used for
 
1801
      table_list  TABLE_LIST object for table to be open, TABLE_LIST::table
 
1802
                  member should point to TABLE object which was used for
1808
1803
                  name-locking.
1809
 
      link_in     true  - if Table object for table to be opened should be
 
1804
      link_in     true  - if TABLE object for table to be opened should be
1810
1805
                          linked into THD::open_tables list.
1811
1806
                  false - placeholder used for name-locking is already in
1812
 
                          this list so we only need to preserve Table::next
 
1807
                          this list so we only need to preserve TABLE::next
1813
1808
                          pointer.
1814
1809
 
1815
1810
  NOTE
1820
1815
    true  - Error
1821
1816
*/
1822
1817
 
1823
 
bool reopen_name_locked_table(THD* thd, TableList* table_list, bool link_in)
 
1818
bool reopen_name_locked_table(THD* thd, TABLE_LIST* table_list, bool link_in)
1824
1819
{
1825
 
  Table *table= table_list->table;
 
1820
  TABLE *table= table_list->table;
1826
1821
  TABLE_SHARE *share;
1827
1822
  char *table_name= table_list->table_name;
1828
 
  Table orig_table;
 
1823
  TABLE orig_table;
1829
1824
 
1830
1825
  safe_mutex_assert_owner(&LOCK_open);
1831
1826
 
1836
1831
 
1837
1832
  if (open_unireg_entry(thd, table, table_list, table_name,
1838
1833
                        table->s->table_cache_key.str,
1839
 
                        table->s->table_cache_key.length))
 
1834
                        table->s->table_cache_key.length, thd->mem_root, 0))
1840
1835
  {
1841
1836
    intern_close_table(table);
1842
1837
    /*
1869
1864
  else
1870
1865
  {
1871
1866
    /*
1872
 
      Table object should be already in THD::open_tables list so we just
1873
 
      need to set Table::next correctly.
 
1867
      TABLE object should be already in THD::open_tables list so we just
 
1868
      need to set TABLE::next correctly.
1874
1869
    */
1875
1870
    table->next= orig_table.next;
1876
1871
  }
1878
1873
  table->tablenr=thd->current_tablenr++;
1879
1874
  table->used_fields=0;
1880
1875
  table->const_table=0;
1881
 
  table->null_row= false;
1882
 
  table->maybe_null= false;
1883
 
  table->force_index= false;
 
1876
  table->null_row= table->maybe_null= table->force_index= 0;
1884
1877
  table->status=STATUS_NO_RECORD;
1885
 
  return false;
 
1878
  return(false);
1886
1879
}
1887
1880
 
1888
1881
 
1895
1888
    @param key         Table cache key for name to be locked
1896
1889
    @param key_length  Table cache key length
1897
1890
 
1898
 
    @return Pointer to Table object used for name locking or 0 in
 
1891
    @return Pointer to TABLE object used for name locking or 0 in
1899
1892
            case of failure.
1900
1893
*/
1901
1894
 
1902
 
Table *table_cache_insert_placeholder(THD *thd, const char *key,
1903
 
                                      uint32_t key_length)
 
1895
TABLE *table_cache_insert_placeholder(THD *thd, const char *key,
 
1896
                                      uint key_length)
1904
1897
{
1905
 
  Table *table;
 
1898
  TABLE *table;
1906
1899
  TABLE_SHARE *share;
1907
1900
  char *key_buff;
1908
1901
 
1926
1919
  table->in_use= thd;
1927
1920
  table->locked_by_name=1;
1928
1921
 
1929
 
  if (my_hash_insert(&open_cache, (unsigned char*)table))
 
1922
  if (my_hash_insert(&open_cache, (uchar*)table))
1930
1923
  {
1931
 
    free((unsigned char*) table);
 
1924
    my_free((uchar*) table, MYF(0));
1932
1925
    return(NULL);
1933
1926
  }
1934
1927
 
1946
1939
    @param[out] table       Out parameter which is either:
1947
1940
                            - set to NULL if table cache contains record for
1948
1941
                              the table or
1949
 
                            - set to point to the Table instance used for
 
1942
                            - set to point to the TABLE instance used for
1950
1943
                              name-locking.
1951
1944
 
1952
1945
    @note This function takes into account all records for table in table
1959
1952
*/
1960
1953
 
1961
1954
bool lock_table_name_if_not_cached(THD *thd, const char *db,
1962
 
                                   const char *table_name, Table **table)
 
1955
                                   const char *table_name, TABLE **table)
1963
1956
{
1964
1957
  char key[MAX_DBKEY_LENGTH];
1965
 
  uint32_t key_length;
1966
 
 
1967
 
  key_length= (uint)(my_stpcpy(my_stpcpy(key, db) + 1, table_name) - key) + 1;
1968
 
  pthread_mutex_lock(&LOCK_open);
1969
 
 
1970
 
  if (hash_search(&open_cache, (unsigned char *)key, key_length))
 
1958
  uint key_length;
 
1959
 
 
1960
  key_length= (uint)(strmov(strmov(key, db) + 1, table_name) - key) + 1;
 
1961
  VOID(pthread_mutex_lock(&LOCK_open));
 
1962
 
 
1963
  if (hash_search(&open_cache, (uchar *)key, key_length))
1971
1964
  {
1972
 
    pthread_mutex_unlock(&LOCK_open);
 
1965
    VOID(pthread_mutex_unlock(&LOCK_open));
1973
1966
    *table= 0;
1974
1967
    return(false);
1975
1968
  }
1976
1969
  if (!(*table= table_cache_insert_placeholder(thd, key, key_length)))
1977
1970
  {
1978
 
    pthread_mutex_unlock(&LOCK_open);
 
1971
    VOID(pthread_mutex_unlock(&LOCK_open));
1979
1972
    return(true);
1980
1973
  }
1981
1974
  (*table)->open_placeholder= 1;
1982
1975
  (*table)->next= thd->open_tables;
1983
1976
  thd->open_tables= *table;
1984
 
  pthread_mutex_unlock(&LOCK_open);
 
1977
  VOID(pthread_mutex_unlock(&LOCK_open));
1985
1978
  return(false);
1986
1979
}
1987
1980
 
2007
2000
    @retval  false  No error. 'exists' out parameter set accordingly.
2008
2001
*/
2009
2002
 
2010
 
bool check_if_table_exists(THD *thd, TableList *table, bool *exists)
 
2003
bool check_if_table_exists(THD *thd, TABLE_LIST *table, bool *exists)
2011
2004
{
2012
2005
  char path[FN_REFLEN];
2013
2006
  int rc;
2061
2054
                        If this is a NULL pointer, then the table is not
2062
2055
                        put in the thread-open-list.
2063
2056
    flags               Bitmap of flags to modify how open works:
2064
 
                          DRIZZLE_LOCK_IGNORE_FLUSH - Open table even if
 
2057
                          MYSQL_LOCK_IGNORE_FLUSH - Open table even if
2065
2058
                          someone has done a flush or namelock on it.
2066
2059
                          No version number checking is done.
2067
 
                          DRIZZLE_OPEN_TEMPORARY_ONLY - Open only temporary
 
2060
                          MYSQL_OPEN_TEMPORARY_ONLY - Open only temporary
2068
2061
                          table not the base table or view.
2069
2062
 
2070
2063
  IMPLEMENTATION
2073
2066
    If table list element for the table to be opened has "create" flag
2074
2067
    set and table does not exist, this function will automatically insert
2075
2068
    a placeholder for exclusive name lock into the open tables cache and
2076
 
    will return the Table instance that corresponds to this placeholder.
 
2069
    will return the TABLE instance that corresponds to this placeholder.
2077
2070
 
2078
2071
  RETURN
2079
2072
    NULL  Open failed.  If refresh is set then one should close
2080
2073
          all other tables and retry the open.
2081
 
    #     Success. Pointer to Table object for open table.
 
2074
    #     Success. Pointer to TABLE object for open table.
2082
2075
*/
2083
2076
 
2084
2077
 
2085
 
Table *open_table(THD *thd, TableList *table_list, bool *refresh, uint32_t flags)
 
2078
TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
 
2079
                  bool *refresh, uint flags)
2086
2080
{
2087
 
  register Table *table;
 
2081
  register TABLE *table;
2088
2082
  char key[MAX_DBKEY_LENGTH];
2089
2083
  unsigned int key_length;
2090
2084
  char *alias= table_list->alias;
2098
2092
    *refresh=0;
2099
2093
 
2100
2094
  /* an open table operation needs a lot of the stack space */
2101
 
  if (check_stack_overrun(thd, STACK_MIN_SIZE_FOR_OPEN, (unsigned char *)&alias))
 
2095
  if (check_stack_overrun(thd, STACK_MIN_SIZE_FOR_OPEN, (uchar *)&alias))
2102
2096
    return(0);
2103
2097
 
2104
2098
  if (thd->killed)
2125
2119
        /*
2126
2120
          We're trying to use the same temporary table twice in a query.
2127
2121
          Right now we don't support this because a temporary table
2128
 
          is always represented by only one Table object in THD, and
 
2122
          is always represented by only one TABLE object in THD, and
2129
2123
          it can not be cloned. Emit an error for an unsupported behaviour.
2130
2124
        */
2131
2125
        if (table->query_id)
2140
2134
    }
2141
2135
  }
2142
2136
 
2143
 
  if (flags & DRIZZLE_OPEN_TEMPORARY_ONLY)
 
2137
  if (flags & MYSQL_OPEN_TEMPORARY_ONLY)
2144
2138
  {
2145
2139
    my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, table_list->table_name);
2146
2140
    return(0);
2155
2149
  */
2156
2150
  if (thd->locked_tables)
2157
2151
  {                                             // Using table locks
2158
 
    Table *best_table= 0;
 
2152
    TABLE *best_table= 0;
2159
2153
    int best_distance= INT_MIN;
2160
2154
    bool check_if_used= false;
2161
2155
    for (table=thd->open_tables; table ; table=table->next)
2177
2171
          return(0);
2178
2172
        }
2179
2173
        /*
2180
 
          When looking for a usable Table, ignore MERGE children, as they
 
2174
          When looking for a usable TABLE, ignore MERGE children, as they
2181
2175
          belong to their parent and cannot be used explicitly.
2182
2176
        */
2183
2177
        if (!my_strcasecmp(system_charset_info, table->alias, alias) &&
2237
2231
    this is the normal use case.
2238
2232
    Now we should:
2239
2233
    - try to find the table in the table cache.
2240
 
    - if one of the discovered Table instances is name-locked
 
2234
    - if one of the discovered TABLE instances is name-locked
2241
2235
      (table->s->version == 0) or some thread has started FLUSH TABLES
2242
2236
      (refresh_version > table->s->version), back off -- we have to wait
2243
2237
      until no one holds a name lock on the table.
2244
 
    - if there is no such Table in the name cache, read the table definition
 
2238
    - if there is no such TABLE in the name cache, read the table definition
2245
2239
    and insert it into the cache.
2246
2240
    We perform all of the above under LOCK_open which currently protects
2247
2241
    the open cache (also known as table cache) and table definitions stored
2248
2242
    on disk.
2249
2243
  */
2250
2244
 
2251
 
  pthread_mutex_lock(&LOCK_open);
 
2245
  VOID(pthread_mutex_lock(&LOCK_open));
2252
2246
 
2253
2247
  /*
2254
2248
    If it's the first table from a list of tables used in a query,
2261
2255
  if (!thd->open_tables)
2262
2256
    thd->version=refresh_version;
2263
2257
  else if ((thd->version != refresh_version) &&
2264
 
           ! (flags & DRIZZLE_LOCK_IGNORE_FLUSH))
 
2258
           ! (flags & MYSQL_LOCK_IGNORE_FLUSH))
2265
2259
  {
2266
2260
    /* Someone did a refresh while thread was opening tables */
2267
2261
    if (refresh)
2268
2262
      *refresh=1;
2269
 
    pthread_mutex_unlock(&LOCK_open);
 
2263
    VOID(pthread_mutex_unlock(&LOCK_open));
2270
2264
    return(0);
2271
2265
  }
2272
2266
 
2282
2276
 
2283
2277
  /*
2284
2278
    Actually try to find the table in the open_cache.
2285
 
    The cache may contain several "Table" instances for the same
 
2279
    The cache may contain several "TABLE" instances for the same
2286
2280
    physical table. The instances that are currently "in use" by
2287
2281
    some thread have their "in_use" member != NULL.
2288
2282
    There is no good reason for having more than one entry in the
2290
2284
    an implicit "pending locks queue" - see
2291
2285
    wait_for_locked_table_names for details.
2292
2286
  */
2293
 
  for (table= (Table*) hash_first(&open_cache, (unsigned char*) key, key_length,
 
2287
  for (table= (TABLE*) hash_first(&open_cache, (uchar*) key, key_length,
2294
2288
                                  &state);
2295
2289
       table && table->in_use ;
2296
 
       table= (Table*) hash_next(&open_cache, (unsigned char*) key, key_length,
 
2290
       table= (TABLE*) hash_next(&open_cache, (uchar*) key, key_length,
2297
2291
                                 &state))
2298
2292
  {
2299
2293
    /*
2303
2297
      (re-)opened and added to the cache.
2304
2298
      If since then we did (or just started) FLUSH TABLES
2305
2299
      statement, refresh_version has been increased.
2306
 
      For "name-locked" Table instances, table->s->version is set
 
2300
      For "name-locked" TABLE instances, table->s->version is set
2307
2301
      to 0 (see lock_table_name for details).
2308
2302
      In case there is a pending FLUSH TABLES or a name lock, we
2309
2303
      need to back off and re-start opening tables.
2316
2310
    */
2317
2311
    if (table->needs_reopen_or_name_lock())
2318
2312
    {
2319
 
      if (flags & DRIZZLE_LOCK_IGNORE_FLUSH)
 
2313
      if (flags & MYSQL_LOCK_IGNORE_FLUSH)
2320
2314
      {
2321
2315
        /* Force close at once after usage */
2322
2316
        thd->version= table->s->version;
2326
2320
      /* Avoid self-deadlocks by detecting self-dependencies. */
2327
2321
      if (table->open_placeholder && table->in_use == thd)
2328
2322
      {
2329
 
        pthread_mutex_unlock(&LOCK_open);
 
2323
        VOID(pthread_mutex_unlock(&LOCK_open));
2330
2324
        my_error(ER_UPDATE_TABLE_USED, MYF(0), table->s->table_name.str);
2331
2325
        return(0);
2332
2326
      }
2367
2361
      }
2368
2362
      else
2369
2363
      {
2370
 
        pthread_mutex_unlock(&LOCK_open);
 
2364
        VOID(pthread_mutex_unlock(&LOCK_open));
2371
2365
      }
2372
2366
      /*
2373
2367
        There is a refresh in progress for this table.
2393
2387
  }
2394
2388
  else
2395
2389
  {
2396
 
    /* Insert a new Table instance into the open cache */
 
2390
    /* Insert a new TABLE instance into the open cache */
2397
2391
    int error;
2398
2392
    /* Free cache if too big */
2399
2393
    while (open_cache.records > table_cache_size && unused_tables)
2400
 
      hash_delete(&open_cache,(unsigned char*) unused_tables); /* purecov: tested */
 
2394
      VOID(hash_delete(&open_cache,(uchar*) unused_tables)); /* purecov: tested */
2401
2395
 
2402
2396
    if (table_list->create)
2403
2397
    {
2405
2399
 
2406
2400
      if (check_if_table_exists(thd, table_list, &exists))
2407
2401
      {
2408
 
        pthread_mutex_unlock(&LOCK_open);
 
2402
        VOID(pthread_mutex_unlock(&LOCK_open));
2409
2403
        return(NULL);
2410
2404
      }
2411
2405
 
2416
2410
        */
2417
2411
        if (!(table= table_cache_insert_placeholder(thd, key, key_length)))
2418
2412
        {
2419
 
          pthread_mutex_unlock(&LOCK_open);
 
2413
          VOID(pthread_mutex_unlock(&LOCK_open));
2420
2414
          return(NULL);
2421
2415
        }
2422
2416
        /*
2427
2421
        table->open_placeholder= 1;
2428
2422
        table->next= thd->open_tables;
2429
2423
        thd->open_tables= table;
2430
 
        pthread_mutex_unlock(&LOCK_open);
 
2424
        VOID(pthread_mutex_unlock(&LOCK_open));
2431
2425
        return(table);
2432
2426
      }
2433
2427
      /* Table exists. Let us try to open it. */
2434
2428
    }
2435
2429
 
2436
2430
    /* make a new table */
2437
 
    if (!(table=(Table*) my_malloc(sizeof(*table),MYF(MY_WME))))
 
2431
    if (!(table=(TABLE*) my_malloc(sizeof(*table),MYF(MY_WME))))
2438
2432
    {
2439
 
      pthread_mutex_unlock(&LOCK_open);
 
2433
      VOID(pthread_mutex_unlock(&LOCK_open));
2440
2434
      return(NULL);
2441
2435
    }
2442
2436
 
2443
 
    error= open_unireg_entry(thd, table, table_list, alias, key, key_length);
 
2437
    error= open_unireg_entry(thd, table, table_list, alias, key, key_length,
 
2438
                             mem_root, (flags & OPEN_VIEW_NO_PARSE));
2444
2439
    /* Combine the follow two */
2445
2440
    if (error > 0)
2446
2441
    {
2447
 
      free((unsigned char*)table);
2448
 
      pthread_mutex_unlock(&LOCK_open);
 
2442
      my_free((uchar*)table, MYF(0));
 
2443
      VOID(pthread_mutex_unlock(&LOCK_open));
2449
2444
      return(NULL);
2450
2445
    }
2451
2446
    if (error < 0)
2452
2447
    {
2453
 
      free((unsigned char*)table);
2454
 
      pthread_mutex_unlock(&LOCK_open);
 
2448
      my_free((uchar*)table, MYF(0));
 
2449
      VOID(pthread_mutex_unlock(&LOCK_open));
2455
2450
      return(0); // VIEW
2456
2451
    }
2457
 
    my_hash_insert(&open_cache,(unsigned char*) table);
 
2452
    VOID(my_hash_insert(&open_cache,(uchar*) table));
2458
2453
  }
2459
2454
 
2460
 
  pthread_mutex_unlock(&LOCK_open);
 
2455
  VOID(pthread_mutex_unlock(&LOCK_open));
2461
2456
  if (refresh)
2462
2457
  {
2463
2458
    table->next=thd->open_tables;               /* Link into simple list */
2474
2469
  /* Fix alias if table name changes */
2475
2470
  if (strcmp(table->alias, alias))
2476
2471
  {
2477
 
    uint32_t length=(uint) strlen(alias)+1;
 
2472
    uint length=(uint) strlen(alias)+1;
2478
2473
    table->alias= (char*) my_realloc((char*) table->alias, length,
2479
2474
                                     MYF(MY_WME));
2480
 
    memcpy((void*) table->alias, alias, length);
 
2475
    memcpy((char*) table->alias, alias, length);
2481
2476
  }
2482
2477
  /* These variables are also set in reopen_table() */
2483
2478
  table->tablenr=thd->current_tablenr++;
2484
2479
  table->used_fields=0;
2485
2480
  table->const_table=0;
2486
 
  table->null_row= false;
2487
 
  table->maybe_null= false;
2488
 
  table->force_index= false;
 
2481
  table->null_row= table->maybe_null= table->force_index= 0;
2489
2482
  table->status=STATUS_NO_RECORD;
2490
2483
  table->insert_values= 0;
2491
2484
  /* Catch wrong handling of the auto_increment_field_not_null. */
2500
2493
}
2501
2494
 
2502
2495
 
2503
 
Table *find_locked_table(THD *thd, const char *db,const char *table_name)
 
2496
TABLE *find_locked_table(THD *thd, const char *db,const char *table_name)
2504
2497
{
2505
2498
  char  key[MAX_DBKEY_LENGTH];
2506
 
  uint32_t key_length=(uint) (my_stpcpy(my_stpcpy(key,db)+1,table_name)-key)+1;
 
2499
  uint key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1;
2507
2500
 
2508
 
  for (Table *table=thd->open_tables; table ; table=table->next)
 
2501
  for (TABLE *table=thd->open_tables; table ; table=table->next)
2509
2502
  {
2510
2503
    if (table->s->table_cache_key.length == key_length &&
2511
2504
        !memcmp(table->s->table_cache_key.str, key, key_length))
2531
2524
   1  error. The old table object is not changed.
2532
2525
*/
2533
2526
 
2534
 
bool reopen_table(Table *table)
 
2527
bool reopen_table(TABLE *table)
2535
2528
{
2536
 
  Table tmp;
 
2529
  TABLE tmp;
2537
2530
  bool error= 1;
2538
2531
  Field **field;
2539
 
  uint32_t key,part;
2540
 
  TableList table_list;
 
2532
  uint key,part;
 
2533
  TABLE_LIST table_list;
2541
2534
  THD *thd= table->in_use;
2542
2535
 
2543
2536
  assert(table->s->ref_count == 0);
2545
2538
 
2546
2539
#ifdef EXTRA_DEBUG
2547
2540
  if (table->db_stat)
2548
 
    sql_print_error(_("Table %s had a open data handler in reopen_table"),
 
2541
    sql_print_error("Table %s had a open data handler in reopen_table",
2549
2542
                    table->alias);
2550
2543
#endif
2551
 
  memset(&table_list, 0, sizeof(TableList));
 
2544
  bzero((char*) &table_list, sizeof(TABLE_LIST));
2552
2545
  table_list.db=         table->s->db.str;
2553
2546
  table_list.table_name= table->s->table_name.str;
2554
2547
  table_list.table=      table;
2559
2552
  if (open_unireg_entry(thd, &tmp, &table_list,
2560
2553
                        table->alias,
2561
2554
                        table->s->table_cache_key.str,
2562
 
                        table->s->table_cache_key.length))
 
2555
                        table->s->table_cache_key.length,
 
2556
                        thd->mem_root, 0))
2563
2557
    goto end;
2564
2558
 
2565
2559
  /* This list copies variables set by open_table */
2581
2575
  tmp.prev=             table->prev;
2582
2576
 
2583
2577
  if (table->file)
2584
 
    closefrm(table, 1);         // close file, free everything
 
2578
    VOID(closefrm(table, 1));           // close file, free everything
2585
2579
 
2586
2580
  *table= tmp;
2587
2581
  table->default_column_bitmaps();
2623
2617
    @note This function assumes that if we are not under LOCK TABLES,
2624
2618
          then there is only one table open and locked. This means that
2625
2619
          the function probably has to be adjusted before it can be used
2626
 
          anywhere outside ALTER Table.
 
2620
          anywhere outside ALTER TABLE.
2627
2621
 
2628
2622
    @note Must not use TABLE_SHARE::table_name/db of the table being closed,
2629
2623
          the strings are used in a loop even after the share may be freed.
2632
2626
void close_data_files_and_morph_locks(THD *thd, const char *db,
2633
2627
                                      const char *table_name)
2634
2628
{
2635
 
  Table *table;
 
2629
  TABLE *table;
2636
2630
 
2637
2631
  safe_mutex_assert_owner(&LOCK_open);
2638
2632
 
2648
2642
 
2649
2643
  /*
2650
2644
    Note that open table list may contain a name-lock placeholder
2651
 
    for target table name if we process ALTER Table ... RENAME.
 
2645
    for target table name if we process ALTER TABLE ... RENAME.
2652
2646
    So loop below makes sense even if we are not under LOCK TABLES.
2653
2647
  */
2654
2648
  for (table=thd->open_tables; table ; table=table->next)
2678
2672
 
2679
2673
    @note Since this function can't properly handle prelocking and
2680
2674
          create placeholders it should be used in very special
2681
 
          situations like FLUSH TABLES or ALTER Table. In general
 
2675
          situations like FLUSH TABLES or ALTER TABLE. In general
2682
2676
          case one should just repeat open_tables()/lock_tables()
2683
2677
          combination when one needs tables to be reopened (for
2684
2678
          example see open_and_lock_tables()).
2690
2684
 
2691
2685
bool reopen_tables(THD *thd, bool get_locks, bool mark_share_as_old)
2692
2686
{
2693
 
  Table *table,*next,**prev;
2694
 
  Table **tables,**tables_ptr;                  // For locks
 
2687
  TABLE *table,*next,**prev;
 
2688
  TABLE **tables,**tables_ptr;                  // For locks
2695
2689
  bool error=0, not_used;
2696
 
  const uint32_t flags= DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN |
2697
 
                    DRIZZLE_LOCK_IGNORE_GLOBAL_READ_LOCK |
2698
 
                    DRIZZLE_LOCK_IGNORE_FLUSH;
 
2690
  const uint flags= MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN |
 
2691
                    MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK |
 
2692
                    MYSQL_LOCK_IGNORE_FLUSH;
2699
2693
 
2700
2694
  if (!thd->open_tables)
2701
2695
    return(0);
2707
2701
      The ptr is checked later
2708
2702
      Do not handle locks of MERGE children.
2709
2703
    */
2710
 
    uint32_t opens=0;
 
2704
    uint opens=0;
2711
2705
    for (table= thd->open_tables; table ; table=table->next)
2712
2706
      opens++;
2713
 
    tables= (Table**) my_alloca(sizeof(Table*)*opens);
 
2707
    tables= (TABLE**) my_alloca(sizeof(TABLE*)*opens);
2714
2708
  }
2715
2709
  else
2716
2710
    tables= &thd->open_tables;
2719
2713
  prev= &thd->open_tables;
2720
2714
  for (table=thd->open_tables; table ; table=next)
2721
2715
  {
2722
 
    uint32_t db_stat=table->db_stat;
 
2716
    uint db_stat=table->db_stat;
2723
2717
    next=table->next;
2724
2718
    if (!tables || (!db_stat && reopen_table(table)))
2725
2719
    {
2726
2720
      my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
2727
 
      hash_delete(&open_cache,(unsigned char*) table);
 
2721
      VOID(hash_delete(&open_cache,(uchar*) table));
2728
2722
      error=1;
2729
2723
    }
2730
2724
    else
2744
2738
  *prev=0;
2745
2739
  if (tables != tables_ptr)                     // Should we get back old locks
2746
2740
  {
2747
 
    DRIZZLE_LOCK *lock;
 
2741
    MYSQL_LOCK *lock;
2748
2742
    /*
2749
2743
      We should always get these locks. Anyway, we must not go into
2750
2744
      wait_for_tables() as it tries to acquire LOCK_open, which is
2769
2763
  }
2770
2764
  if (get_locks && tables)
2771
2765
  {
2772
 
    my_afree((unsigned char*) tables);
 
2766
    my_afree((uchar*) tables);
2773
2767
  }
2774
2768
  broadcast_refresh();
2775
2769
  return(error);
2777
2771
 
2778
2772
 
2779
2773
/**
2780
 
    Close handlers for tables in list, but leave the Table structure
 
2774
    Close handlers for tables in list, but leave the TABLE structure
2781
2775
    intact so that we can re-open these quickly.
2782
2776
 
2783
2777
    @param thd           Thread context
2784
 
    @param table         Head of the list of Table objects
 
2778
    @param table         Head of the list of TABLE objects
2785
2779
    @param morph_locks   true  - remove locks which we have on tables being closed
2786
2780
                                 but ensure that no DML or DDL will sneak in before
2787
2781
                                 we will re-open the table (i.e. temporarily morph
2790
2784
    @param send_refresh  Should we awake waiters even if we didn't close any tables?
2791
2785
*/
2792
2786
 
2793
 
static void close_old_data_files(THD *thd, Table *table, bool morph_locks,
 
2787
static void close_old_data_files(THD *thd, TABLE *table, bool morph_locks,
2794
2788
                                 bool send_refresh)
2795
2789
{
2796
2790
  bool found= send_refresh;
2807
2801
      {
2808
2802
        if (morph_locks)
2809
2803
        {
2810
 
          Table *ulcktbl= table;
 
2804
          TABLE *ulcktbl= table;
2811
2805
          if (ulcktbl->lock_count)
2812
2806
          {
2813
2807
            /*
2833
2827
          }
2834
2828
          /*
2835
2829
            We want to protect the table from concurrent DDL operations
2836
 
            (like RENAME Table) until we will re-open and re-lock it.
 
2830
            (like RENAME TABLE) until we will re-open and re-lock it.
2837
2831
          */
2838
2832
          table->open_placeholder= 1;
2839
2833
        }
2845
2839
          We come here only in close-for-back-off scenario. So we have to
2846
2840
          "close" create placeholder here to avoid deadlocks (for example,
2847
2841
          in case of concurrent execution of CREATE TABLE t1 SELECT * FROM t2
2848
 
          and RENAME Table t2 TO t1). In close-for-re-open scenario we will
 
2842
          and RENAME TABLE t2 TO t1). In close-for-re-open scenario we will
2849
2843
          probably want to let it stay.
2850
2844
 
2851
2845
          Note "***": We must not enter this branch if the placeholder
2868
2862
  if the table is closed
2869
2863
*/
2870
2864
 
2871
 
bool table_is_used(Table *table, bool wait_for_name_lock)
 
2865
bool table_is_used(TABLE *table, bool wait_for_name_lock)
2872
2866
{
2873
2867
  do
2874
2868
  {
2875
2869
    char *key= table->s->table_cache_key.str;
2876
 
    uint32_t key_length= table->s->table_cache_key.length;
 
2870
    uint key_length= table->s->table_cache_key.length;
2877
2871
 
2878
2872
    HASH_SEARCH_STATE state;
2879
 
    for (Table *search= (Table*) hash_first(&open_cache, (unsigned char*) key,
 
2873
    for (TABLE *search= (TABLE*) hash_first(&open_cache, (uchar*) key,
2880
2874
                                             key_length, &state);
2881
2875
         search ;
2882
 
         search= (Table*) hash_next(&open_cache, (unsigned char*) key,
 
2876
         search= (TABLE*) hash_next(&open_cache, (uchar*) key,
2883
2877
                                    key_length, &state))
2884
2878
    {
2885
2879
      if (search->in_use == table->in_use)
2906
2900
{
2907
2901
  bool result;
2908
2902
 
2909
 
  thd->set_proc_info("Waiting for tables");
 
2903
  thd_proc_info(thd, "Waiting for tables");
2910
2904
  pthread_mutex_lock(&LOCK_open);
2911
2905
  while (!thd->killed)
2912
2906
  {
2922
2916
  else
2923
2917
  {
2924
2918
    /* Now we can open all tables without any interference */
2925
 
    thd->set_proc_info("Reopen tables");
 
2919
    thd_proc_info(thd, "Reopen tables");
2926
2920
    thd->version= refresh_version;
2927
2921
    result=reopen_tables(thd,0,0);
2928
2922
  }
2929
2923
  pthread_mutex_unlock(&LOCK_open);
2930
 
  thd->set_proc_info(0);
 
2924
  thd_proc_info(thd, 0);
2931
2925
  return(result);
2932
2926
}
2933
2927
 
2944
2938
  INFORMATION
2945
2939
    This is only called on drop tables
2946
2940
 
2947
 
    The Table object for the dropped table is unlocked but still kept around
 
2941
    The TABLE object for the dropped table is unlocked but still kept around
2948
2942
    as a name lock, which means that the table will be available for other
2949
2943
    thread as soon as we call unlock_table_names().
2950
2944
    If there is multiple copies of the table locked, all copies except
2956
2950
*/
2957
2951
 
2958
2952
 
2959
 
Table *drop_locked_tables(THD *thd,const char *db, const char *table_name)
 
2953
TABLE *drop_locked_tables(THD *thd,const char *db, const char *table_name)
2960
2954
{
2961
 
  Table *table,*next,**prev, *found= 0;
 
2955
  TABLE *table,*next,**prev, *found= 0;
2962
2956
  prev= &thd->open_tables;
2963
2957
 
2964
2958
  /*
2989
2983
      else
2990
2984
      {
2991
2985
        /* We already have a name lock, remove copy */
2992
 
        hash_delete(&open_cache,(unsigned char*) table);
 
2986
        VOID(hash_delete(&open_cache,(uchar*) table));
2993
2987
      }
2994
2988
    }
2995
2989
    else
3003
2997
    broadcast_refresh();
3004
2998
  if (thd->locked_tables && thd->locked_tables->table_count == 0)
3005
2999
  {
3006
 
    free((unsigned char*) thd->locked_tables);
 
3000
    my_free((uchar*) thd->locked_tables,MYF(0));
3007
3001
    thd->locked_tables=0;
3008
3002
  }
3009
3003
  return(found);
3011
3005
 
3012
3006
 
3013
3007
/*
3014
 
  If we have the table open, which only happens when a LOCK Table has been
 
3008
  If we have the table open, which only happens when a LOCK TABLE has been
3015
3009
  done on the table, change the lock type to a lock that will abort all
3016
3010
  other threads trying to get the lock.
3017
3011
*/
3018
3012
 
3019
3013
void abort_locked_tables(THD *thd,const char *db, const char *table_name)
3020
3014
{
3021
 
  Table *table;
 
3015
  TABLE *table;
3022
3016
  for (table= thd->open_tables; table ; table= table->next)
3023
3017
  {
3024
3018
    if (!strcmp(table->s->table_name.str, table_name) &&
3059
3053
    share opens have been executed while one table was open all the
3060
3054
    time).
3061
3055
 
3062
 
    share->table_map_id is not UINT32_MAX.
 
3056
    share->table_map_id is not ~0UL.
3063
3057
 */
3064
3058
void assign_new_table_id(TABLE_SHARE *share)
3065
3059
{
3066
 
  static uint32_t last_table_id= UINT32_MAX;
 
3060
  static ulong last_table_id= ~0UL;
3067
3061
 
3068
3062
  /* Preconditions */
3069
3063
  assert(share != NULL);
3074
3068
    There is one reserved number that cannot be used.  Remember to
3075
3069
    change this when 6-byte global table id's are introduced.
3076
3070
  */
3077
 
  if (unlikely(tid == UINT32_MAX))
 
3071
  if (unlikely(tid == ~0UL))
3078
3072
    tid= ++last_table_id;
3079
3073
  share->table_map_id= tid;
3080
3074
 
3081
3075
  /* Post conditions */
3082
 
  assert(share->table_map_id != UINT32_MAX);
 
3076
  assert(share->table_map_id != ~0UL);
3083
3077
 
3084
3078
  return;
3085
3079
}
3091
3085
    open_unireg_entry()
3092
3086
    thd                 Thread handle
3093
3087
    entry               Store open table definition here
3094
 
    table_list          TableList with db, table_name
 
3088
    table_list          TABLE_LIST with db, table_name & belong_to_view
3095
3089
    alias               Alias name
3096
3090
    cache_key           Key for share_cache
3097
3091
    cache_key_length    length of cache_key
 
3092
    mem_root            temporary mem_root for parsing
 
3093
    flags               the OPEN_VIEW_NO_PARSE flag to be passed to
 
3094
                        openfrm()/open_new_frm()
3098
3095
 
3099
3096
  NOTES
3100
3097
   Extra argument for open is taken from thd->open_options
3105
3102
    #   Error
3106
3103
*/
3107
3104
 
3108
 
static int open_unireg_entry(THD *thd, Table *entry, TableList *table_list,
 
3105
static int open_unireg_entry(THD *thd, TABLE *entry, TABLE_LIST *table_list,
3109
3106
                             const char *alias,
3110
 
                             char *cache_key, uint32_t cache_key_length)
 
3107
                             char *cache_key, uint cache_key_length,
 
3108
                             MEM_ROOT *mem_root __attribute__((__unused__)),
 
3109
                             uint flags __attribute__((__unused__)))
3111
3110
{
3112
3111
  int error;
3113
3112
  TABLE_SHARE *share;
3114
 
  uint32_t discover_retry_count= 0;
 
3113
  uint discover_retry_count= 0;
3115
3114
 
3116
3115
  safe_mutex_assert_owner(&LOCK_open);
3117
3116
retry:
3118
3117
  if (!(share= get_table_share_with_create(thd, table_list, cache_key,
3119
3118
                                           cache_key_length, 
 
3119
                                           OPEN_VIEW |
3120
3120
                                           table_list->i_s_requested_object,
3121
3121
                                           &error)))
3122
3122
    return(1);
3126
3126
                                               HA_OPEN_RNDFILE |
3127
3127
                                               HA_GET_INDEX |
3128
3128
                                               HA_TRY_READ_ONLY),
3129
 
                                       (EXTRA_RECORD),
 
3129
                                       (READ_KEYINFO | COMPUTE_TYPES |
 
3130
                                        EXTRA_RECORD),
3130
3131
                                       thd->open_options, entry, OTM_OPEN)))
3131
3132
  {
3132
3133
    if (error == 7)                             // Table def changed
3162
3163
      release_table_share(share, RELEASE_WAIT_FOR_DROP);
3163
3164
      if (!thd->killed)
3164
3165
      {
3165
 
        drizzle_reset_errors(thd, 1);         // Clear warnings
 
3166
        mysql_reset_errors(thd, 1);         // Clear warnings
3166
3167
        thd->clear_error();                 // Clear error message
3167
3168
        goto retry;
3168
3169
      }
3188
3189
                               (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
3189
3190
                                       HA_GET_INDEX |
3190
3191
                                       HA_TRY_READ_ONLY),
3191
 
                               EXTRA_RECORD,
 
3192
                               READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD,
3192
3193
                               ha_open_options | HA_OPEN_FOR_REPAIR,
3193
3194
                               entry, OTM_OPEN) || ! entry->file ||
3194
3195
        (entry->file->is_crashed() && entry->file->ha_check_and_repair(thd)))
3196
3197
       /* Give right error message */
3197
3198
       thd->clear_error();
3198
3199
       my_error(ER_NOT_KEYFILE, MYF(0), share->table_name.str, my_errno);
3199
 
       sql_print_error(_("Couldn't repair table: %s.%s"), share->db.str,
 
3200
       sql_print_error("Couldn't repair table: %s.%s", share->db.str,
3200
3201
                       share->table_name.str);
3201
3202
       if (entry->file)
3202
3203
        closefrm(entry, 0);
3222
3223
    if (mysql_bin_log.is_open())
3223
3224
    {
3224
3225
      char *query, *end;
3225
 
      uint32_t query_buf_size= 20 + share->db.length + share->table_name.length +1;
 
3226
      uint query_buf_size= 20 + share->db.length + share->table_name.length +1;
3226
3227
      if ((query= (char*) my_malloc(query_buf_size,MYF(MY_WME))))
3227
3228
      {
3228
3229
        /* this DELETE FROM is needed even with row-based binlogging */
3229
 
        end = strxmov(my_stpcpy(query, "DELETE FROM `"),
3230
 
                      share->db.str,"`.`",share->table_name.str,"`", NULL);
 
3230
        end = strxmov(strmov(query, "DELETE FROM `"),
 
3231
                      share->db.str,"`.`",share->table_name.str,"`", NullS);
3231
3232
        thd->binlog_query(THD::STMT_QUERY_TYPE,
3232
3233
                          query, (ulong)(end-query), false, false);
3233
 
        free(query);
 
3234
        my_free(query, MYF(0));
3234
3235
      }
3235
3236
      else
3236
3237
      {
3239
3240
          DBA on top of warning the client (which will automatically be done
3240
3241
          because of MYF(MY_WME) in my_malloc() above).
3241
3242
        */
3242
 
        sql_print_error(_("When opening HEAP table, could not allocate memory "
3243
 
                          "to write 'DELETE FROM `%s`.`%s`' to the binary log"),
 
3243
        sql_print_error("When opening HEAP table, could not allocate memory "
 
3244
                        "to write 'DELETE FROM `%s`.`%s`' to the binary log",
3244
3245
                        table_list->db, table_list->table_name);
3245
3246
        closefrm(entry, 0);
3246
3247
        goto err;
3264
3265
    start - list of tables in/out
3265
3266
    counter - number of opened tables will be return using this parameter
3266
3267
    flags   - bitmap of flags to modify how the tables will be open:
3267
 
              DRIZZLE_LOCK_IGNORE_FLUSH - open table even if someone has
 
3268
              MYSQL_LOCK_IGNORE_FLUSH - open table even if someone has
3268
3269
              done a flush or namelock on it.
3269
3270
 
3270
3271
  NOTE
3283
3284
    -1 - error
3284
3285
*/
3285
3286
 
3286
 
int open_tables(THD *thd, TableList **start, uint32_t *counter, uint32_t flags)
 
3287
int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
3287
3288
{
3288
 
  TableList *tables= NULL;
 
3289
  TABLE_LIST *tables= NULL;
3289
3290
  bool refresh;
3290
3291
  int result=0;
3291
3292
  MEM_ROOT new_frm_mem;
3301
3302
  thd->current_tablenr= 0;
3302
3303
 restart:
3303
3304
  *counter= 0;
3304
 
  thd->set_proc_info("Opening tables");
 
3305
  thd_proc_info(thd, "Opening tables");
3305
3306
 
3306
3307
  /*
3307
3308
    For every table in the list of tables to open, try to find or open
3322
3323
      continue;
3323
3324
    }
3324
3325
    /*
3325
 
      If this TableList object is a placeholder for an information_schema
 
3326
      If this TABLE_LIST object is a placeholder for an information_schema
3326
3327
      table, create a temporary table to represent the information_schema
3327
3328
      table in the query. Do not fill it yet - will be filled during
3328
3329
      execution.
3340
3341
      not opened yet. Try to open the table.
3341
3342
    */
3342
3343
    if (!tables->table)
3343
 
      tables->table= open_table(thd, tables, &refresh, flags);
 
3344
      tables->table= open_table(thd, tables, &new_frm_mem, &refresh, flags);
3344
3345
 
3345
3346
    if (!tables->table)
3346
3347
    {
3381
3382
    }
3382
3383
  }
3383
3384
 
3384
 
  thd->set_proc_info(0);
 
3385
  thd_proc_info(thd, 0);
3385
3386
  free_root(&new_frm_mem, MYF(0));              // Free pre-alloced block
3386
3387
 
3387
3388
  if (result && tables)
3388
3389
  {
3389
3390
    /*
3390
3391
      Some functions determine success as (tables->table != NULL).
3391
 
      tables->table is in thd->open_tables.
 
3392
      tables->table is in thd->open_tables. It won't go lost. If the
 
3393
      error happens on a MERGE child, clear the parents TABLE reference.
3392
3394
    */
 
3395
    if (tables->parent_l)
 
3396
      tables->parent_l->table= NULL;
3393
3397
    tables->table= NULL;
3394
3398
  }
3395
3399
  return(result);
3410
3414
  1     error
3411
3415
*/
3412
3416
 
3413
 
static bool check_lock_and_start_stmt(THD *thd, Table *table,
 
3417
static bool check_lock_and_start_stmt(THD *thd, TABLE *table,
3414
3418
                                      thr_lock_type lock_type)
3415
3419
{
3416
3420
  int error;
3460
3464
    and locking issues because it does not call lock_tables().
3461
3465
*/
3462
3466
 
3463
 
Table *open_n_lock_single_table(THD *thd, TableList *table_l,
 
3467
TABLE *open_n_lock_single_table(THD *thd, TABLE_LIST *table_l,
3464
3468
                                thr_lock_type lock_type)
3465
3469
{
3466
 
  TableList *save_next_global;
 
3470
  TABLE_LIST *save_next_global;
3467
3471
 
3468
3472
  /* Remember old 'next' pointer. */
3469
3473
  save_next_global= table_l->next_global;
3472
3476
 
3473
3477
  /* Set requested lock type. */
3474
3478
  table_l->lock_type= lock_type;
 
3479
  /* Allow to open real tables only. */
 
3480
  table_l->required_type= FRMTYPE_TABLE;
3475
3481
 
3476
3482
  /* Open the table. */
3477
3483
  if (simple_open_n_lock_tables(thd, table_l))
3508
3514
      table_list->table         table
3509
3515
*/
3510
3516
 
3511
 
Table *open_ltable(THD *thd, TableList *table_list, thr_lock_type lock_type,
3512
 
                   uint32_t lock_flags)
 
3517
TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type,
 
3518
                   uint lock_flags)
3513
3519
{
3514
 
  Table *table;
 
3520
  TABLE *table;
3515
3521
  bool refresh;
3516
3522
 
3517
 
  thd->set_proc_info("Opening table");
 
3523
  thd_proc_info(thd, "Opening table");
3518
3524
  thd->current_tablenr= 0;
3519
 
  while (!(table= open_table(thd, table_list, &refresh, 0)) &&
 
3525
  /* open_ltable can be used only for BASIC TABLEs */
 
3526
  table_list->required_type= FRMTYPE_TABLE;
 
3527
  while (!(table= open_table(thd, table_list, thd->mem_root, &refresh, 0)) &&
3520
3528
         refresh)
3521
3529
    ;
3522
3530
 
3539
3547
    }
3540
3548
  }
3541
3549
 
3542
 
  thd->set_proc_info(0);
 
3550
  thd_proc_info(thd, 0);
3543
3551
  return(table);
3544
3552
}
3545
3553
 
3568
3576
    the third argument set appropriately.
3569
3577
*/
3570
3578
 
3571
 
int open_and_lock_tables_derived(THD *thd, TableList *tables, bool derived)
 
3579
int open_and_lock_tables_derived(THD *thd, TABLE_LIST *tables, bool derived)
3572
3580
{
3573
 
  uint32_t counter;
 
3581
  uint counter;
3574
3582
  bool need_reopen;
3575
3583
 
3576
3584
  for ( ; ; ) 
3601
3609
    thd         - thread handler
3602
3610
    tables      - list of tables for open
3603
3611
    flags       - bitmap of flags to modify how the tables will be open:
3604
 
                  DRIZZLE_LOCK_IGNORE_FLUSH - open table even if someone has
 
3612
                  MYSQL_LOCK_IGNORE_FLUSH - open table even if someone has
3605
3613
                  done a flush or namelock on it.
3606
3614
 
3607
3615
  RETURN
3613
3621
    data from the tables.
3614
3622
*/
3615
3623
 
3616
 
bool open_normal_and_derived_tables(THD *thd, TableList *tables, uint32_t flags)
 
3624
bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags)
3617
3625
{
3618
 
  uint32_t counter;
 
3626
  uint counter;
3619
3627
  assert(!thd->fill_derived_tables());
3620
3628
  if (open_tables(thd, &tables, &counter, flags) ||
3621
3629
      mysql_handle_derived(thd->lex, &mysql_derived_prepare))
3661
3669
   @param tables Tables involved in the query
3662
3670
 */
3663
3671
 
3664
 
int decide_logging_format(THD *thd, TableList *tables)
 
3672
int decide_logging_format(THD *thd, TABLE_LIST *tables)
3665
3673
{
3666
3674
  if (mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG))
3667
3675
  {
3668
3676
    handler::Table_flags flags_some_set= handler::Table_flags();
3669
3677
    handler::Table_flags flags_all_set= ~handler::Table_flags();
3670
 
    bool multi_engine= false;
 
3678
    my_bool multi_engine= false;
3671
3679
    void* prev_ht= NULL;
3672
 
    for (TableList *table= tables; table; table= table->next_global)
 
3680
    for (TABLE_LIST *table= tables; table; table= table->next_global)
3673
3681
    {
3674
3682
      if (!table->placeholder() && table->lock_type >= TL_WRITE_ALLOW_WRITE)
3675
3683
      {
3705
3713
                " but not allowed by this combination of engines");
3706
3714
    }
3707
3715
 
 
3716
    /*
 
3717
      If more than one engine is involved in the statement and at
 
3718
      least one is doing it's own logging (is *self-logging*), the
 
3719
      statement cannot be logged atomically, so we generate an error
 
3720
      rather than allowing the binlog to become corrupt.
 
3721
     */
 
3722
    if (multi_engine &&
 
3723
        (flags_some_set & HA_HAS_OWN_BINLOGGING))
 
3724
    {
 
3725
      error= ER_BINLOG_LOGGING_IMPOSSIBLE;
 
3726
      my_error(error, MYF(0),
 
3727
               "Statement cannot be written atomically since more"
 
3728
               " than one engine involved and at least one engine"
 
3729
               " is self-logging");
 
3730
    }
 
3731
 
3708
3732
    if (error)
3709
3733
      return -1;
3710
3734
 
3758
3782
   -1   Error
3759
3783
*/
3760
3784
 
3761
 
int lock_tables(THD *thd, TableList *tables, uint32_t count, bool *need_reopen)
 
3785
int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
3762
3786
{
3763
 
  TableList *table;
 
3787
  TABLE_LIST *table;
3764
3788
 
3765
3789
  /*
3766
3790
    We can't meet statement requiring prelocking if we already
3774
3798
  if (!thd->locked_tables)
3775
3799
  {
3776
3800
    assert(thd->lock == 0);     // You must lock everything at once
3777
 
    Table **start,**ptr;
3778
 
    uint32_t lock_flag= DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN;
 
3801
    TABLE **start,**ptr;
 
3802
    uint lock_flag= MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN;
3779
3803
 
3780
 
    if (!(ptr=start=(Table**) thd->alloc(sizeof(Table*)*count)))
 
3804
    if (!(ptr=start=(TABLE**) thd->alloc(sizeof(TABLE*)*count)))
3781
3805
      return(-1);
3782
3806
    for (table= tables; table; table= table->next_global)
3783
3807
    {
3793
3817
  }
3794
3818
  else
3795
3819
  {
3796
 
    TableList *first_not_own= thd->lex->first_not_own_table();
 
3820
    TABLE_LIST *first_not_own= thd->lex->first_not_own_table();
3797
3821
    /*
3798
3822
      When open_and_lock_tables() is called for a single table out of
3799
3823
      a table list, the 'next_global' chain is temporarily broken. We
3829
3853
 
3830
3854
*/
3831
3855
 
3832
 
void close_tables_for_reopen(THD *thd, TableList **tables)
 
3856
void close_tables_for_reopen(THD *thd, TABLE_LIST **tables)
3833
3857
{
3834
3858
  /*
3835
3859
    If table list consists only from tables from prelocking set, table list
3838
3862
  if (thd->lex->first_not_own_table() == *tables)
3839
3863
    *tables= 0;
3840
3864
  thd->lex->chop_off_not_own_tables();
3841
 
  for (TableList *tmp= *tables; tmp; tmp= tmp->next_global)
 
3865
  for (TABLE_LIST *tmp= *tables; tmp; tmp= tmp->next_global)
3842
3866
    tmp->table= 0;
3843
3867
  close_thread_tables(thd);
3844
3868
}
3861
3885
 
3862
3886
 RETURN
3863
3887
   0  Error
3864
 
   #  Table object
 
3888
   #  TABLE object
3865
3889
*/
3866
3890
 
3867
 
Table *open_temporary_table(THD *thd, const char *path, const char *db,
 
3891
TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
3868
3892
                            const char *table_name, bool link_in_list,
3869
3893
                            open_table_mode open_mode)
3870
3894
{
3871
 
  Table *tmp_table;
 
3895
  TABLE *tmp_table;
3872
3896
  TABLE_SHARE *share;
3873
3897
  char cache_key[MAX_DBKEY_LENGTH], *saved_cache_key, *tmp_path;
3874
 
  uint32_t key_length;
3875
 
  TableList table_list;
 
3898
  uint key_length;
 
3899
  TABLE_LIST table_list;
3876
3900
 
3877
3901
  table_list.db=         (char*) db;
3878
3902
  table_list.table_name= (char*) table_name;
3879
3903
  /* Create the cache_key for temporary tables */
3880
3904
  key_length= create_table_def_key(thd, cache_key, &table_list, 1);
3881
3905
 
3882
 
  if (!(tmp_table= (Table*) my_malloc(sizeof(*tmp_table) + sizeof(*share) +
 
3906
  if (!(tmp_table= (TABLE*) my_malloc(sizeof(*tmp_table) + sizeof(*share) +
3883
3907
                                      strlen(path)+1 + key_length,
3884
3908
                                      MYF(MY_WME))))
3885
3909
    return(0);                          /* purecov: inspected */
3886
3910
 
3887
3911
  share= (TABLE_SHARE*) (tmp_table+1);
3888
3912
  tmp_path= (char*) (share+1);
3889
 
  saved_cache_key= my_stpcpy(tmp_path, path)+1;
 
3913
  saved_cache_key= strmov(tmp_path, path)+1;
3890
3914
  memcpy(saved_cache_key, cache_key, key_length);
3891
3915
 
3892
3916
  init_tmp_table_share(thd, share, saved_cache_key, key_length,
3893
 
                       strchr(saved_cache_key, '\0')+1, tmp_path);
 
3917
                       strend(saved_cache_key)+1, tmp_path);
3894
3918
 
3895
3919
  if (open_table_def(thd, share, 0) ||
3896
3920
      open_table_from_share(thd, share, table_name,
3898
3922
                            (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
3899
3923
                                    HA_GET_INDEX),
3900
3924
                            (open_mode == OTM_ALTER) ?
3901
 
                              (EXTRA_RECORD | OPEN_FRM_FILE_ONLY)
3902
 
                            : (EXTRA_RECORD),
 
3925
                              (READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD |
 
3926
                               OPEN_FRM_FILE_ONLY)
 
3927
                            : (READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD),
3903
3928
                            ha_open_options,
3904
3929
                            tmp_table, open_mode))
3905
3930
  {
3906
3931
    /* No need to lock share->mutex as this is not needed for tmp tables */
3907
3932
    free_table_share(share);
3908
 
    free((char*) tmp_table);
 
3933
    my_free((char*) tmp_table,MYF(0));
3909
3934
    return(0);
3910
3935
  }
3911
3936
 
3944
3969
  handler *file;
3945
3970
  char *ext;
3946
3971
 
3947
 
  my_stpcpy(ext= strchr(path, '\0'), reg_ext);
 
3972
  strmov(ext= strend(path), reg_ext);
3948
3973
  if (my_delete(path,MYF(0)))
3949
3974
    error=1; /* purecov: inspected */
3950
3975
  *ext= 0;                              // remove extension
3952
3977
  if (!frm_only && file && file->ha_delete_table(path))
3953
3978
  {
3954
3979
    error=1;
3955
 
    sql_print_warning(_("Could not remove temporary table: '%s', error: %d"),
 
3980
    sql_print_warning("Could not remove temporary table: '%s', error: %d",
3956
3981
                      path, my_errno);
3957
3982
  }
3958
3983
  delete file;
3975
4000
 
3976
4001
#define WRONG_GRANT (Field*) -1
3977
4002
 
3978
 
static void update_field_dependencies(THD *thd, Field *field, Table *table)
 
4003
static void update_field_dependencies(THD *thd, Field *field, TABLE *table)
3979
4004
{
3980
4005
  if (thd->mark_used_columns != MARK_COLUMNS_NONE)
3981
4006
  {
4017
4042
 
4018
4043
 
4019
4044
/*
 
4045
  Find a field by name in a view that uses merge algorithm.
 
4046
 
 
4047
  SYNOPSIS
 
4048
    find_field_in_view()
 
4049
    thd                         thread handler
 
4050
    table_list                  view to search for 'name'
 
4051
    name                        name of field
 
4052
    length                      length of name
 
4053
    item_name                   name of item if it will be created (VIEW)
 
4054
    ref                         expression substituted in VIEW should be passed
 
4055
                                using this reference (return view_ref_found)
 
4056
    register_tree_change        true if ref is not stack variable and we
 
4057
                                need register changes in item tree
 
4058
 
 
4059
  RETURN
 
4060
    0                   field is not found
 
4061
    view_ref_found      found value in VIEW (real result is in *ref)
 
4062
    #                   pointer to field - only for schema table fields
 
4063
*/
 
4064
 
 
4065
static Field *
 
4066
find_field_in_view(THD *thd, TABLE_LIST *table_list,
 
4067
                   const char *name, uint length __attribute__((__unused__)),
 
4068
                   const char *item_name __attribute__((__unused__)),
 
4069
                   Item **ref,
 
4070
                   bool register_tree_change __attribute__((__unused__)))
 
4071
{
 
4072
  Field_iterator_view field_it;
 
4073
  field_it.set(table_list);
 
4074
  
 
4075
  assert(table_list->schema_table_reformed ||
 
4076
              (ref != 0 && (0) != 0));
 
4077
  for (; !field_it.end_of_fields(); field_it.next())
 
4078
  {
 
4079
    if (!my_strcasecmp(system_charset_info, field_it.name(), name))
 
4080
    {
 
4081
      /*
 
4082
        create_item() may, or may not create a new Item, depending on
 
4083
        the column reference. See create_view_field() for details.
 
4084
      */
 
4085
      Item *item= field_it.create_item(thd);
 
4086
      
 
4087
      if (!item)
 
4088
        return(0);
 
4089
      /*
 
4090
       *ref != NULL means that *ref contains the item that we need to
 
4091
       replace. If the item was aliased by the user, set the alias to
 
4092
       the replacing item.
 
4093
       We need to set alias on both ref itself and on ref real item.
 
4094
      */
 
4095
      if (*ref && !(*ref)->is_autogenerated_name)
 
4096
      {
 
4097
        item->set_name((*ref)->name, (*ref)->name_length,
 
4098
                       system_charset_info);
 
4099
        item->real_item()->set_name((*ref)->name, (*ref)->name_length,
 
4100
                       system_charset_info);
 
4101
      }
 
4102
      if (register_tree_change)
 
4103
        thd->change_item_tree(ref, item);
 
4104
      else
 
4105
        *ref= item;
 
4106
      return((Field*) view_ref_found);
 
4107
    }
 
4108
  }
 
4109
  return(0);
 
4110
}
 
4111
 
 
4112
 
 
4113
/*
4020
4114
  Find field by name in a NATURAL/USING join table reference.
4021
4115
 
4022
4116
  SYNOPSIS
4046
4140
*/
4047
4141
 
4048
4142
static Field *
4049
 
find_field_in_natural_join(THD *thd, TableList *table_ref, const char *name,
4050
 
                           uint32_t length __attribute__((unused)),
4051
 
                           Item **ref __attribute__((unused)), bool register_tree_change __attribute__((unused)),
4052
 
                           TableList **actual_table)
 
4143
find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
 
4144
                           uint length __attribute__((__unused__)),
 
4145
                           Item **ref, bool register_tree_change,
 
4146
                           TABLE_LIST **actual_table)
4053
4147
{
4054
4148
  List_iterator_fast<Natural_join_column>
4055
4149
    field_it(*(table_ref->join_columns));
4074
4168
  }
4075
4169
  if (!nj_col)
4076
4170
    return(NULL);
 
4171
 
 
4172
  if (nj_col->view_field)
 
4173
  {
 
4174
    Item *item;
 
4175
    /*
 
4176
      create_item() may, or may not create a new Item, depending on the
 
4177
      column reference. See create_view_field() for details.
 
4178
    */
 
4179
    item= nj_col->create_item(thd);
 
4180
    /*
 
4181
     *ref != NULL means that *ref contains the item that we need to
 
4182
     replace. If the item was aliased by the user, set the alias to
 
4183
     the replacing item.
 
4184
     We need to set alias on both ref itself and on ref real item.
 
4185
     */
 
4186
    if (*ref && !(*ref)->is_autogenerated_name)
 
4187
    {
 
4188
      item->set_name((*ref)->name, (*ref)->name_length,
 
4189
                     system_charset_info);
 
4190
      item->real_item()->set_name((*ref)->name, (*ref)->name_length,
 
4191
                                  system_charset_info);
 
4192
    }
 
4193
 
 
4194
    if (!item)
 
4195
      return(NULL);
 
4196
    assert(nj_col->table_field == NULL);
 
4197
    if (nj_col->table_ref->schema_table_reformed)
 
4198
    {
 
4199
      /*
 
4200
        Translation table items are always Item_fields and fixed
 
4201
        already('mysql_schema_table' function). So we can return
 
4202
        ->field. It is used only for 'show & where' commands.
 
4203
      */
 
4204
      return(((Item_field*) (nj_col->view_field->item))->field);
 
4205
    }
 
4206
    if (register_tree_change)
 
4207
      thd->change_item_tree(ref, item);
 
4208
    else
 
4209
      *ref= item;
 
4210
    found_field= (Field*) view_ref_found;
 
4211
  }
 
4212
  else
4077
4213
  {
4078
4214
    /* This is a base table. */
 
4215
    assert(nj_col->view_field == NULL);
4079
4216
    assert(nj_col->table_ref->table == nj_col->table_field->table);
4080
4217
    found_field= nj_col->table_field;
4081
4218
    update_field_dependencies(thd, found_field, nj_col->table_ref->table);
4106
4243
*/
4107
4244
 
4108
4245
Field *
4109
 
find_field_in_table(THD *thd, Table *table, const char *name, uint32_t length,
4110
 
                    bool allow_rowid, uint32_t *cached_field_index_ptr)
 
4246
find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
 
4247
                    bool allow_rowid, uint *cached_field_index_ptr)
4111
4248
{
4112
4249
  Field **field_ptr, *field;
4113
 
  uint32_t cached_field_index= *cached_field_index_ptr;
 
4250
  uint cached_field_index= *cached_field_index_ptr;
4114
4251
 
4115
4252
  /* We assume here that table->field < NO_CACHED_FIELD_INDEX = UINT_MAX */
4116
4253
  if (cached_field_index < table->s->fields &&
4119
4256
    field_ptr= table->field + cached_field_index;
4120
4257
  else if (table->s->name_hash.records)
4121
4258
  {
4122
 
    field_ptr= (Field**) hash_search(&table->s->name_hash, (unsigned char*) name,
 
4259
    field_ptr= (Field**) hash_search(&table->s->name_hash, (uchar*) name,
4123
4260
                                     length);
4124
4261
    if (field_ptr)
4125
4262
    {
4141
4278
 
4142
4279
  if (field_ptr && *field_ptr)
4143
4280
  {
4144
 
    if ((*field_ptr)->vcol_info)
4145
 
    {
4146
 
      if (thd->mark_used_columns != MARK_COLUMNS_NONE)
4147
 
      {
4148
 
        Item *vcol_item= (*field_ptr)->vcol_info->expr_item;
4149
 
        assert(vcol_item);
4150
 
        vcol_item->walk(&Item::register_field_in_read_map, 1, (unsigned char *) 0);
4151
 
        /* 
4152
 
          Set the virtual field for write here if 
4153
 
          1) this procedure is called for a read-only operation (SELECT), and
4154
 
          2) the virtual column is not phycically stored in the table
4155
 
        */
4156
 
        if ((thd->mark_used_columns != MARK_COLUMNS_WRITE) && 
4157
 
            (not (*field_ptr)->is_stored))
4158
 
          bitmap_set_bit((*field_ptr)->table->write_set, (*field_ptr)->field_index);
4159
 
      }
4160
 
    }
4161
4281
    *cached_field_index_ptr= field_ptr - table->field;
4162
4282
    field= *field_ptr;
4163
4283
  }
4219
4339
*/
4220
4340
 
4221
4341
Field *
4222
 
find_field_in_table_ref(THD *thd, TableList *table_list,
4223
 
                        const char *name, uint32_t length,
 
4342
find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
 
4343
                        const char *name, uint length,
4224
4344
                        const char *item_name, const char *db_name,
4225
4345
                        const char *table_name, Item **ref,
4226
4346
                        bool check_privileges, bool allow_rowid,
4227
 
                        uint32_t *cached_field_index_ptr,
4228
 
                        bool register_tree_change, TableList **actual_table)
 
4347
                        uint *cached_field_index_ptr,
 
4348
                        bool register_tree_change, TABLE_LIST **actual_table)
4229
4349
{
4230
 
  Field *fld= NULL;
 
4350
  Field *fld;
4231
4351
 
4232
4352
  assert(table_list->alias);
4233
4353
  assert(name);
4268
4388
 
4269
4389
  if (table_list->field_translation)
4270
4390
  {
 
4391
    /* 'table_list' is a view or an information schema table. */
 
4392
    if ((fld= find_field_in_view(thd, table_list, name, length, item_name, ref,
 
4393
                                 register_tree_change)))
 
4394
      *actual_table= table_list;
4271
4395
  }
4272
4396
  else if (!table_list->nested_join)
4273
4397
  {
4289
4413
    */
4290
4414
    if (table_name && table_name[0])
4291
4415
    {
4292
 
      List_iterator<TableList> it(table_list->nested_join->join_list);
4293
 
      TableList *table;
 
4416
      List_iterator<TABLE_LIST> it(table_list->nested_join->join_list);
 
4417
      TABLE_LIST *table;
4294
4418
      while ((table= it++))
4295
4419
      {
4296
4420
        if ((fld= find_field_in_table_ref(thd, table, name, length, item_name,
4330
4454
          else
4331
4455
          {
4332
4456
            if (thd->mark_used_columns == MARK_COLUMNS_READ)
4333
 
              it->walk(&Item::register_field_in_read_map, 1, (unsigned char *) 0);
 
4457
              it->walk(&Item::register_field_in_read_map, 1, (uchar *) 0);
4334
4458
          }
4335
4459
        }
4336
4460
        else
4337
4461
          field_to_set= fld;
4338
4462
        if (field_to_set)
4339
4463
        {
4340
 
          Table *table= field_to_set->table;
 
4464
          TABLE *table= field_to_set->table;
4341
4465
          if (thd->mark_used_columns == MARK_COLUMNS_READ)
4342
4466
            bitmap_set_bit(table->read_set, field_to_set->field_index);
4343
4467
          else
4364
4488
    #                   pointer to field
4365
4489
*/
4366
4490
 
4367
 
Field *find_field_in_table_sef(Table *table, const char *name)
 
4491
Field *find_field_in_table_sef(TABLE *table, const char *name)
4368
4492
{
4369
4493
  Field **field_ptr;
4370
4494
  if (table->s->name_hash.records)
4371
4495
  {
4372
 
    field_ptr= (Field**)hash_search(&table->s->name_hash,(unsigned char*) name,
 
4496
    field_ptr= (Field**)hash_search(&table->s->name_hash,(uchar*) name,
4373
4497
                                    strlen(name));
4374
4498
    if (field_ptr)
4375
4499
    {
4431
4555
 
4432
4556
Field *
4433
4557
find_field_in_tables(THD *thd, Item_ident *item,
4434
 
                     TableList *first_table, TableList *last_table,
 
4558
                     TABLE_LIST *first_table, TABLE_LIST *last_table,
4435
4559
                     Item **ref, find_item_error_report_type report_error,
4436
4560
                     bool check_privileges, bool register_tree_change)
4437
4561
{
4439
4563
  const char *db= item->db_name;
4440
4564
  const char *table_name= item->table_name;
4441
4565
  const char *name= item->field_name;
4442
 
  uint32_t length=(uint) strlen(name);
 
4566
  uint length=(uint) strlen(name);
4443
4567
  char name_buff[NAME_LEN+1];
4444
 
  TableList *cur_table= first_table;
4445
 
  TableList *actual_table;
 
4568
  TABLE_LIST *cur_table= first_table;
 
4569
  TABLE_LIST *actual_table;
4446
4570
  bool allow_rowid;
4447
4571
 
4448
4572
  if (!table_name || !table_name[0])
4457
4581
  {
4458
4582
    /*
4459
4583
      This shortcut is used by prepared statements. We assume that
4460
 
      TableList *first_table is not changed during query execution (which
 
4584
      TABLE_LIST *first_table is not changed during query execution (which
4461
4585
      is true for all queries except RENAME but luckily RENAME doesn't
4462
4586
      use fields...) so we can rely on reusing pointer to its member.
4463
4587
      With this optimization we also miss case when addition of one more
4464
4588
      field makes some prepared query ambiguous and so erroneous, but we
4465
4589
      accept this trade off.
4466
4590
    */
4467
 
    TableList *table_ref= item->cached_table;
 
4591
    TABLE_LIST *table_ref= item->cached_table;
4468
4592
    /*
4469
4593
      The condition (table_ref->view == NULL) ensures that we will call
4470
4594
      find_field_in_table even in the case of information schema tables
4488
4612
        Only views fields should be marked as dependent, not an underlying
4489
4613
        fields.
4490
4614
      */
 
4615
      if (!table_ref->belong_to_view)
4491
4616
      {
4492
4617
        SELECT_LEX *current_sel= thd->lex->current_select;
4493
4618
        SELECT_LEX *last_select= table_ref->select_lex;
4599
4724
    char buff[NAME_LEN*2+1];
4600
4725
    if (db && db[0])
4601
4726
    {
4602
 
      strxnmov(buff,sizeof(buff)-1,db,".",table_name,NULL);
 
4727
      strxnmov(buff,sizeof(buff)-1,db,".",table_name,NullS);
4603
4728
      table_name=buff;
4604
4729
    }
4605
4730
    my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, thd->where);
4654
4779
 
4655
4780
 
4656
4781
Item **
4657
 
find_item_in_list(Item *find, List<Item> &items, uint32_t *counter,
 
4782
find_item_in_list(Item *find, List<Item> &items, uint *counter,
4658
4783
                  find_item_error_report_type report_error,
4659
4784
                  enum_resolution_type *resolution)
4660
4785
{
4669
4794
    (and not an item that happens to have a name).
4670
4795
  */
4671
4796
  bool is_ref_by_name= 0;
4672
 
  uint32_t unaliased_counter= 0;
 
4797
  uint unaliased_counter= 0;
4673
4798
 
4674
4799
  *resolution= NOT_RESOLVED;
4675
4800
 
4682
4807
    db_name=    ((Item_ident*) find)->db_name;
4683
4808
  }
4684
4809
 
4685
 
  for (uint32_t i= 0; (item=li++); i++)
 
4810
  for (uint i= 0; (item=li++); i++)
4686
4811
  {
4687
4812
    if (field_name && item->real_item()->type() == Item::FIELD_ITEM)
4688
4813
    {
4924
5049
*/
4925
5050
 
4926
5051
static bool
4927
 
set_new_item_local_context(THD *thd, Item_ident *item, TableList *table_ref)
 
5052
set_new_item_local_context(THD *thd, Item_ident *item, TABLE_LIST *table_ref)
4928
5053
{
4929
5054
  Name_resolution_context *context;
4930
5055
  if (!(context= new (thd->mem_root) Name_resolution_context))
4969
5094
*/
4970
5095
 
4971
5096
static bool
4972
 
mark_common_columns(THD *thd, TableList *table_ref_1, TableList *table_ref_2,
4973
 
                    List<String> *using_fields, uint32_t *found_using_fields)
 
5097
mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
 
5098
                    List<String> *using_fields, uint *found_using_fields)
4974
5099
{
4975
5100
  Field_iterator_table_ref it_1, it_2;
4976
5101
  Natural_join_column *nj_col_1, *nj_col_2;
4980
5105
    Leaf table references to which new natural join columns are added
4981
5106
    if the leaves are != NULL.
4982
5107
  */
4983
 
  TableList *leaf_1= (table_ref_1->nested_join &&
 
5108
  TABLE_LIST *leaf_1= (table_ref_1->nested_join &&
4984
5109
                       !table_ref_1->is_natural_join) ?
4985
5110
                      NULL : table_ref_1;
4986
 
  TableList *leaf_2= (table_ref_2->nested_join &&
 
5111
  TABLE_LIST *leaf_2= (table_ref_2->nested_join &&
4987
5112
                       !table_ref_2->is_natural_join) ?
4988
5113
                      NULL : table_ref_2;
4989
5114
 
5070
5195
        goto err;                               // out of memory
5071
5196
 
5072
5197
      /*
 
5198
        The following assert checks that the two created items are of
 
5199
        type Item_ident.
 
5200
      */
 
5201
      assert(!thd->lex->current_select->no_wrap_view_item);
 
5202
      /*
5073
5203
        In the case of no_wrap_view_item == 0, the created items must be
5074
5204
        of sub-classes of Item_ident.
5075
5205
      */
5110
5240
 
5111
5241
      if (field_1)
5112
5242
      {
5113
 
        Table *table_1= nj_col_1->table_ref->table;
 
5243
        TABLE *table_1= nj_col_1->table_ref->table;
5114
5244
        /* Mark field_1 used for table cache. */
5115
5245
        bitmap_set_bit(table_1->read_set, field_1->field_index);
5116
5246
        table_1->covering_keys.intersect(field_1->part_of_key);
5118
5248
      }
5119
5249
      if (field_2)
5120
5250
      {
5121
 
        Table *table_2= nj_col_2->table_ref->table;
 
5251
        TABLE *table_2= nj_col_2->table_ref->table;
5122
5252
        /* Mark field_2 used for table cache. */
5123
5253
        bitmap_set_bit(table_2->read_set, field_2->field_index);
5124
5254
        table_2->covering_keys.intersect(field_2->part_of_key);
5183
5313
*/
5184
5314
 
5185
5315
static bool
5186
 
store_natural_using_join_columns(THD *thd __attribute__((unused)),
5187
 
                                 TableList *natural_using_join,
5188
 
                                 TableList *table_ref_1,
5189
 
                                 TableList *table_ref_2,
 
5316
store_natural_using_join_columns(THD *thd __attribute__((__unused__)),
 
5317
                                 TABLE_LIST *natural_using_join,
 
5318
                                 TABLE_LIST *table_ref_1,
 
5319
                                 TABLE_LIST *table_ref_2,
5190
5320
                                 List<String> *using_fields,
5191
 
                                 uint32_t found_using_fields)
 
5321
                                 uint found_using_fields)
5192
5322
{
5193
5323
  Field_iterator_table_ref it_1, it_2;
5194
5324
  Natural_join_column *nj_col_1, *nj_col_2;
5286
5416
  DESCRIPTION
5287
5417
    The procedure performs a post-order traversal of a nested join tree
5288
5418
    and materializes the row types of NATURAL/USING joins in a
5289
 
    bottom-up manner until it reaches the TableList elements that
 
5419
    bottom-up manner until it reaches the TABLE_LIST elements that
5290
5420
    represent the top-most NATURAL/USING joins. The procedure should be
5291
5421
    applied to each element of SELECT_LEX::top_join_list (i.e. to each
5292
5422
    top-level element of the FROM clause).
5302
5432
*/
5303
5433
 
5304
5434
static bool
5305
 
store_top_level_join_columns(THD *thd, TableList *table_ref,
5306
 
                             TableList *left_neighbor,
5307
 
                             TableList *right_neighbor)
 
5435
store_top_level_join_columns(THD *thd, TABLE_LIST *table_ref,
 
5436
                             TABLE_LIST *left_neighbor,
 
5437
                             TABLE_LIST *right_neighbor)
5308
5438
{
5309
5439
  bool result= true;
5310
5440
 
5311
5441
  /* Call the procedure recursively for each nested table reference. */
5312
5442
  if (table_ref->nested_join)
5313
5443
  {
5314
 
    List_iterator_fast<TableList> nested_it(table_ref->nested_join->join_list);
5315
 
    TableList *same_level_left_neighbor= nested_it++;
5316
 
    TableList *same_level_right_neighbor= NULL;
 
5444
    List_iterator_fast<TABLE_LIST> nested_it(table_ref->nested_join->join_list);
 
5445
    TABLE_LIST *same_level_left_neighbor= nested_it++;
 
5446
    TABLE_LIST *same_level_right_neighbor= NULL;
5317
5447
    /* Left/right-most neighbors, possibly at higher levels in the join tree. */
5318
 
    TableList *real_left_neighbor, *real_right_neighbor;
 
5448
    TABLE_LIST *real_left_neighbor, *real_right_neighbor;
5319
5449
 
5320
5450
    while (same_level_left_neighbor)
5321
5451
    {
5322
 
      TableList *cur_table_ref= same_level_left_neighbor;
 
5452
      TABLE_LIST *cur_table_ref= same_level_left_neighbor;
5323
5453
      same_level_left_neighbor= nested_it++;
5324
5454
      /*
5325
5455
        The order of RIGHT JOIN operands is reversed in 'join list' to
5337
5467
      {
5338
5468
        /* This can happen only for JOIN ... ON. */
5339
5469
        assert(table_ref->nested_join->join_list.elements == 2);
5340
 
        std::swap(same_level_left_neighbor, cur_table_ref);
 
5470
        swap_variables(TABLE_LIST*, same_level_left_neighbor, cur_table_ref);
5341
5471
      }
5342
5472
 
5343
5473
      /*
5365
5495
  {
5366
5496
    assert(table_ref->nested_join &&
5367
5497
                table_ref->nested_join->join_list.elements == 2);
5368
 
    List_iterator_fast<TableList> operand_it(table_ref->nested_join->join_list);
 
5498
    List_iterator_fast<TABLE_LIST> operand_it(table_ref->nested_join->join_list);
5369
5499
    /*
5370
5500
      Notice that the order of join operands depends on whether table_ref
5371
5501
      represents a LEFT or a RIGHT join. In a RIGHT join, the operands are
5372
5502
      in inverted order.
5373
5503
     */
5374
 
    TableList *table_ref_2= operand_it++; /* Second NATURAL join operand.*/
5375
 
    TableList *table_ref_1= operand_it++; /* First NATURAL join operand. */
 
5504
    TABLE_LIST *table_ref_2= operand_it++; /* Second NATURAL join operand.*/
 
5505
    TABLE_LIST *table_ref_1= operand_it++; /* First NATURAL join operand. */
5376
5506
    List<String> *using_fields= table_ref->join_using_fields;
5377
 
    uint32_t found_using_fields;
 
5507
    uint found_using_fields;
5378
5508
 
5379
5509
    /*
5380
5510
      The two join operands were interchanged in the parser, change the order
5381
5511
      back for 'mark_common_columns'.
5382
5512
    */
5383
5513
    if (table_ref_2->outer_join & JOIN_TYPE_RIGHT)
5384
 
      std::swap(table_ref_1, table_ref_2);
 
5514
      swap_variables(TABLE_LIST*, table_ref_1, table_ref_2);
5385
5515
    if (mark_common_columns(thd, table_ref_1, table_ref_2,
5386
5516
                            using_fields, &found_using_fields))
5387
5517
      goto err;
5392
5522
      same as of an equivalent LEFT JOIN.
5393
5523
    */
5394
5524
    if (table_ref_1->outer_join & JOIN_TYPE_RIGHT)
5395
 
      std::swap(table_ref_1, table_ref_2);
 
5525
      swap_variables(TABLE_LIST*, table_ref_1, table_ref_2);
5396
5526
    if (store_natural_using_join_columns(thd, table_ref, table_ref_1,
5397
5527
                                         table_ref_2, using_fields,
5398
5528
                                         found_using_fields))
5414
5544
    /* Change this table reference to become a leaf for name resolution. */
5415
5545
    if (left_neighbor)
5416
5546
    {
5417
 
      TableList *last_leaf_on_the_left;
 
5547
      TABLE_LIST *last_leaf_on_the_left;
5418
5548
      last_leaf_on_the_left= left_neighbor->last_leaf_for_name_resolution();
5419
5549
      last_leaf_on_the_left->next_name_resolution_table= table_ref;
5420
5550
    }
5421
5551
    if (right_neighbor)
5422
5552
    {
5423
 
      TableList *first_leaf_on_the_right;
 
5553
      TABLE_LIST *first_leaf_on_the_right;
5424
5554
      first_leaf_on_the_right= right_neighbor->first_leaf_for_name_resolution();
5425
5555
      table_ref->next_name_resolution_table= first_leaf_on_the_right;
5426
5556
    }
5459
5589
    false  OK
5460
5590
*/
5461
5591
static bool setup_natural_join_row_types(THD *thd,
5462
 
                                         List<TableList> *from_clause,
 
5592
                                         List<TABLE_LIST> *from_clause,
5463
5593
                                         Name_resolution_context *context)
5464
5594
{
5465
5595
  thd->where= "from clause";
5466
5596
  if (from_clause->elements == 0)
5467
5597
    return false; /* We come here in the case of UNIONs. */
5468
5598
 
5469
 
  List_iterator_fast<TableList> table_ref_it(*from_clause);
5470
 
  TableList *table_ref; /* Current table reference. */
 
5599
  List_iterator_fast<TABLE_LIST> table_ref_it(*from_clause);
 
5600
  TABLE_LIST *table_ref; /* Current table reference. */
5471
5601
  /* Table reference to the left of the current. */
5472
 
  TableList *left_neighbor;
 
5602
  TABLE_LIST *left_neighbor;
5473
5603
  /* Table reference to the right of the current. */
5474
 
  TableList *right_neighbor= NULL;
 
5604
  TABLE_LIST *right_neighbor= NULL;
5475
5605
 
5476
5606
  /* Note that tables in the list are in reversed order */
5477
5607
  for (left_neighbor= table_ref_it++; left_neighbor ; )
5478
5608
  {
5479
5609
    table_ref= left_neighbor;
5480
5610
    left_neighbor= table_ref_it++;
5481
 
    if (store_top_level_join_columns(thd, table_ref,
5482
 
                                     left_neighbor, right_neighbor))
5483
 
      return true;
5484
 
    if (left_neighbor)
 
5611
    /* For stored procedures do not redo work if already done. */
 
5612
    if (context->select_lex->first_execution)
5485
5613
    {
5486
 
      TableList *first_leaf_on_the_right;
5487
 
      first_leaf_on_the_right= table_ref->first_leaf_for_name_resolution();
5488
 
      left_neighbor->next_name_resolution_table= first_leaf_on_the_right;
 
5614
      if (store_top_level_join_columns(thd, table_ref,
 
5615
                                       left_neighbor, right_neighbor))
 
5616
        return true;
 
5617
      if (left_neighbor)
 
5618
      {
 
5619
        TABLE_LIST *first_leaf_on_the_right;
 
5620
        first_leaf_on_the_right= table_ref->first_leaf_for_name_resolution();
 
5621
        left_neighbor->next_name_resolution_table= first_leaf_on_the_right;
 
5622
      }
5489
5623
    }
5490
5624
    right_neighbor= table_ref;
5491
5625
  }
5509
5643
****************************************************************************/
5510
5644
 
5511
5645
int setup_wild(THD *thd,
5512
 
               TableList *tables __attribute__((unused)),
 
5646
               TABLE_LIST *tables __attribute__((__unused__)),
5513
5647
               List<Item> &fields,
5514
5648
               List<Item> *sum_func_list,
5515
 
               uint32_t wild_num)
 
5649
               uint wild_num)
5516
5650
{
5517
5651
  if (!wild_num)
5518
5652
    return(0);
5528
5662
        ((Item_field*) item)->field_name[0] == '*' &&
5529
5663
        !((Item_field*) item)->field)
5530
5664
    {
5531
 
      uint32_t elem= fields.elements;
 
5665
      uint elem= fields.elements;
5532
5666
      bool any_privileges= ((Item_field *) item)->any_privileges;
5533
5667
      Item_subselect *subsel= thd->lex->current_select->master_unit()->item;
5534
5668
      if (subsel &&
5600
5734
    ref_pointer_array
5601
5735
  */
5602
5736
  if (ref_pointer_array)
5603
 
    memset(ref_pointer_array, 0, sizeof(Item *) * fields.elements);
 
5737
    bzero(ref_pointer_array, sizeof(Item *) * fields.elements);
5604
5738
 
5605
5739
  Item **ref= ref_pointer_array;
5606
5740
  thd->lex->current_select->cur_pos_in_select_list= 0;
5641
5775
  RETURN pointer on pointer to next_leaf of last element
5642
5776
*/
5643
5777
 
5644
 
TableList **make_leaves_list(TableList **list, TableList *tables)
 
5778
TABLE_LIST **make_leaves_list(TABLE_LIST **list, TABLE_LIST *tables)
5645
5779
{
5646
 
  for (TableList *table= tables; table; table= table->next_local)
 
5780
  for (TABLE_LIST *table= tables; table; table= table->next_local)
5647
5781
  {
5648
5782
    {
5649
5783
      *list= table;
5682
5816
*/
5683
5817
 
5684
5818
bool setup_tables(THD *thd, Name_resolution_context *context,
5685
 
                  List<TableList> *from_clause, TableList *tables,
5686
 
                  TableList **leaves, bool select_insert)
 
5819
                  List<TABLE_LIST> *from_clause, TABLE_LIST *tables,
 
5820
                  TABLE_LIST **leaves, bool select_insert)
5687
5821
{
5688
 
  uint32_t tablenr= 0;
 
5822
  uint tablenr= 0;
5689
5823
 
5690
5824
  assert ((select_insert && !tables->next_name_resolution_table) || !tables || 
5691
5825
               (context->table_list && context->first_name_resolution_table));
5693
5827
    this is used for INSERT ... SELECT.
5694
5828
    For select we setup tables except first (and its underlying tables)
5695
5829
  */
5696
 
  TableList *first_select_table= (select_insert ?
 
5830
  TABLE_LIST *first_select_table= (select_insert ?
5697
5831
                                   tables->next_local:
5698
5832
                                   0);
5699
5833
  if (!(*leaves))
5700
5834
    make_leaves_list(leaves, tables);
5701
5835
 
5702
 
  TableList *table_list;
 
5836
  TABLE_LIST *table_list;
5703
5837
  for (table_list= *leaves;
5704
5838
       table_list;
5705
5839
       table_list= table_list->next_leaf, tablenr++)
5706
5840
  {
5707
 
    Table *table= table_list->table;
 
5841
    TABLE *table= table_list->table;
5708
5842
    table->pos_in_table_list= table_list;
5709
5843
    if (first_select_table &&
5710
5844
        table_list->top_table() == first_select_table)
5756
5890
*/
5757
5891
bool setup_tables_and_check_access(THD *thd, 
5758
5892
                                   Name_resolution_context *context,
5759
 
                                   List<TableList> *from_clause,
5760
 
                                   TableList *tables,
5761
 
                                   TableList **leaves,
 
5893
                                   List<TABLE_LIST> *from_clause,
 
5894
                                   TABLE_LIST *tables,
 
5895
                                   TABLE_LIST **leaves,
5762
5896
                                   bool select_insert)
5763
5897
{
5764
 
  TableList *leaves_tmp= NULL;
 
5898
  TABLE_LIST *leaves_tmp= NULL;
5765
5899
  bool first_table= true;
5766
5900
 
5767
5901
  if (setup_tables(thd, context, from_clause, tables,
5773
5907
 
5774
5908
  for (; leaves_tmp; leaves_tmp= leaves_tmp->next_leaf)
5775
5909
  {
 
5910
    if (leaves_tmp->belong_to_view)
 
5911
    {
 
5912
      return true;
 
5913
    }
5776
5914
    first_table= 0;
5777
5915
  }
5778
5916
  return false;
5793
5931
     1  error
5794
5932
*/
5795
5933
 
5796
 
bool get_key_map_from_key_list(key_map *map, Table *table,
 
5934
bool get_key_map_from_key_list(key_map *map, TABLE *table,
5797
5935
                               List<String> *index_list)
5798
5936
{
5799
5937
  List_iterator_fast<String> it(*index_list);
5800
5938
  String *name;
5801
 
  uint32_t pos;
 
5939
  uint pos;
5802
5940
 
5803
5941
  map->clear_all();
5804
5942
  while ((name=it++))
5840
5978
bool
5841
5979
insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
5842
5980
              const char *table_name, List_iterator<Item> *it,
5843
 
              bool any_privileges __attribute__((unused)))
 
5981
              bool any_privileges __attribute__((__unused__)))
5844
5982
{
5845
5983
  Field_iterator_table_ref field_iterator;
5846
5984
  bool found;
5865
6003
    else treat natural joins as leaves and do not iterate over their underlying
5866
6004
    tables.
5867
6005
  */
5868
 
  for (TableList *tables= (table_name ? context->table_list :
 
6006
  for (TABLE_LIST *tables= (table_name ? context->table_list :
5869
6007
                            context->first_name_resolution_table);
5870
6008
       tables;
5871
6009
       tables= (table_name ? tables->next_local :
5873
6011
       )
5874
6012
  {
5875
6013
    Field *field;
5876
 
    Table *table= tables->table;
 
6014
    TABLE *table= tables->table;
5877
6015
 
5878
6016
    assert(tables->is_leaf_for_name_resolution());
5879
6017
 
5915
6053
      {
5916
6054
        /* Mark fields as used to allow storage engine to optimze access */
5917
6055
        bitmap_set_bit(field->table->read_set, field->field_index);
5918
 
        /*
5919
 
          Mark virtual fields for write and others that the virtual fields
5920
 
          depend on for read.
5921
 
        */
5922
 
        if (field->vcol_info)
5923
 
        {
5924
 
          Item *vcol_item= field->vcol_info->expr_item;
5925
 
          assert(vcol_item);
5926
 
          vcol_item->walk(&Item::register_field_in_read_map, 1, (unsigned char *) 0);
5927
 
          bitmap_set_bit(field->table->write_set, field->field_index);
5928
 
        }
5929
6056
        if (table)
5930
6057
        {
5931
6058
          table->covering_keys.intersect(field->part_of_key);
5933
6060
        }
5934
6061
        if (tables->is_natural_join)
5935
6062
        {
5936
 
          Table *field_table;
 
6063
          TABLE *field_table;
5937
6064
          /*
5938
6065
            In this case we are sure that the column ref will not be created
5939
6066
            because it was already created and stored with the natural join.
6000
6127
    false if all is OK
6001
6128
*/
6002
6129
 
6003
 
int setup_conds(THD *thd, TableList *tables __attribute__((unused)),
6004
 
                TableList *leaves,
 
6130
int setup_conds(THD *thd, TABLE_LIST *tables __attribute__((__unused__)),
 
6131
                TABLE_LIST *leaves,
6005
6132
                COND **conds)
6006
6133
{
6007
6134
  SELECT_LEX *select_lex= thd->lex->current_select;
6008
 
  TableList *table= NULL;       // For HP compilers
 
6135
  TABLE_LIST *table= NULL;      // For HP compilers
6009
6136
  void *save_thd_marker= thd->thd_marker;
6010
6137
  /*
6011
6138
    it_is_update set to true when tables of primary SELECT_LEX (SELECT_LEX
6039
6166
  */
6040
6167
  for (table= leaves; table; table= table->next_leaf)
6041
6168
  {
6042
 
    TableList *embedded; /* The table at the current level of nesting. */
6043
 
    TableList *embedding= table; /* The parent nested table reference. */
 
6169
    TABLE_LIST *embedded; /* The table at the current level of nesting. */
 
6170
    TABLE_LIST *embedding= table; /* The parent nested table reference. */
6044
6171
    do
6045
6172
    {
6046
6173
      embedded= embedding;
6103
6230
  List_iterator_fast<Item> f(fields),v(values);
6104
6231
  Item *value, *fld;
6105
6232
  Item_field *field;
6106
 
  Table *table= 0;
6107
 
  List<Table> tbl_list;
6108
 
  bool abort_on_warning_saved= thd->abort_on_warning;
6109
 
  tbl_list.empty();
 
6233
  TABLE *table= 0;
6110
6234
 
6111
6235
  /*
6112
6236
    Reset the table->auto_increment_field_not_null as it is valid for
6140
6264
    table= rfield->table;
6141
6265
    if (rfield == table->next_number_field)
6142
6266
      table->auto_increment_field_not_null= true;
6143
 
    if (rfield->vcol_info && 
6144
 
        value->type() != Item::DEFAULT_VALUE_ITEM && 
6145
 
        value->type() != Item::NULL_ITEM &&
6146
 
        table->s->table_category != TABLE_CATEGORY_TEMPORARY)
6147
 
    {
6148
 
      thd->abort_on_warning= false;
6149
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
6150
 
                          ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN,
6151
 
                          ER(ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN),
6152
 
                          rfield->field_name, table->s->table_name.str);
6153
 
      thd->abort_on_warning= abort_on_warning_saved;
6154
 
    }
6155
6267
    if ((value->save_in_field(rfield, 0) < 0) && !ignore_errors)
6156
6268
    {
6157
6269
      my_message(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), MYF(0));
6158
6270
      goto err;
6159
6271
    }
6160
 
    tbl_list.push_back(table);
6161
 
  }
6162
 
  /* Update virtual fields*/
6163
 
  thd->abort_on_warning= false;
6164
 
  if (tbl_list.head())
6165
 
  {
6166
 
    List_iterator_fast<Table> t(tbl_list);
6167
 
    Table *prev_table= 0;
6168
 
    while ((table= t++))
6169
 
    {
6170
 
      /*
6171
 
        Do simple optimization to prevent unnecessary re-generating 
6172
 
        values for virtual fields
6173
 
      */
6174
 
      if (table != prev_table)
6175
 
      {
6176
 
        prev_table= table;
6177
 
        if (table->vfield)
6178
 
        {
6179
 
          if (update_virtual_fields_marked_for_write(table, false))
6180
 
            goto err;
6181
 
        }
6182
 
      }
6183
 
    }
6184
 
  }
6185
 
  thd->abort_on_warning= abort_on_warning_saved;
 
6272
  }
6186
6273
  return(thd->is_error());
6187
6274
err:
6188
 
  thd->abort_on_warning= abort_on_warning_saved;
6189
6275
  if (table)
6190
6276
    table->auto_increment_field_not_null= false;
6191
6277
  return(true);
6214
6300
 
6215
6301
bool
6216
6302
fill_record(THD *thd, Field **ptr, List<Item> &values,
6217
 
            bool ignore_errors __attribute__((unused)))
 
6303
            bool ignore_errors __attribute__((__unused__)))
6218
6304
{
6219
6305
  List_iterator_fast<Item> v(values);
6220
6306
  Item *value;
6221
 
  Table *table= 0;
 
6307
  TABLE *table= 0;
 
6308
 
6222
6309
  Field *field;
6223
 
  List<Table> tbl_list;
6224
 
  bool abort_on_warning_saved= thd->abort_on_warning;
6225
 
  
6226
 
  tbl_list.empty();
6227
6310
  /*
6228
6311
    Reset the table->auto_increment_field_not_null as it is valid for
6229
6312
    only one row.
6243
6326
    table= field->table;
6244
6327
    if (field == table->next_number_field)
6245
6328
      table->auto_increment_field_not_null= true;
6246
 
    if (field->vcol_info && 
6247
 
        value->type() != Item::DEFAULT_VALUE_ITEM && 
6248
 
        value->type() != Item::NULL_ITEM &&
6249
 
        table->s->table_category != TABLE_CATEGORY_TEMPORARY)
6250
 
    {
6251
 
      thd->abort_on_warning= false;
6252
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
6253
 
                          ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN,
6254
 
                          ER(ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN),
6255
 
                          field->field_name, table->s->table_name.str);
6256
 
      thd->abort_on_warning= abort_on_warning_saved;
6257
 
    }
6258
6329
    if (value->save_in_field(field, 0) < 0)
6259
6330
      goto err;
6260
 
    tbl_list.push_back(table);
6261
 
  }
6262
 
  /* Update virtual fields*/
6263
 
  thd->abort_on_warning= false;
6264
 
  if (tbl_list.head())
6265
 
  {
6266
 
    List_iterator_fast<Table> t(tbl_list);
6267
 
    Table *prev_table= 0;
6268
 
    while ((table= t++))
6269
 
    {
6270
 
      /*
6271
 
        Do simple optimization to prevent unnecessary re-generating 
6272
 
        values for virtual fields
6273
 
      */
6274
 
      if (table != prev_table)
6275
 
      {
6276
 
        prev_table= table;
6277
 
        if (table->vfield)
6278
 
        {
6279
 
          if (update_virtual_fields_marked_for_write(table, false))
6280
 
          {
6281
 
            goto err;
6282
 
          }
6283
 
        }
6284
 
      }
6285
 
    }
6286
 
  }
6287
 
  thd->abort_on_warning= abort_on_warning_saved;
 
6331
  }
6288
6332
  return(thd->is_error());
6289
6333
 
6290
6334
err:
6291
 
  thd->abort_on_warning= abort_on_warning_saved;
6292
6335
  if (table)
6293
6336
    table->auto_increment_field_not_null= false;
6294
6337
  return(true);
6295
6338
}
6296
6339
 
6297
6340
 
6298
 
bool mysql_rm_tmp_tables(void)
 
6341
my_bool mysql_rm_tmp_tables(void)
6299
6342
{
6300
 
  uint32_t i, idx;
 
6343
  uint i, idx;
6301
6344
  char  filePath[FN_REFLEN], *tmpdir, filePathCopy[FN_REFLEN];
6302
6345
  MY_DIR *dirp;
6303
6346
  FILEINFO *file;
6327
6370
                                   (file->name[1] == '.' &&  !file->name[2])))
6328
6371
        continue;
6329
6372
 
6330
 
      if (!memcmp(file->name, tmp_file_prefix, tmp_file_prefix_length))
 
6373
      if (!bcmp((uchar*) file->name, (uchar*) tmp_file_prefix,
 
6374
                tmp_file_prefix_length))
6331
6375
      {
6332
6376
        char *ext= fn_ext(file->name);
6333
 
        uint32_t ext_len= strlen(ext);
6334
 
        uint32_t filePath_len= snprintf(filePath, sizeof(filePath),
 
6377
        uint ext_len= strlen(ext);
 
6378
        uint filePath_len= snprintf(filePath, sizeof(filePath),
6335
6379
                                    "%s%c%s", tmpdir, FN_LIBCHAR,
6336
6380
                                    file->name);
6337
 
        if (!memcmp(reg_ext, ext, ext_len))
 
6381
        if (!bcmp((uchar*) reg_ext, (uchar*) ext, ext_len))
6338
6382
        {
6339
6383
          handler *handler_file= 0;
6340
6384
          /* We should cut file extention before deleting of table */
6355
6399
          So we hide error messages which happnes during deleting of these
6356
6400
          files(MYF(0)).
6357
6401
        */
6358
 
        my_delete(filePath, MYF(0)); 
 
6402
        VOID(my_delete(filePath, MYF(0))); 
6359
6403
      }
6360
6404
    }
6361
6405
    my_dirend(dirp);
6386
6430
 
6387
6431
void remove_db_from_cache(const char *db)
6388
6432
{
6389
 
  for (uint32_t idx=0 ; idx < open_cache.records ; idx++)
 
6433
  for (uint idx=0 ; idx < open_cache.records ; idx++)
6390
6434
  {
6391
 
    Table *table=(Table*) hash_element(&open_cache,idx);
 
6435
    TABLE *table=(TABLE*) hash_element(&open_cache,idx);
6392
6436
    if (!strcmp(table->s->db.str, db))
6393
6437
    {
6394
6438
      table->s->version= 0L;                    /* Free when thread is ready */
6397
6441
    }
6398
6442
  }
6399
6443
  while (unused_tables && !unused_tables->s->version)
6400
 
    hash_delete(&open_cache,(unsigned char*) unused_tables);
 
6444
    VOID(hash_delete(&open_cache,(uchar*) unused_tables));
6401
6445
}
6402
6446
 
6403
6447
 
6413
6457
{
6414
6458
  (void) pthread_mutex_lock(&LOCK_open);
6415
6459
  while (unused_tables)
6416
 
    hash_delete(&open_cache,(unsigned char*) unused_tables);
 
6460
    hash_delete(&open_cache,(uchar*) unused_tables);
6417
6461
  (void) pthread_mutex_unlock(&LOCK_open);
6418
6462
}
6419
6463
 
6434
6478
*/
6435
6479
 
6436
6480
bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
6437
 
                             uint32_t flags)
 
6481
                             uint flags)
6438
6482
{
6439
6483
  char key[MAX_DBKEY_LENGTH];
6440
 
  uint32_t key_length;
6441
 
  Table *table;
 
6484
  uint key_length;
 
6485
  TABLE *table;
6442
6486
  TABLE_SHARE *share;
6443
6487
  bool result= 0, signalled= 0;
6444
6488
 
6445
 
  key_length=(uint) (my_stpcpy(my_stpcpy(key,db)+1,table_name)-key)+1;
 
6489
  key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1;
6446
6490
  for (;;)
6447
6491
  {
6448
6492
    HASH_SEARCH_STATE state;
6449
6493
    result= signalled= 0;
6450
6494
 
6451
 
    for (table= (Table*) hash_first(&open_cache, (unsigned char*) key, key_length,
 
6495
    for (table= (TABLE*) hash_first(&open_cache, (uchar*) key, key_length,
6452
6496
                                    &state);
6453
6497
         table;
6454
 
         table= (Table*) hash_next(&open_cache, (unsigned char*) key, key_length,
 
6498
         table= (TABLE*) hash_next(&open_cache, (uchar*) key, key_length,
6455
6499
                                   &state))
6456
6500
    {
6457
6501
      THD *in_use;
6482
6526
          open_tables list. Aborting the MERGE lock after a child was
6483
6527
          closed and before the parent is closed would be fatal.
6484
6528
        */
6485
 
        for (Table *thd_table= in_use->open_tables;
 
6529
        for (TABLE *thd_table= in_use->open_tables;
6486
6530
             thd_table ;
6487
6531
             thd_table= thd_table->next)
6488
6532
        {
6495
6539
        result= result || (flags & RTFC_OWNED_BY_THD_FLAG);
6496
6540
    }
6497
6541
    while (unused_tables && !unused_tables->s->version)
6498
 
      hash_delete(&open_cache,(unsigned char*) unused_tables);
 
6542
      VOID(hash_delete(&open_cache,(uchar*) unused_tables));
6499
6543
 
6500
6544
    /* Remove table from table definition cache if it's not in use */
6501
 
    if ((share= (TABLE_SHARE*) hash_search(&table_def_cache,(unsigned char*) key,
 
6545
    if ((share= (TABLE_SHARE*) hash_search(&table_def_cache,(uchar*) key,
6502
6546
                                           key_length)))
6503
6547
    {
6504
6548
      share->version= 0;                          // Mark for delete
6505
6549
      if (share->ref_count == 0)
6506
6550
      {
6507
6551
        pthread_mutex_lock(&share->mutex);
6508
 
        hash_delete(&table_def_cache, (unsigned char*) share);
 
6552
        VOID(hash_delete(&table_def_cache, (uchar*) share));
6509
6553
      }
6510
6554
    }
6511
6555
 
6528
6572
            It can happen that another thread has opened the
6529
6573
            table but has not yet locked any table at all. Since
6530
6574
            it can be locked waiting for a table that our thread
6531
 
            has done LOCK Table x WRITE on previously, we need to
 
6575
            has done LOCK TABLE x WRITE on previously, we need to
6532
6576
            ensure that the thread actually hears our signal
6533
6577
            before we go to sleep. Thus we wait for a short time
6534
6578
            and then we retry another loop in the
6551
6595
{
6552
6596
  return a->length == b->length && !strncmp(a->str, b->str, a->length);
6553
6597
}
 
6598
 
 
6599
 
 
6600
/*
 
6601
  Open and lock system tables for read.
 
6602
 
 
6603
  SYNOPSIS
 
6604
    open_system_tables_for_read()
 
6605
      thd         Thread context.
 
6606
      table_list  List of tables to open.
 
6607
      backup      Pointer to Open_tables_state instance where
 
6608
                  information about currently open tables will be
 
6609
                  saved, and from which will be restored when we will
 
6610
                  end work with system tables.
 
6611
 
 
6612
  NOTES
 
6613
    Thanks to restrictions which we put on opening and locking of
 
6614
    system tables for writing, we can open and lock them for reading
 
6615
    even when we already have some other tables open and locked.  One
 
6616
    must call close_system_tables() to close systems tables opened
 
6617
    with this call.
 
6618
 
 
6619
  RETURN
 
6620
    false   Success
 
6621
    true    Error
 
6622
*/
 
6623
 
 
6624
bool
 
6625
open_system_tables_for_read(THD *thd, TABLE_LIST *table_list,
 
6626
                            Open_tables_state *backup)
 
6627
{
 
6628
  thd->reset_n_backup_open_tables_state(backup);
 
6629
 
 
6630
  uint count= 0;
 
6631
  bool not_used;
 
6632
  for (TABLE_LIST *tables= table_list; tables; tables= tables->next_global)
 
6633
  {
 
6634
    TABLE *table= open_table(thd, tables, thd->mem_root, &not_used,
 
6635
                             MYSQL_LOCK_IGNORE_FLUSH);
 
6636
    if (!table)
 
6637
      goto error;
 
6638
 
 
6639
    assert(table->s->table_category == TABLE_CATEGORY_SYSTEM);
 
6640
 
 
6641
    table->use_all_columns();
 
6642
    table->reginfo.lock_type= tables->lock_type;
 
6643
    tables->table= table;
 
6644
    count++;
 
6645
  }
 
6646
 
 
6647
  {
 
6648
    TABLE **list= (TABLE**) thd->alloc(sizeof(TABLE*) * count);
 
6649
    TABLE **ptr= list;
 
6650
    for (TABLE_LIST *tables= table_list; tables; tables= tables->next_global)
 
6651
      *(ptr++)= tables->table;
 
6652
 
 
6653
    thd->lock= mysql_lock_tables(thd, list, count,
 
6654
                                 MYSQL_LOCK_IGNORE_FLUSH, &not_used);
 
6655
  }
 
6656
  if (thd->lock)
 
6657
    return(false);
 
6658
 
 
6659
error:
 
6660
  close_system_tables(thd, backup);
 
6661
 
 
6662
  return(true);
 
6663
}
 
6664
 
 
6665
 
 
6666
/*
 
6667
  Close system tables, opened with open_system_tables_for_read().
 
6668
 
 
6669
  SYNOPSIS
 
6670
    close_system_tables()
 
6671
      thd     Thread context
 
6672
      backup  Pointer to Open_tables_state instance which holds
 
6673
              information about tables which were open before we
 
6674
              decided to access system tables.
 
6675
*/
 
6676
 
 
6677
void
 
6678
close_system_tables(THD *thd, Open_tables_state *backup)
 
6679
{
 
6680
  close_thread_tables(thd);
 
6681
  thd->restore_backup_open_tables_state(backup);
 
6682
}
 
6683
 
 
6684
 
 
6685
/*
 
6686
  Open and lock one system table for update.
 
6687
 
 
6688
  SYNOPSIS
 
6689
    open_system_table_for_update()
 
6690
      thd        Thread context.
 
6691
      one_table  Table to open.
 
6692
 
 
6693
  NOTES
 
6694
    Table opened with this call should closed using close_thread_tables().
 
6695
 
 
6696
  RETURN
 
6697
    0   Error
 
6698
    #   Pointer to TABLE object of system table
 
6699
*/
 
6700
 
 
6701
TABLE *
 
6702
open_system_table_for_update(THD *thd, TABLE_LIST *one_table)
 
6703
{
 
6704
  TABLE *table= open_ltable(thd, one_table, one_table->lock_type, 0);
 
6705
  if (table)
 
6706
  {
 
6707
    assert(table->s->table_category == TABLE_CATEGORY_SYSTEM);
 
6708
    table->use_all_columns();
 
6709
  }
 
6710
 
 
6711
  return(table);
 
6712
}
 
6713
 
6554
6714
/**
6555
6715
  @} (end of group Data_Dictionary)
6556
6716
*/