~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_base.cc

  • Committer: Monty Taylor
  • Date: 2008-09-15 17:24:04 UTC
  • Revision ID: monty@inaugust.com-20080915172404-ygh6hiyu0q7qpa9x
Removed strndup calls.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
#include <drizzled/server_includes.h>
19
19
#include <drizzled/sql_select.h>
20
20
#include <mysys/my_dir.h>
21
 
#include <drizzled/error.h>
22
 
#include <drizzled/gettext.h>
23
 
#include <drizzled/nested_join.h>
24
 
 
25
 
#if TIME_WITH_SYS_TIME
26
 
# include <sys/time.h>
27
 
# include <time.h>
28
 
#else
29
 
# if HAVE_SYS_TIME_H
30
 
#  include <sys/time.h>
31
 
# else
32
 
#  include <time.h>
33
 
# endif
34
 
#endif
35
 
 
36
 
/**
37
 
  return true if the table was created explicitly.
38
 
*/
39
 
inline bool is_user_table(Table * table)
40
 
{
41
 
  const char *name= table->s->table_name.str;
42
 
  return strncmp(name, tmp_file_prefix, tmp_file_prefix_length);
43
 
}
44
 
 
 
21
#include <drizzled/drizzled_error_messages.h>
 
22
#include <libdrizzle/gettext.h>
 
23
 
 
24
#define FLAGSTR(S,F) ((S) & (F) ? #F " " : "")
45
25
 
46
26
/**
47
27
  @defgroup Data_Dictionary Data Dictionary
54
34
static pthread_mutex_t LOCK_table_share;
55
35
static bool table_def_inited= 0;
56
36
 
57
 
static int open_unireg_entry(Session *session, Table *entry, TableList *table_list,
 
37
static int open_unireg_entry(THD *thd, Table *entry, TableList *table_list,
58
38
                             const char *alias,
59
 
                             char *cache_key, uint32_t cache_key_length);
 
39
                             char *cache_key, uint cache_key_length);
60
40
static void free_cache_entry(Table *entry);
61
 
static void close_old_data_files(Session *session, Table *table, bool morph_locks,
 
41
static void close_old_data_files(THD *thd, Table *table, bool morph_locks,
62
42
                                 bool send_refresh);
63
43
 
64
44
 
65
 
extern "C" unsigned char *table_cache_key(const unsigned char *record, size_t *length,
 
45
extern "C" uchar *table_cache_key(const uchar *record, size_t *length,
66
46
                                  bool not_used __attribute__((unused)))
67
47
{
68
48
  Table *entry=(Table*) record;
69
49
  *length= entry->s->table_cache_key.length;
70
 
  return (unsigned char*) entry->s->table_cache_key.str;
 
50
  return (uchar*) entry->s->table_cache_key.str;
71
51
}
72
52
 
73
53
 
89
69
  return;
90
70
}
91
71
 
92
 
uint32_t cached_open_tables(void)
 
72
uint cached_open_tables(void)
93
73
{
94
74
  return open_cache.records;
95
75
}
99
79
 
100
80
  SYNOPSIS
101
81
    create_table_def_key()
102
 
    session                     Thread handler
 
82
    thd                 Thread handler
103
83
    key                 Create key here (must be of size MAX_DBKEY_LENGTH)
104
84
    table_list          Table definition
105
85
    tmp_table           Set if table is a tmp table
119
99
    Length of key
120
100
*/
121
101
 
122
 
uint32_t create_table_def_key(Session *session, char *key, TableList *table_list,
 
102
uint create_table_def_key(THD *thd, char *key, TableList *table_list,
123
103
                          bool tmp_table)
124
104
{
125
 
  uint32_t key_length= (uint) (my_stpcpy(my_stpcpy(key, table_list->db)+1,
 
105
  uint key_length= (uint) (stpcpy(stpcpy(key, table_list->db)+1,
126
106
                                  table_list->table_name)-key)+1;
127
107
  if (tmp_table)
128
108
  {
129
 
    int4store(key + key_length, session->server_id);
130
 
    int4store(key + key_length + 4, session->variables.pseudo_thread_id);
 
109
    int4store(key + key_length, thd->server_id);
 
110
    int4store(key + key_length + 4, thd->variables.pseudo_thread_id);
131
111
    key_length+= TMP_TABLE_KEY_EXTRA;
132
112
  }
133
113
  return key_length;
139
119
  Functions to handle table definition cach (TABLE_SHARE)
140
120
*****************************************************************************/
141
121
 
142
 
extern "C" unsigned char *table_def_key(const unsigned char *record, size_t *length,
 
122
extern "C" uchar *table_def_key(const uchar *record, size_t *length,
143
123
                                bool not_used __attribute__((unused)))
144
124
{
145
125
  TABLE_SHARE *entry=(TABLE_SHARE*) record;
146
126
  *length= entry->table_cache_key.length;
147
 
  return (unsigned char*) entry->table_cache_key.str;
 
127
  return (uchar*) entry->table_cache_key.str;
148
128
}
149
129
 
150
130
 
188
168
}
189
169
 
190
170
 
191
 
uint32_t cached_table_definitions(void)
 
171
uint cached_table_definitions(void)
192
172
{
193
173
  return table_def_cache.records;
194
174
}
198
178
  Get TABLE_SHARE for a table.
199
179
 
200
180
  get_table_share()
201
 
  session                       Thread handle
 
181
  thd                   Thread handle
202
182
  table_list            Table that should be opened
203
183
  key                   Table cache key
204
184
  key_length            Length of key
219
199
   #  Share for table
220
200
*/
221
201
 
222
 
TABLE_SHARE *get_table_share(Session *session, TableList *table_list, char *key,
223
 
                             uint32_t key_length, uint32_t db_flags, int *error)
 
202
TABLE_SHARE *get_table_share(THD *thd, TableList *table_list, char *key,
 
203
                             uint key_length, uint db_flags, int *error)
224
204
{
225
205
  TABLE_SHARE *share;
226
206
 
227
207
  *error= 0;
228
208
 
229
209
  /* Read table definition from cache */
230
 
  if ((share= (TABLE_SHARE*) hash_search(&table_def_cache,(unsigned char*) key,
 
210
  if ((share= (TABLE_SHARE*) hash_search(&table_def_cache,(uchar*) key,
231
211
                                         key_length)))
232
212
    goto found;
233
213
 
257
237
   */
258
238
  assign_new_table_id(share);
259
239
 
260
 
  if (my_hash_insert(&table_def_cache, (unsigned char*) share))
 
240
  if (my_hash_insert(&table_def_cache, (uchar*) share))
261
241
  {
262
242
    free_table_share(share);
263
243
    return(0);                          // return error
264
244
  }
265
 
  if (open_table_def(session, share, db_flags))
 
245
  if (open_table_def(thd, share, db_flags))
266
246
  {
267
247
    *error= share->error;
268
 
    (void) hash_delete(&table_def_cache, (unsigned char*) share);
 
248
    (void) hash_delete(&table_def_cache, (uchar*) share);
269
249
    return(0);
270
250
  }
271
251
  share->ref_count++;                           // Mark in use
308
288
         oldest_unused_share->next)
309
289
  {
310
290
    pthread_mutex_lock(&oldest_unused_share->mutex);
311
 
    hash_delete(&table_def_cache, (unsigned char*) oldest_unused_share);
 
291
    VOID(hash_delete(&table_def_cache, (uchar*) oldest_unused_share));
312
292
  }
313
293
 
314
294
  return(share);
322
302
*/
323
303
 
324
304
static TABLE_SHARE
325
 
*get_table_share_with_create(Session *session, TableList *table_list,
326
 
                             char *key, uint32_t key_length,
327
 
                             uint32_t db_flags, int *error)
 
305
*get_table_share_with_create(THD *thd, TableList *table_list,
 
306
                             char *key, uint key_length,
 
307
                             uint db_flags, int *error)
328
308
{
329
309
  TABLE_SHARE *share;
330
310
  int tmp;
331
311
 
332
 
  share= get_table_share(session, table_list, key, key_length, db_flags, error);
 
312
  share= get_table_share(thd, table_list, key, key_length, db_flags, error);
333
313
  /*
334
314
    If share is not NULL, we found an existing share.
335
315
 
349
329
 
350
330
    @todo Rework alternative ways to deal with ER_NO_SUCH Table.
351
331
  */
352
 
  if (share || (session->is_error() && (session->main_da.sql_errno() != ER_NO_SUCH_TABLE)))
 
332
  if (share || (thd->is_error() && (thd->main_da.sql_errno() != ER_NO_SUCH_TABLE)))
353
333
 
354
334
    return(share);
355
335
 
356
336
  /* Table didn't exist. Check if some engine can provide it */
357
 
  if ((tmp= ha_create_table_from_engine(session, table_list->db,
 
337
  if ((tmp= ha_create_table_from_engine(thd, table_list->db,
358
338
                                        table_list->table_name)) < 0)
359
339
    return(0);
360
340
 
361
341
  if (tmp)
362
342
  {
363
343
    /* Give right error message */
364
 
    session->clear_error();
 
344
    thd->clear_error();
365
345
    my_printf_error(ER_UNKNOWN_ERROR,
366
346
                    "Failed to open '%-.64s', error while "
367
347
                    "unpacking from engine",
369
349
    return(0);
370
350
  }
371
351
  /* Table existed in engine. Let's open it */
372
 
  drizzle_reset_errors(session, 1);                   // Clear warnings
373
 
  session->clear_error();                           // Clear error message
374
 
  return(get_table_share(session, table_list, key, key_length,
 
352
  drizzle_reset_errors(thd, 1);                   // Clear warnings
 
353
  thd->clear_error();                           // Clear error message
 
354
  return(get_table_share(thd, table_list, key, key_length,
375
355
                              db_flags, error));
376
356
}
377
357
 
426
406
 
427
407
  if (to_be_deleted)
428
408
  {
429
 
    hash_delete(&table_def_cache, (unsigned char*) share);
 
409
    hash_delete(&table_def_cache, (uchar*) share);
430
410
    return;
431
411
  }
432
412
  pthread_mutex_unlock(&share->mutex);
451
431
{
452
432
  char key[NAME_LEN*2+2];
453
433
  TableList table_list;
454
 
  uint32_t key_length;
 
434
  uint key_length;
455
435
  safe_mutex_assert_owner(&LOCK_open);
456
436
 
457
437
  table_list.db= (char*) db;
458
438
  table_list.table_name= (char*) table_name;
459
 
  key_length= create_table_def_key((Session*) 0, key, &table_list, 0);
460
 
  return (TABLE_SHARE*) hash_search(&table_def_cache,(unsigned char*) key, key_length);
 
439
  key_length= create_table_def_key((THD*) 0, key, &table_list, 0);
 
440
  return (TABLE_SHARE*) hash_search(&table_def_cache,(uchar*) key, key_length);
461
441
}  
462
442
 
463
443
 
472
452
    By leaving the table in the table cache, it disallows any other thread
473
453
    to open the table
474
454
 
475
 
    session->killed will be set if we run out of memory
 
455
    thd->killed will be set if we run out of memory
476
456
 
477
457
    If closing a MERGE child, the calling function has to take care for
478
458
    closing the parent too, if necessary.
519
499
 
520
500
  SYNOPSIS
521
501
    list_open_tables()
522
 
    session                     Thread Session
 
502
    thd                 Thread THD
523
503
    wild                SQL like expression
524
504
 
525
505
  NOTES
532
512
    #           Pointer to list of names of open tables.
533
513
*/
534
514
 
535
 
OPEN_TableList *list_open_tables(Session *session __attribute__((unused)),
 
515
OPEN_TableList *list_open_tables(THD *thd __attribute__((unused)),
536
516
                                  const char *db, const char *wild)
537
517
{
538
518
  int result = 0;
539
519
  OPEN_TableList **start_list, *open_list;
540
520
  TableList table_list;
541
521
 
542
 
  pthread_mutex_lock(&LOCK_open);
 
522
  VOID(pthread_mutex_lock(&LOCK_open));
543
523
  memset(&table_list, 0, sizeof(table_list));
544
524
  start_list= &open_list;
545
525
  open_list=0;
546
526
 
547
 
  for (uint32_t idx=0 ; result == 0 && idx < open_cache.records; idx++)
 
527
  for (uint idx=0 ; result == 0 && idx < open_cache.records; idx++)
548
528
  {
549
529
    OPEN_TableList *table;
550
530
    Table *entry=(Table*) hash_element(&open_cache,idx);
580
560
      open_list=0;                              // Out of memory
581
561
      break;
582
562
    }
583
 
    my_stpcpy((*start_list)->table=
584
 
           my_stpcpy(((*start_list)->db= (char*) ((*start_list)+1)),
 
563
    stpcpy((*start_list)->table=
 
564
           stpcpy(((*start_list)->db= (char*) ((*start_list)+1)),
585
565
                  share->db.str)+1,
586
566
           share->table_name.str);
587
567
    (*start_list)->in_use= entry->in_use ? 1 : 0;
589
569
    start_list= &(*start_list)->next;
590
570
    *start_list=0;
591
571
  }
592
 
  pthread_mutex_unlock(&LOCK_open);
 
572
  VOID(pthread_mutex_unlock(&LOCK_open));
593
573
  return(open_list);
594
574
}
595
575
 
602
582
{                                               // Free all structures
603
583
  free_io_cache(table);
604
584
  if (table->file)                              // Not true if name lock
605
 
    closefrm(table, 1);                 // close file
 
585
    VOID(closefrm(table, 1));                   // close file
606
586
  return;
607
587
}
608
588
 
631
611
        unused_tables=0;
632
612
    }
633
613
  }
634
 
  free((unsigned char*) table);
 
614
  my_free((uchar*) table,MYF(0));
635
615
  return;
636
616
}
637
617
 
642
622
  if (table->sort.io_cache)
643
623
  {
644
624
    close_cached_file(table->sort.io_cache);
645
 
    free((unsigned char*) table->sort.io_cache);
 
625
    my_free((uchar*) table->sort.io_cache,MYF(0));
646
626
    table->sort.io_cache=0;
647
627
  }
648
628
  return;
652
632
/*
653
633
  Close all tables which aren't in use by any thread
654
634
 
655
 
  @param session Thread context
 
635
  @param thd Thread context
656
636
  @param tables List of tables to remove from the cache
657
637
  @param have_lock If LOCK_open is locked
658
638
  @param wait_for_refresh Wait for a impending flush
660
640
         won't proceed while write-locked tables are being reopened by other
661
641
         threads.
662
642
 
663
 
  @remark Session can be NULL, but then wait_for_refresh must be false
 
643
  @remark THD can be NULL, but then wait_for_refresh must be false
664
644
          and tables must be NULL.
665
645
*/
666
646
 
667
 
bool close_cached_tables(Session *session, TableList *tables, bool have_lock,
 
647
bool close_cached_tables(THD *thd, TableList *tables, bool have_lock,
668
648
                         bool wait_for_refresh, bool wait_for_placeholders)
669
649
{
670
650
  bool result=0;
671
 
  assert(session || (!wait_for_refresh && !tables));
 
651
  assert(thd || (!wait_for_refresh && !tables));
672
652
 
673
653
  if (!have_lock)
674
 
    pthread_mutex_lock(&LOCK_open);
 
654
    VOID(pthread_mutex_lock(&LOCK_open));
675
655
  if (!tables)
676
656
  {
677
657
    refresh_version++;                          // Force close of open tables
678
658
    while (unused_tables)
679
659
    {
680
660
#ifdef EXTRA_DEBUG
681
 
      if (hash_delete(&open_cache,(unsigned char*) unused_tables))
 
661
      if (hash_delete(&open_cache,(uchar*) unused_tables))
682
662
        printf("Warning: Couldn't delete open table from hash\n");
683
663
#else
684
 
      hash_delete(&open_cache,(unsigned char*) unused_tables);
 
664
      VOID(hash_delete(&open_cache,(uchar*) unused_tables));
685
665
#endif
686
666
    }
687
667
    /* Free table shares */
688
668
    while (oldest_unused_share->next)
689
669
    {
690
670
      pthread_mutex_lock(&oldest_unused_share->mutex);
691
 
      hash_delete(&table_def_cache, (unsigned char*) oldest_unused_share);
 
671
      VOID(hash_delete(&table_def_cache, (uchar*) oldest_unused_share));
692
672
    }
693
673
    if (wait_for_refresh)
694
674
    {
729
709
        after the call to close_old_data_files() i.e. after removal of
730
710
        current thread locks.
731
711
      */
732
 
      for (uint32_t idx=0 ; idx < open_cache.records ; idx++)
 
712
      for (uint idx=0 ; idx < open_cache.records ; idx++)
733
713
      {
734
714
        Table *table=(Table*) hash_element(&open_cache,idx);
735
715
        if (table->in_use)
742
722
    bool found=0;
743
723
    for (TableList *table= tables; table; table= table->next_local)
744
724
    {
745
 
      if (remove_table_from_cache(session, table->db, table->table_name,
746
 
                                  RTFC_OWNED_BY_Session_FLAG))
 
725
      if (remove_table_from_cache(thd, table->db, table->table_name,
 
726
                                  RTFC_OWNED_BY_THD_FLAG))
747
727
        found=1;
748
728
    }
749
729
    if (!found)
756
736
      If there is any table that has a lower refresh_version, wait until
757
737
      this is closed (or this thread is killed) before returning
758
738
    */
759
 
    session->mysys_var->current_mutex= &LOCK_open;
760
 
    session->mysys_var->current_cond= &COND_refresh;
761
 
    session->set_proc_info("Flushing tables");
 
739
    thd->mysys_var->current_mutex= &LOCK_open;
 
740
    thd->mysys_var->current_cond= &COND_refresh;
 
741
    thd_proc_info(thd, "Flushing tables");
762
742
 
763
 
    close_old_data_files(session,session->open_tables,1,1);
764
 
    mysql_ha_flush(session);
 
743
    close_old_data_files(thd,thd->open_tables,1,1);
 
744
    mysql_ha_flush(thd);
765
745
 
766
746
    bool found=1;
767
747
    /* Wait until all threads has closed all the tables we had locked */
768
 
    while (found && ! session->killed)
 
748
    while (found && ! thd->killed)
769
749
    {
770
750
      found=0;
771
 
      for (uint32_t idx=0 ; idx < open_cache.records ; idx++)
 
751
      for (uint idx=0 ; idx < open_cache.records ; idx++)
772
752
      {
773
753
        Table *table=(Table*) hash_element(&open_cache,idx);
774
754
        /* Avoid a self-deadlock. */
775
 
        if (table->in_use == session)
 
755
        if (table->in_use == thd)
776
756
          continue;
777
757
        /*
778
758
          Note that we wait here only for tables which are actually open, and
802
782
      old locks. This should always succeed (unless some external process
803
783
      has removed the tables)
804
784
    */
805
 
    session->in_lock_tables=1;
806
 
    result=reopen_tables(session,1,1);
807
 
    session->in_lock_tables=0;
 
785
    thd->in_lock_tables=1;
 
786
    result=reopen_tables(thd,1,1);
 
787
    thd->in_lock_tables=0;
808
788
    /* Set version for table */
809
 
    for (Table *table=session->open_tables; table ; table= table->next)
 
789
    for (Table *table=thd->open_tables; table ; table= table->next)
810
790
    {
811
791
      /*
812
792
        Preserve the version (0) of write locked tables so that a impending
817
797
    }
818
798
  }
819
799
  if (!have_lock)
820
 
    pthread_mutex_unlock(&LOCK_open);
 
800
    VOID(pthread_mutex_unlock(&LOCK_open));
821
801
  if (wait_for_refresh)
822
802
  {
823
 
    pthread_mutex_lock(&session->mysys_var->mutex);
824
 
    session->mysys_var->current_mutex= 0;
825
 
    session->mysys_var->current_cond= 0;
826
 
    session->set_proc_info(0);
827
 
    pthread_mutex_unlock(&session->mysys_var->mutex);
 
803
    pthread_mutex_lock(&thd->mysys_var->mutex);
 
804
    thd->mysys_var->current_mutex= 0;
 
805
    thd->mysys_var->current_cond= 0;
 
806
    thd_proc_info(thd, 0);
 
807
    pthread_mutex_unlock(&thd->mysys_var->mutex);
828
808
  }
829
809
  return(result);
830
810
}
835
815
  if specified string is NULL, then any table with a connection string.
836
816
*/
837
817
 
838
 
bool close_cached_connection_tables(Session *session, bool if_wait_for_refresh,
 
818
bool close_cached_connection_tables(THD *thd, bool if_wait_for_refresh,
839
819
                                    LEX_STRING *connection, bool have_lock)
840
820
{
841
 
  uint32_t idx;
 
821
  uint idx;
842
822
  TableList tmp, *tables= NULL;
843
823
  bool result= false;
844
 
  assert(session);
 
824
  assert(thd);
845
825
 
846
826
  memset(&tmp, 0, sizeof(TableList));
847
827
 
848
828
  if (!have_lock)
849
 
    pthread_mutex_lock(&LOCK_open);
 
829
    VOID(pthread_mutex_lock(&LOCK_open));
850
830
 
851
831
  for (idx= 0; idx < table_def_cache.records; idx++)
852
832
  {
871
851
    tmp.table_name= share->table_name.str;
872
852
    tmp.next_local= tables;
873
853
 
874
 
    tables= (TableList *) memdup_root(session->mem_root, (char*)&tmp, 
 
854
    tables= (TableList *) memdup_root(thd->mem_root, (char*)&tmp, 
875
855
                                       sizeof(TableList));
876
856
  }
877
857
 
878
858
  if (tables)
879
 
    result= close_cached_tables(session, tables, true, false, false);
 
859
    result= close_cached_tables(thd, tables, true, false, false);
880
860
 
881
861
  if (!have_lock)
882
 
    pthread_mutex_unlock(&LOCK_open);
 
862
    VOID(pthread_mutex_unlock(&LOCK_open));
883
863
 
884
864
  if (if_wait_for_refresh)
885
865
  {
886
 
    pthread_mutex_lock(&session->mysys_var->mutex);
887
 
    session->mysys_var->current_mutex= 0;
888
 
    session->mysys_var->current_cond= 0;
889
 
    session->set_proc_info(0);
890
 
    pthread_mutex_unlock(&session->mysys_var->mutex);
 
866
    pthread_mutex_lock(&thd->mysys_var->mutex);
 
867
    thd->mysys_var->current_mutex= 0;
 
868
    thd->mysys_var->current_cond= 0;
 
869
    thd->set_proc_info(0);
 
870
    pthread_mutex_unlock(&thd->mysys_var->mutex);
891
871
  }
892
872
 
893
873
  return(result);
898
878
  Mark all temporary tables which were used by the current statement or
899
879
  substatement as free for reuse, but only if the query_id can be cleared.
900
880
 
901
 
  @param session thread context
 
881
  @param thd thread context
902
882
 
903
883
  @remark For temp tables associated with a open SQL HANDLER the query_id
904
884
          is not reset until the HANDLER is closed.
905
885
*/
906
886
 
907
 
static void mark_temp_tables_as_free_for_reuse(Session *session)
 
887
static void mark_temp_tables_as_free_for_reuse(THD *thd)
908
888
{
909
 
  for (Table *table= session->temporary_tables ; table ; table= table->next)
 
889
  for (Table *table= thd->temporary_tables ; table ; table= table->next)
910
890
  {
911
 
    if ((table->query_id == session->query_id) && ! table->open_by_handler)
 
891
    if ((table->query_id == thd->query_id) && ! table->open_by_handler)
912
892
    {
913
893
      table->query_id= 0;
914
894
      table->file->ha_reset();
923
903
 
924
904
  SYNOPSIS
925
905
    mark_used_tables_as_free_for_reuse()
926
 
      session   - thread context
 
906
      thd   - thread context
927
907
      table - head of the list of tables
928
908
 
929
909
  DESCRIPTION
932
912
 
933
913
  NOTE
934
914
    The reason we reset query_id is that it's not enough to just test
935
 
    if table->query_id != session->query_id to know if a table is in use.
 
915
    if table->query_id != thd->query_id to know if a table is in use.
936
916
 
937
917
    For example
938
918
    SELECT f1_that_uses_t1() FROM t1;
940
920
    set to query_id of original query.
941
921
*/
942
922
 
943
 
static void mark_used_tables_as_free_for_reuse(Session *session, Table *table)
 
923
static void mark_used_tables_as_free_for_reuse(THD *thd, Table *table)
944
924
{
945
925
  for (; table ; table= table->next)
946
926
  {
947
 
    if (table->query_id == session->query_id)
 
927
    if (table->query_id == thd->query_id)
948
928
    {
949
929
      table->query_id= 0;
950
930
      table->file->ha_reset();
956
936
/**
957
937
  Auxiliary function to close all tables in the open_tables list.
958
938
 
959
 
  @param session Thread context.
 
939
  @param thd Thread context.
960
940
 
961
941
  @remark It should not ordinarily be called directly.
962
942
*/
963
943
 
964
 
static void close_open_tables(Session *session)
 
944
static void close_open_tables(THD *thd)
965
945
{
966
946
  bool found_old_table= 0;
967
947
 
968
948
  safe_mutex_assert_not_owner(&LOCK_open);
969
949
 
970
 
  pthread_mutex_lock(&LOCK_open);
 
950
  VOID(pthread_mutex_lock(&LOCK_open));
971
951
 
972
 
  while (session->open_tables)
973
 
    found_old_table|= close_thread_table(session, &session->open_tables);
974
 
  session->some_tables_deleted= 0;
 
952
  while (thd->open_tables)
 
953
    found_old_table|= close_thread_table(thd, &thd->open_tables);
 
954
  thd->some_tables_deleted= 0;
975
955
 
976
956
  /* Free tables to hold down open files */
977
957
  while (open_cache.records > table_cache_size && unused_tables)
978
 
    hash_delete(&open_cache,(unsigned char*) unused_tables); /* purecov: tested */
 
958
    VOID(hash_delete(&open_cache,(uchar*) unused_tables)); /* purecov: tested */
979
959
  if (found_old_table)
980
960
  {
981
961
    /* Tell threads waiting for refresh that something has happened */
982
962
    broadcast_refresh();
983
963
  }
984
964
 
985
 
  pthread_mutex_unlock(&LOCK_open);
 
965
  VOID(pthread_mutex_unlock(&LOCK_open));
986
966
}
987
967
 
988
968
 
992
972
 
993
973
  SYNOPSIS
994
974
    close_thread_tables()
995
 
    session                     Thread handler
 
975
    thd                 Thread handler
996
976
 
997
977
  IMPLEMENTATION
998
978
    Unlocks tables and frees derived tables.
1004
984
    leave prelocked mode if needed.
1005
985
*/
1006
986
 
1007
 
void close_thread_tables(Session *session)
 
987
void close_thread_tables(THD *thd)
1008
988
{
1009
989
  Table *table;
1010
990
 
1011
991
  /*
1012
 
    We are assuming here that session->derived_tables contains ONLY derived
 
992
    We are assuming here that thd->derived_tables contains ONLY derived
1013
993
    tables for this substatement. i.e. instead of approach which uses
1014
994
    query_id matching for determining which of the derived tables belong
1015
995
    to this substatement we rely on the ability of substatements to
1016
 
    save/restore session->derived_tables during their execution.
 
996
    save/restore thd->derived_tables during their execution.
1017
997
 
1018
998
    TODO: Probably even better approach is to simply associate list of
1019
999
          derived tables with (sub-)statement instead of thread and destroy
1020
1000
          them at the end of its execution.
1021
1001
  */
1022
 
  if (session->derived_tables)
 
1002
  if (thd->derived_tables)
1023
1003
  {
1024
1004
    Table *next;
1025
1005
    /*
1026
1006
      Close all derived tables generated in queries like
1027
1007
      SELECT * FROM (SELECT * FROM t1)
1028
1008
    */
1029
 
    for (table= session->derived_tables ; table ; table= next)
 
1009
    for (table= thd->derived_tables ; table ; table= next)
1030
1010
    {
1031
1011
      next= table->next;
1032
 
      table->free_tmp_table(session);
 
1012
      table->free_tmp_table(thd);
1033
1013
    }
1034
 
    session->derived_tables= 0;
 
1014
    thd->derived_tables= 0;
1035
1015
  }
1036
1016
 
1037
1017
  /*
1038
1018
    Mark all temporary tables used by this statement as free for reuse.
1039
1019
  */
1040
 
  mark_temp_tables_as_free_for_reuse(session);
 
1020
  mark_temp_tables_as_free_for_reuse(thd);
1041
1021
  /*
1042
1022
    Let us commit transaction for statement. Since in 5.0 we only have
1043
1023
    one statement transaction and don't allow several nested statement
1046
1026
    does not belong to statement for which we do close_thread_tables()).
1047
1027
    TODO: This should be fixed in later releases.
1048
1028
   */
1049
 
  if (!(session->state_flags & Open_tables_state::BACKUPS_AVAIL))
 
1029
  if (!(thd->state_flags & Open_tables_state::BACKUPS_AVAIL))
1050
1030
  {
1051
 
    session->main_da.can_overwrite_status= true;
1052
 
    ha_autocommit_or_rollback(session, session->is_error());
1053
 
    session->main_da.can_overwrite_status= false;
1054
 
    session->transaction.stmt.reset();
 
1031
    thd->main_da.can_overwrite_status= true;
 
1032
    ha_autocommit_or_rollback(thd, thd->is_error());
 
1033
    thd->main_da.can_overwrite_status= false;
 
1034
    thd->transaction.stmt.reset();
1055
1035
  }
1056
1036
 
1057
 
  if (session->locked_tables)
 
1037
  if (thd->locked_tables)
1058
1038
  {
1059
1039
 
1060
1040
    /* Ensure we are calling ha_reset() for all used tables */
1061
 
    mark_used_tables_as_free_for_reuse(session, session->open_tables);
 
1041
    mark_used_tables_as_free_for_reuse(thd, thd->open_tables);
1062
1042
 
1063
1043
    /*
1064
1044
      We are under simple LOCK TABLES so should not do anything else.
1066
1046
    return;
1067
1047
  }
1068
1048
 
1069
 
  if (session->lock)
 
1049
  if (thd->lock)
1070
1050
  {
1071
1051
    /*
1072
1052
      For RBR we flush the pending event just before we unlock all the
1077
1057
      handled either before writing a query log event (inside
1078
1058
      binlog_query()) or when preparing a pending event.
1079
1059
     */
1080
 
    session->binlog_flush_pending_rows_event(true);
1081
 
    mysql_unlock_tables(session, session->lock);
1082
 
    session->lock=0;
 
1060
    thd->binlog_flush_pending_rows_event(true);
 
1061
    mysql_unlock_tables(thd, thd->lock);
 
1062
    thd->lock=0;
1083
1063
  }
1084
1064
  /*
1085
1065
    Note that we need to hold LOCK_open while changing the
1088
1068
    Closing a MERGE child before the parent would be fatal if the
1089
1069
    other thread tries to abort the MERGE lock in between.
1090
1070
  */
1091
 
  if (session->open_tables)
1092
 
    close_open_tables(session);
 
1071
  if (thd->open_tables)
 
1072
    close_open_tables(thd);
1093
1073
 
1094
1074
  return;
1095
1075
}
1097
1077
 
1098
1078
/* move one table to free list */
1099
1079
 
1100
 
bool close_thread_table(Session *session, Table **table_ptr)
 
1080
bool close_thread_table(THD *thd, Table **table_ptr)
1101
1081
{
1102
1082
  bool found_old_table= 0;
1103
1083
  Table *table= *table_ptr;
1108
1088
  *table_ptr=table->next;
1109
1089
 
1110
1090
  if (table->needs_reopen_or_name_lock() ||
1111
 
      session->version != refresh_version || !table->db_stat)
 
1091
      thd->version != refresh_version || !table->db_stat)
1112
1092
  {
1113
 
    hash_delete(&open_cache,(unsigned char*) table);
 
1093
    VOID(hash_delete(&open_cache,(uchar*) table));
1114
1094
    found_old_table=1;
1115
1095
  }
1116
1096
  else
1139
1119
 
1140
1120
 
1141
1121
/* close_temporary_tables' internal, 4 is due to uint4korr definition */
1142
 
static inline uint32_t  tmpkeyval(Session *session __attribute__((unused)),
 
1122
static inline uint  tmpkeyval(THD *thd __attribute__((unused)),
1143
1123
                              Table *table)
1144
1124
{
1145
1125
  return uint4korr(table->s->table_cache_key.str + table->s->table_cache_key.length - 4);
1151
1131
  creates one DROP TEMPORARY Table binlog event for each pseudo-thread 
1152
1132
*/
1153
1133
 
1154
 
void close_temporary_tables(Session *session)
 
1134
void close_temporary_tables(THD *thd)
1155
1135
{
1156
1136
  Table *table;
1157
1137
  Table *next= NULL;
1158
1138
  Table *prev_table;
1159
 
  /* Assume session->options has OPTION_QUOTE_SHOW_CREATE */
 
1139
  /* Assume thd->options has OPTION_QUOTE_SHOW_CREATE */
1160
1140
  bool was_quote_show= true;
1161
1141
 
1162
 
  if (!session->temporary_tables)
 
1142
  if (!thd->temporary_tables)
1163
1143
    return;
1164
1144
 
1165
 
  if (!mysql_bin_log.is_open() || session->current_stmt_binlog_row_based)
 
1145
  if (!mysql_bin_log.is_open() || thd->current_stmt_binlog_row_based)
1166
1146
  {
1167
1147
    Table *tmp_next;
1168
 
    for (table= session->temporary_tables; table; table= tmp_next)
 
1148
    for (table= thd->temporary_tables; table; table= tmp_next)
1169
1149
    {
1170
1150
      tmp_next= table->next;
1171
1151
      close_temporary(table, 1, 1);
1172
1152
    }
1173
 
    session->temporary_tables= 0;
 
1153
    thd->temporary_tables= 0;
1174
1154
    return;
1175
1155
  }
1176
1156
 
1177
1157
  /* Better add "if exists", in case a RESET MASTER has been done */
1178
1158
  const char stub[]= "DROP /*!40005 TEMPORARY */ Table IF EXISTS ";
1179
 
  uint32_t stub_len= sizeof(stub) - 1;
 
1159
  uint stub_len= sizeof(stub) - 1;
1180
1160
  char buf[256];
1181
1161
  String s_query= String(buf, sizeof(buf), system_charset_info);
1182
1162
  bool found_user_tables= false;
1188
1168
    of sublists of equal pseudo_thread_id
1189
1169
  */
1190
1170
 
1191
 
  for (prev_table= session->temporary_tables, table= prev_table->next;
 
1171
  for (prev_table= thd->temporary_tables, table= prev_table->next;
1192
1172
       table;
1193
1173
       prev_table= table, table= table->next)
1194
1174
  {
1197
1177
    {
1198
1178
      if (!found_user_tables)
1199
1179
        found_user_tables= true;
1200
 
      for (prev_sorted= NULL, sorted= session->temporary_tables; sorted != table;
 
1180
      for (prev_sorted= NULL, sorted= thd->temporary_tables; sorted != table;
1201
1181
           prev_sorted= sorted, sorted= sorted->next)
1202
1182
      {
1203
1183
        if (!is_user_table(sorted) ||
1204
 
            tmpkeyval(session, sorted) > tmpkeyval(session, table))
 
1184
            tmpkeyval(thd, sorted) > tmpkeyval(thd, table))
1205
1185
        {
1206
1186
          /* move into the sorted part of the list from the unsorted */
1207
1187
          prev_table->next= table->next;
1212
1192
          }
1213
1193
          else
1214
1194
          {
1215
 
            session->temporary_tables= table;
 
1195
            thd->temporary_tables= table;
1216
1196
          }
1217
1197
          table= prev_table;
1218
1198
          break;
1223
1203
 
1224
1204
  /* We always quote db,table names though it is slight overkill */
1225
1205
  if (found_user_tables &&
1226
 
      !(was_quote_show= test(session->options & OPTION_QUOTE_SHOW_CREATE)))
 
1206
      !(was_quote_show= test(thd->options & OPTION_QUOTE_SHOW_CREATE)))
1227
1207
  {
1228
 
    session->options |= OPTION_QUOTE_SHOW_CREATE;
 
1208
    thd->options |= OPTION_QUOTE_SHOW_CREATE;
1229
1209
  }
1230
1210
 
1231
1211
  /* scan sorted tmps to generate sequence of DROP */
1232
 
  for (table= session->temporary_tables; table; table= next)
 
1212
  for (table= thd->temporary_tables; table; table= next)
1233
1213
  {
1234
1214
    if (is_user_table(table))
1235
1215
    {
1236
 
      my_thread_id save_pseudo_thread_id= session->variables.pseudo_thread_id;
 
1216
      my_thread_id save_pseudo_thread_id= thd->variables.pseudo_thread_id;
1237
1217
      /* Set pseudo_thread_id to be that of the processed table */
1238
 
      session->variables.pseudo_thread_id= tmpkeyval(session, table);
 
1218
      thd->variables.pseudo_thread_id= tmpkeyval(thd, table);
1239
1219
      /*
1240
1220
        Loop forward through all tables within the sublist of
1241
1221
        common pseudo_thread_id to create single DROP query.
1242
1222
      */
1243
1223
      for (s_query.length(stub_len);
1244
1224
           table && is_user_table(table) &&
1245
 
             tmpkeyval(session, table) == session->variables.pseudo_thread_id;
 
1225
             tmpkeyval(thd, table) == thd->variables.pseudo_thread_id;
1246
1226
           table= next)
1247
1227
      {
1248
1228
        /*
1249
1229
          We are going to add 4 ` around the db/table names and possible more
1250
1230
          due to special characters in the names
1251
1231
        */
1252
 
        append_identifier(session, &s_query, table->s->db.str, strlen(table->s->db.str));
 
1232
        append_identifier(thd, &s_query, table->s->db.str, strlen(table->s->db.str));
1253
1233
        s_query.append('.');
1254
 
        append_identifier(session, &s_query, table->s->table_name.str,
 
1234
        append_identifier(thd, &s_query, table->s->table_name.str,
1255
1235
                          strlen(table->s->table_name.str));
1256
1236
        s_query.append(',');
1257
1237
        next= table->next;
1258
1238
        close_temporary(table, 1, 1);
1259
1239
      }
1260
 
      session->clear_error();
1261
 
      const CHARSET_INFO * const cs_save= session->variables.character_set_client;
1262
 
      session->variables.character_set_client= system_charset_info;
1263
 
      Query_log_event qinfo(session, s_query.ptr(),
 
1240
      thd->clear_error();
 
1241
      const CHARSET_INFO * const cs_save= thd->variables.character_set_client;
 
1242
      thd->variables.character_set_client= system_charset_info;
 
1243
      Query_log_event qinfo(thd, s_query.ptr(),
1264
1244
                            s_query.length() - 1 /* to remove trailing ',' */,
1265
1245
                            0, false);
1266
 
      session->variables.character_set_client= cs_save;
 
1246
      thd->variables.character_set_client= cs_save;
1267
1247
      /*
1268
1248
        Imagine the thread had created a temp table, then was doing a
1269
1249
        SELECT, and the SELECT was killed. Then it's not clever to
1276
1256
      */
1277
1257
      qinfo.error_code= 0;
1278
1258
      mysql_bin_log.write(&qinfo);
1279
 
      session->variables.pseudo_thread_id= save_pseudo_thread_id;
 
1259
      thd->variables.pseudo_thread_id= save_pseudo_thread_id;
1280
1260
    }
1281
1261
    else
1282
1262
    {
1285
1265
    }
1286
1266
  }
1287
1267
  if (!was_quote_show)
1288
 
    session->options&= ~OPTION_QUOTE_SHOW_CREATE; /* restore option */
1289
 
  session->temporary_tables=0;
 
1268
    thd->options&= ~OPTION_QUOTE_SHOW_CREATE; /* restore option */
 
1269
  thd->temporary_tables=0;
1290
1270
}
1291
1271
 
1292
1272
/*
1329
1309
 
1330
1310
  SYNOPSIS
1331
1311
    unique_table()
1332
 
    session                   thread handle
 
1312
    thd                   thread handle
1333
1313
    table                 table which should be checked
1334
1314
    table_list            list of tables
1335
1315
    check_alias           whether to check tables' aliases
1336
1316
 
1337
1317
  NOTE: to exclude derived tables from check we use following mechanism:
1338
 
    a) during derived table processing set Session::derived_tables_processing
 
1318
    a) during derived table processing set THD::derived_tables_processing
1339
1319
    b) JOIN::prepare set SELECT::exclude_from_table_unique_test if
1340
 
       Session::derived_tables_processing set. (we can't use JOIN::execute
 
1320
       THD::derived_tables_processing set. (we can't use JOIN::execute
1341
1321
       because for PS we perform only JOIN::prepare, but we can't set this
1342
1322
       flag in JOIN::prepare if we are not sure that we are in derived table
1343
1323
       processing loop, because multi-update call fix_fields() for some its
1360
1340
    0 if table is unique
1361
1341
*/
1362
1342
 
1363
 
TableList* unique_table(Session *session, TableList *table, TableList *table_list,
 
1343
TableList* unique_table(THD *thd, TableList *table, TableList *table_list,
1364
1344
                         bool check_alias)
1365
1345
{
1366
1346
  TableList *res;
1395
1375
  for (;;)
1396
1376
  {
1397
1377
    if (((! (res= find_table_in_global_list(table_list, d_name, t_name))) &&
1398
 
         (! (res= mysql_lock_have_duplicate(session, table, table_list)))) ||
 
1378
         (! (res= mysql_lock_have_duplicate(thd, table, table_list)))) ||
1399
1379
        ((!res->table || res->table != table->table) &&
1400
1380
         (!check_alias || !(lower_case_table_names ?
1401
1381
          my_strcasecmp(files_charset_info, t_alias, res->alias) :
1435
1415
}
1436
1416
 
1437
1417
 
1438
 
Table *find_temporary_table(Session *session, const char *db, const char *table_name)
 
1418
Table *find_temporary_table(THD *thd, const char *db, const char *table_name)
1439
1419
{
1440
1420
  TableList table_list;
1441
1421
 
1442
1422
  table_list.db= (char*) db;
1443
1423
  table_list.table_name= (char*) table_name;
1444
 
  return find_temporary_table(session, &table_list);
 
1424
  return find_temporary_table(thd, &table_list);
1445
1425
}
1446
1426
 
1447
1427
 
1448
 
Table *find_temporary_table(Session *session, TableList *table_list)
 
1428
Table *find_temporary_table(THD *thd, TableList *table_list)
1449
1429
{
1450
1430
  char  key[MAX_DBKEY_LENGTH];
1451
1431
  uint  key_length;
1452
1432
  Table *table;
1453
1433
 
1454
 
  key_length= create_table_def_key(session, key, table_list, 1);
1455
 
  for (table=session->temporary_tables ; table ; table= table->next)
 
1434
  key_length= create_table_def_key(thd, key, table_list, 1);
 
1435
  for (table=thd->temporary_tables ; table ; table= table->next)
1456
1436
  {
1457
1437
    if (table->s->table_cache_key.length == key_length &&
1458
1438
        !memcmp(table->s->table_cache_key.str, key, key_length))
1465
1445
/**
1466
1446
  Drop a temporary table.
1467
1447
 
1468
 
  Try to locate the table in the list of session->temporary_tables.
 
1448
  Try to locate the table in the list of thd->temporary_tables.
1469
1449
  If the table is found:
1470
1450
   - if the table is being used by some outer statement, fail.
1471
 
   - if the table is in session->locked_tables, unlock it and
 
1451
   - if the table is in thd->locked_tables, unlock it and
1472
1452
     remove it from the list of locked tables. Currently only transactional
1473
1453
     temporary tables are present in the locked_tables list.
1474
1454
   - Close the temporary table, remove its .FRM
1479
1459
  or ALTER Table. Even though part of the work done by this function
1480
1460
  is redundant when the table is internal, as long as we
1481
1461
  link both internal and user temporary tables into the same
1482
 
  session->temporary_tables list, it's impossible to tell here whether
 
1462
  thd->temporary_tables list, it's impossible to tell here whether
1483
1463
  we're dealing with an internal or a user temporary table.
1484
1464
 
1485
1465
  @retval  0  the table was found and dropped successfully.
1488
1468
  @retval -1  the table is in use by a outer query
1489
1469
*/
1490
1470
 
1491
 
int drop_temporary_table(Session *session, TableList *table_list)
 
1471
int drop_temporary_table(THD *thd, TableList *table_list)
1492
1472
{
1493
1473
  Table *table;
1494
1474
 
1495
 
  if (!(table= find_temporary_table(session, table_list)))
 
1475
  if (!(table= find_temporary_table(thd, table_list)))
1496
1476
    return(1);
1497
1477
 
1498
1478
  /* Table might be in use by some outer statement. */
1499
 
  if (table->query_id && table->query_id != session->query_id)
 
1479
  if (table->query_id && table->query_id != thd->query_id)
1500
1480
  {
1501
1481
    my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
1502
1482
    return(-1);
1506
1486
    If LOCK TABLES list is not empty and contains this table,
1507
1487
    unlock the table and remove the table from this list.
1508
1488
  */
1509
 
  mysql_lock_remove(session, session->locked_tables, table, false);
1510
 
  close_temporary_table(session, table, 1, 1);
 
1489
  mysql_lock_remove(thd, thd->locked_tables, table, false);
 
1490
  close_temporary_table(thd, table, 1, 1);
1511
1491
  return(0);
1512
1492
}
1513
1493
 
1514
1494
/*
1515
 
  unlink from session->temporary tables and close temporary table
 
1495
  unlink from thd->temporary tables and close temporary table
1516
1496
*/
1517
1497
 
1518
 
void close_temporary_table(Session *session, Table *table,
 
1498
void close_temporary_table(THD *thd, Table *table,
1519
1499
                           bool free_share, bool delete_table)
1520
1500
{
1521
1501
  if (table->prev)
1527
1507
  else
1528
1508
  {
1529
1509
    /* removing the item from the list */
1530
 
    assert(table == session->temporary_tables);
 
1510
    assert(table == thd->temporary_tables);
1531
1511
    /*
1532
1512
      slave must reset its temporary list pointer to zero to exclude
1533
1513
      passing non-zero value to end_slave via rli->save_temporary_tables
1534
1514
      when no temp tables opened, see an invariant below.
1535
1515
    */
1536
 
    session->temporary_tables= table->next;
1537
 
    if (session->temporary_tables)
 
1516
    thd->temporary_tables= table->next;
 
1517
    if (thd->temporary_tables)
1538
1518
      table->next->prev= 0;
1539
1519
  }
1540
 
  if (session->slave_thread)
 
1520
  if (thd->slave_thread)
1541
1521
  {
1542
1522
    /* natural invariant of temporary_tables */
1543
 
    assert(slave_open_temp_tables || !session->temporary_tables);
 
1523
    assert(slave_open_temp_tables || !thd->temporary_tables);
1544
1524
    slave_open_temp_tables--;
1545
1525
  }
1546
1526
  close_temporary(table, free_share, delete_table);
1552
1532
  Close and delete a temporary table
1553
1533
 
1554
1534
  NOTE
1555
 
    This dosn't unlink table from session->temporary
 
1535
    This dosn't unlink table from thd->temporary
1556
1536
    If this is needed, use close_temporary_table()
1557
1537
*/
1558
1538
 
1572
1552
  if (free_share)
1573
1553
  {
1574
1554
    free_table_share(table->s);
1575
 
    free((char*) table);
 
1555
    my_free((char*) table,MYF(0));
1576
1556
  }
1577
1557
  return;
1578
1558
}
1583
1563
  only if the ALTER contained a RENAME clause (otherwise, table_name is the old
1584
1564
  name).
1585
1565
  Prepares a table cache key, which is the concatenation of db, table_name and
1586
 
  session->slave_proxy_id, separated by '\0'.
 
1566
  thd->slave_proxy_id, separated by '\0'.
1587
1567
*/
1588
1568
 
1589
 
bool rename_temporary_table(Session* session, Table *table, const char *db,
 
1569
bool rename_temporary_table(THD* thd, Table *table, const char *db,
1590
1570
                            const char *table_name)
1591
1571
{
1592
1572
  char *key;
1593
 
  uint32_t key_length;
 
1573
  uint key_length;
1594
1574
  TABLE_SHARE *share= table->s;
1595
1575
  TableList table_list;
1596
1576
 
1599
1579
 
1600
1580
  table_list.db= (char*) db;
1601
1581
  table_list.table_name= (char*) table_name;
1602
 
  key_length= create_table_def_key(session, key, &table_list, 1);
 
1582
  key_length= create_table_def_key(thd, key, &table_list, 1);
1603
1583
  share->set_table_cache_key(key, key_length);
1604
1584
  return(0);
1605
1585
}
1626
1606
    Remove all instances of table from thread's open list and
1627
1607
    table cache.
1628
1608
 
1629
 
    @param  session     Thread context
 
1609
    @param  thd     Thread context
1630
1610
    @param  find    Table to remove
1631
1611
    @param  unlock  true  - free all locks on tables removed that are
1632
1612
                            done with LOCK TABLES
1637
1617
          not locked (for example already unlocked).
1638
1618
*/
1639
1619
 
1640
 
void unlink_open_table(Session *session, Table *find, bool unlock)
 
1620
void unlink_open_table(THD *thd, Table *find, bool unlock)
1641
1621
{
1642
1622
  char key[MAX_DBKEY_LENGTH];
1643
 
  uint32_t key_length= find->s->table_cache_key.length;
 
1623
  uint key_length= find->s->table_cache_key.length;
1644
1624
  Table *list, **prev;
1645
1625
 
1646
1626
  safe_mutex_assert_owner(&LOCK_open);
1653
1633
    Closing a MERGE child before the parent would be fatal if the
1654
1634
    other thread tries to abort the MERGE lock in between.
1655
1635
  */
1656
 
  for (prev= &session->open_tables; *prev; )
 
1636
  for (prev= &thd->open_tables; *prev; )
1657
1637
  {
1658
1638
    list= *prev;
1659
1639
 
1660
1640
    if (list->s->table_cache_key.length == key_length &&
1661
1641
        !memcmp(list->s->table_cache_key.str, key, key_length))
1662
1642
    {
1663
 
      if (unlock && session->locked_tables)
1664
 
        mysql_lock_remove(session, session->locked_tables, list, true);
 
1643
      if (unlock && thd->locked_tables)
 
1644
        mysql_lock_remove(thd, thd->locked_tables, list, true);
1665
1645
 
1666
1646
      /* Remove table from open_tables list. */
1667
1647
      *prev= list->next;
1668
1648
      /* Close table. */
1669
 
      hash_delete(&open_cache,(unsigned char*) list); // Close table
 
1649
      VOID(hash_delete(&open_cache,(uchar*) list)); // Close table
1670
1650
    }
1671
1651
    else
1672
1652
    {
1684
1664
/**
1685
1665
    Auxiliary routine which closes and drops open table.
1686
1666
 
1687
 
    @param  session         Thread handle
 
1667
    @param  thd         Thread handle
1688
1668
    @param  table       Table object for table to be dropped
1689
1669
    @param  db_name     Name of database for this table
1690
1670
    @param  table_name  Name of this table
1700
1680
          table that was locked with LOCK TABLES.
1701
1681
*/
1702
1682
 
1703
 
void drop_open_table(Session *session, Table *table, const char *db_name,
 
1683
void drop_open_table(THD *thd, Table *table, const char *db_name,
1704
1684
                     const char *table_name)
1705
1685
{
1706
1686
  if (table->s->tmp_table)
1707
 
    close_temporary_table(session, table, 1, 1);
 
1687
    close_temporary_table(thd, table, 1, 1);
1708
1688
  else
1709
1689
  {
1710
1690
    handlerton *table_type= table->s->db_type();
1711
 
    pthread_mutex_lock(&LOCK_open);
 
1691
    VOID(pthread_mutex_lock(&LOCK_open));
1712
1692
    /*
1713
1693
      unlink_open_table() also tells threads waiting for refresh or close
1714
1694
      that something has happened.
1715
1695
    */
1716
 
    unlink_open_table(session, table, false);
 
1696
    unlink_open_table(thd, table, false);
1717
1697
    quick_rm_table(table_type, db_name, table_name, 0);
1718
 
    pthread_mutex_unlock(&LOCK_open);
 
1698
    VOID(pthread_mutex_unlock(&LOCK_open));
1719
1699
  }
1720
1700
}
1721
1701
 
1725
1705
 
1726
1706
   SYNOPSIS
1727
1707
     wait_for_condition()
1728
 
     session    Thread handler
 
1708
     thd        Thread handler
1729
1709
     mutex      mutex that is currently hold that is associated with condition
1730
1710
                Will be unlocked on return     
1731
1711
     cond       Condition to wait for
1732
1712
*/
1733
1713
 
1734
 
void wait_for_condition(Session *session, pthread_mutex_t *mutex, pthread_cond_t *cond)
 
1714
void wait_for_condition(THD *thd, pthread_mutex_t *mutex, pthread_cond_t *cond)
1735
1715
{
1736
1716
  /* Wait until the current table is up to date */
1737
1717
  const char *proc_info;
1738
 
  session->mysys_var->current_mutex= mutex;
1739
 
  session->mysys_var->current_cond= cond;
1740
 
  proc_info=session->get_proc_info();
1741
 
  session->set_proc_info("Waiting for table");
1742
 
  if (!session->killed)
 
1718
  thd->mysys_var->current_mutex= mutex;
 
1719
  thd->mysys_var->current_cond= cond;
 
1720
  proc_info=thd->get_proc_info();
 
1721
  thd_proc_info(thd, "Waiting for table");
 
1722
  if (!thd->killed)
1743
1723
    (void) pthread_cond_wait(cond, mutex);
1744
1724
 
1745
1725
  /*
1754
1734
  */
1755
1735
    
1756
1736
  pthread_mutex_unlock(mutex);
1757
 
  pthread_mutex_lock(&session->mysys_var->mutex);
1758
 
  session->mysys_var->current_mutex= 0;
1759
 
  session->mysys_var->current_cond= 0;
1760
 
  session->set_proc_info(proc_info);
1761
 
  pthread_mutex_unlock(&session->mysys_var->mutex);
 
1737
  pthread_mutex_lock(&thd->mysys_var->mutex);
 
1738
  thd->mysys_var->current_mutex= 0;
 
1739
  thd->mysys_var->current_cond= 0;
 
1740
  thd_proc_info(thd, proc_info);
 
1741
  pthread_mutex_unlock(&thd->mysys_var->mutex);
1762
1742
  return;
1763
1743
}
1764
1744
 
1767
1747
  Exclusively name-lock a table that is already write-locked by the
1768
1748
  current thread.
1769
1749
 
1770
 
  @param session current thread context
 
1750
  @param thd current thread context
1771
1751
  @param tables table list containing one table to open.
1772
1752
 
1773
1753
  @return false on success, true otherwise.
1774
1754
*/
1775
1755
 
1776
 
bool name_lock_locked_table(Session *session, TableList *tables)
 
1756
bool name_lock_locked_table(THD *thd, TableList *tables)
1777
1757
{
1778
1758
  /* Under LOCK TABLES we must only accept write locked tables. */
1779
 
  tables->table= find_locked_table(session, tables->db, tables->table_name);
 
1759
  tables->table= find_locked_table(thd, tables->db, tables->table_name);
1780
1760
 
1781
1761
  if (!tables->table)
1782
1762
    my_error(ER_TABLE_NOT_LOCKED, MYF(0), tables->alias);
1788
1768
      Ensures that table is opened only by this thread and that no
1789
1769
      other statement will open this table.
1790
1770
    */
1791
 
    wait_while_table_is_used(session, tables->table, HA_EXTRA_FORCE_REOPEN);
 
1771
    wait_while_table_is_used(thd, tables->table, HA_EXTRA_FORCE_REOPEN);
1792
1772
    return(false);
1793
1773
  }
1794
1774
 
1801
1781
 
1802
1782
  SYNOPSIS
1803
1783
    reopen_name_locked_table()
1804
 
      session         Thread handle
 
1784
      thd         Thread handle
1805
1785
      table_list  TableList object for table to be open, TableList::table
1806
1786
                  member should point to Table object which was used for
1807
1787
                  name-locking.
1808
1788
      link_in     true  - if Table object for table to be opened should be
1809
 
                          linked into Session::open_tables list.
 
1789
                          linked into THD::open_tables list.
1810
1790
                  false - placeholder used for name-locking is already in
1811
1791
                          this list so we only need to preserve Table::next
1812
1792
                          pointer.
1819
1799
    true  - Error
1820
1800
*/
1821
1801
 
1822
 
bool reopen_name_locked_table(Session* session, TableList* table_list, bool link_in)
 
1802
bool reopen_name_locked_table(THD* thd, TableList* table_list, bool link_in)
1823
1803
{
1824
1804
  Table *table= table_list->table;
1825
1805
  TABLE_SHARE *share;
1828
1808
 
1829
1809
  safe_mutex_assert_owner(&LOCK_open);
1830
1810
 
1831
 
  if (session->killed || !table)
 
1811
  if (thd->killed || !table)
1832
1812
    return(true);
1833
1813
 
1834
1814
  orig_table= *table;
1835
1815
 
1836
 
  if (open_unireg_entry(session, table, table_list, table_name,
 
1816
  if (open_unireg_entry(thd, table, table_list, table_name,
1837
1817
                        table->s->table_cache_key.str,
1838
1818
                        table->s->table_cache_key.length))
1839
1819
  {
1858
1838
    before we will get table-level lock on this table.
1859
1839
  */
1860
1840
  share->version=0;
1861
 
  table->in_use = session;
 
1841
  table->in_use = thd;
1862
1842
 
1863
1843
  if (link_in)
1864
1844
  {
1865
 
    table->next= session->open_tables;
1866
 
    session->open_tables= table;
 
1845
    table->next= thd->open_tables;
 
1846
    thd->open_tables= table;
1867
1847
  }
1868
1848
  else
1869
1849
  {
1870
1850
    /*
1871
 
      Table object should be already in Session::open_tables list so we just
 
1851
      Table object should be already in THD::open_tables list so we just
1872
1852
      need to set Table::next correctly.
1873
1853
    */
1874
1854
    table->next= orig_table.next;
1875
1855
  }
1876
1856
 
1877
 
  table->tablenr=session->current_tablenr++;
 
1857
  table->tablenr=thd->current_tablenr++;
1878
1858
  table->used_fields=0;
1879
1859
  table->const_table=0;
1880
1860
  table->null_row= false;
1890
1870
    which will prevent its opening (or creation) (a.k.a lock
1891
1871
    table name).
1892
1872
 
1893
 
    @param session         Thread context
 
1873
    @param thd         Thread context
1894
1874
    @param key         Table cache key for name to be locked
1895
1875
    @param key_length  Table cache key length
1896
1876
 
1898
1878
            case of failure.
1899
1879
*/
1900
1880
 
1901
 
Table *table_cache_insert_placeholder(Session *session, const char *key,
1902
 
                                      uint32_t key_length)
 
1881
Table *table_cache_insert_placeholder(THD *thd, const char *key,
 
1882
                                      uint key_length)
1903
1883
{
1904
1884
  Table *table;
1905
1885
  TABLE_SHARE *share;
1922
1902
  table->s= share;
1923
1903
  share->set_table_cache_key(key_buff, key, key_length);
1924
1904
  share->tmp_table= INTERNAL_TMP_TABLE;  // for intern_close_table
1925
 
  table->in_use= session;
 
1905
  table->in_use= thd;
1926
1906
  table->locked_by_name=1;
1927
1907
 
1928
 
  if (my_hash_insert(&open_cache, (unsigned char*)table))
 
1908
  if (my_hash_insert(&open_cache, (uchar*)table))
1929
1909
  {
1930
 
    free((unsigned char*) table);
 
1910
    my_free((uchar*) table, MYF(0));
1931
1911
    return(NULL);
1932
1912
  }
1933
1913
 
1939
1919
    Obtain an exclusive name lock on the table if it is not cached
1940
1920
    in the table cache.
1941
1921
 
1942
 
    @param      session         Thread context
 
1922
    @param      thd         Thread context
1943
1923
    @param      db          Name of database
1944
1924
    @param      table_name  Name of table
1945
1925
    @param[out] table       Out parameter which is either:
1957
1937
    @retval  false  Success. 'table' parameter set according to above rules.
1958
1938
*/
1959
1939
 
1960
 
bool lock_table_name_if_not_cached(Session *session, const char *db,
 
1940
bool lock_table_name_if_not_cached(THD *thd, const char *db,
1961
1941
                                   const char *table_name, Table **table)
1962
1942
{
1963
1943
  char key[MAX_DBKEY_LENGTH];
1964
 
  uint32_t key_length;
1965
 
 
1966
 
  key_length= (uint)(my_stpcpy(my_stpcpy(key, db) + 1, table_name) - key) + 1;
1967
 
  pthread_mutex_lock(&LOCK_open);
1968
 
 
1969
 
  if (hash_search(&open_cache, (unsigned char *)key, key_length))
 
1944
  uint key_length;
 
1945
 
 
1946
  key_length= (uint)(stpcpy(stpcpy(key, db) + 1, table_name) - key) + 1;
 
1947
  VOID(pthread_mutex_lock(&LOCK_open));
 
1948
 
 
1949
  if (hash_search(&open_cache, (uchar *)key, key_length))
1970
1950
  {
1971
 
    pthread_mutex_unlock(&LOCK_open);
 
1951
    VOID(pthread_mutex_unlock(&LOCK_open));
1972
1952
    *table= 0;
1973
1953
    return(false);
1974
1954
  }
1975
 
  if (!(*table= table_cache_insert_placeholder(session, key, key_length)))
 
1955
  if (!(*table= table_cache_insert_placeholder(thd, key, key_length)))
1976
1956
  {
1977
 
    pthread_mutex_unlock(&LOCK_open);
 
1957
    VOID(pthread_mutex_unlock(&LOCK_open));
1978
1958
    return(true);
1979
1959
  }
1980
1960
  (*table)->open_placeholder= 1;
1981
 
  (*table)->next= session->open_tables;
1982
 
  session->open_tables= *table;
1983
 
  pthread_mutex_unlock(&LOCK_open);
 
1961
  (*table)->next= thd->open_tables;
 
1962
  thd->open_tables= *table;
 
1963
  VOID(pthread_mutex_unlock(&LOCK_open));
1984
1964
  return(false);
1985
1965
}
1986
1966
 
1989
1969
    Check that table exists in table definition cache, on disk
1990
1970
    or in some storage engine.
1991
1971
 
1992
 
    @param       session     Thread context
 
1972
    @param       thd     Thread context
1993
1973
    @param       table   Table list element
1994
1974
    @param[out]  exists  Out parameter which is set to true if table
1995
1975
                         exists and to false otherwise.
2006
1986
    @retval  false  No error. 'exists' out parameter set accordingly.
2007
1987
*/
2008
1988
 
2009
 
bool check_if_table_exists(Session *session, TableList *table, bool *exists)
 
1989
bool check_if_table_exists(THD *thd, TableList *table, bool *exists)
2010
1990
{
2011
1991
  char path[FN_REFLEN];
2012
1992
  int rc;
2026
2006
 
2027
2007
  /* .FRM file doesn't exist. Check if some engine can provide it. */
2028
2008
 
2029
 
  rc= ha_create_table_from_engine(session, table->db, table->table_name);
 
2009
  rc= ha_create_table_from_engine(thd, table->db, table->table_name);
2030
2010
 
2031
2011
  if (rc < 0)
2032
2012
  {
2053
2033
 
2054
2034
  SYNOPSIS
2055
2035
    open_table()
2056
 
    session                 Thread context.
 
2036
    thd                 Thread context.
2057
2037
    table_list          Open first table in list.
2058
2038
    refresh      INOUT  Pointer to memory that will be set to 1 if
2059
2039
                        we need to close all tables and reopen them.
2081
2061
*/
2082
2062
 
2083
2063
 
2084
 
Table *open_table(Session *session, TableList *table_list, bool *refresh, uint32_t flags)
 
2064
Table *open_table(THD *thd, TableList *table_list, bool *refresh, uint flags)
2085
2065
{
2086
2066
  register Table *table;
2087
2067
  char key[MAX_DBKEY_LENGTH];
2089
2069
  char *alias= table_list->alias;
2090
2070
  HASH_SEARCH_STATE state;
2091
2071
 
2092
 
  /* Parsing of partitioning information from .frm needs session->lex set up. */
2093
 
  assert(session->lex->is_lex_started);
 
2072
  /* Parsing of partitioning information from .frm needs thd->lex set up. */
 
2073
  assert(thd->lex->is_lex_started);
2094
2074
 
2095
2075
  /* find a unused table in the open table cache */
2096
2076
  if (refresh)
2097
2077
    *refresh=0;
2098
2078
 
2099
2079
  /* an open table operation needs a lot of the stack space */
2100
 
  if (check_stack_overrun(session, STACK_MIN_SIZE_FOR_OPEN, (unsigned char *)&alias))
2101
 
    return(0);
2102
 
 
2103
 
  if (session->killed)
2104
 
    return(0);
2105
 
 
2106
 
  key_length= (create_table_def_key(session, key, table_list, 1) -
 
2080
  if (check_stack_overrun(thd, STACK_MIN_SIZE_FOR_OPEN, (uchar *)&alias))
 
2081
    return(0);
 
2082
 
 
2083
  if (thd->killed)
 
2084
    return(0);
 
2085
 
 
2086
  key_length= (create_table_def_key(thd, key, table_list, 1) -
2107
2087
               TMP_TABLE_KEY_EXTRA);
2108
2088
 
2109
2089
  /*
2114
2094
    TODO: move this block into a separate function.
2115
2095
  */
2116
2096
  {
2117
 
    for (table= session->temporary_tables; table ; table=table->next)
 
2097
    for (table= thd->temporary_tables; table ; table=table->next)
2118
2098
    {
2119
2099
      if (table->s->table_cache_key.length == key_length +
2120
2100
          TMP_TABLE_KEY_EXTRA &&
2124
2104
        /*
2125
2105
          We're trying to use the same temporary table twice in a query.
2126
2106
          Right now we don't support this because a temporary table
2127
 
          is always represented by only one Table object in Session, and
 
2107
          is always represented by only one Table object in THD, and
2128
2108
          it can not be cloned. Emit an error for an unsupported behaviour.
2129
2109
        */
2130
2110
        if (table->query_id)
2132
2112
          my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
2133
2113
          return(0);
2134
2114
        }
2135
 
        table->query_id= session->query_id;
2136
 
        session->thread_specific_used= true;
 
2115
        table->query_id= thd->query_id;
 
2116
        thd->thread_specific_used= true;
2137
2117
        goto reset;
2138
2118
      }
2139
2119
    }
2152
2132
    open not pre-opened tables in pre-locked/LOCK TABLES mode.
2153
2133
    TODO: move this block into a separate function.
2154
2134
  */
2155
 
  if (session->locked_tables)
 
2135
  if (thd->locked_tables)
2156
2136
  {                                             // Using table locks
2157
2137
    Table *best_table= 0;
2158
2138
    int best_distance= INT_MIN;
2159
2139
    bool check_if_used= false;
2160
 
    for (table=session->open_tables; table ; table=table->next)
 
2140
    for (table=thd->open_tables; table ; table=table->next)
2161
2141
    {
2162
2142
      if (table->s->table_cache_key.length == key_length &&
2163
2143
          !memcmp(table->s->table_cache_key.str, key, key_length))
2164
2144
      {
2165
2145
        if (check_if_used && table->query_id &&
2166
 
            table->query_id != session->query_id)
 
2146
            table->query_id != thd->query_id)
2167
2147
        {
2168
2148
          /*
2169
2149
            If we are in stored function or trigger we should ensure that
2180
2160
          belong to their parent and cannot be used explicitly.
2181
2161
        */
2182
2162
        if (!my_strcasecmp(system_charset_info, table->alias, alias) &&
2183
 
            table->query_id != session->query_id)  /* skip tables already used */
 
2163
            table->query_id != thd->query_id)  /* skip tables already used */
2184
2164
        {
2185
2165
          int distance= ((int) table->reginfo.lock_type -
2186
2166
                         (int) table_list->lock_type);
2217
2197
    if (best_table)
2218
2198
    {
2219
2199
      table= best_table;
2220
 
      table->query_id= session->query_id;
 
2200
      table->query_id= thd->query_id;
2221
2201
      goto reset;
2222
2202
    }
2223
2203
    /*
2247
2227
    on disk.
2248
2228
  */
2249
2229
 
2250
 
  pthread_mutex_lock(&LOCK_open);
 
2230
  VOID(pthread_mutex_lock(&LOCK_open));
2251
2231
 
2252
2232
  /*
2253
2233
    If it's the first table from a list of tables used in a query,
2257
2237
    and try to reopen them.
2258
2238
    Note: refresh_version is currently changed only during FLUSH TABLES.
2259
2239
  */
2260
 
  if (!session->open_tables)
2261
 
    session->version=refresh_version;
2262
 
  else if ((session->version != refresh_version) &&
 
2240
  if (!thd->open_tables)
 
2241
    thd->version=refresh_version;
 
2242
  else if ((thd->version != refresh_version) &&
2263
2243
           ! (flags & DRIZZLE_LOCK_IGNORE_FLUSH))
2264
2244
  {
2265
2245
    /* Someone did a refresh while thread was opening tables */
2266
2246
    if (refresh)
2267
2247
      *refresh=1;
2268
 
    pthread_mutex_unlock(&LOCK_open);
 
2248
    VOID(pthread_mutex_unlock(&LOCK_open));
2269
2249
    return(0);
2270
2250
  }
2271
2251
 
2276
2256
    is pending for any table of the handler_tables list, otherwise a
2277
2257
    deadlock may occur.
2278
2258
  */
2279
 
  if (session->handler_tables)
2280
 
    mysql_ha_flush(session);
 
2259
  if (thd->handler_tables)
 
2260
    mysql_ha_flush(thd);
2281
2261
 
2282
2262
  /*
2283
2263
    Actually try to find the table in the open_cache.
2289
2269
    an implicit "pending locks queue" - see
2290
2270
    wait_for_locked_table_names for details.
2291
2271
  */
2292
 
  for (table= (Table*) hash_first(&open_cache, (unsigned char*) key, key_length,
 
2272
  for (table= (Table*) hash_first(&open_cache, (uchar*) key, key_length,
2293
2273
                                  &state);
2294
2274
       table && table->in_use ;
2295
 
       table= (Table*) hash_next(&open_cache, (unsigned char*) key, key_length,
 
2275
       table= (Table*) hash_next(&open_cache, (uchar*) key, key_length,
2296
2276
                                 &state))
2297
2277
  {
2298
2278
    /*
2318
2298
      if (flags & DRIZZLE_LOCK_IGNORE_FLUSH)
2319
2299
      {
2320
2300
        /* Force close at once after usage */
2321
 
        session->version= table->s->version;
 
2301
        thd->version= table->s->version;
2322
2302
        continue;
2323
2303
      }
2324
2304
 
2325
2305
      /* Avoid self-deadlocks by detecting self-dependencies. */
2326
 
      if (table->open_placeholder && table->in_use == session)
 
2306
      if (table->open_placeholder && table->in_use == thd)
2327
2307
      {
2328
 
        pthread_mutex_unlock(&LOCK_open);
 
2308
        VOID(pthread_mutex_unlock(&LOCK_open));
2329
2309
        my_error(ER_UPDATE_TABLE_USED, MYF(0), table->s->table_name.str);
2330
2310
        return(0);
2331
2311
      }
2343
2323
        the earlier call to mysql_ha_flush() in this same critical
2344
2324
        section.
2345
2325
      */
2346
 
      close_old_data_files(session,session->open_tables,0,0);
 
2326
      close_old_data_files(thd,thd->open_tables,0,0);
2347
2327
      /*
2348
2328
        Back-off part 2: try to avoid "busy waiting" on the table:
2349
2329
        if the table is in use by some other thread, we suspend
2359
2339
        after we open first instance but before we open second
2360
2340
        instance.
2361
2341
      */
2362
 
      if (table->in_use != session)
 
2342
      if (table->in_use != thd)
2363
2343
      {
2364
2344
        /* wait_for_conditionwill unlock LOCK_open for us */
2365
 
        wait_for_condition(session, &LOCK_open, &COND_refresh);
 
2345
        wait_for_condition(thd, &LOCK_open, &COND_refresh);
2366
2346
      }
2367
2347
      else
2368
2348
      {
2369
 
        pthread_mutex_unlock(&LOCK_open);
 
2349
        VOID(pthread_mutex_unlock(&LOCK_open));
2370
2350
      }
2371
2351
      /*
2372
2352
        There is a refresh in progress for this table.
2388
2368
    }
2389
2369
    table->prev->next=table->next;              /* Remove from unused list */
2390
2370
    table->next->prev=table->prev;
2391
 
    table->in_use= session;
 
2371
    table->in_use= thd;
2392
2372
  }
2393
2373
  else
2394
2374
  {
2396
2376
    int error;
2397
2377
    /* Free cache if too big */
2398
2378
    while (open_cache.records > table_cache_size && unused_tables)
2399
 
      hash_delete(&open_cache,(unsigned char*) unused_tables); /* purecov: tested */
 
2379
      VOID(hash_delete(&open_cache,(uchar*) unused_tables)); /* purecov: tested */
2400
2380
 
2401
2381
    if (table_list->create)
2402
2382
    {
2403
2383
      bool exists;
2404
2384
 
2405
 
      if (check_if_table_exists(session, table_list, &exists))
 
2385
      if (check_if_table_exists(thd, table_list, &exists))
2406
2386
      {
2407
 
        pthread_mutex_unlock(&LOCK_open);
 
2387
        VOID(pthread_mutex_unlock(&LOCK_open));
2408
2388
        return(NULL);
2409
2389
      }
2410
2390
 
2413
2393
        /*
2414
2394
          Table to be created, so we need to create placeholder in table-cache.
2415
2395
        */
2416
 
        if (!(table= table_cache_insert_placeholder(session, key, key_length)))
 
2396
        if (!(table= table_cache_insert_placeholder(thd, key, key_length)))
2417
2397
        {
2418
 
          pthread_mutex_unlock(&LOCK_open);
 
2398
          VOID(pthread_mutex_unlock(&LOCK_open));
2419
2399
          return(NULL);
2420
2400
        }
2421
2401
        /*
2424
2404
          by other trying to take name-lock.
2425
2405
        */
2426
2406
        table->open_placeholder= 1;
2427
 
        table->next= session->open_tables;
2428
 
        session->open_tables= table;
2429
 
        pthread_mutex_unlock(&LOCK_open);
 
2407
        table->next= thd->open_tables;
 
2408
        thd->open_tables= table;
 
2409
        VOID(pthread_mutex_unlock(&LOCK_open));
2430
2410
        return(table);
2431
2411
      }
2432
2412
      /* Table exists. Let us try to open it. */
2435
2415
    /* make a new table */
2436
2416
    if (!(table=(Table*) my_malloc(sizeof(*table),MYF(MY_WME))))
2437
2417
    {
2438
 
      pthread_mutex_unlock(&LOCK_open);
 
2418
      VOID(pthread_mutex_unlock(&LOCK_open));
2439
2419
      return(NULL);
2440
2420
    }
2441
2421
 
2442
 
    error= open_unireg_entry(session, table, table_list, alias, key, key_length);
 
2422
    error= open_unireg_entry(thd, table, table_list, alias, key, key_length);
2443
2423
    /* Combine the follow two */
2444
2424
    if (error > 0)
2445
2425
    {
2446
 
      free((unsigned char*)table);
2447
 
      pthread_mutex_unlock(&LOCK_open);
 
2426
      my_free((uchar*)table, MYF(0));
 
2427
      VOID(pthread_mutex_unlock(&LOCK_open));
2448
2428
      return(NULL);
2449
2429
    }
2450
2430
    if (error < 0)
2451
2431
    {
2452
 
      free((unsigned char*)table);
2453
 
      pthread_mutex_unlock(&LOCK_open);
 
2432
      my_free((uchar*)table, MYF(0));
 
2433
      VOID(pthread_mutex_unlock(&LOCK_open));
2454
2434
      return(0); // VIEW
2455
2435
    }
2456
 
    my_hash_insert(&open_cache,(unsigned char*) table);
 
2436
    VOID(my_hash_insert(&open_cache,(uchar*) table));
2457
2437
  }
2458
2438
 
2459
 
  pthread_mutex_unlock(&LOCK_open);
 
2439
  VOID(pthread_mutex_unlock(&LOCK_open));
2460
2440
  if (refresh)
2461
2441
  {
2462
 
    table->next=session->open_tables;           /* Link into simple list */
2463
 
    session->open_tables=table;
 
2442
    table->next=thd->open_tables;               /* Link into simple list */
 
2443
    thd->open_tables=table;
2464
2444
  }
2465
2445
  table->reginfo.lock_type=TL_READ;             /* Assume read */
2466
2446
 
2467
2447
 reset:
2468
2448
  assert(table->s->ref_count > 0 || table->s->tmp_table != NO_TMP_TABLE);
2469
2449
 
2470
 
  if (session->lex->need_correct_ident())
 
2450
  if (thd->lex->need_correct_ident())
2471
2451
    table->alias_name_used= my_strcasecmp(table_alias_charset,
2472
2452
                                          table->s->table_name.str, alias);
2473
2453
  /* Fix alias if table name changes */
2474
2454
  if (strcmp(table->alias, alias))
2475
2455
  {
2476
 
    uint32_t length=(uint) strlen(alias)+1;
 
2456
    uint length=(uint) strlen(alias)+1;
2477
2457
    table->alias= (char*) my_realloc((char*) table->alias, length,
2478
2458
                                     MYF(MY_WME));
2479
2459
    memcpy((void*) table->alias, alias, length);
2480
2460
  }
2481
2461
  /* These variables are also set in reopen_table() */
2482
 
  table->tablenr=session->current_tablenr++;
 
2462
  table->tablenr=thd->current_tablenr++;
2483
2463
  table->used_fields=0;
2484
2464
  table->const_table=0;
2485
2465
  table->null_row= false;
2499
2479
}
2500
2480
 
2501
2481
 
2502
 
Table *find_locked_table(Session *session, const char *db,const char *table_name)
 
2482
Table *find_locked_table(THD *thd, const char *db,const char *table_name)
2503
2483
{
2504
2484
  char  key[MAX_DBKEY_LENGTH];
2505
 
  uint32_t key_length=(uint) (my_stpcpy(my_stpcpy(key,db)+1,table_name)-key)+1;
 
2485
  uint key_length=(uint) (stpcpy(stpcpy(key,db)+1,table_name)-key)+1;
2506
2486
 
2507
 
  for (Table *table=session->open_tables; table ; table=table->next)
 
2487
  for (Table *table=thd->open_tables; table ; table=table->next)
2508
2488
  {
2509
2489
    if (table->s->table_cache_key.length == key_length &&
2510
2490
        !memcmp(table->s->table_cache_key.str, key, key_length))
2535
2515
  Table tmp;
2536
2516
  bool error= 1;
2537
2517
  Field **field;
2538
 
  uint32_t key,part;
 
2518
  uint key,part;
2539
2519
  TableList table_list;
2540
 
  Session *session= table->in_use;
 
2520
  THD *thd= table->in_use;
2541
2521
 
2542
2522
  assert(table->s->ref_count == 0);
2543
2523
  assert(!table->sort.io_cache);
2552
2532
  table_list.table_name= table->s->table_name.str;
2553
2533
  table_list.table=      table;
2554
2534
 
2555
 
  if (wait_for_locked_table_names(session, &table_list))
 
2535
  if (wait_for_locked_table_names(thd, &table_list))
2556
2536
    return(1);                             // Thread was killed
2557
2537
 
2558
 
  if (open_unireg_entry(session, &tmp, &table_list,
 
2538
  if (open_unireg_entry(thd, &tmp, &table_list,
2559
2539
                        table->alias,
2560
2540
                        table->s->table_cache_key.str,
2561
2541
                        table->s->table_cache_key.length))
2572
2552
  tmp.s->table_map_id=  table->s->table_map_id;
2573
2553
 
2574
2554
  /* Get state */
2575
 
  tmp.in_use=           session;
 
2555
  tmp.in_use=           thd;
2576
2556
  tmp.reginfo.lock_type=table->reginfo.lock_type;
2577
2557
 
2578
2558
  /* Replace table in open list */
2580
2560
  tmp.prev=             table->prev;
2581
2561
 
2582
2562
  if (table->file)
2583
 
    closefrm(table, 1);         // close file, free everything
 
2563
    VOID(closefrm(table, 1));           // close file, free everything
2584
2564
 
2585
2565
  *table= tmp;
2586
2566
  table->default_column_bitmaps();
2615
2595
    Close all instances of a table open by this thread and replace
2616
2596
    them with exclusive name-locks.
2617
2597
 
2618
 
    @param session        Thread context
 
2598
    @param thd        Thread context
2619
2599
    @param db         Database name for the table to be closed
2620
2600
    @param table_name Name of the table to be closed
2621
2601
 
2628
2608
          the strings are used in a loop even after the share may be freed.
2629
2609
*/
2630
2610
 
2631
 
void close_data_files_and_morph_locks(Session *session, const char *db,
 
2611
void close_data_files_and_morph_locks(THD *thd, const char *db,
2632
2612
                                      const char *table_name)
2633
2613
{
2634
2614
  Table *table;
2635
2615
 
2636
2616
  safe_mutex_assert_owner(&LOCK_open);
2637
2617
 
2638
 
  if (session->lock)
 
2618
  if (thd->lock)
2639
2619
  {
2640
2620
    /*
2641
2621
      If we are not under LOCK TABLES we should have only one table
2642
2622
      open and locked so it makes sense to remove the lock at once.
2643
2623
    */
2644
 
    mysql_unlock_tables(session, session->lock);
2645
 
    session->lock= 0;
 
2624
    mysql_unlock_tables(thd, thd->lock);
 
2625
    thd->lock= 0;
2646
2626
  }
2647
2627
 
2648
2628
  /*
2650
2630
    for target table name if we process ALTER Table ... RENAME.
2651
2631
    So loop below makes sense even if we are not under LOCK TABLES.
2652
2632
  */
2653
 
  for (table=session->open_tables; table ; table=table->next)
 
2633
  for (table=thd->open_tables; table ; table=table->next)
2654
2634
  {
2655
2635
    if (!strcmp(table->s->table_name.str, table_name) &&
2656
2636
        !strcmp(table->s->db.str, db))
2657
2637
    {
2658
 
      if (session->locked_tables)
 
2638
      if (thd->locked_tables)
2659
2639
      {
2660
 
        mysql_lock_remove(session, session->locked_tables, table, true);
 
2640
        mysql_lock_remove(thd, thd->locked_tables, table, true);
2661
2641
      }
2662
2642
      table->open_placeholder= 1;
2663
2643
      close_handle_and_leave_table_as_lock(table);
2670
2650
/**
2671
2651
    Reopen all tables with closed data files.
2672
2652
 
2673
 
    @param session         Thread context
 
2653
    @param thd         Thread context
2674
2654
    @param get_locks   Should we get locks after reopening tables ?
2675
2655
    @param mark_share_as_old  Mark share as old to protect from a impending
2676
2656
                              global read lock.
2687
2667
    @return false in case of success, true - otherwise.
2688
2668
*/
2689
2669
 
2690
 
bool reopen_tables(Session *session, bool get_locks, bool mark_share_as_old)
 
2670
bool reopen_tables(THD *thd, bool get_locks, bool mark_share_as_old)
2691
2671
{
2692
2672
  Table *table,*next,**prev;
2693
2673
  Table **tables,**tables_ptr;                  // For locks
2694
2674
  bool error=0, not_used;
2695
 
  const uint32_t flags= DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN |
 
2675
  const uint flags= DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN |
2696
2676
                    DRIZZLE_LOCK_IGNORE_GLOBAL_READ_LOCK |
2697
2677
                    DRIZZLE_LOCK_IGNORE_FLUSH;
2698
2678
 
2699
 
  if (!session->open_tables)
 
2679
  if (!thd->open_tables)
2700
2680
    return(0);
2701
2681
 
2702
2682
  safe_mutex_assert_owner(&LOCK_open);
2706
2686
      The ptr is checked later
2707
2687
      Do not handle locks of MERGE children.
2708
2688
    */
2709
 
    uint32_t opens=0;
2710
 
    for (table= session->open_tables; table ; table=table->next)
 
2689
    uint opens=0;
 
2690
    for (table= thd->open_tables; table ; table=table->next)
2711
2691
      opens++;
2712
2692
    tables= (Table**) my_alloca(sizeof(Table*)*opens);
2713
2693
  }
2714
2694
  else
2715
 
    tables= &session->open_tables;
 
2695
    tables= &thd->open_tables;
2716
2696
  tables_ptr =tables;
2717
2697
 
2718
 
  prev= &session->open_tables;
2719
 
  for (table=session->open_tables; table ; table=next)
 
2698
  prev= &thd->open_tables;
 
2699
  for (table=thd->open_tables; table ; table=next)
2720
2700
  {
2721
 
    uint32_t db_stat=table->db_stat;
 
2701
    uint db_stat=table->db_stat;
2722
2702
    next=table->next;
2723
2703
    if (!tables || (!db_stat && reopen_table(table)))
2724
2704
    {
2725
2705
      my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
2726
 
      hash_delete(&open_cache,(unsigned char*) table);
 
2706
      VOID(hash_delete(&open_cache,(uchar*) table));
2727
2707
      error=1;
2728
2708
    }
2729
2709
    else
2749
2729
      wait_for_tables() as it tries to acquire LOCK_open, which is
2750
2730
      already locked.
2751
2731
    */
2752
 
    session->some_tables_deleted=0;
2753
 
    if ((lock= mysql_lock_tables(session, tables, (uint) (tables_ptr - tables),
 
2732
    thd->some_tables_deleted=0;
 
2733
    if ((lock= mysql_lock_tables(thd, tables, (uint) (tables_ptr - tables),
2754
2734
                                 flags, &not_used)))
2755
2735
    {
2756
 
      session->locked_tables=mysql_lock_merge(session->locked_tables,lock);
 
2736
      thd->locked_tables=mysql_lock_merge(thd->locked_tables,lock);
2757
2737
    }
2758
2738
    else
2759
2739
    {
2768
2748
  }
2769
2749
  if (get_locks && tables)
2770
2750
  {
2771
 
    my_afree((unsigned char*) tables);
 
2751
    my_afree((uchar*) tables);
2772
2752
  }
2773
2753
  broadcast_refresh();
2774
2754
  return(error);
2779
2759
    Close handlers for tables in list, but leave the Table structure
2780
2760
    intact so that we can re-open these quickly.
2781
2761
 
2782
 
    @param session           Thread context
 
2762
    @param thd           Thread context
2783
2763
    @param table         Head of the list of Table objects
2784
2764
    @param morph_locks   true  - remove locks which we have on tables being closed
2785
2765
                                 but ensure that no DML or DDL will sneak in before
2789
2769
    @param send_refresh  Should we awake waiters even if we didn't close any tables?
2790
2770
*/
2791
2771
 
2792
 
static void close_old_data_files(Session *session, Table *table, bool morph_locks,
 
2772
static void close_old_data_files(THD *thd, Table *table, bool morph_locks,
2793
2773
                                 bool send_refresh)
2794
2774
{
2795
2775
  bool found= send_refresh;
2815
2795
              lock on it. This will also give them a chance to close their
2816
2796
              instances of this table.
2817
2797
            */
2818
 
            mysql_lock_abort(session, ulcktbl, true);
2819
 
            mysql_lock_remove(session, session->locked_tables, ulcktbl, true);
 
2798
            mysql_lock_abort(thd, ulcktbl, true);
 
2799
            mysql_lock_remove(thd, thd->locked_tables, ulcktbl, true);
2820
2800
            ulcktbl->lock_count= 0;
2821
2801
          }
2822
2802
          if ((ulcktbl != table) && ulcktbl->db_stat)
2872
2852
  do
2873
2853
  {
2874
2854
    char *key= table->s->table_cache_key.str;
2875
 
    uint32_t key_length= table->s->table_cache_key.length;
 
2855
    uint key_length= table->s->table_cache_key.length;
2876
2856
 
2877
2857
    HASH_SEARCH_STATE state;
2878
 
    for (Table *search= (Table*) hash_first(&open_cache, (unsigned char*) key,
 
2858
    for (Table *search= (Table*) hash_first(&open_cache, (uchar*) key,
2879
2859
                                             key_length, &state);
2880
2860
         search ;
2881
 
         search= (Table*) hash_next(&open_cache, (unsigned char*) key,
 
2861
         search= (Table*) hash_next(&open_cache, (uchar*) key,
2882
2862
                                    key_length, &state))
2883
2863
    {
2884
2864
      if (search->in_use == table->in_use)
2901
2881
 
2902
2882
/* Wait until all used tables are refreshed */
2903
2883
 
2904
 
bool wait_for_tables(Session *session)
 
2884
bool wait_for_tables(THD *thd)
2905
2885
{
2906
2886
  bool result;
2907
2887
 
2908
 
  session->set_proc_info("Waiting for tables");
 
2888
  thd_proc_info(thd, "Waiting for tables");
2909
2889
  pthread_mutex_lock(&LOCK_open);
2910
 
  while (!session->killed)
 
2890
  while (!thd->killed)
2911
2891
  {
2912
 
    session->some_tables_deleted=0;
2913
 
    close_old_data_files(session,session->open_tables,0,dropping_tables != 0);
2914
 
    mysql_ha_flush(session);
2915
 
    if (!table_is_used(session->open_tables,1))
 
2892
    thd->some_tables_deleted=0;
 
2893
    close_old_data_files(thd,thd->open_tables,0,dropping_tables != 0);
 
2894
    mysql_ha_flush(thd);
 
2895
    if (!table_is_used(thd->open_tables,1))
2916
2896
      break;
2917
2897
    (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
2918
2898
  }
2919
 
  if (session->killed)
 
2899
  if (thd->killed)
2920
2900
    result= 1;                                  // aborted
2921
2901
  else
2922
2902
  {
2923
2903
    /* Now we can open all tables without any interference */
2924
 
    session->set_proc_info("Reopen tables");
2925
 
    session->version= refresh_version;
2926
 
    result=reopen_tables(session,0,0);
 
2904
    thd_proc_info(thd, "Reopen tables");
 
2905
    thd->version= refresh_version;
 
2906
    result=reopen_tables(thd,0,0);
2927
2907
  }
2928
2908
  pthread_mutex_unlock(&LOCK_open);
2929
 
  session->set_proc_info(0);
 
2909
  thd_proc_info(thd, 0);
2930
2910
  return(result);
2931
2911
}
2932
2912
 
2936
2916
 
2937
2917
  SYNOPSIS
2938
2918
    drop_locked_tables()
2939
 
    session                     Thread thandler
 
2919
    thd                 Thread thandler
2940
2920
    db                  Database
2941
2921
    table_name          Table name
2942
2922
 
2955
2935
*/
2956
2936
 
2957
2937
 
2958
 
Table *drop_locked_tables(Session *session,const char *db, const char *table_name)
 
2938
Table *drop_locked_tables(THD *thd,const char *db, const char *table_name)
2959
2939
{
2960
2940
  Table *table,*next,**prev, *found= 0;
2961
 
  prev= &session->open_tables;
 
2941
  prev= &thd->open_tables;
2962
2942
 
2963
2943
  /*
2964
2944
    Note that we need to hold LOCK_open while changing the
2967
2947
    Closing a MERGE child before the parent would be fatal if the
2968
2948
    other thread tries to abort the MERGE lock in between.
2969
2949
  */
2970
 
  for (table= session->open_tables; table ; table=next)
 
2950
  for (table= thd->open_tables; table ; table=next)
2971
2951
  {
2972
2952
    next=table->next;
2973
2953
    if (!strcmp(table->s->table_name.str, table_name) &&
2974
2954
        !strcmp(table->s->db.str, db))
2975
2955
    {
2976
 
      mysql_lock_remove(session, session->locked_tables, table, true);
 
2956
      mysql_lock_remove(thd, thd->locked_tables, table, true);
2977
2957
 
2978
2958
      if (!found)
2979
2959
      {
2988
2968
      else
2989
2969
      {
2990
2970
        /* We already have a name lock, remove copy */
2991
 
        hash_delete(&open_cache,(unsigned char*) table);
 
2971
        VOID(hash_delete(&open_cache,(uchar*) table));
2992
2972
      }
2993
2973
    }
2994
2974
    else
3000
2980
  *prev=0;
3001
2981
  if (found)
3002
2982
    broadcast_refresh();
3003
 
  if (session->locked_tables && session->locked_tables->table_count == 0)
 
2983
  if (thd->locked_tables && thd->locked_tables->table_count == 0)
3004
2984
  {
3005
 
    free((unsigned char*) session->locked_tables);
3006
 
    session->locked_tables=0;
 
2985
    my_free((uchar*) thd->locked_tables,MYF(0));
 
2986
    thd->locked_tables=0;
3007
2987
  }
3008
2988
  return(found);
3009
2989
}
3015
2995
  other threads trying to get the lock.
3016
2996
*/
3017
2997
 
3018
 
void abort_locked_tables(Session *session,const char *db, const char *table_name)
 
2998
void abort_locked_tables(THD *thd,const char *db, const char *table_name)
3019
2999
{
3020
3000
  Table *table;
3021
 
  for (table= session->open_tables; table ; table= table->next)
 
3001
  for (table= thd->open_tables; table ; table= table->next)
3022
3002
  {
3023
3003
    if (!strcmp(table->s->table_name.str, table_name) &&
3024
3004
        !strcmp(table->s->db.str, db))
3025
3005
    {
3026
3006
      /* If MERGE child, forward lock handling to parent. */
3027
 
      mysql_lock_abort(session, table, true);
 
3007
      mysql_lock_abort(thd, table, true);
3028
3008
      break;
3029
3009
    }
3030
3010
  }
3088
3068
 
3089
3069
  SYNOPSIS
3090
3070
    open_unireg_entry()
3091
 
    session                     Thread handle
 
3071
    thd                 Thread handle
3092
3072
    entry               Store open table definition here
3093
3073
    table_list          TableList with db, table_name
3094
3074
    alias               Alias name
3096
3076
    cache_key_length    length of cache_key
3097
3077
 
3098
3078
  NOTES
3099
 
   Extra argument for open is taken from session->open_options
 
3079
   Extra argument for open is taken from thd->open_options
3100
3080
   One must have a lock on LOCK_open when calling this function
3101
3081
 
3102
3082
  RETURN
3104
3084
    #   Error
3105
3085
*/
3106
3086
 
3107
 
static int open_unireg_entry(Session *session, Table *entry, TableList *table_list,
 
3087
static int open_unireg_entry(THD *thd, Table *entry, TableList *table_list,
3108
3088
                             const char *alias,
3109
 
                             char *cache_key, uint32_t cache_key_length)
 
3089
                             char *cache_key, uint cache_key_length)
3110
3090
{
3111
3091
  int error;
3112
3092
  TABLE_SHARE *share;
3113
 
  uint32_t discover_retry_count= 0;
 
3093
  uint discover_retry_count= 0;
3114
3094
 
3115
3095
  safe_mutex_assert_owner(&LOCK_open);
3116
3096
retry:
3117
 
  if (!(share= get_table_share_with_create(session, table_list, cache_key,
 
3097
  if (!(share= get_table_share_with_create(thd, table_list, cache_key,
3118
3098
                                           cache_key_length, 
3119
3099
                                           table_list->i_s_requested_object,
3120
3100
                                           &error)))
3121
3101
    return(1);
3122
3102
 
3123
 
  while ((error= open_table_from_share(session, share, alias,
 
3103
  while ((error= open_table_from_share(thd, share, alias,
3124
3104
                                       (uint) (HA_OPEN_KEYFILE |
3125
3105
                                               HA_OPEN_RNDFILE |
3126
3106
                                               HA_GET_INDEX |
3127
3107
                                               HA_TRY_READ_ONLY),
3128
3108
                                       (EXTRA_RECORD),
3129
 
                                       session->open_options, entry, OTM_OPEN)))
 
3109
                                       thd->open_options, entry, OTM_OPEN)))
3130
3110
  {
3131
3111
    if (error == 7)                             // Table def changed
3132
3112
    {
3147
3127
        - Start waiting that the share is released
3148
3128
        - Retry by opening all tables again
3149
3129
      */
3150
 
      if (ha_create_table_from_engine(session, table_list->db,
 
3130
      if (ha_create_table_from_engine(thd, table_list->db,
3151
3131
                                      table_list->table_name))
3152
3132
        goto err;
3153
3133
      /*
3159
3139
        goto err;
3160
3140
      /* Free share and wait until it's released by all threads */
3161
3141
      release_table_share(share, RELEASE_WAIT_FOR_DROP);
3162
 
      if (!session->killed)
 
3142
      if (!thd->killed)
3163
3143
      {
3164
 
        drizzle_reset_errors(session, 1);         // Clear warnings
3165
 
        session->clear_error();                 // Clear error message
 
3144
        drizzle_reset_errors(thd, 1);         // Clear warnings
 
3145
        thd->clear_error();                 // Clear error message
3166
3146
        goto retry;
3167
3147
      }
3168
3148
      return(1);
3170
3150
    if (!entry->s || !entry->s->crashed)
3171
3151
      goto err;
3172
3152
     // Code below is for repairing a crashed file
3173
 
     if ((error= lock_table_name(session, table_list, true)))
 
3153
     if ((error= lock_table_name(thd, table_list, true)))
3174
3154
     {
3175
3155
       if (error < 0)
3176
3156
        goto err;
3177
 
       if (wait_for_locked_table_names(session, table_list))
 
3157
       if (wait_for_locked_table_names(thd, table_list))
3178
3158
       {
3179
 
        unlock_table_name(session, table_list);
 
3159
        unlock_table_name(thd, table_list);
3180
3160
        goto err;
3181
3161
       }
3182
3162
     }
3183
3163
     pthread_mutex_unlock(&LOCK_open);
3184
 
     session->clear_error();                            // Clear error message
 
3164
     thd->clear_error();                                // Clear error message
3185
3165
     error= 0;
3186
 
     if (open_table_from_share(session, share, alias,
 
3166
     if (open_table_from_share(thd, share, alias,
3187
3167
                               (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
3188
3168
                                       HA_GET_INDEX |
3189
3169
                                       HA_TRY_READ_ONLY),
3190
3170
                               EXTRA_RECORD,
3191
3171
                               ha_open_options | HA_OPEN_FOR_REPAIR,
3192
3172
                               entry, OTM_OPEN) || ! entry->file ||
3193
 
        (entry->file->is_crashed() && entry->file->ha_check_and_repair(session)))
 
3173
        (entry->file->is_crashed() && entry->file->ha_check_and_repair(thd)))
3194
3174
     {
3195
3175
       /* Give right error message */
3196
 
       session->clear_error();
 
3176
       thd->clear_error();
3197
3177
       my_error(ER_NOT_KEYFILE, MYF(0), share->table_name.str, my_errno);
3198
3178
       sql_print_error(_("Couldn't repair table: %s.%s"), share->db.str,
3199
3179
                       share->table_name.str);
3202
3182
       error=1;
3203
3183
     }
3204
3184
     else
3205
 
       session->clear_error();                  // Clear error message
 
3185
       thd->clear_error();                      // Clear error message
3206
3186
     pthread_mutex_lock(&LOCK_open);
3207
 
     unlock_table_name(session, table_list);
 
3187
     unlock_table_name(thd, table_list);
3208
3188
 
3209
3189
     if (error)
3210
3190
       goto err;
3221
3201
    if (mysql_bin_log.is_open())
3222
3202
    {
3223
3203
      char *query, *end;
3224
 
      uint32_t query_buf_size= 20 + share->db.length + share->table_name.length +1;
 
3204
      uint query_buf_size= 20 + share->db.length + share->table_name.length +1;
3225
3205
      if ((query= (char*) my_malloc(query_buf_size,MYF(MY_WME))))
3226
3206
      {
3227
3207
        /* this DELETE FROM is needed even with row-based binlogging */
3228
 
        end = strxmov(my_stpcpy(query, "DELETE FROM `"),
3229
 
                      share->db.str,"`.`",share->table_name.str,"`", NULL);
3230
 
        session->binlog_query(Session::STMT_QUERY_TYPE,
 
3208
        end = strxmov(stpcpy(query, "DELETE FROM `"),
 
3209
                      share->db.str,"`.`",share->table_name.str,"`", NullS);
 
3210
        thd->binlog_query(THD::STMT_QUERY_TYPE,
3231
3211
                          query, (ulong)(end-query), false, false);
3232
 
        free(query);
 
3212
        my_free(query, MYF(0));
3233
3213
      }
3234
3214
      else
3235
3215
      {
3259
3239
 
3260
3240
  SYNOPSIS
3261
3241
    open_tables()
3262
 
    session - thread handler
 
3242
    thd - thread handler
3263
3243
    start - list of tables in/out
3264
3244
    counter - number of opened tables will be return using this parameter
3265
3245
    flags   - bitmap of flags to modify how the tables will be open:
3282
3262
    -1 - error
3283
3263
*/
3284
3264
 
3285
 
int open_tables(Session *session, TableList **start, uint32_t *counter, uint32_t flags)
 
3265
int open_tables(THD *thd, TableList **start, uint *counter, uint flags)
3286
3266
{
3287
3267
  TableList *tables= NULL;
3288
3268
  bool refresh;
3297
3277
  */
3298
3278
  init_sql_alloc(&new_frm_mem, 8024, 8024);
3299
3279
 
3300
 
  session->current_tablenr= 0;
 
3280
  thd->current_tablenr= 0;
3301
3281
 restart:
3302
3282
  *counter= 0;
3303
 
  session->set_proc_info("Opening tables");
 
3283
  thd_proc_info(thd, "Opening tables");
3304
3284
 
3305
3285
  /*
3306
3286
    For every table in the list of tables to open, try to find or open
3328
3308
    */
3329
3309
    if (tables->schema_table)
3330
3310
    {
3331
 
      if (!mysql_schema_table(session, session->lex, tables))
 
3311
      if (!mysql_schema_table(thd, thd->lex, tables))
3332
3312
        continue;
3333
3313
      return(-1);
3334
3314
    }
3339
3319
      not opened yet. Try to open the table.
3340
3320
    */
3341
3321
    if (!tables->table)
3342
 
      tables->table= open_table(session, tables, &refresh, flags);
 
3322
      tables->table= open_table(thd, tables, &refresh, flags);
3343
3323
 
3344
3324
    if (!tables->table)
3345
3325
    {
3361
3341
          we pretend that we have finished calculation which we were doing
3362
3342
          currently.
3363
3343
        */
3364
 
        close_tables_for_reopen(session, start);
 
3344
        close_tables_for_reopen(thd, start);
3365
3345
        goto restart;
3366
3346
      }
3367
3347
 
3371
3351
      result= -1;                               // Fatal error
3372
3352
      break;
3373
3353
    }
3374
 
    if (tables->lock_type != TL_UNLOCK && ! session->locked_tables)
 
3354
    if (tables->lock_type != TL_UNLOCK && ! thd->locked_tables)
3375
3355
    {
3376
3356
      if (tables->lock_type == TL_WRITE_DEFAULT)
3377
 
        tables->table->reginfo.lock_type= session->update_lock_default;
 
3357
        tables->table->reginfo.lock_type= thd->update_lock_default;
3378
3358
      else if (tables->table->s->tmp_table == NO_TMP_TABLE)
3379
3359
        tables->table->reginfo.lock_type= tables->lock_type;
3380
3360
    }
3381
3361
  }
3382
3362
 
3383
 
  session->set_proc_info(0);
 
3363
  thd_proc_info(thd, 0);
3384
3364
  free_root(&new_frm_mem, MYF(0));              // Free pre-alloced block
3385
3365
 
3386
3366
  if (result && tables)
3387
3367
  {
3388
3368
    /*
3389
3369
      Some functions determine success as (tables->table != NULL).
3390
 
      tables->table is in session->open_tables.
 
3370
      tables->table is in thd->open_tables.
3391
3371
    */
3392
3372
    tables->table= NULL;
3393
3373
  }
3400
3380
 
3401
3381
  SYNOPSIS
3402
3382
    check_lock_and_start_stmt()
3403
 
    session                     Thread handle
 
3383
    thd                 Thread handle
3404
3384
    table_list          Table to check
3405
3385
    lock_type           Lock used for table
3406
3386
 
3409
3389
  1     error
3410
3390
*/
3411
3391
 
3412
 
static bool check_lock_and_start_stmt(Session *session, Table *table,
 
3392
static bool check_lock_and_start_stmt(THD *thd, Table *table,
3413
3393
                                      thr_lock_type lock_type)
3414
3394
{
3415
3395
  int error;
3420
3400
    my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0),table->alias);
3421
3401
    return(1);
3422
3402
  }
3423
 
  if ((error=table->file->start_stmt(session, lock_type)))
 
3403
  if ((error=table->file->start_stmt(thd, lock_type)))
3424
3404
  {
3425
3405
    table->file->print_error(error,MYF(0));
3426
3406
    return(1);
3432
3412
/**
3433
3413
  @brief Open and lock one table
3434
3414
 
3435
 
  @param[in]    session             thread handle
 
3415
  @param[in]    thd             thread handle
3436
3416
  @param[in]    table_l         table to open is first table in this list
3437
3417
  @param[in]    lock_type       lock to use for table
3438
3418
 
3459
3439
    and locking issues because it does not call lock_tables().
3460
3440
*/
3461
3441
 
3462
 
Table *open_n_lock_single_table(Session *session, TableList *table_l,
 
3442
Table *open_n_lock_single_table(THD *thd, TableList *table_l,
3463
3443
                                thr_lock_type lock_type)
3464
3444
{
3465
3445
  TableList *save_next_global;
3473
3453
  table_l->lock_type= lock_type;
3474
3454
 
3475
3455
  /* Open the table. */
3476
 
  if (simple_open_n_lock_tables(session, table_l))
 
3456
  if (simple_open_n_lock_tables(thd, table_l))
3477
3457
    table_l->table= NULL; /* Just to be sure. */
3478
3458
 
3479
3459
  /* Restore list. */
3488
3468
 
3489
3469
  SYNOPSIS
3490
3470
    open_ltable()
3491
 
    session                     Thread handler
 
3471
    thd                 Thread handler
3492
3472
    table_list          Table to open is first table in this list
3493
3473
    lock_type           Lock to use for open
3494
3474
    lock_flags          Flags passed to mysql_lock_table
3507
3487
      table_list->table         table
3508
3488
*/
3509
3489
 
3510
 
Table *open_ltable(Session *session, TableList *table_list, thr_lock_type lock_type,
3511
 
                   uint32_t lock_flags)
 
3490
Table *open_ltable(THD *thd, TableList *table_list, thr_lock_type lock_type,
 
3491
                   uint lock_flags)
3512
3492
{
3513
3493
  Table *table;
3514
3494
  bool refresh;
3515
3495
 
3516
 
  session->set_proc_info("Opening table");
3517
 
  session->current_tablenr= 0;
3518
 
  while (!(table= open_table(session, table_list, &refresh, 0)) &&
 
3496
  thd_proc_info(thd, "Opening table");
 
3497
  thd->current_tablenr= 0;
 
3498
  while (!(table= open_table(thd, table_list, &refresh, 0)) &&
3519
3499
         refresh)
3520
3500
    ;
3521
3501
 
3523
3503
  {
3524
3504
    table_list->lock_type= lock_type;
3525
3505
    table_list->table=     table;
3526
 
    if (session->locked_tables)
 
3506
    if (thd->locked_tables)
3527
3507
    {
3528
 
      if (check_lock_and_start_stmt(session, table, lock_type))
 
3508
      if (check_lock_and_start_stmt(thd, table, lock_type))
3529
3509
        table= 0;
3530
3510
    }
3531
3511
    else
3532
3512
    {
3533
 
      assert(session->lock == 0);       // You must lock everything at once
 
3513
      assert(thd->lock == 0);   // You must lock everything at once
3534
3514
      if ((table->reginfo.lock_type= lock_type) != TL_UNLOCK)
3535
 
        if (! (session->lock= mysql_lock_tables(session, &table_list->table, 1,
 
3515
        if (! (thd->lock= mysql_lock_tables(thd, &table_list->table, 1,
3536
3516
                                            lock_flags, &refresh)))
3537
3517
          table= 0;
3538
3518
    }
3539
3519
  }
3540
3520
 
3541
 
  session->set_proc_info(0);
 
3521
  thd_proc_info(thd, 0);
3542
3522
  return(table);
3543
3523
}
3544
3524
 
3548
3528
 
3549
3529
  SYNOPSIS
3550
3530
    open_and_lock_tables_derived()
3551
 
    session             - thread handler
 
3531
    thd         - thread handler
3552
3532
    tables      - list of tables for open&locking
3553
3533
    derived     - if to handle derived tables
3554
3534
 
3561
3541
 
3562
3542
  NOTE
3563
3543
    There are two convenience functions:
3564
 
    - simple_open_n_lock_tables(session, tables)  without derived handling
3565
 
    - open_and_lock_tables(session, tables)       with derived handling
 
3544
    - simple_open_n_lock_tables(thd, tables)  without derived handling
 
3545
    - open_and_lock_tables(thd, tables)       with derived handling
3566
3546
    Both inline functions call open_and_lock_tables_derived() with
3567
3547
    the third argument set appropriately.
3568
3548
*/
3569
3549
 
3570
 
int open_and_lock_tables_derived(Session *session, TableList *tables, bool derived)
 
3550
int open_and_lock_tables_derived(THD *thd, TableList *tables, bool derived)
3571
3551
{
3572
 
  uint32_t counter;
 
3552
  uint counter;
3573
3553
  bool need_reopen;
3574
3554
 
3575
3555
  for ( ; ; ) 
3576
3556
  {
3577
 
    if (open_tables(session, &tables, &counter, 0))
 
3557
    if (open_tables(thd, &tables, &counter, 0))
3578
3558
      return(-1);
3579
3559
 
3580
 
    if (!lock_tables(session, tables, counter, &need_reopen))
 
3560
    if (!lock_tables(thd, tables, counter, &need_reopen))
3581
3561
      break;
3582
3562
    if (!need_reopen)
3583
3563
      return(-1);
3584
 
    close_tables_for_reopen(session, &tables);
 
3564
    close_tables_for_reopen(thd, &tables);
3585
3565
  }
3586
3566
  if (derived &&
3587
 
      (mysql_handle_derived(session->lex, &mysql_derived_prepare) ||
3588
 
       (session->fill_derived_tables() &&
3589
 
        mysql_handle_derived(session->lex, &mysql_derived_filling))))
 
3567
      (mysql_handle_derived(thd->lex, &mysql_derived_prepare) ||
 
3568
       (thd->fill_derived_tables() &&
 
3569
        mysql_handle_derived(thd->lex, &mysql_derived_filling))))
3590
3570
    return(true); /* purecov: inspected */
3591
3571
  return(0);
3592
3572
}
3597
3577
 
3598
3578
  SYNOPSIS
3599
3579
    open_normal_and_derived_tables
3600
 
    session             - thread handler
 
3580
    thd         - thread handler
3601
3581
    tables      - list of tables for open
3602
3582
    flags       - bitmap of flags to modify how the tables will be open:
3603
3583
                  DRIZZLE_LOCK_IGNORE_FLUSH - open table even if someone has
3612
3592
    data from the tables.
3613
3593
*/
3614
3594
 
3615
 
bool open_normal_and_derived_tables(Session *session, TableList *tables, uint32_t flags)
 
3595
bool open_normal_and_derived_tables(THD *thd, TableList *tables, uint flags)
3616
3596
{
3617
 
  uint32_t counter;
3618
 
  assert(!session->fill_derived_tables());
3619
 
  if (open_tables(session, &tables, &counter, flags) ||
3620
 
      mysql_handle_derived(session->lex, &mysql_derived_prepare))
 
3597
  uint counter;
 
3598
  assert(!thd->fill_derived_tables());
 
3599
  if (open_tables(thd, &tables, &counter, flags) ||
 
3600
      mysql_handle_derived(thd->lex, &mysql_derived_prepare))
3621
3601
    return(true); /* purecov: inspected */
3622
3602
  return(0);
3623
3603
}
3656
3636
 
3657
3637
   3. Otherwise, statement-based logging is used.
3658
3638
 
3659
 
   @param session    Client thread
 
3639
   @param thd    Client thread
3660
3640
   @param tables Tables involved in the query
3661
3641
 */
3662
3642
 
3663
 
int decide_logging_format(Session *session, TableList *tables)
 
3643
int decide_logging_format(THD *thd, TableList *tables)
3664
3644
{
3665
 
  if (mysql_bin_log.is_open() && (session->options & OPTION_BIN_LOG))
 
3645
  if (mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG))
3666
3646
  {
3667
3647
    handler::Table_flags flags_some_set= handler::Table_flags();
3668
3648
    handler::Table_flags flags_all_set= ~handler::Table_flags();
3688
3668
               "Statement cannot be logged to the binary log in"
3689
3669
               " row-based nor statement-based format");
3690
3670
    }
3691
 
    else if (session->variables.binlog_format == BINLOG_FORMAT_STMT &&
 
3671
    else if (thd->variables.binlog_format == BINLOG_FORMAT_STMT &&
3692
3672
             (flags_all_set & HA_BINLOG_STMT_CAPABLE) == 0)
3693
3673
    {
3694
3674
      my_error((error= ER_BINLOG_LOGGING_IMPOSSIBLE), MYF(0),
3695
3675
                "Statement-based format required for this statement,"
3696
3676
                " but not allowed by this combination of engines");
3697
3677
    }
3698
 
    else if ((session->variables.binlog_format == BINLOG_FORMAT_ROW ||
3699
 
              session->lex->is_stmt_unsafe()) &&
 
3678
    else if ((thd->variables.binlog_format == BINLOG_FORMAT_ROW ||
 
3679
              thd->lex->is_stmt_unsafe()) &&
3700
3680
             (flags_all_set & HA_BINLOG_ROW_CAPABLE) == 0)
3701
3681
    {
3702
3682
      my_error((error= ER_BINLOG_LOGGING_IMPOSSIBLE), MYF(0),
3704
3684
                " but not allowed by this combination of engines");
3705
3685
    }
3706
3686
 
 
3687
    /*
 
3688
      If more than one engine is involved in the statement and at
 
3689
      least one is doing it's own logging (is *self-logging*), the
 
3690
      statement cannot be logged atomically, so we generate an error
 
3691
      rather than allowing the binlog to become corrupt.
 
3692
     */
 
3693
    if (multi_engine &&
 
3694
        (flags_some_set & HA_HAS_OWN_BINLOGGING))
 
3695
    {
 
3696
      error= ER_BINLOG_LOGGING_IMPOSSIBLE;
 
3697
      my_error(error, MYF(0),
 
3698
               "Statement cannot be written atomically since more"
 
3699
               " than one engine involved and at least one engine"
 
3700
               " is self-logging");
 
3701
    }
 
3702
 
3707
3703
    if (error)
3708
3704
      return -1;
3709
3705
 
3719
3715
      this code in reset_current_stmt_binlog_row_based(), it has to be
3720
3716
      here.
3721
3717
    */
3722
 
    if (session->lex->is_stmt_unsafe() ||
 
3718
    if (thd->lex->is_stmt_unsafe() ||
3723
3719
        (flags_all_set & HA_BINLOG_STMT_CAPABLE) == 0)
3724
3720
    {
3725
 
      session->set_current_stmt_binlog_row_based_if_mixed();
 
3721
      thd->set_current_stmt_binlog_row_based_if_mixed();
3726
3722
    }
3727
3723
  }
3728
3724
 
3734
3730
 
3735
3731
  SYNOPSIS
3736
3732
    lock_tables()
3737
 
    session                     Thread handler
 
3733
    thd                 Thread handler
3738
3734
    tables              Tables to lock
3739
3735
    count               Number of opened tables
3740
3736
    need_reopen         Out parameter which if true indicates that some
3750
3746
 
3751
3747
    If query for which we are calling this function marked as requring
3752
3748
    prelocking, this function will do implicit LOCK TABLES and change
3753
 
    session::prelocked_mode accordingly.
 
3749
    thd::prelocked_mode accordingly.
3754
3750
 
3755
3751
  RETURN VALUES
3756
3752
   0    ok
3757
3753
   -1   Error
3758
3754
*/
3759
3755
 
3760
 
int lock_tables(Session *session, TableList *tables, uint32_t count, bool *need_reopen)
 
3756
int lock_tables(THD *thd, TableList *tables, uint count, bool *need_reopen)
3761
3757
{
3762
3758
  TableList *table;
3763
3759
 
3768
3764
  *need_reopen= false;
3769
3765
 
3770
3766
  if (!tables)
3771
 
    return(decide_logging_format(session, tables));
 
3767
    return(decide_logging_format(thd, tables));
3772
3768
 
3773
 
  if (!session->locked_tables)
 
3769
  if (!thd->locked_tables)
3774
3770
  {
3775
 
    assert(session->lock == 0); // You must lock everything at once
 
3771
    assert(thd->lock == 0);     // You must lock everything at once
3776
3772
    Table **start,**ptr;
3777
 
    uint32_t lock_flag= DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN;
 
3773
    uint lock_flag= DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN;
3778
3774
 
3779
 
    if (!(ptr=start=(Table**) session->alloc(sizeof(Table*)*count)))
 
3775
    if (!(ptr=start=(Table**) thd->alloc(sizeof(Table*)*count)))
3780
3776
      return(-1);
3781
3777
    for (table= tables; table; table= table->next_global)
3782
3778
    {
3784
3780
        *(ptr++)= table->table;
3785
3781
    }
3786
3782
 
3787
 
    if (!(session->lock= mysql_lock_tables(session, start, (uint) (ptr - start),
 
3783
    if (!(thd->lock= mysql_lock_tables(thd, start, (uint) (ptr - start),
3788
3784
                                       lock_flag, need_reopen)))
3789
3785
    {
3790
3786
      return(-1);
3792
3788
  }
3793
3789
  else
3794
3790
  {
3795
 
    TableList *first_not_own= session->lex->first_not_own_table();
 
3791
    TableList *first_not_own= thd->lex->first_not_own_table();
3796
3792
    /*
3797
3793
      When open_and_lock_tables() is called for a single table out of
3798
3794
      a table list, the 'next_global' chain is temporarily broken. We
3806
3802
         table= table->next_global)
3807
3803
    {
3808
3804
      if (!table->placeholder() &&
3809
 
          check_lock_and_start_stmt(session, table->table, table->lock_type))
 
3805
          check_lock_and_start_stmt(thd, table->table, table->lock_type))
3810
3806
      {
3811
3807
        return(-1);
3812
3808
      }
3813
3809
    }
3814
3810
  }
3815
3811
 
3816
 
  return(decide_logging_format(session, tables));
 
3812
  return(decide_logging_format(thd, tables));
3817
3813
}
3818
3814
 
3819
3815
 
3823
3819
 
3824
3820
  SYNOPSIS
3825
3821
    close_tables_for_reopen()
3826
 
      session    in     Thread context
 
3822
      thd    in     Thread context
3827
3823
      tables in/out List of tables which we were trying to open and lock
3828
3824
 
3829
3825
*/
3830
3826
 
3831
 
void close_tables_for_reopen(Session *session, TableList **tables)
 
3827
void close_tables_for_reopen(THD *thd, TableList **tables)
3832
3828
{
3833
3829
  /*
3834
3830
    If table list consists only from tables from prelocking set, table list
3835
3831
    for new attempt should be empty, so we have to update list's root pointer.
3836
3832
  */
3837
 
  if (session->lex->first_not_own_table() == *tables)
 
3833
  if (thd->lex->first_not_own_table() == *tables)
3838
3834
    *tables= 0;
3839
 
  session->lex->chop_off_not_own_tables();
 
3835
  thd->lex->chop_off_not_own_tables();
3840
3836
  for (TableList *tmp= *tables; tmp; tmp= tmp->next_global)
3841
3837
    tmp->table= 0;
3842
 
  close_thread_tables(session);
 
3838
  close_thread_tables(thd);
3843
3839
}
3844
3840
 
3845
3841
 
3848
3844
 
3849
3845
  SYNPOSIS
3850
3846
    open_temporary_table()
3851
 
    session               Thread object
 
3847
    thd           Thread object
3852
3848
    path          Path (without .frm)
3853
3849
    db            database
3854
3850
    table_name    Table name
3855
 
    link_in_list  1 if table should be linked into session->temporary_tables
 
3851
    link_in_list  1 if table should be linked into thd->temporary_tables
3856
3852
 
3857
3853
 NOTES:
3858
3854
    Used by alter_table to open a temporary table and when creating
3863
3859
   #  Table object
3864
3860
*/
3865
3861
 
3866
 
Table *open_temporary_table(Session *session, const char *path, const char *db,
 
3862
Table *open_temporary_table(THD *thd, const char *path, const char *db,
3867
3863
                            const char *table_name, bool link_in_list,
3868
3864
                            open_table_mode open_mode)
3869
3865
{
3870
3866
  Table *tmp_table;
3871
3867
  TABLE_SHARE *share;
3872
3868
  char cache_key[MAX_DBKEY_LENGTH], *saved_cache_key, *tmp_path;
3873
 
  uint32_t key_length;
 
3869
  uint key_length;
3874
3870
  TableList table_list;
3875
3871
 
3876
3872
  table_list.db=         (char*) db;
3877
3873
  table_list.table_name= (char*) table_name;
3878
3874
  /* Create the cache_key for temporary tables */
3879
 
  key_length= create_table_def_key(session, cache_key, &table_list, 1);
 
3875
  key_length= create_table_def_key(thd, cache_key, &table_list, 1);
3880
3876
 
3881
3877
  if (!(tmp_table= (Table*) my_malloc(sizeof(*tmp_table) + sizeof(*share) +
3882
3878
                                      strlen(path)+1 + key_length,
3885
3881
 
3886
3882
  share= (TABLE_SHARE*) (tmp_table+1);
3887
3883
  tmp_path= (char*) (share+1);
3888
 
  saved_cache_key= my_stpcpy(tmp_path, path)+1;
 
3884
  saved_cache_key= stpcpy(tmp_path, path)+1;
3889
3885
  memcpy(saved_cache_key, cache_key, key_length);
3890
3886
 
3891
 
  init_tmp_table_share(session, share, saved_cache_key, key_length,
 
3887
  init_tmp_table_share(thd, share, saved_cache_key, key_length,
3892
3888
                       strchr(saved_cache_key, '\0')+1, tmp_path);
3893
3889
 
3894
 
  if (open_table_def(session, share, 0) ||
3895
 
      open_table_from_share(session, share, table_name,
 
3890
  if (open_table_def(thd, share, 0) ||
 
3891
      open_table_from_share(thd, share, table_name,
3896
3892
                            (open_mode == OTM_ALTER) ? 0 :
3897
3893
                            (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
3898
3894
                                    HA_GET_INDEX),
3904
3900
  {
3905
3901
    /* No need to lock share->mutex as this is not needed for tmp tables */
3906
3902
    free_table_share(share);
3907
 
    free((char*) tmp_table);
 
3903
    my_free((char*) tmp_table,MYF(0));
3908
3904
    return(0);
3909
3905
  }
3910
3906
 
3924
3920
  if (link_in_list)
3925
3921
  {
3926
3922
    /* growing temp list at the head */
3927
 
    tmp_table->next= session->temporary_tables;
 
3923
    tmp_table->next= thd->temporary_tables;
3928
3924
    if (tmp_table->next)
3929
3925
      tmp_table->next->prev= tmp_table;
3930
 
    session->temporary_tables= tmp_table;
3931
 
    session->temporary_tables->prev= 0;
3932
 
    if (session->slave_thread)
 
3926
    thd->temporary_tables= tmp_table;
 
3927
    thd->temporary_tables->prev= 0;
 
3928
    if (thd->slave_thread)
3933
3929
      slave_open_temp_tables++;
3934
3930
  }
3935
3931
  tmp_table->pos_in_table_list= 0;
3943
3939
  handler *file;
3944
3940
  char *ext;
3945
3941
 
3946
 
  my_stpcpy(ext= strchr(path, '\0'), reg_ext);
 
3942
  stpcpy(ext= strchr(path, '\0'), reg_ext);
3947
3943
  if (my_delete(path,MYF(0)))
3948
3944
    error=1; /* purecov: inspected */
3949
3945
  *ext= 0;                              // remove extension
3950
 
  file= get_new_handler((TABLE_SHARE*) 0, current_session->mem_root, base);
 
3946
  file= get_new_handler((TABLE_SHARE*) 0, current_thd->mem_root, base);
3951
3947
  if (!frm_only && file && file->ha_delete_table(path))
3952
3948
  {
3953
3949
    error=1;
3974
3970
 
3975
3971
#define WRONG_GRANT (Field*) -1
3976
3972
 
3977
 
static void update_field_dependencies(Session *session, Field *field, Table *table)
 
3973
static void update_field_dependencies(THD *thd, Field *field, Table *table)
3978
3974
{
3979
 
  if (session->mark_used_columns != MARK_COLUMNS_NONE)
 
3975
  if (thd->mark_used_columns != MARK_COLUMNS_NONE)
3980
3976
  {
3981
3977
    MY_BITMAP *current_bitmap, *other_bitmap;
3982
3978
 
3988
3984
    table->covering_keys.intersect(field->part_of_key);
3989
3985
    table->merge_keys.merge(field->part_of_key);
3990
3986
 
3991
 
    if (session->mark_used_columns == MARK_COLUMNS_READ)
 
3987
    if (thd->mark_used_columns == MARK_COLUMNS_READ)
3992
3988
    {
3993
3989
      current_bitmap= table->read_set;
3994
3990
      other_bitmap=   table->write_set;
4001
3997
 
4002
3998
    if (bitmap_fast_test_and_set(current_bitmap, field->field_index))
4003
3999
    {
4004
 
      if (session->mark_used_columns == MARK_COLUMNS_WRITE)
4005
 
        session->dup_field= field;
 
4000
      if (thd->mark_used_columns == MARK_COLUMNS_WRITE)
 
4001
        thd->dup_field= field;
4006
4002
      return;
4007
4003
    }
4008
4004
    if (table->get_fields_in_item_tree)
4020
4016
 
4021
4017
  SYNOPSIS
4022
4018
    find_field_in_natural_join()
4023
 
    session                      [in]  thread handler
 
4019
    thd                  [in]  thread handler
4024
4020
    table_ref            [in]  table reference to search
4025
4021
    name                 [in]  name of field
4026
4022
    length               [in]  length of name
4045
4041
*/
4046
4042
 
4047
4043
static Field *
4048
 
find_field_in_natural_join(Session *session, TableList *table_ref, const char *name,
4049
 
                           uint32_t length __attribute__((unused)),
 
4044
find_field_in_natural_join(THD *thd, TableList *table_ref, const char *name,
 
4045
                           uint length __attribute__((unused)),
4050
4046
                           Item **ref __attribute__((unused)), bool register_tree_change __attribute__((unused)),
4051
4047
                           TableList **actual_table)
4052
4048
{
4065
4061
    {
4066
4062
      if (nj_col)
4067
4063
      {
4068
 
        my_error(ER_NON_UNIQ_ERROR, MYF(0), name, session->where);
 
4064
        my_error(ER_NON_UNIQ_ERROR, MYF(0), name, thd->where);
4069
4065
        return(NULL);
4070
4066
      }
4071
4067
      nj_col= curr_nj_col;
4077
4073
    /* This is a base table. */
4078
4074
    assert(nj_col->table_ref->table == nj_col->table_field->table);
4079
4075
    found_field= nj_col->table_field;
4080
 
    update_field_dependencies(session, found_field, nj_col->table_ref->table);
 
4076
    update_field_dependencies(thd, found_field, nj_col->table_ref->table);
4081
4077
  }
4082
4078
 
4083
4079
  *actual_table= nj_col->table_ref;
4091
4087
 
4092
4088
  SYNOPSIS
4093
4089
    find_field_in_table()
4094
 
    session                             thread handler
 
4090
    thd                         thread handler
4095
4091
    table                       table where to search for the field
4096
4092
    name                        name of field
4097
4093
    length                      length of name
4105
4101
*/
4106
4102
 
4107
4103
Field *
4108
 
find_field_in_table(Session *session, Table *table, const char *name, uint32_t length,
4109
 
                    bool allow_rowid, uint32_t *cached_field_index_ptr)
 
4104
find_field_in_table(THD *thd, Table *table, const char *name, uint length,
 
4105
                    bool allow_rowid, uint *cached_field_index_ptr)
4110
4106
{
4111
4107
  Field **field_ptr, *field;
4112
 
  uint32_t cached_field_index= *cached_field_index_ptr;
 
4108
  uint cached_field_index= *cached_field_index_ptr;
4113
4109
 
4114
4110
  /* We assume here that table->field < NO_CACHED_FIELD_INDEX = UINT_MAX */
4115
4111
  if (cached_field_index < table->s->fields &&
4118
4114
    field_ptr= table->field + cached_field_index;
4119
4115
  else if (table->s->name_hash.records)
4120
4116
  {
4121
 
    field_ptr= (Field**) hash_search(&table->s->name_hash, (unsigned char*) name,
 
4117
    field_ptr= (Field**) hash_search(&table->s->name_hash, (uchar*) name,
4122
4118
                                     length);
4123
4119
    if (field_ptr)
4124
4120
    {
4140
4136
 
4141
4137
  if (field_ptr && *field_ptr)
4142
4138
  {
4143
 
    if ((*field_ptr)->vcol_info)
4144
 
    {
4145
 
      if (session->mark_used_columns != MARK_COLUMNS_NONE)
4146
 
      {
4147
 
        Item *vcol_item= (*field_ptr)->vcol_info->expr_item;
4148
 
        assert(vcol_item);
4149
 
        vcol_item->walk(&Item::register_field_in_read_map, 1, (unsigned char *) 0);
4150
 
        /* 
4151
 
          Set the virtual field for write here if 
4152
 
          1) this procedure is called for a read-only operation (SELECT), and
4153
 
          2) the virtual column is not phycically stored in the table
4154
 
        */
4155
 
        if ((session->mark_used_columns != MARK_COLUMNS_WRITE) && 
4156
 
            (not (*field_ptr)->is_stored))
4157
 
          bitmap_set_bit((*field_ptr)->table->write_set, (*field_ptr)->field_index);
4158
 
      }
4159
 
    }
4160
4139
    *cached_field_index_ptr= field_ptr - table->field;
4161
4140
    field= *field_ptr;
4162
4141
  }
4169
4148
    field= table->field[table->s->rowid_field_offset-1];
4170
4149
  }
4171
4150
 
4172
 
  update_field_dependencies(session, field, table);
 
4151
  update_field_dependencies(thd, field, table);
4173
4152
 
4174
4153
  return(field);
4175
4154
}
4180
4159
 
4181
4160
  SYNOPSIS
4182
4161
    find_field_in_table_ref()
4183
 
    session                        [in]  thread handler
 
4162
    thd                    [in]  thread handler
4184
4163
    table_list             [in]  table reference to search
4185
4164
    name                   [in]  name of field
4186
4165
    length                 [in]  field length of name
4218
4197
*/
4219
4198
 
4220
4199
Field *
4221
 
find_field_in_table_ref(Session *session, TableList *table_list,
4222
 
                        const char *name, uint32_t length,
 
4200
find_field_in_table_ref(THD *thd, TableList *table_list,
 
4201
                        const char *name, uint length,
4223
4202
                        const char *item_name, const char *db_name,
4224
4203
                        const char *table_name, Item **ref,
4225
4204
                        bool check_privileges, bool allow_rowid,
4226
 
                        uint32_t *cached_field_index_ptr,
 
4205
                        uint *cached_field_index_ptr,
4227
4206
                        bool register_tree_change, TableList **actual_table)
4228
4207
{
4229
4208
  Field *fld= NULL;
4272
4251
  {
4273
4252
    /* 'table_list' is a stored table. */
4274
4253
    assert(table_list->table);
4275
 
    if ((fld= find_field_in_table(session, table_list->table, name, length,
 
4254
    if ((fld= find_field_in_table(thd, table_list->table, name, length,
4276
4255
                                  allow_rowid,
4277
4256
                                  cached_field_index_ptr)))
4278
4257
      *actual_table= table_list;
4292
4271
      TableList *table;
4293
4272
      while ((table= it++))
4294
4273
      {
4295
 
        if ((fld= find_field_in_table_ref(session, table, name, length, item_name,
 
4274
        if ((fld= find_field_in_table_ref(thd, table, name, length, item_name,
4296
4275
                                          db_name, table_name, ref,
4297
4276
                                          check_privileges, allow_rowid,
4298
4277
                                          cached_field_index_ptr,
4307
4286
      natural join, thus if the field is not qualified, we will search
4308
4287
      directly the top-most NATURAL/USING join.
4309
4288
    */
4310
 
    fld= find_field_in_natural_join(session, table_list, name, length, ref,
 
4289
    fld= find_field_in_natural_join(thd, table_list, name, length, ref,
4311
4290
                                    register_tree_change, actual_table);
4312
4291
  }
4313
4292
 
4314
4293
  if (fld)
4315
4294
  {
4316
 
      if (session->mark_used_columns != MARK_COLUMNS_NONE)
 
4295
      if (thd->mark_used_columns != MARK_COLUMNS_NONE)
4317
4296
      {
4318
4297
        /*
4319
4298
          Get rw_set correct for this field so that the handler
4328
4307
            field_to_set= ((Item_field*)it)->field;
4329
4308
          else
4330
4309
          {
4331
 
            if (session->mark_used_columns == MARK_COLUMNS_READ)
4332
 
              it->walk(&Item::register_field_in_read_map, 1, (unsigned char *) 0);
 
4310
            if (thd->mark_used_columns == MARK_COLUMNS_READ)
 
4311
              it->walk(&Item::register_field_in_read_map, 1, (uchar *) 0);
4333
4312
          }
4334
4313
        }
4335
4314
        else
4337
4316
        if (field_to_set)
4338
4317
        {
4339
4318
          Table *table= field_to_set->table;
4340
 
          if (session->mark_used_columns == MARK_COLUMNS_READ)
 
4319
          if (thd->mark_used_columns == MARK_COLUMNS_READ)
4341
4320
            bitmap_set_bit(table->read_set, field_to_set->field_index);
4342
4321
          else
4343
4322
            bitmap_set_bit(table->write_set, field_to_set->field_index);
4368
4347
  Field **field_ptr;
4369
4348
  if (table->s->name_hash.records)
4370
4349
  {
4371
 
    field_ptr= (Field**)hash_search(&table->s->name_hash,(unsigned char*) name,
 
4350
    field_ptr= (Field**)hash_search(&table->s->name_hash,(uchar*) name,
4372
4351
                                    strlen(name));
4373
4352
    if (field_ptr)
4374
4353
    {
4399
4378
 
4400
4379
  SYNOPSIS
4401
4380
    find_field_in_tables()
4402
 
    session                       pointer to current thread structure
 
4381
    thd                   pointer to current thread structure
4403
4382
    item                  field item that should be found
4404
4383
    first_table           list of tables to be searched for item
4405
4384
    last_table            end of the list of tables to search for item. If NULL
4429
4408
*/
4430
4409
 
4431
4410
Field *
4432
 
find_field_in_tables(Session *session, Item_ident *item,
 
4411
find_field_in_tables(THD *thd, Item_ident *item,
4433
4412
                     TableList *first_table, TableList *last_table,
4434
4413
                     Item **ref, find_item_error_report_type report_error,
4435
4414
                     bool check_privileges, bool register_tree_change)
4438
4417
  const char *db= item->db_name;
4439
4418
  const char *table_name= item->table_name;
4440
4419
  const char *name= item->field_name;
4441
 
  uint32_t length=(uint) strlen(name);
 
4420
  uint length=(uint) strlen(name);
4442
4421
  char name_buff[NAME_LEN+1];
4443
4422
  TableList *cur_table= first_table;
4444
4423
  TableList *actual_table;
4470
4449
      when table_ref->field_translation != NULL.
4471
4450
      */
4472
4451
    if (table_ref->table)
4473
 
      found= find_field_in_table(session, table_ref->table, name, length,
 
4452
      found= find_field_in_table(thd, table_ref->table, name, length,
4474
4453
                                 true, &(item->cached_field_index));
4475
4454
    else
4476
 
      found= find_field_in_table_ref(session, table_ref, name, length, item->name,
 
4455
      found= find_field_in_table_ref(thd, table_ref, name, length, item->name,
4477
4456
                                     NULL, NULL, ref, check_privileges,
4478
4457
                                     true, &(item->cached_field_index),
4479
4458
                                     register_tree_change,
4488
4467
        fields.
4489
4468
      */
4490
4469
      {
4491
 
        SELECT_LEX *current_sel= session->lex->current_select;
 
4470
        SELECT_LEX *current_sel= thd->lex->current_select;
4492
4471
        SELECT_LEX *last_select= table_ref->select_lex;
4493
4472
        /*
4494
4473
          If the field was an outer referencee, mark all selects using this
4495
4474
          sub query as dependent on the outer query
4496
4475
        */
4497
4476
        if (current_sel != last_select)
4498
 
          mark_select_range_as_dependent(session, last_select, current_sel,
 
4477
          mark_select_range_as_dependent(thd, last_select, current_sel,
4499
4478
                                         found, *ref, item);
4500
4479
      }
4501
4480
      return found;
4520
4499
  for (; cur_table != last_table ;
4521
4500
       cur_table= cur_table->next_name_resolution_table)
4522
4501
  {
4523
 
    Field *cur_field= find_field_in_table_ref(session, cur_table, name, length,
 
4502
    Field *cur_field= find_field_in_table_ref(thd, cur_table, name, length,
4524
4503
                                              item->name, db, table_name, ref,
4525
 
                                              (session->lex->sql_command ==
 
4504
                                              (thd->lex->sql_command ==
4526
4505
                                               SQLCOM_SHOW_FIELDS)
4527
4506
                                              ? false : check_privileges,
4528
4507
                                              allow_rowid,
4533
4512
    {
4534
4513
      if (cur_field == WRONG_GRANT)
4535
4514
      {
4536
 
        if (session->lex->sql_command != SQLCOM_SHOW_FIELDS)
 
4515
        if (thd->lex->sql_command != SQLCOM_SHOW_FIELDS)
4537
4516
          return (Field*) 0;
4538
4517
 
4539
 
        session->clear_error();
4540
 
        cur_field= find_field_in_table_ref(session, cur_table, name, length,
 
4518
        thd->clear_error();
 
4519
        cur_field= find_field_in_table_ref(thd, cur_table, name, length,
4541
4520
                                           item->name, db, table_name, ref,
4542
4521
                                           false,
4543
4522
                                           allow_rowid,
4561
4540
      item->cached_table= (!actual_table->cacheable_table || found) ?
4562
4541
                          0 : actual_table;
4563
4542
 
4564
 
      assert(session->where);
 
4543
      assert(thd->where);
4565
4544
      /*
4566
4545
        If we found a fully qualified field we return it directly as it can't
4567
4546
        have duplicates.
4574
4553
        if (report_error == REPORT_ALL_ERRORS ||
4575
4554
            report_error == IGNORE_EXCEPT_NON_UNIQUE)
4576
4555
          my_error(ER_NON_UNIQ_ERROR, MYF(0),
4577
 
                   table_name ? item->full_name() : name, session->where);
 
4556
                   table_name ? item->full_name() : name, thd->where);
4578
4557
        return (Field*) 0;
4579
4558
      }
4580
4559
      found= cur_field;
4598
4577
    char buff[NAME_LEN*2+1];
4599
4578
    if (db && db[0])
4600
4579
    {
4601
 
      /* We're in an error condition, two extra strlen's aren't going
4602
 
       * to kill us */
4603
 
      assert(strlen(db) <= NAME_LEN);
4604
 
      assert(strlen(table_name) <= NAME_LEN);
4605
 
      strcpy(buff, db);
4606
 
      strcat(buff,".");
4607
 
      strcat(buff, table_name);
 
4580
      strxnmov(buff,sizeof(buff)-1,db,".",table_name,NullS);
4608
4581
      table_name=buff;
4609
4582
    }
4610
 
    my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, session->where);
 
4583
    my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, thd->where);
4611
4584
  }
4612
4585
  else
4613
4586
  {
4614
4587
    if (report_error == REPORT_ALL_ERRORS ||
4615
4588
        report_error == REPORT_EXCEPT_NON_UNIQUE)
4616
 
      my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), session->where);
 
4589
      my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), thd->where);
4617
4590
    else
4618
4591
      found= not_found_field;
4619
4592
  }
4659
4632
 
4660
4633
 
4661
4634
Item **
4662
 
find_item_in_list(Item *find, List<Item> &items, uint32_t *counter,
 
4635
find_item_in_list(Item *find, List<Item> &items, uint *counter,
4663
4636
                  find_item_error_report_type report_error,
4664
4637
                  enum_resolution_type *resolution)
4665
4638
{
4674
4647
    (and not an item that happens to have a name).
4675
4648
  */
4676
4649
  bool is_ref_by_name= 0;
4677
 
  uint32_t unaliased_counter= 0;
 
4650
  uint unaliased_counter= 0;
4678
4651
 
4679
4652
  *resolution= NOT_RESOLVED;
4680
4653
 
4687
4660
    db_name=    ((Item_ident*) find)->db_name;
4688
4661
  }
4689
4662
 
4690
 
  for (uint32_t i= 0; (item=li++); i++)
 
4663
  for (uint i= 0; (item=li++); i++)
4691
4664
  {
4692
4665
    if (field_name && item->real_item()->type() == Item::FIELD_ITEM)
4693
4666
    {
4739
4712
            */
4740
4713
            if (report_error != IGNORE_ERRORS)
4741
4714
              my_error(ER_NON_UNIQ_ERROR, MYF(0),
4742
 
                       find->full_name(), current_session->where);
 
4715
                       find->full_name(), current_thd->where);
4743
4716
            return (Item**) 0;
4744
4717
          }
4745
4718
          found_unaliased= li.ref();
4770
4743
              continue;                           // Same field twice
4771
4744
            if (report_error != IGNORE_ERRORS)
4772
4745
              my_error(ER_NON_UNIQ_ERROR, MYF(0),
4773
 
                       find->full_name(), current_session->where);
 
4746
                       find->full_name(), current_thd->where);
4774
4747
            return (Item**) 0;
4775
4748
          }
4776
4749
          found= li.ref();
4851
4824
    {
4852
4825
      if (report_error != IGNORE_ERRORS)
4853
4826
        my_error(ER_NON_UNIQ_ERROR, MYF(0),
4854
 
                 find->full_name(), current_session->where);
 
4827
                 find->full_name(), current_thd->where);
4855
4828
      return (Item **) 0;
4856
4829
    }
4857
4830
    if (found_unaliased)
4867
4840
  {
4868
4841
    if (report_error == REPORT_ALL_ERRORS)
4869
4842
      my_error(ER_BAD_FIELD_ERROR, MYF(0),
4870
 
               find->full_name(), current_session->where);
 
4843
               find->full_name(), current_thd->where);
4871
4844
    return (Item **) 0;
4872
4845
  }
4873
4846
  else
4915
4888
 
4916
4889
  SYNOPSIS
4917
4890
    set_new_item_local_context()
4918
 
    session        pointer to current thread
 
4891
    thd        pointer to current thread
4919
4892
    item       item for which new context is created and set
4920
4893
    table_ref  table ref where an item showld be resolved
4921
4894
 
4929
4902
*/
4930
4903
 
4931
4904
static bool
4932
 
set_new_item_local_context(Session *session, Item_ident *item, TableList *table_ref)
 
4905
set_new_item_local_context(THD *thd, Item_ident *item, TableList *table_ref)
4933
4906
{
4934
4907
  Name_resolution_context *context;
4935
 
  if (!(context= new (session->mem_root) Name_resolution_context))
 
4908
  if (!(context= new (thd->mem_root) Name_resolution_context))
4936
4909
    return true;
4937
4910
  context->init();
4938
4911
  context->first_name_resolution_table=
4947
4920
 
4948
4921
  SYNOPSIS
4949
4922
    mark_common_columns()
4950
 
    session                [in] current thread
 
4923
    thd                [in] current thread
4951
4924
    table_ref_1        [in] the first (left) join operand
4952
4925
    table_ref_2        [in] the second (right) join operand
4953
4926
    using_fields       [in] if the join is JOIN...USING - the join columns,
4974
4947
*/
4975
4948
 
4976
4949
static bool
4977
 
mark_common_columns(Session *session, TableList *table_ref_1, TableList *table_ref_2,
4978
 
                    List<String> *using_fields, uint32_t *found_using_fields)
 
4950
mark_common_columns(THD *thd, TableList *table_ref_1, TableList *table_ref_2,
 
4951
                    List<String> *using_fields, uint *found_using_fields)
4979
4952
{
4980
4953
  Field_iterator_table_ref it_1, it_2;
4981
4954
  Natural_join_column *nj_col_1, *nj_col_2;
5038
5011
        if (cur_nj_col_2->is_common ||
5039
5012
            (found && (!using_fields || is_using_column_1)))
5040
5013
        {
5041
 
          my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1, session->where);
 
5014
          my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1, thd->where);
5042
5015
          goto err;
5043
5016
        }
5044
5017
        nj_col_2= cur_nj_col_2;
5064
5037
    */
5065
5038
    if (nj_col_2 && (!using_fields ||is_using_column_1))
5066
5039
    {
5067
 
      Item *item_1=   nj_col_1->create_item(session);
5068
 
      Item *item_2=   nj_col_2->create_item(session);
 
5040
      Item *item_1=   nj_col_1->create_item(thd);
 
5041
      Item *item_2=   nj_col_2->create_item(thd);
5069
5042
      Field *field_1= nj_col_1->field();
5070
5043
      Field *field_2= nj_col_2->field();
5071
5044
      Item_ident *item_ident_1, *item_ident_2;
5095
5068
        resolution of these items, and to enable proper name resolution of
5096
5069
        the items during the execute phase of PS.
5097
5070
      */
5098
 
      if (set_new_item_local_context(session, item_ident_1, nj_col_1->table_ref) ||
5099
 
          set_new_item_local_context(session, item_ident_2, nj_col_2->table_ref))
 
5071
      if (set_new_item_local_context(thd, item_ident_1, nj_col_1->table_ref) ||
 
5072
          set_new_item_local_context(thd, item_ident_2, nj_col_2->table_ref))
5100
5073
        goto err;
5101
5074
 
5102
5075
      if (!(eq_cond= new Item_func_eq(item_ident_1, item_ident_2)))
5157
5130
 
5158
5131
  SYNOPSIS
5159
5132
    store_natural_using_join_columns()
5160
 
    session                current thread
 
5133
    thd                current thread
5161
5134
    natural_using_join the table reference of the NATURAL/USING join
5162
5135
    table_ref_1        the first (left) operand (of a NATURAL/USING join).
5163
5136
    table_ref_2        the second (right) operand (of a NATURAL/USING join).
5188
5161
*/
5189
5162
 
5190
5163
static bool
5191
 
store_natural_using_join_columns(Session *session __attribute__((unused)),
 
5164
store_natural_using_join_columns(THD *thd __attribute__((unused)),
5192
5165
                                 TableList *natural_using_join,
5193
5166
                                 TableList *table_ref_1,
5194
5167
                                 TableList *table_ref_2,
5195
5168
                                 List<String> *using_fields,
5196
 
                                 uint32_t found_using_fields)
 
5169
                                 uint found_using_fields)
5197
5170
{
5198
5171
  Field_iterator_table_ref it_1, it_2;
5199
5172
  Natural_join_column *nj_col_1, *nj_col_2;
5242
5215
        if (!(common_field= it++))
5243
5216
        {
5244
5217
          my_error(ER_BAD_FIELD_ERROR, MYF(0), using_field_name_ptr,
5245
 
                   current_session->where);
 
5218
                   current_thd->where);
5246
5219
          goto err;
5247
5220
        }
5248
5221
        if (!my_strcasecmp(system_charset_info,
5281
5254
 
5282
5255
  SYNOPSIS
5283
5256
    store_top_level_join_columns()
5284
 
    session            current thread
 
5257
    thd            current thread
5285
5258
    table_ref      nested join or table in a FROM clause
5286
5259
    left_neighbor  neighbor table reference to the left of table_ref at the
5287
5260
                   same level in the join tree
5307
5280
*/
5308
5281
 
5309
5282
static bool
5310
 
store_top_level_join_columns(Session *session, TableList *table_ref,
 
5283
store_top_level_join_columns(THD *thd, TableList *table_ref,
5311
5284
                             TableList *left_neighbor,
5312
5285
                             TableList *right_neighbor)
5313
5286
{
5355
5328
                           same_level_right_neighbor : right_neighbor;
5356
5329
 
5357
5330
      if (cur_table_ref->nested_join &&
5358
 
          store_top_level_join_columns(session, cur_table_ref,
 
5331
          store_top_level_join_columns(thd, cur_table_ref,
5359
5332
                                       real_left_neighbor, real_right_neighbor))
5360
5333
        goto err;
5361
5334
      same_level_right_neighbor= cur_table_ref;
5379
5352
    TableList *table_ref_2= operand_it++; /* Second NATURAL join operand.*/
5380
5353
    TableList *table_ref_1= operand_it++; /* First NATURAL join operand. */
5381
5354
    List<String> *using_fields= table_ref->join_using_fields;
5382
 
    uint32_t found_using_fields;
 
5355
    uint found_using_fields;
5383
5356
 
5384
5357
    /*
5385
5358
      The two join operands were interchanged in the parser, change the order
5387
5360
    */
5388
5361
    if (table_ref_2->outer_join & JOIN_TYPE_RIGHT)
5389
5362
      std::swap(table_ref_1, table_ref_2);
5390
 
    if (mark_common_columns(session, table_ref_1, table_ref_2,
 
5363
    if (mark_common_columns(thd, table_ref_1, table_ref_2,
5391
5364
                            using_fields, &found_using_fields))
5392
5365
      goto err;
5393
5366
 
5398
5371
    */
5399
5372
    if (table_ref_1->outer_join & JOIN_TYPE_RIGHT)
5400
5373
      std::swap(table_ref_1, table_ref_2);
5401
 
    if (store_natural_using_join_columns(session, table_ref, table_ref_1,
 
5374
    if (store_natural_using_join_columns(thd, table_ref, table_ref_1,
5402
5375
                                         table_ref_2, using_fields,
5403
5376
                                         found_using_fields))
5404
5377
      goto err;
5445
5418
 
5446
5419
  SYNOPSIS
5447
5420
    setup_natural_join_row_types()
5448
 
    session          current thread
 
5421
    thd          current thread
5449
5422
    from_clause  list of top-level table references in a FROM clause
5450
5423
 
5451
5424
  DESCRIPTION
5463
5436
    true   Error
5464
5437
    false  OK
5465
5438
*/
5466
 
static bool setup_natural_join_row_types(Session *session,
 
5439
static bool setup_natural_join_row_types(THD *thd,
5467
5440
                                         List<TableList> *from_clause,
5468
5441
                                         Name_resolution_context *context)
5469
5442
{
5470
 
  session->where= "from clause";
 
5443
  thd->where= "from clause";
5471
5444
  if (from_clause->elements == 0)
5472
5445
    return false; /* We come here in the case of UNIONs. */
5473
5446
 
5483
5456
  {
5484
5457
    table_ref= left_neighbor;
5485
5458
    left_neighbor= table_ref_it++;
5486
 
    if (store_top_level_join_columns(session, table_ref,
5487
 
                                     left_neighbor, right_neighbor))
5488
 
      return true;
5489
 
    if (left_neighbor)
 
5459
    /* For stored procedures do not redo work if already done. */
 
5460
    if (context->select_lex->first_execution)
5490
5461
    {
5491
 
      TableList *first_leaf_on_the_right;
5492
 
      first_leaf_on_the_right= table_ref->first_leaf_for_name_resolution();
5493
 
      left_neighbor->next_name_resolution_table= first_leaf_on_the_right;
 
5462
      if (store_top_level_join_columns(thd, table_ref,
 
5463
                                       left_neighbor, right_neighbor))
 
5464
        return true;
 
5465
      if (left_neighbor)
 
5466
      {
 
5467
        TableList *first_leaf_on_the_right;
 
5468
        first_leaf_on_the_right= table_ref->first_leaf_for_name_resolution();
 
5469
        left_neighbor->next_name_resolution_table= first_leaf_on_the_right;
 
5470
      }
5494
5471
    }
5495
5472
    right_neighbor= table_ref;
5496
5473
  }
5513
5490
** Expand all '*' in given fields
5514
5491
****************************************************************************/
5515
5492
 
5516
 
int setup_wild(Session *session,
 
5493
int setup_wild(THD *thd,
5517
5494
               TableList *tables __attribute__((unused)),
5518
5495
               List<Item> &fields,
5519
5496
               List<Item> *sum_func_list,
5520
 
               uint32_t wild_num)
 
5497
               uint wild_num)
5521
5498
{
5522
5499
  if (!wild_num)
5523
5500
    return(0);
5525
5502
  Item *item;
5526
5503
  List_iterator<Item> it(fields);
5527
5504
 
5528
 
  session->lex->current_select->cur_pos_in_select_list= 0;
 
5505
  thd->lex->current_select->cur_pos_in_select_list= 0;
5529
5506
  while (wild_num && (item= it++))
5530
5507
  {
5531
5508
    if (item->type() == Item::FIELD_ITEM &&
5533
5510
        ((Item_field*) item)->field_name[0] == '*' &&
5534
5511
        !((Item_field*) item)->field)
5535
5512
    {
5536
 
      uint32_t elem= fields.elements;
 
5513
      uint elem= fields.elements;
5537
5514
      bool any_privileges= ((Item_field *) item)->any_privileges;
5538
 
      Item_subselect *subsel= session->lex->current_select->master_unit()->item;
 
5515
      Item_subselect *subsel= thd->lex->current_select->master_unit()->item;
5539
5516
      if (subsel &&
5540
5517
          subsel->substype() == Item_subselect::EXISTS_SUBS)
5541
5518
      {
5547
5524
        it.replace(new Item_int("Not_used", (int64_t) 1,
5548
5525
                                MY_INT64_NUM_DECIMAL_DIGITS));
5549
5526
      }
5550
 
      else if (insert_fields(session, ((Item_field*) item)->context,
 
5527
      else if (insert_fields(thd, ((Item_field*) item)->context,
5551
5528
                             ((Item_field*) item)->db_name,
5552
5529
                             ((Item_field*) item)->table_name, &it,
5553
5530
                             any_privileges))
5566
5543
      wild_num--;
5567
5544
    }
5568
5545
    else
5569
 
      session->lex->current_select->cur_pos_in_select_list++;
 
5546
      thd->lex->current_select->cur_pos_in_select_list++;
5570
5547
  }
5571
 
  session->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
 
5548
  thd->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
5572
5549
  return(0);
5573
5550
}
5574
5551
 
5576
5553
** Check that all given fields exists and fill struct with current data
5577
5554
****************************************************************************/
5578
5555
 
5579
 
bool setup_fields(Session *session, Item **ref_pointer_array,
 
5556
bool setup_fields(THD *thd, Item **ref_pointer_array,
5580
5557
                  List<Item> &fields, enum_mark_columns mark_used_columns,
5581
5558
                  List<Item> *sum_func_list, bool allow_sum_func)
5582
5559
{
5583
5560
  register Item *item;
5584
 
  enum_mark_columns save_mark_used_columns= session->mark_used_columns;
5585
 
  nesting_map save_allow_sum_func= session->lex->allow_sum_func;
 
5561
  enum_mark_columns save_mark_used_columns= thd->mark_used_columns;
 
5562
  nesting_map save_allow_sum_func= thd->lex->allow_sum_func;
5586
5563
  List_iterator<Item> it(fields);
5587
5564
  bool save_is_item_list_lookup;
5588
5565
 
5589
 
  session->mark_used_columns= mark_used_columns;
 
5566
  thd->mark_used_columns= mark_used_columns;
5590
5567
  if (allow_sum_func)
5591
 
    session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
5592
 
  session->where= Session::DEFAULT_WHERE;
5593
 
  save_is_item_list_lookup= session->lex->current_select->is_item_list_lookup;
5594
 
  session->lex->current_select->is_item_list_lookup= 0;
 
5568
    thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
 
5569
  thd->where= THD::DEFAULT_WHERE;
 
5570
  save_is_item_list_lookup= thd->lex->current_select->is_item_list_lookup;
 
5571
  thd->lex->current_select->is_item_list_lookup= 0;
5595
5572
 
5596
5573
  /*
5597
5574
    To prevent fail on forward lookup we fill it with zerows,
5608
5585
    memset(ref_pointer_array, 0, sizeof(Item *) * fields.elements);
5609
5586
 
5610
5587
  Item **ref= ref_pointer_array;
5611
 
  session->lex->current_select->cur_pos_in_select_list= 0;
 
5588
  thd->lex->current_select->cur_pos_in_select_list= 0;
5612
5589
  while ((item= it++))
5613
5590
  {
5614
 
    if ((!item->fixed && item->fix_fields(session, it.ref())) || (item= *(it.ref()))->check_cols(1))
 
5591
    if ((!item->fixed && item->fix_fields(thd, it.ref())) || (item= *(it.ref()))->check_cols(1))
5615
5592
    {
5616
 
      session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
5617
 
      session->lex->allow_sum_func= save_allow_sum_func;
5618
 
      session->mark_used_columns= save_mark_used_columns;
 
5593
      thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
 
5594
      thd->lex->allow_sum_func= save_allow_sum_func;
 
5595
      thd->mark_used_columns= save_mark_used_columns;
5619
5596
      return(true); /* purecov: inspected */
5620
5597
    }
5621
5598
    if (ref)
5622
5599
      *(ref++)= item;
5623
5600
    if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM &&
5624
5601
        sum_func_list)
5625
 
      item->split_sum_func(session, ref_pointer_array, *sum_func_list);
5626
 
    session->used_tables|= item->used_tables();
5627
 
    session->lex->current_select->cur_pos_in_select_list++;
 
5602
      item->split_sum_func(thd, ref_pointer_array, *sum_func_list);
 
5603
    thd->used_tables|= item->used_tables();
 
5604
    thd->lex->current_select->cur_pos_in_select_list++;
5628
5605
  }
5629
 
  session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
5630
 
  session->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
 
5606
  thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
 
5607
  thd->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
5631
5608
 
5632
 
  session->lex->allow_sum_func= save_allow_sum_func;
5633
 
  session->mark_used_columns= save_mark_used_columns;
5634
 
  return(test(session->is_error()));
 
5609
  thd->lex->allow_sum_func= save_allow_sum_func;
 
5610
  thd->mark_used_columns= save_mark_used_columns;
 
5611
  return(test(thd->is_error()));
5635
5612
}
5636
5613
 
5637
5614
 
5663
5640
 
5664
5641
  SYNOPSIS
5665
5642
    setup_tables()
5666
 
    session               Thread handler
 
5643
    thd           Thread handler
5667
5644
    context       name resolution contest to setup table list there
5668
5645
    from_clause   Top-level list of table references in the FROM clause
5669
5646
    tables        Table list (select_lex->table_list)
5686
5663
    true  error
5687
5664
*/
5688
5665
 
5689
 
bool setup_tables(Session *session, Name_resolution_context *context,
 
5666
bool setup_tables(THD *thd, Name_resolution_context *context,
5690
5667
                  List<TableList> *from_clause, TableList *tables,
5691
5668
                  TableList **leaves, bool select_insert)
5692
5669
{
5693
 
  uint32_t tablenr= 0;
 
5670
  uint tablenr= 0;
5694
5671
 
5695
5672
  assert ((select_insert && !tables->next_name_resolution_table) || !tables || 
5696
5673
               (context->table_list && context->first_name_resolution_table));
5729
5706
  }
5730
5707
 
5731
5708
  /* Precompute and store the row types of NATURAL/USING joins. */
5732
 
  if (setup_natural_join_row_types(session, from_clause, context))
 
5709
  if (setup_natural_join_row_types(thd, from_clause, context))
5733
5710
    return(1);
5734
5711
 
5735
5712
  return(0);
5741
5718
 
5742
5719
  SYNOPSIS
5743
5720
    setup_tables_and_check_view_access()
5744
 
    session               Thread handler
 
5721
    thd           Thread handler
5745
5722
    context       name resolution contest to setup table list there
5746
5723
    from_clause   Top-level list of table references in the FROM clause
5747
5724
    tables        Table list (select_lex->table_list)
5759
5736
    false ok;  In this case *map will include the chosen index
5760
5737
    true  error
5761
5738
*/
5762
 
bool setup_tables_and_check_access(Session *session, 
 
5739
bool setup_tables_and_check_access(THD *thd, 
5763
5740
                                   Name_resolution_context *context,
5764
5741
                                   List<TableList> *from_clause,
5765
5742
                                   TableList *tables,
5769
5746
  TableList *leaves_tmp= NULL;
5770
5747
  bool first_table= true;
5771
5748
 
5772
 
  if (setup_tables(session, context, from_clause, tables,
 
5749
  if (setup_tables(thd, context, from_clause, tables,
5773
5750
                   &leaves_tmp, select_insert))
5774
5751
    return true;
5775
5752
 
5803
5780
{
5804
5781
  List_iterator_fast<String> it(*index_list);
5805
5782
  String *name;
5806
 
  uint32_t pos;
 
5783
  uint pos;
5807
5784
 
5808
5785
  map->clear_all();
5809
5786
  while ((name=it++))
5829
5806
 
5830
5807
  SYNOPSIS
5831
5808
    insert_fields()
5832
 
    session                     Thread handler
 
5809
    thd                 Thread handler
5833
5810
    context             Context for name resolution
5834
5811
    db_name             Database name in case of 'database_name.table_name.*'
5835
5812
    table_name          Table name in case of 'table_name.*'
5843
5820
*/
5844
5821
 
5845
5822
bool
5846
 
insert_fields(Session *session, Name_resolution_context *context, const char *db_name,
 
5823
insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
5847
5824
              const char *table_name, List_iterator<Item> *it,
5848
5825
              bool any_privileges __attribute__((unused)))
5849
5826
{
5891
5868
      views and natural joins this update is performed inside the loop below.
5892
5869
    */
5893
5870
    if (table)
5894
 
      session->used_tables|= table->map;
 
5871
      thd->used_tables|= table->map;
5895
5872
 
5896
5873
    /*
5897
5874
      Initialize a generic field iterator for the current table reference.
5905
5882
    {
5906
5883
      Item *item;
5907
5884
 
5908
 
      if (!(item= field_iterator.create_item(session)))
 
5885
      if (!(item= field_iterator.create_item(thd)))
5909
5886
        return(true);
5910
5887
 
5911
5888
      if (!found)
5920
5897
      {
5921
5898
        /* Mark fields as used to allow storage engine to optimze access */
5922
5899
        bitmap_set_bit(field->table->read_set, field->field_index);
5923
 
        /*
5924
 
          Mark virtual fields for write and others that the virtual fields
5925
 
          depend on for read.
5926
 
        */
5927
 
        if (field->vcol_info)
5928
 
        {
5929
 
          Item *vcol_item= field->vcol_info->expr_item;
5930
 
          assert(vcol_item);
5931
 
          vcol_item->walk(&Item::register_field_in_read_map, 1, (unsigned char *) 0);
5932
 
          bitmap_set_bit(field->table->write_set, field->field_index);
5933
 
        }
5934
5900
        if (table)
5935
5901
        {
5936
5902
          table->covering_keys.intersect(field->part_of_key);
5950
5916
          field_table= nj_col->table_ref->table;
5951
5917
          if (field_table)
5952
5918
          {
5953
 
            session->used_tables|= field_table->map;
 
5919
            thd->used_tables|= field_table->map;
5954
5920
            field_table->covering_keys.intersect(field->part_of_key);
5955
5921
            field_table->merge_keys.merge(field->part_of_key);
5956
5922
            field_table->used_fields++;
5958
5924
        }
5959
5925
      }
5960
5926
      else
5961
 
        session->used_tables|= item->used_tables();
5962
 
      session->lex->current_select->cur_pos_in_select_list++;
 
5927
        thd->used_tables|= item->used_tables();
 
5928
      thd->lex->current_select->cur_pos_in_select_list++;
5963
5929
    }
5964
5930
    /*
5965
5931
      In case of stored tables, all fields are considered as used,
5992
5958
 
5993
5959
  SYNOPSIS
5994
5960
    setup_conds()
5995
 
    session     thread handler
 
5961
    thd     thread handler
5996
5962
    tables  list of tables for name resolving (select_lex->table_list)
5997
5963
    leaves  list of leaves of join table tree (select_lex->leaf_tables)
5998
5964
    conds   WHERE clause
6005
5971
    false if all is OK
6006
5972
*/
6007
5973
 
6008
 
int setup_conds(Session *session, TableList *tables __attribute__((unused)),
 
5974
int setup_conds(THD *thd, TableList *tables __attribute__((unused)),
6009
5975
                TableList *leaves,
6010
5976
                COND **conds)
6011
5977
{
6012
 
  SELECT_LEX *select_lex= session->lex->current_select;
 
5978
  SELECT_LEX *select_lex= thd->lex->current_select;
6013
5979
  TableList *table= NULL;       // For HP compilers
6014
 
  void *save_session_marker= session->session_marker;
 
5980
  void *save_thd_marker= thd->thd_marker;
6015
5981
  /*
6016
5982
    it_is_update set to true when tables of primary SELECT_LEX (SELECT_LEX
6017
5983
    which belong to LEX, i.e. most up SELECT) will be updated by
6023
5989
  bool save_is_item_list_lookup= select_lex->is_item_list_lookup;
6024
5990
  select_lex->is_item_list_lookup= 0;
6025
5991
 
6026
 
  session->mark_used_columns= MARK_COLUMNS_READ;
 
5992
  thd->mark_used_columns= MARK_COLUMNS_READ;
6027
5993
  select_lex->cond_count= 0;
6028
5994
  select_lex->between_count= 0;
6029
5995
  select_lex->max_equal_elems= 0;
6030
5996
 
6031
 
  session->session_marker= (void*)1;
 
5997
  thd->thd_marker= (void*)1;
6032
5998
  if (*conds)
6033
5999
  {
6034
 
    session->where="where clause";
6035
 
    if ((!(*conds)->fixed && (*conds)->fix_fields(session, conds)) ||
 
6000
    thd->where="where clause";
 
6001
    if ((!(*conds)->fixed && (*conds)->fix_fields(thd, conds)) ||
6036
6002
        (*conds)->check_cols(1))
6037
6003
      goto err_no_arena;
6038
6004
  }
6039
 
  session->session_marker= save_session_marker;
 
6005
  thd->thd_marker= save_thd_marker;
6040
6006
 
6041
6007
  /*
6042
6008
    Apply fix_fields() to all ON clauses at all levels of nesting,
6052
6018
      if (embedded->on_expr)
6053
6019
      {
6054
6020
        /* Make a join an a expression */
6055
 
        session->session_marker= (void*)embedded;
6056
 
        session->where="on clause";
6057
 
        if ((!embedded->on_expr->fixed && embedded->on_expr->fix_fields(session, &embedded->on_expr)) ||
 
6021
        thd->thd_marker= (void*)embedded;
 
6022
        thd->where="on clause";
 
6023
        if ((!embedded->on_expr->fixed && embedded->on_expr->fix_fields(thd, &embedded->on_expr)) ||
6058
6024
            embedded->on_expr->check_cols(1))
6059
6025
          goto err_no_arena;
6060
6026
        select_lex->cond_count++;
6065
6031
           embedding->nested_join->join_list.head() == embedded);
6066
6032
 
6067
6033
  }
6068
 
  session->session_marker= save_session_marker;
 
6034
  thd->thd_marker= save_thd_marker;
6069
6035
 
6070
 
  session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
6071
 
  return(test(session->is_error()));
 
6036
  thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
 
6037
  return(test(thd->is_error()));
6072
6038
 
6073
6039
err_no_arena:
6074
6040
  select_lex->is_item_list_lookup= save_is_item_list_lookup;
6087
6053
 
6088
6054
  SYNOPSIS
6089
6055
    fill_record()
6090
 
    session           thread handler
 
6056
    thd           thread handler
6091
6057
    fields        Item_fields list to be filled
6092
6058
    values        values to fill with
6093
6059
    ignore_errors true if we should ignore errors
6103
6069
*/
6104
6070
 
6105
6071
bool
6106
 
fill_record(Session * session, List<Item> &fields, List<Item> &values, bool ignore_errors)
 
6072
fill_record(THD * thd, List<Item> &fields, List<Item> &values, bool ignore_errors)
6107
6073
{
6108
6074
  List_iterator_fast<Item> f(fields),v(values);
6109
6075
  Item *value, *fld;
6110
6076
  Item_field *field;
6111
6077
  Table *table= 0;
6112
 
  List<Table> tbl_list;
6113
 
  bool abort_on_warning_saved= session->abort_on_warning;
6114
 
  tbl_list.empty();
6115
6078
 
6116
6079
  /*
6117
6080
    Reset the table->auto_increment_field_not_null as it is valid for
6145
6108
    table= rfield->table;
6146
6109
    if (rfield == table->next_number_field)
6147
6110
      table->auto_increment_field_not_null= true;
6148
 
    if (rfield->vcol_info && 
6149
 
        value->type() != Item::DEFAULT_VALUE_ITEM && 
6150
 
        value->type() != Item::NULL_ITEM &&
6151
 
        table->s->table_category != TABLE_CATEGORY_TEMPORARY)
6152
 
    {
6153
 
      session->abort_on_warning= false;
6154
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
6155
 
                          ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN,
6156
 
                          ER(ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN),
6157
 
                          rfield->field_name, table->s->table_name.str);
6158
 
      session->abort_on_warning= abort_on_warning_saved;
6159
 
    }
6160
6111
    if ((value->save_in_field(rfield, 0) < 0) && !ignore_errors)
6161
6112
    {
6162
6113
      my_message(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), MYF(0));
6163
6114
      goto err;
6164
6115
    }
6165
 
    tbl_list.push_back(table);
6166
 
  }
6167
 
  /* Update virtual fields*/
6168
 
  session->abort_on_warning= false;
6169
 
  if (tbl_list.head())
6170
 
  {
6171
 
    List_iterator_fast<Table> t(tbl_list);
6172
 
    Table *prev_table= 0;
6173
 
    while ((table= t++))
6174
 
    {
6175
 
      /*
6176
 
        Do simple optimization to prevent unnecessary re-generating 
6177
 
        values for virtual fields
6178
 
      */
6179
 
      if (table != prev_table)
6180
 
      {
6181
 
        prev_table= table;
6182
 
        if (table->vfield)
6183
 
        {
6184
 
          if (update_virtual_fields_marked_for_write(table, false))
6185
 
            goto err;
6186
 
        }
6187
 
      }
6188
 
    }
6189
 
  }
6190
 
  session->abort_on_warning= abort_on_warning_saved;
6191
 
  return(session->is_error());
 
6116
  }
 
6117
  return(thd->is_error());
6192
6118
err:
6193
 
  session->abort_on_warning= abort_on_warning_saved;
6194
6119
  if (table)
6195
6120
    table->auto_increment_field_not_null= false;
6196
6121
  return(true);
6202
6127
 
6203
6128
  SYNOPSIS
6204
6129
    fill_record()
6205
 
    session           thread handler
 
6130
    thd           thread handler
6206
6131
    ptr           pointer on pointer to record
6207
6132
    values        list of fields
6208
6133
    ignore_errors true if we should ignore errors
6218
6143
*/
6219
6144
 
6220
6145
bool
6221
 
fill_record(Session *session, Field **ptr, List<Item> &values,
 
6146
fill_record(THD *thd, Field **ptr, List<Item> &values,
6222
6147
            bool ignore_errors __attribute__((unused)))
6223
6148
{
6224
6149
  List_iterator_fast<Item> v(values);
6225
6150
  Item *value;
6226
6151
  Table *table= 0;
 
6152
 
6227
6153
  Field *field;
6228
 
  List<Table> tbl_list;
6229
 
  bool abort_on_warning_saved= session->abort_on_warning;
6230
 
  
6231
 
  tbl_list.empty();
6232
6154
  /*
6233
6155
    Reset the table->auto_increment_field_not_null as it is valid for
6234
6156
    only one row.
6242
6164
    table= (*ptr)->table;
6243
6165
    table->auto_increment_field_not_null= false;
6244
6166
  }
6245
 
  while ((field = *ptr++) && ! session->is_error())
 
6167
  while ((field = *ptr++) && ! thd->is_error())
6246
6168
  {
6247
6169
    value=v++;
6248
6170
    table= field->table;
6249
6171
    if (field == table->next_number_field)
6250
6172
      table->auto_increment_field_not_null= true;
6251
 
    if (field->vcol_info && 
6252
 
        value->type() != Item::DEFAULT_VALUE_ITEM && 
6253
 
        value->type() != Item::NULL_ITEM &&
6254
 
        table->s->table_category != TABLE_CATEGORY_TEMPORARY)
6255
 
    {
6256
 
      session->abort_on_warning= false;
6257
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
6258
 
                          ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN,
6259
 
                          ER(ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN),
6260
 
                          field->field_name, table->s->table_name.str);
6261
 
      session->abort_on_warning= abort_on_warning_saved;
6262
 
    }
6263
6173
    if (value->save_in_field(field, 0) < 0)
6264
6174
      goto err;
6265
 
    tbl_list.push_back(table);
6266
 
  }
6267
 
  /* Update virtual fields*/
6268
 
  session->abort_on_warning= false;
6269
 
  if (tbl_list.head())
6270
 
  {
6271
 
    List_iterator_fast<Table> t(tbl_list);
6272
 
    Table *prev_table= 0;
6273
 
    while ((table= t++))
6274
 
    {
6275
 
      /*
6276
 
        Do simple optimization to prevent unnecessary re-generating 
6277
 
        values for virtual fields
6278
 
      */
6279
 
      if (table != prev_table)
6280
 
      {
6281
 
        prev_table= table;
6282
 
        if (table->vfield)
6283
 
        {
6284
 
          if (update_virtual_fields_marked_for_write(table, false))
6285
 
          {
6286
 
            goto err;
6287
 
          }
6288
 
        }
6289
 
      }
6290
 
    }
6291
 
  }
6292
 
  session->abort_on_warning= abort_on_warning_saved;
6293
 
  return(session->is_error());
 
6175
  }
 
6176
  return(thd->is_error());
6294
6177
 
6295
6178
err:
6296
 
  session->abort_on_warning= abort_on_warning_saved;
6297
6179
  if (table)
6298
6180
    table->auto_increment_field_not_null= false;
6299
6181
  return(true);
6302
6184
 
6303
6185
bool mysql_rm_tmp_tables(void)
6304
6186
{
6305
 
  uint32_t i, idx;
 
6187
  uint i, idx;
6306
6188
  char  filePath[FN_REFLEN], *tmpdir, filePathCopy[FN_REFLEN];
6307
6189
  MY_DIR *dirp;
6308
6190
  FILEINFO *file;
6309
6191
  TABLE_SHARE share;
6310
 
  Session *session;
 
6192
  THD *thd;
6311
6193
 
6312
 
  if (!(session= new Session))
 
6194
  if (!(thd= new THD))
6313
6195
    return(1);
6314
 
  session->thread_stack= (char*) &session;
6315
 
  session->store_globals();
 
6196
  thd->thread_stack= (char*) &thd;
 
6197
  thd->store_globals();
6316
6198
 
6317
6199
  for (i=0; i<=mysql_tmpdir_list.max; i++)
6318
6200
  {
6335
6217
      if (!memcmp(file->name, tmp_file_prefix, tmp_file_prefix_length))
6336
6218
      {
6337
6219
        char *ext= fn_ext(file->name);
6338
 
        uint32_t ext_len= strlen(ext);
6339
 
        uint32_t filePath_len= snprintf(filePath, sizeof(filePath),
 
6220
        uint ext_len= strlen(ext);
 
6221
        uint filePath_len= snprintf(filePath, sizeof(filePath),
6340
6222
                                    "%s%c%s", tmpdir, FN_LIBCHAR,
6341
6223
                                    file->name);
6342
6224
        if (!memcmp(reg_ext, ext, ext_len))
6345
6227
          /* We should cut file extention before deleting of table */
6346
6228
          memcpy(filePathCopy, filePath, filePath_len - ext_len);
6347
6229
          filePathCopy[filePath_len - ext_len]= 0;
6348
 
          init_tmp_table_share(session, &share, "", 0, "", filePathCopy);
6349
 
          if (!open_table_def(session, &share, 0) &&
6350
 
              ((handler_file= get_new_handler(&share, session->mem_root,
 
6230
          init_tmp_table_share(thd, &share, "", 0, "", filePathCopy);
 
6231
          if (!open_table_def(thd, &share, 0) &&
 
6232
              ((handler_file= get_new_handler(&share, thd->mem_root,
6351
6233
                                              share.db_type()))))
6352
6234
          {
6353
6235
            handler_file->ha_delete_table(filePathCopy);
6360
6242
          So we hide error messages which happnes during deleting of these
6361
6243
          files(MYF(0)).
6362
6244
        */
6363
 
        my_delete(filePath, MYF(0)); 
 
6245
        VOID(my_delete(filePath, MYF(0))); 
6364
6246
      }
6365
6247
    }
6366
6248
    my_dirend(dirp);
6367
6249
  }
6368
 
  delete session;
6369
 
  pthread_setspecific(THR_Session,  0);
 
6250
  delete thd;
 
6251
  my_pthread_setspecific_ptr(THR_THD,  0);
6370
6252
  return(0);
6371
6253
}
6372
6254
 
6391
6273
 
6392
6274
void remove_db_from_cache(const char *db)
6393
6275
{
6394
 
  for (uint32_t idx=0 ; idx < open_cache.records ; idx++)
 
6276
  for (uint idx=0 ; idx < open_cache.records ; idx++)
6395
6277
  {
6396
6278
    Table *table=(Table*) hash_element(&open_cache,idx);
6397
6279
    if (!strcmp(table->s->db.str, db))
6402
6284
    }
6403
6285
  }
6404
6286
  while (unused_tables && !unused_tables->s->version)
6405
 
    hash_delete(&open_cache,(unsigned char*) unused_tables);
 
6287
    VOID(hash_delete(&open_cache,(uchar*) unused_tables));
6406
6288
}
6407
6289
 
6408
6290
 
6418
6300
{
6419
6301
  (void) pthread_mutex_lock(&LOCK_open);
6420
6302
  while (unused_tables)
6421
 
    hash_delete(&open_cache,(unsigned char*) unused_tables);
 
6303
    hash_delete(&open_cache,(uchar*) unused_tables);
6422
6304
  (void) pthread_mutex_unlock(&LOCK_open);
6423
6305
}
6424
6306
 
6438
6320
    1  Table is in use by another thread
6439
6321
*/
6440
6322
 
6441
 
bool remove_table_from_cache(Session *session, const char *db, const char *table_name,
6442
 
                             uint32_t flags)
 
6323
bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
 
6324
                             uint flags)
6443
6325
{
6444
6326
  char key[MAX_DBKEY_LENGTH];
6445
 
  uint32_t key_length;
 
6327
  uint key_length;
6446
6328
  Table *table;
6447
6329
  TABLE_SHARE *share;
6448
6330
  bool result= 0, signalled= 0;
6449
6331
 
6450
 
  key_length=(uint) (my_stpcpy(my_stpcpy(key,db)+1,table_name)-key)+1;
 
6332
  key_length=(uint) (stpcpy(stpcpy(key,db)+1,table_name)-key)+1;
6451
6333
  for (;;)
6452
6334
  {
6453
6335
    HASH_SEARCH_STATE state;
6454
6336
    result= signalled= 0;
6455
6337
 
6456
 
    for (table= (Table*) hash_first(&open_cache, (unsigned char*) key, key_length,
 
6338
    for (table= (Table*) hash_first(&open_cache, (uchar*) key, key_length,
6457
6339
                                    &state);
6458
6340
         table;
6459
 
         table= (Table*) hash_next(&open_cache, (unsigned char*) key, key_length,
 
6341
         table= (Table*) hash_next(&open_cache, (uchar*) key, key_length,
6460
6342
                                   &state))
6461
6343
    {
6462
 
      Session *in_use;
 
6344
      THD *in_use;
6463
6345
 
6464
6346
      table->s->version=0L;             /* Free when thread is ready */
6465
6347
      if (!(in_use=table->in_use))
6466
6348
      {
6467
6349
        relink_unused(table);
6468
6350
      }
6469
 
      else if (in_use != session)
 
6351
      else if (in_use != thd)
6470
6352
      {
6471
6353
        /*
6472
6354
          Mark that table is going to be deleted from cache. This will
6487
6369
          open_tables list. Aborting the MERGE lock after a child was
6488
6370
          closed and before the parent is closed would be fatal.
6489
6371
        */
6490
 
        for (Table *session_table= in_use->open_tables;
6491
 
             session_table ;
6492
 
             session_table= session_table->next)
 
6372
        for (Table *thd_table= in_use->open_tables;
 
6373
             thd_table ;
 
6374
             thd_table= thd_table->next)
6493
6375
        {
6494
6376
          /* Do not handle locks of MERGE children. */
6495
 
          if (session_table->db_stat)   // If table is open
6496
 
            signalled|= mysql_lock_abort_for_thread(session, session_table);
 
6377
          if (thd_table->db_stat)       // If table is open
 
6378
            signalled|= mysql_lock_abort_for_thread(thd, thd_table);
6497
6379
        }
6498
6380
      }
6499
6381
      else
6500
 
        result= result || (flags & RTFC_OWNED_BY_Session_FLAG);
 
6382
        result= result || (flags & RTFC_OWNED_BY_THD_FLAG);
6501
6383
    }
6502
6384
    while (unused_tables && !unused_tables->s->version)
6503
 
      hash_delete(&open_cache,(unsigned char*) unused_tables);
 
6385
      VOID(hash_delete(&open_cache,(uchar*) unused_tables));
6504
6386
 
6505
6387
    /* Remove table from table definition cache if it's not in use */
6506
 
    if ((share= (TABLE_SHARE*) hash_search(&table_def_cache,(unsigned char*) key,
 
6388
    if ((share= (TABLE_SHARE*) hash_search(&table_def_cache,(uchar*) key,
6507
6389
                                           key_length)))
6508
6390
    {
6509
6391
      share->version= 0;                          // Mark for delete
6510
6392
      if (share->ref_count == 0)
6511
6393
      {
6512
6394
        pthread_mutex_lock(&share->mutex);
6513
 
        hash_delete(&table_def_cache, (unsigned char*) share);
 
6395
        VOID(hash_delete(&table_def_cache, (uchar*) share));
6514
6396
      }
6515
6397
    }
6516
6398
 
6521
6403
        reopen their tables
6522
6404
      */
6523
6405
      broadcast_refresh();
6524
 
      if (!(flags & RTFC_CHECK_KILLED_FLAG) || !session->killed)
 
6406
      if (!(flags & RTFC_CHECK_KILLED_FLAG) || !thd->killed)
6525
6407
      {
6526
6408
        dropping_tables++;
6527
6409
        if (likely(signalled))