~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_base.cc

  • Committer: Monty Taylor
  • Date: 2009-03-25 21:06:47 UTC
  • mto: This revision was merged to the branch mainline in revision 964.
  • Revision ID: mordred@inaugust.com-20090325210647-7j1tm98gvct3jxsu
Removed legacy_db_type.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
/* Basic functions needed by many modules */
18
18
#include <drizzled/server_includes.h>
 
19
#include <drizzled/virtual_column_info.h>
 
20
#include <drizzled/field/timestamp.h>
 
21
#include <drizzled/field/null.h>
 
22
 
 
23
#include <signal.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
#include <mysys/my_pthread.h>
 
36
 
19
37
#include <drizzled/sql_select.h>
20
38
#include <mysys/my_dir.h>
21
 
#include <drizzled/drizzled_error_messages.h>
22
 
#include <libdrizzle/gettext.h>
 
39
#include <drizzled/error.h>
 
40
#include <drizzled/gettext.h>
 
41
#include <drizzled/nested_join.h>
 
42
#include <drizzled/sql_base.h>
 
43
#include <drizzled/show.h>
 
44
#include <drizzled/item/cmpfunc.h>
 
45
#include <drizzled/replicator.h>
 
46
#include <drizzled/check_stack_overrun.h>
 
47
#include <drizzled/lock.h>
23
48
 
24
 
#define FLAGSTR(S,F) ((S) & (F) ? #F " " : "")
25
49
 
26
50
/**
27
51
  @defgroup Data_Dictionary Data Dictionary
34
58
static pthread_mutex_t LOCK_table_share;
35
59
static bool table_def_inited= 0;
36
60
 
37
 
static int open_unireg_entry(THD *thd, Table *entry, TableList *table_list,
 
61
static int open_unireg_entry(Session *session, Table *entry, TableList *table_list,
38
62
                             const char *alias,
39
63
                             char *cache_key, uint32_t cache_key_length);
40
 
static void free_cache_entry(Table *entry);
41
 
static void close_old_data_files(THD *thd, Table *table, bool morph_locks,
 
64
extern "C" void free_cache_entry(void *entry);
 
65
static void close_old_data_files(Session *session, Table *table, bool morph_locks,
42
66
                                 bool send_refresh);
43
67
 
44
68
 
45
69
extern "C" unsigned char *table_cache_key(const unsigned char *record, size_t *length,
46
 
                                  bool not_used __attribute__((unused)))
 
70
                                  bool )
47
71
{
48
72
  Table *entry=(Table*) record;
49
73
  *length= entry->s->table_cache_key.length;
53
77
 
54
78
bool table_cache_init(void)
55
79
{
56
 
  return hash_init(&open_cache, &my_charset_bin, table_cache_size+16,
 
80
  return hash_init(&open_cache, &my_charset_bin,
 
81
                   (size_t) table_cache_size+16,
57
82
                   0, 0, table_cache_key,
58
 
                   (hash_free_key) free_cache_entry, 0);
 
83
                   free_cache_entry, 0);
59
84
}
60
85
 
61
86
void table_cache_free(void)
79
104
 
80
105
  SYNOPSIS
81
106
    create_table_def_key()
82
 
    thd                 Thread handler
 
107
    session                     Thread handler
83
108
    key                 Create key here (must be of size MAX_DBKEY_LENGTH)
84
109
    table_list          Table definition
85
110
    tmp_table           Set if table is a tmp table
99
124
    Length of key
100
125
*/
101
126
 
102
 
uint32_t create_table_def_key(THD *thd, char *key, TableList *table_list,
 
127
uint32_t create_table_def_key(Session *session, char *key, TableList *table_list,
103
128
                          bool tmp_table)
104
129
{
105
 
  uint32_t key_length= (uint) (my_stpcpy(my_stpcpy(key, table_list->db)+1,
106
 
                                  table_list->table_name)-key)+1;
 
130
  uint32_t key_length;
 
131
  char *key_pos= key;
 
132
  key_pos= strcpy(key_pos, table_list->db) + strlen(table_list->db);
 
133
  key_pos= strcpy(key_pos+1, table_list->table_name) +
 
134
                  strlen(table_list->table_name);
 
135
  key_length= (uint32_t)(key_pos-key)+1;
 
136
 
107
137
  if (tmp_table)
108
138
  {
109
 
    int4store(key + key_length, thd->server_id);
110
 
    int4store(key + key_length + 4, thd->variables.pseudo_thread_id);
 
139
    int4store(key + key_length, session->server_id);
 
140
    int4store(key + key_length + 4, session->variables.pseudo_thread_id);
111
141
    key_length+= TMP_TABLE_KEY_EXTRA;
112
142
  }
113
143
  return key_length;
120
150
*****************************************************************************/
121
151
 
122
152
extern "C" unsigned char *table_def_key(const unsigned char *record, size_t *length,
123
 
                                bool not_used __attribute__((unused)))
 
153
                                bool )
124
154
{
125
155
  TABLE_SHARE *entry=(TABLE_SHARE*) record;
126
156
  *length= entry->table_cache_key.length;
150
180
  oldest_unused_share= &end_of_unused_share;
151
181
  end_of_unused_share.prev= &oldest_unused_share;
152
182
 
153
 
  return hash_init(&table_def_cache, &my_charset_bin, table_def_size,
 
183
  return hash_init(&table_def_cache, &my_charset_bin, (size_t)table_def_size,
154
184
                   0, 0, table_def_key,
155
185
                   (hash_free_key) table_def_free_entry, 0);
156
186
}
178
208
  Get TABLE_SHARE for a table.
179
209
 
180
210
  get_table_share()
181
 
  thd                   Thread handle
 
211
  session                       Thread handle
182
212
  table_list            Table that should be opened
183
213
  key                   Table cache key
184
214
  key_length            Length of key
199
229
   #  Share for table
200
230
*/
201
231
 
202
 
TABLE_SHARE *get_table_share(THD *thd, TableList *table_list, char *key,
 
232
TABLE_SHARE *get_table_share(Session *session, TableList *table_list, char *key,
203
233
                             uint32_t key_length, uint32_t db_flags, int *error)
204
234
{
205
235
  TABLE_SHARE *share;
242
272
    free_table_share(share);
243
273
    return(0);                          // return error
244
274
  }
245
 
  if (open_table_def(thd, share, db_flags))
 
275
  if (open_table_def(session, share, db_flags))
246
276
  {
247
277
    *error= share->error;
248
278
    (void) hash_delete(&table_def_cache, (unsigned char*) share);
253
283
  return(share);
254
284
 
255
285
found:
256
 
  /* 
 
286
  /*
257
287
     We found an existing table definition. Return it if we didn't get
258
288
     an error when reading the table definition from file.
259
289
  */
302
332
*/
303
333
 
304
334
static TABLE_SHARE
305
 
*get_table_share_with_create(THD *thd, TableList *table_list,
 
335
*get_table_share_with_create(Session *session, TableList *table_list,
306
336
                             char *key, uint32_t key_length,
307
337
                             uint32_t db_flags, int *error)
308
338
{
309
339
  TABLE_SHARE *share;
310
 
  int tmp;
311
340
 
312
 
  share= get_table_share(thd, table_list, key, key_length, db_flags, error);
 
341
  share= get_table_share(session, table_list, key, key_length, db_flags, error);
313
342
  /*
314
343
    If share is not NULL, we found an existing share.
315
344
 
316
345
    If share is NULL, and there is no error, we're inside
317
346
    pre-locking, which silences 'ER_NO_SUCH_TABLE' errors
318
 
    with the intention to silently drop non-existing tables 
 
347
    with the intention to silently drop non-existing tables
319
348
    from the pre-locking list. In this case we still need to try
320
349
    auto-discover before returning a NULL share.
321
350
 
322
351
    If share is NULL and the error is ER_NO_SUCH_TABLE, this is
323
 
    the same as above, only that the error was not silenced by 
 
352
    the same as above, only that the error was not silenced by
324
353
    pre-locking. Once again, we need to try to auto-discover
325
354
    the share.
326
355
 
329
358
 
330
359
    @todo Rework alternative ways to deal with ER_NO_SUCH Table.
331
360
  */
332
 
  if (share || (thd->is_error() && (thd->main_da.sql_errno() != ER_NO_SUCH_TABLE)))
 
361
  if (share || (session->is_error() && (session->main_da.sql_errno() != ER_NO_SUCH_TABLE)))
333
362
 
334
363
    return(share);
335
364
 
336
 
  /* Table didn't exist. Check if some engine can provide it */
337
 
  if ((tmp= ha_create_table_from_engine(thd, table_list->db,
338
 
                                        table_list->table_name)) < 0)
339
 
    return(0);
340
 
 
341
 
  if (tmp)
342
 
  {
343
 
    /* Give right error message */
344
 
    thd->clear_error();
345
 
    my_printf_error(ER_UNKNOWN_ERROR,
346
 
                    "Failed to open '%-.64s', error while "
347
 
                    "unpacking from engine",
348
 
                    MYF(0), table_list->table_name);
349
 
    return(0);
350
 
  }
351
 
  /* Table existed in engine. Let's open it */
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,
355
 
                              db_flags, error));
 
365
  return 0;
356
366
}
357
367
 
358
368
 
359
 
/* 
 
369
/*
360
370
   Mark that we are not using table share anymore.
361
371
 
362
372
   SYNOPSIS
378
388
*/
379
389
 
380
390
void release_table_share(TABLE_SHARE *share,
381
 
                         enum release_type type __attribute__((unused)))
 
391
                         enum release_type )
382
392
{
383
393
  bool to_be_deleted= 0;
384
394
 
436
446
 
437
447
  table_list.db= (char*) db;
438
448
  table_list.table_name= (char*) table_name;
439
 
  key_length= create_table_def_key((THD*) 0, key, &table_list, 0);
 
449
  key_length= create_table_def_key((Session*) 0, key, &table_list, 0);
440
450
  return (TABLE_SHARE*) hash_search(&table_def_cache,(unsigned char*) key, key_length);
441
 
}  
 
451
}
442
452
 
443
453
 
444
454
/*
452
462
    By leaving the table in the table cache, it disallows any other thread
453
463
    to open the table
454
464
 
455
 
    thd->killed will be set if we run out of memory
 
465
    session->killed will be set if we run out of memory
456
466
 
457
467
    If closing a MERGE child, the calling function has to take care for
458
468
    closing the parent too, if necessary.
499
509
 
500
510
  SYNOPSIS
501
511
    list_open_tables()
502
 
    thd                 Thread THD
503
512
    wild                SQL like expression
504
513
 
505
514
  NOTES
512
521
    #           Pointer to list of names of open tables.
513
522
*/
514
523
 
515
 
OPEN_TableList *list_open_tables(THD *thd __attribute__((unused)),
516
 
                                  const char *db, const char *wild)
 
524
OPEN_TableList *list_open_tables(const char *db, const char *wild)
517
525
{
518
526
  int result = 0;
519
527
  OPEN_TableList **start_list, *open_list;
560
568
      open_list=0;                              // Out of memory
561
569
      break;
562
570
    }
563
 
    my_stpcpy((*start_list)->table=
564
 
           my_stpcpy(((*start_list)->db= (char*) ((*start_list)+1)),
565
 
                  share->db.str)+1,
566
 
           share->table_name.str);
 
571
    strcpy((*start_list)->table=
 
572
           strcpy(((*start_list)->db= (char*) ((*start_list)+1)),
 
573
           share->db.str)+share->db.length+1,
 
574
           share->table_name.str);
567
575
    (*start_list)->in_use= entry->in_use ? 1 : 0;
568
576
    (*start_list)->locked= entry->locked_by_name ? 1 : 0;
569
577
    start_list= &(*start_list)->next;
582
590
{                                               // Free all structures
583
591
  free_io_cache(table);
584
592
  if (table->file)                              // Not true if name lock
585
 
    closefrm(table, 1);                 // close file
 
593
    table->closefrm(true);                      // close file
586
594
  return;
587
595
}
588
596
 
591
599
 
592
600
  SYNOPSIS
593
601
    free_cache_entry()
594
 
    table               Table to remove
 
602
    entry               Table to remove
595
603
 
596
604
  NOTE
597
605
    We need to have a lock on LOCK_open when calling this
598
606
*/
599
607
 
600
 
static void free_cache_entry(Table *table)
 
608
void free_cache_entry(void *entry)
601
609
{
 
610
  Table *table= static_cast<Table *>(entry);
602
611
  intern_close_table(table);
603
612
  if (!table->in_use)
604
613
  {
611
620
        unused_tables=0;
612
621
    }
613
622
  }
614
 
  free((unsigned char*) table);
 
623
  free(table);
615
624
  return;
616
625
}
617
626
 
622
631
  if (table->sort.io_cache)
623
632
  {
624
633
    close_cached_file(table->sort.io_cache);
625
 
    free((unsigned char*) table->sort.io_cache);
626
 
    table->sort.io_cache=0;
 
634
    delete table->sort.io_cache;
 
635
    table->sort.io_cache= 0;
627
636
  }
628
637
  return;
629
638
}
632
641
/*
633
642
  Close all tables which aren't in use by any thread
634
643
 
635
 
  @param thd Thread context
 
644
  @param session Thread context
636
645
  @param tables List of tables to remove from the cache
637
646
  @param have_lock If LOCK_open is locked
638
647
  @param wait_for_refresh Wait for a impending flush
640
649
         won't proceed while write-locked tables are being reopened by other
641
650
         threads.
642
651
 
643
 
  @remark THD can be NULL, but then wait_for_refresh must be false
 
652
  @remark Session can be NULL, but then wait_for_refresh must be false
644
653
          and tables must be NULL.
645
654
*/
646
655
 
647
 
bool close_cached_tables(THD *thd, TableList *tables, bool have_lock,
 
656
bool close_cached_tables(Session *session, TableList *tables, bool have_lock,
648
657
                         bool wait_for_refresh, bool wait_for_placeholders)
649
658
{
650
659
  bool result=0;
651
 
  assert(thd || (!wait_for_refresh && !tables));
 
660
  assert(session || (!wait_for_refresh && !tables));
652
661
 
653
662
  if (!have_lock)
654
663
    pthread_mutex_lock(&LOCK_open);
722
731
    bool found=0;
723
732
    for (TableList *table= tables; table; table= table->next_local)
724
733
    {
725
 
      if (remove_table_from_cache(thd, table->db, table->table_name,
726
 
                                  RTFC_OWNED_BY_THD_FLAG))
 
734
      if (remove_table_from_cache(session, table->db, table->table_name,
 
735
                                  RTFC_OWNED_BY_Session_FLAG))
727
736
        found=1;
728
737
    }
729
738
    if (!found)
736
745
      If there is any table that has a lower refresh_version, wait until
737
746
      this is closed (or this thread is killed) before returning
738
747
    */
739
 
    thd->mysys_var->current_mutex= &LOCK_open;
740
 
    thd->mysys_var->current_cond= &COND_refresh;
741
 
    thd_proc_info(thd, "Flushing tables");
 
748
    session->mysys_var->current_mutex= &LOCK_open;
 
749
    session->mysys_var->current_cond= &COND_refresh;
 
750
    session->set_proc_info("Flushing tables");
742
751
 
743
 
    close_old_data_files(thd,thd->open_tables,1,1);
744
 
    mysql_ha_flush(thd);
 
752
    close_old_data_files(session,session->open_tables,1,1);
745
753
 
746
754
    bool found=1;
747
755
    /* Wait until all threads has closed all the tables we had locked */
748
 
    while (found && ! thd->killed)
 
756
    while (found && ! session->killed)
749
757
    {
750
758
      found=0;
751
759
      for (uint32_t idx=0 ; idx < open_cache.records ; idx++)
752
760
      {
753
761
        Table *table=(Table*) hash_element(&open_cache,idx);
754
762
        /* Avoid a self-deadlock. */
755
 
        if (table->in_use == thd)
 
763
        if (table->in_use == session)
756
764
          continue;
757
765
        /*
758
766
          Note that we wait here only for tables which are actually open, and
782
790
      old locks. This should always succeed (unless some external process
783
791
      has removed the tables)
784
792
    */
785
 
    thd->in_lock_tables=1;
786
 
    result=reopen_tables(thd,1,1);
787
 
    thd->in_lock_tables=0;
 
793
    session->in_lock_tables=1;
 
794
    result=reopen_tables(session,1,1);
 
795
    session->in_lock_tables=0;
788
796
    /* Set version for table */
789
 
    for (Table *table=thd->open_tables; table ; table= table->next)
 
797
    for (Table *table=session->open_tables; table ; table= table->next)
790
798
    {
791
799
      /*
792
800
        Preserve the version (0) of write locked tables so that a impending
800
808
    pthread_mutex_unlock(&LOCK_open);
801
809
  if (wait_for_refresh)
802
810
  {
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);
 
811
    pthread_mutex_lock(&session->mysys_var->mutex);
 
812
    session->mysys_var->current_mutex= 0;
 
813
    session->mysys_var->current_cond= 0;
 
814
    session->set_proc_info(0);
 
815
    pthread_mutex_unlock(&session->mysys_var->mutex);
808
816
  }
809
817
  return(result);
810
818
}
815
823
  if specified string is NULL, then any table with a connection string.
816
824
*/
817
825
 
818
 
bool close_cached_connection_tables(THD *thd, bool if_wait_for_refresh,
 
826
bool close_cached_connection_tables(Session *session, bool if_wait_for_refresh,
819
827
                                    LEX_STRING *connection, bool have_lock)
820
828
{
821
829
  uint32_t idx;
822
830
  TableList tmp, *tables= NULL;
823
831
  bool result= false;
824
 
  assert(thd);
 
832
  assert(session);
825
833
 
826
834
  memset(&tmp, 0, sizeof(TableList));
827
835
 
851
859
    tmp.table_name= share->table_name.str;
852
860
    tmp.next_local= tables;
853
861
 
854
 
    tables= (TableList *) memdup_root(thd->mem_root, (char*)&tmp, 
 
862
    tables= (TableList *) memdup_root(session->mem_root, (char*)&tmp,
855
863
                                       sizeof(TableList));
856
864
  }
857
865
 
858
866
  if (tables)
859
 
    result= close_cached_tables(thd, tables, true, false, false);
 
867
    result= close_cached_tables(session, tables, true, false, false);
860
868
 
861
869
  if (!have_lock)
862
870
    pthread_mutex_unlock(&LOCK_open);
863
871
 
864
872
  if (if_wait_for_refresh)
865
873
  {
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);
 
874
    pthread_mutex_lock(&session->mysys_var->mutex);
 
875
    session->mysys_var->current_mutex= 0;
 
876
    session->mysys_var->current_cond= 0;
 
877
    session->set_proc_info(0);
 
878
    pthread_mutex_unlock(&session->mysys_var->mutex);
871
879
  }
872
880
 
873
881
  return(result);
878
886
  Mark all temporary tables which were used by the current statement or
879
887
  substatement as free for reuse, but only if the query_id can be cleared.
880
888
 
881
 
  @param thd thread context
 
889
  @param session thread context
882
890
 
883
891
  @remark For temp tables associated with a open SQL HANDLER the query_id
884
892
          is not reset until the HANDLER is closed.
885
893
*/
886
894
 
887
 
static void mark_temp_tables_as_free_for_reuse(THD *thd)
 
895
static void mark_temp_tables_as_free_for_reuse(Session *session)
888
896
{
889
 
  for (Table *table= thd->temporary_tables ; table ; table= table->next)
 
897
  for (Table *table= session->temporary_tables ; table ; table= table->next)
890
898
  {
891
 
    if ((table->query_id == thd->query_id) && ! table->open_by_handler)
 
899
    if ((table->query_id == session->query_id) && ! table->open_by_handler)
892
900
    {
893
901
      table->query_id= 0;
894
902
      table->file->ha_reset();
903
911
 
904
912
  SYNOPSIS
905
913
    mark_used_tables_as_free_for_reuse()
906
 
      thd   - thread context
 
914
      session   - thread context
907
915
      table - head of the list of tables
908
916
 
909
917
  DESCRIPTION
912
920
 
913
921
  NOTE
914
922
    The reason we reset query_id is that it's not enough to just test
915
 
    if table->query_id != thd->query_id to know if a table is in use.
 
923
    if table->query_id != session->query_id to know if a table is in use.
916
924
 
917
925
    For example
918
926
    SELECT f1_that_uses_t1() FROM t1;
920
928
    set to query_id of original query.
921
929
*/
922
930
 
923
 
static void mark_used_tables_as_free_for_reuse(THD *thd, Table *table)
 
931
static void mark_used_tables_as_free_for_reuse(Session *session, Table *table)
924
932
{
925
933
  for (; table ; table= table->next)
926
934
  {
927
 
    if (table->query_id == thd->query_id)
 
935
    if (table->query_id == session->query_id)
928
936
    {
929
937
      table->query_id= 0;
930
938
      table->file->ha_reset();
936
944
/**
937
945
  Auxiliary function to close all tables in the open_tables list.
938
946
 
939
 
  @param thd Thread context.
 
947
  @param session Thread context.
940
948
 
941
949
  @remark It should not ordinarily be called directly.
942
950
*/
943
951
 
944
 
static void close_open_tables(THD *thd)
 
952
static void close_open_tables(Session *session)
945
953
{
946
954
  bool found_old_table= 0;
947
955
 
949
957
 
950
958
  pthread_mutex_lock(&LOCK_open);
951
959
 
952
 
  while (thd->open_tables)
953
 
    found_old_table|= close_thread_table(thd, &thd->open_tables);
954
 
  thd->some_tables_deleted= 0;
 
960
  while (session->open_tables)
 
961
    found_old_table|= close_thread_table(session, &session->open_tables);
 
962
  session->some_tables_deleted= 0;
955
963
 
956
964
  /* Free tables to hold down open files */
957
965
  while (open_cache.records > table_cache_size && unused_tables)
972
980
 
973
981
  SYNOPSIS
974
982
    close_thread_tables()
975
 
    thd                 Thread handler
 
983
    session                     Thread handler
976
984
 
977
985
  IMPLEMENTATION
978
986
    Unlocks tables and frees derived tables.
984
992
    leave prelocked mode if needed.
985
993
*/
986
994
 
987
 
void close_thread_tables(THD *thd)
 
995
void close_thread_tables(Session *session)
988
996
{
989
997
  Table *table;
990
998
 
991
999
  /*
992
 
    We are assuming here that thd->derived_tables contains ONLY derived
 
1000
    We are assuming here that session->derived_tables contains ONLY derived
993
1001
    tables for this substatement. i.e. instead of approach which uses
994
1002
    query_id matching for determining which of the derived tables belong
995
1003
    to this substatement we rely on the ability of substatements to
996
 
    save/restore thd->derived_tables during their execution.
 
1004
    save/restore session->derived_tables during their execution.
997
1005
 
998
1006
    TODO: Probably even better approach is to simply associate list of
999
1007
          derived tables with (sub-)statement instead of thread and destroy
1000
1008
          them at the end of its execution.
1001
1009
  */
1002
 
  if (thd->derived_tables)
 
1010
  if (session->derived_tables)
1003
1011
  {
1004
1012
    Table *next;
1005
1013
    /*
1006
1014
      Close all derived tables generated in queries like
1007
1015
      SELECT * FROM (SELECT * FROM t1)
1008
1016
    */
1009
 
    for (table= thd->derived_tables ; table ; table= next)
 
1017
    for (table= session->derived_tables ; table ; table= next)
1010
1018
    {
1011
1019
      next= table->next;
1012
 
      table->free_tmp_table(thd);
 
1020
      table->free_tmp_table(session);
1013
1021
    }
1014
 
    thd->derived_tables= 0;
 
1022
    session->derived_tables= 0;
1015
1023
  }
1016
1024
 
1017
1025
  /*
1018
1026
    Mark all temporary tables used by this statement as free for reuse.
1019
1027
  */
1020
 
  mark_temp_tables_as_free_for_reuse(thd);
 
1028
  mark_temp_tables_as_free_for_reuse(session);
1021
1029
  /*
1022
1030
    Let us commit transaction for statement. Since in 5.0 we only have
1023
1031
    one statement transaction and don't allow several nested statement
1026
1034
    does not belong to statement for which we do close_thread_tables()).
1027
1035
    TODO: This should be fixed in later releases.
1028
1036
   */
1029
 
  if (!(thd->state_flags & Open_tables_state::BACKUPS_AVAIL))
 
1037
  if (!(session->state_flags & Open_tables_state::BACKUPS_AVAIL))
1030
1038
  {
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();
 
1039
    session->main_da.can_overwrite_status= true;
 
1040
    ha_autocommit_or_rollback(session, session->is_error());
 
1041
    session->main_da.can_overwrite_status= false;
 
1042
    session->transaction.stmt.reset();
1035
1043
  }
1036
1044
 
1037
 
  if (thd->locked_tables)
 
1045
  if (session->locked_tables)
1038
1046
  {
1039
1047
 
1040
1048
    /* Ensure we are calling ha_reset() for all used tables */
1041
 
    mark_used_tables_as_free_for_reuse(thd, thd->open_tables);
 
1049
    mark_used_tables_as_free_for_reuse(session, session->open_tables);
1042
1050
 
1043
1051
    /*
1044
1052
      We are under simple LOCK TABLES so should not do anything else.
1046
1054
    return;
1047
1055
  }
1048
1056
 
1049
 
  if (thd->lock)
 
1057
  if (session->lock)
1050
1058
  {
1051
1059
    /*
1052
1060
      For RBR we flush the pending event just before we unlock all the
1057
1065
      handled either before writing a query log event (inside
1058
1066
      binlog_query()) or when preparing a pending event.
1059
1067
     */
1060
 
    thd->binlog_flush_pending_rows_event(true);
1061
 
    mysql_unlock_tables(thd, thd->lock);
1062
 
    thd->lock=0;
 
1068
    mysql_unlock_tables(session, session->lock);
 
1069
    session->lock=0;
1063
1070
  }
1064
1071
  /*
1065
1072
    Note that we need to hold LOCK_open while changing the
1068
1075
    Closing a MERGE child before the parent would be fatal if the
1069
1076
    other thread tries to abort the MERGE lock in between.
1070
1077
  */
1071
 
  if (thd->open_tables)
1072
 
    close_open_tables(thd);
 
1078
  if (session->open_tables)
 
1079
    close_open_tables(session);
1073
1080
 
1074
1081
  return;
1075
1082
}
1077
1084
 
1078
1085
/* move one table to free list */
1079
1086
 
1080
 
bool close_thread_table(THD *thd, Table **table_ptr)
 
1087
bool close_thread_table(Session *session, Table **table_ptr)
1081
1088
{
1082
1089
  bool found_old_table= 0;
1083
1090
  Table *table= *table_ptr;
1088
1095
  *table_ptr=table->next;
1089
1096
 
1090
1097
  if (table->needs_reopen_or_name_lock() ||
1091
 
      thd->version != refresh_version || !table->db_stat)
 
1098
      session->version != refresh_version || !table->db_stat)
1092
1099
  {
1093
1100
    hash_delete(&open_cache,(unsigned char*) table);
1094
1101
    found_old_table=1;
1117
1124
  return(found_old_table);
1118
1125
}
1119
1126
 
1120
 
 
1121
 
/* close_temporary_tables' internal, 4 is due to uint4korr definition */
1122
 
static inline uint32_t  tmpkeyval(THD *thd __attribute__((unused)),
1123
 
                              Table *table)
1124
 
{
1125
 
  return uint4korr(table->s->table_cache_key.str + table->s->table_cache_key.length - 4);
1126
 
}
1127
 
 
1128
 
 
1129
 
/*
1130
 
  Close all temporary tables created by 'CREATE TEMPORARY TABLE' for thread
1131
 
  creates one DROP TEMPORARY Table binlog event for each pseudo-thread 
1132
 
*/
1133
 
 
1134
 
void close_temporary_tables(THD *thd)
1135
 
{
1136
 
  Table *table;
1137
 
  Table *next= NULL;
1138
 
  Table *prev_table;
1139
 
  /* Assume thd->options has OPTION_QUOTE_SHOW_CREATE */
1140
 
  bool was_quote_show= true;
1141
 
 
1142
 
  if (!thd->temporary_tables)
1143
 
    return;
1144
 
 
1145
 
  if (!mysql_bin_log.is_open() || thd->current_stmt_binlog_row_based)
1146
 
  {
1147
 
    Table *tmp_next;
1148
 
    for (table= thd->temporary_tables; table; table= tmp_next)
1149
 
    {
1150
 
      tmp_next= table->next;
1151
 
      close_temporary(table, 1, 1);
1152
 
    }
1153
 
    thd->temporary_tables= 0;
1154
 
    return;
1155
 
  }
1156
 
 
1157
 
  /* Better add "if exists", in case a RESET MASTER has been done */
1158
 
  const char stub[]= "DROP /*!40005 TEMPORARY */ Table IF EXISTS ";
1159
 
  uint32_t stub_len= sizeof(stub) - 1;
1160
 
  char buf[256];
1161
 
  String s_query= String(buf, sizeof(buf), system_charset_info);
1162
 
  bool found_user_tables= false;
1163
 
 
1164
 
  memcpy(buf, stub, stub_len);
1165
 
 
1166
 
  /*
1167
 
    Insertion sort of temp tables by pseudo_thread_id to build ordered list
1168
 
    of sublists of equal pseudo_thread_id
1169
 
  */
1170
 
 
1171
 
  for (prev_table= thd->temporary_tables, table= prev_table->next;
1172
 
       table;
1173
 
       prev_table= table, table= table->next)
1174
 
  {
1175
 
    Table *prev_sorted /* same as for prev_table */, *sorted;
1176
 
    if (is_user_table(table))
1177
 
    {
1178
 
      if (!found_user_tables)
1179
 
        found_user_tables= true;
1180
 
      for (prev_sorted= NULL, sorted= thd->temporary_tables; sorted != table;
1181
 
           prev_sorted= sorted, sorted= sorted->next)
1182
 
      {
1183
 
        if (!is_user_table(sorted) ||
1184
 
            tmpkeyval(thd, sorted) > tmpkeyval(thd, table))
1185
 
        {
1186
 
          /* move into the sorted part of the list from the unsorted */
1187
 
          prev_table->next= table->next;
1188
 
          table->next= sorted;
1189
 
          if (prev_sorted)
1190
 
          {
1191
 
            prev_sorted->next= table;
1192
 
          }
1193
 
          else
1194
 
          {
1195
 
            thd->temporary_tables= table;
1196
 
          }
1197
 
          table= prev_table;
1198
 
          break;
1199
 
        }
1200
 
      }
1201
 
    }
1202
 
  }
1203
 
 
1204
 
  /* We always quote db,table names though it is slight overkill */
1205
 
  if (found_user_tables &&
1206
 
      !(was_quote_show= test(thd->options & OPTION_QUOTE_SHOW_CREATE)))
1207
 
  {
1208
 
    thd->options |= OPTION_QUOTE_SHOW_CREATE;
1209
 
  }
1210
 
 
1211
 
  /* scan sorted tmps to generate sequence of DROP */
1212
 
  for (table= thd->temporary_tables; table; table= next)
1213
 
  {
1214
 
    if (is_user_table(table))
1215
 
    {
1216
 
      my_thread_id save_pseudo_thread_id= thd->variables.pseudo_thread_id;
1217
 
      /* Set pseudo_thread_id to be that of the processed table */
1218
 
      thd->variables.pseudo_thread_id= tmpkeyval(thd, table);
1219
 
      /*
1220
 
        Loop forward through all tables within the sublist of
1221
 
        common pseudo_thread_id to create single DROP query.
1222
 
      */
1223
 
      for (s_query.length(stub_len);
1224
 
           table && is_user_table(table) &&
1225
 
             tmpkeyval(thd, table) == thd->variables.pseudo_thread_id;
1226
 
           table= next)
1227
 
      {
1228
 
        /*
1229
 
          We are going to add 4 ` around the db/table names and possible more
1230
 
          due to special characters in the names
1231
 
        */
1232
 
        append_identifier(thd, &s_query, table->s->db.str, strlen(table->s->db.str));
1233
 
        s_query.append('.');
1234
 
        append_identifier(thd, &s_query, table->s->table_name.str,
1235
 
                          strlen(table->s->table_name.str));
1236
 
        s_query.append(',');
1237
 
        next= table->next;
1238
 
        close_temporary(table, 1, 1);
1239
 
      }
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(),
1244
 
                            s_query.length() - 1 /* to remove trailing ',' */,
1245
 
                            0, false);
1246
 
      thd->variables.character_set_client= cs_save;
1247
 
      /*
1248
 
        Imagine the thread had created a temp table, then was doing a
1249
 
        SELECT, and the SELECT was killed. Then it's not clever to
1250
 
        mark the statement above as "killed", because it's not really
1251
 
        a statement updating data, and there are 99.99% chances it
1252
 
        will succeed on slave.  If a real update (one updating a
1253
 
        persistent table) was killed on the master, then this real
1254
 
        update will be logged with error_code=killed, rightfully
1255
 
        causing the slave to stop.
1256
 
      */
1257
 
      qinfo.error_code= 0;
1258
 
      mysql_bin_log.write(&qinfo);
1259
 
      thd->variables.pseudo_thread_id= save_pseudo_thread_id;
1260
 
    }
1261
 
    else
1262
 
    {
1263
 
      next= table->next;
1264
 
      close_temporary(table, 1, 1);
1265
 
    }
1266
 
  }
1267
 
  if (!was_quote_show)
1268
 
    thd->options&= ~OPTION_QUOTE_SHOW_CREATE; /* restore option */
1269
 
  thd->temporary_tables=0;
1270
 
}
1271
 
 
1272
1127
/*
1273
1128
  Find table in list.
1274
1129
 
1309
1164
 
1310
1165
  SYNOPSIS
1311
1166
    unique_table()
1312
 
    thd                   thread handle
 
1167
    session                   thread handle
1313
1168
    table                 table which should be checked
1314
1169
    table_list            list of tables
1315
1170
    check_alias           whether to check tables' aliases
1316
1171
 
1317
1172
  NOTE: to exclude derived tables from check we use following mechanism:
1318
 
    a) during derived table processing set THD::derived_tables_processing
 
1173
    a) during derived table processing set Session::derived_tables_processing
1319
1174
    b) JOIN::prepare set SELECT::exclude_from_table_unique_test if
1320
 
       THD::derived_tables_processing set. (we can't use JOIN::execute
 
1175
       Session::derived_tables_processing set. (we can't use JOIN::execute
1321
1176
       because for PS we perform only JOIN::prepare, but we can't set this
1322
1177
       flag in JOIN::prepare if we are not sure that we are in derived table
1323
1178
       processing loop, because multi-update call fix_fields() for some its
1340
1195
    0 if table is unique
1341
1196
*/
1342
1197
 
1343
 
TableList* unique_table(THD *thd, TableList *table, TableList *table_list,
 
1198
TableList* unique_table(Session *session, TableList *table, TableList *table_list,
1344
1199
                         bool check_alias)
1345
1200
{
1346
1201
  TableList *res;
1375
1230
  for (;;)
1376
1231
  {
1377
1232
    if (((! (res= find_table_in_global_list(table_list, d_name, t_name))) &&
1378
 
         (! (res= mysql_lock_have_duplicate(thd, table, table_list)))) ||
 
1233
         (! (res= mysql_lock_have_duplicate(session, table, table_list)))) ||
1379
1234
        ((!res->table || res->table != table->table) &&
1380
1235
         (!check_alias || !(lower_case_table_names ?
1381
1236
          my_strcasecmp(files_charset_info, t_alias, res->alias) :
1408
1263
*/
1409
1264
 
1410
1265
void update_non_unique_table_error(TableList *update,
1411
 
                                   const char *operation __attribute__((unused)),
1412
 
                                   TableList *duplicate __attribute__((unused)))
 
1266
                                   const char *,
 
1267
                                   TableList *)
1413
1268
{
1414
1269
  my_error(ER_UPDATE_TABLE_USED, MYF(0), update->alias);
1415
1270
}
1416
1271
 
1417
1272
 
1418
 
Table *find_temporary_table(THD *thd, const char *db, const char *table_name)
 
1273
Table *find_temporary_table(Session *session, const char *db, const char *table_name)
1419
1274
{
1420
1275
  TableList table_list;
1421
1276
 
1422
1277
  table_list.db= (char*) db;
1423
1278
  table_list.table_name= (char*) table_name;
1424
 
  return find_temporary_table(thd, &table_list);
 
1279
  return find_temporary_table(session, &table_list);
1425
1280
}
1426
1281
 
1427
1282
 
1428
 
Table *find_temporary_table(THD *thd, TableList *table_list)
 
1283
Table *find_temporary_table(Session *session, TableList *table_list)
1429
1284
{
1430
1285
  char  key[MAX_DBKEY_LENGTH];
1431
1286
  uint  key_length;
1432
1287
  Table *table;
1433
1288
 
1434
 
  key_length= create_table_def_key(thd, key, table_list, 1);
1435
 
  for (table=thd->temporary_tables ; table ; table= table->next)
 
1289
  key_length= create_table_def_key(session, key, table_list, 1);
 
1290
  for (table=session->temporary_tables ; table ; table= table->next)
1436
1291
  {
1437
1292
    if (table->s->table_cache_key.length == key_length &&
1438
1293
        !memcmp(table->s->table_cache_key.str, key, key_length))
1445
1300
/**
1446
1301
  Drop a temporary table.
1447
1302
 
1448
 
  Try to locate the table in the list of thd->temporary_tables.
 
1303
  Try to locate the table in the list of session->temporary_tables.
1449
1304
  If the table is found:
1450
1305
   - if the table is being used by some outer statement, fail.
1451
 
   - if the table is in thd->locked_tables, unlock it and
 
1306
   - if the table is in session->locked_tables, unlock it and
1452
1307
     remove it from the list of locked tables. Currently only transactional
1453
1308
     temporary tables are present in the locked_tables list.
1454
1309
   - Close the temporary table, remove its .FRM
1459
1314
  or ALTER Table. Even though part of the work done by this function
1460
1315
  is redundant when the table is internal, as long as we
1461
1316
  link both internal and user temporary tables into the same
1462
 
  thd->temporary_tables list, it's impossible to tell here whether
 
1317
  session->temporary_tables list, it's impossible to tell here whether
1463
1318
  we're dealing with an internal or a user temporary table.
1464
1319
 
1465
1320
  @retval  0  the table was found and dropped successfully.
1468
1323
  @retval -1  the table is in use by a outer query
1469
1324
*/
1470
1325
 
1471
 
int drop_temporary_table(THD *thd, TableList *table_list)
 
1326
int drop_temporary_table(Session *session, TableList *table_list)
1472
1327
{
1473
1328
  Table *table;
1474
1329
 
1475
 
  if (!(table= find_temporary_table(thd, table_list)))
 
1330
  if (!(table= find_temporary_table(session, table_list)))
1476
1331
    return(1);
1477
1332
 
1478
1333
  /* Table might be in use by some outer statement. */
1479
 
  if (table->query_id && table->query_id != thd->query_id)
 
1334
  if (table->query_id && table->query_id != session->query_id)
1480
1335
  {
1481
1336
    my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
1482
1337
    return(-1);
1486
1341
    If LOCK TABLES list is not empty and contains this table,
1487
1342
    unlock the table and remove the table from this list.
1488
1343
  */
1489
 
  mysql_lock_remove(thd, thd->locked_tables, table, false);
1490
 
  close_temporary_table(thd, table, 1, 1);
 
1344
  mysql_lock_remove(session, session->locked_tables, table, false);
 
1345
  close_temporary_table(session, table, 1, 1);
1491
1346
  return(0);
1492
1347
}
1493
1348
 
1494
1349
/*
1495
 
  unlink from thd->temporary tables and close temporary table
 
1350
  unlink from session->temporary tables and close temporary table
1496
1351
*/
1497
1352
 
1498
 
void close_temporary_table(THD *thd, Table *table,
 
1353
void close_temporary_table(Session *session, Table *table,
1499
1354
                           bool free_share, bool delete_table)
1500
1355
{
1501
1356
  if (table->prev)
1507
1362
  else
1508
1363
  {
1509
1364
    /* removing the item from the list */
1510
 
    assert(table == thd->temporary_tables);
 
1365
    assert(table == session->temporary_tables);
1511
1366
    /*
1512
1367
      slave must reset its temporary list pointer to zero to exclude
1513
1368
      passing non-zero value to end_slave via rli->save_temporary_tables
1514
1369
      when no temp tables opened, see an invariant below.
1515
1370
    */
1516
 
    thd->temporary_tables= table->next;
1517
 
    if (thd->temporary_tables)
 
1371
    session->temporary_tables= table->next;
 
1372
    if (session->temporary_tables)
1518
1373
      table->next->prev= 0;
1519
1374
  }
1520
 
  if (thd->slave_thread)
1521
 
  {
1522
 
    /* natural invariant of temporary_tables */
1523
 
    assert(slave_open_temp_tables || !thd->temporary_tables);
1524
 
    slave_open_temp_tables--;
1525
 
  }
1526
1375
  close_temporary(table, free_share, delete_table);
1527
1376
  return;
1528
1377
}
1532
1381
  Close and delete a temporary table
1533
1382
 
1534
1383
  NOTE
1535
 
    This dosn't unlink table from thd->temporary
 
1384
    This dosn't unlink table from session->temporary
1536
1385
    If this is needed, use close_temporary_table()
1537
1386
*/
1538
1387
 
1539
1388
void close_temporary(Table *table, bool free_share, bool delete_table)
1540
1389
{
1541
 
  handlerton *table_type= table->s->db_type();
 
1390
  StorageEngine *table_type= table->s->db_type();
1542
1391
 
1543
1392
  free_io_cache(table);
1544
 
  closefrm(table, 0);
1545
 
  /*
1546
 
     Check that temporary table has not been created with
1547
 
     frm_only because it has then not been created in any storage engine
1548
 
   */
 
1393
  table->closefrm(false);
 
1394
 
1549
1395
  if (delete_table)
1550
 
    rm_temporary_table(table_type, table->s->path.str, 
1551
 
                       table->s->tmp_table == TMP_TABLE_FRM_FILE_ONLY);
 
1396
    rm_temporary_table(table_type, table->s->path.str);
 
1397
 
1552
1398
  if (free_share)
1553
1399
  {
1554
1400
    free_table_share(table->s);
1563
1409
  only if the ALTER contained a RENAME clause (otherwise, table_name is the old
1564
1410
  name).
1565
1411
  Prepares a table cache key, which is the concatenation of db, table_name and
1566
 
  thd->slave_proxy_id, separated by '\0'.
 
1412
  session->slave_proxy_id, separated by '\0'.
1567
1413
*/
1568
1414
 
1569
 
bool rename_temporary_table(THD* thd, Table *table, const char *db,
 
1415
bool rename_temporary_table(Session* session, Table *table, const char *db,
1570
1416
                            const char *table_name)
1571
1417
{
1572
1418
  char *key;
1575
1421
  TableList table_list;
1576
1422
 
1577
1423
  if (!(key=(char*) alloc_root(&share->mem_root, MAX_DBKEY_LENGTH)))
1578
 
    return(1);                          /* purecov: inspected */
 
1424
    return true;                                /* purecov: inspected */
1579
1425
 
1580
1426
  table_list.db= (char*) db;
1581
1427
  table_list.table_name= (char*) table_name;
1582
 
  key_length= create_table_def_key(thd, key, &table_list, 1);
 
1428
  key_length= create_table_def_key(session, key, &table_list, 1);
1583
1429
  share->set_table_cache_key(key, key_length);
1584
 
  return(0);
 
1430
 
 
1431
  return false;
1585
1432
}
1586
1433
 
1587
1434
 
1606
1453
    Remove all instances of table from thread's open list and
1607
1454
    table cache.
1608
1455
 
1609
 
    @param  thd     Thread context
 
1456
    @param  session     Thread context
1610
1457
    @param  find    Table to remove
1611
1458
    @param  unlock  true  - free all locks on tables removed that are
1612
1459
                            done with LOCK TABLES
1617
1464
          not locked (for example already unlocked).
1618
1465
*/
1619
1466
 
1620
 
void unlink_open_table(THD *thd, Table *find, bool unlock)
 
1467
void unlink_open_table(Session *session, Table *find, bool unlock)
1621
1468
{
1622
1469
  char key[MAX_DBKEY_LENGTH];
1623
1470
  uint32_t key_length= find->s->table_cache_key.length;
1633
1480
    Closing a MERGE child before the parent would be fatal if the
1634
1481
    other thread tries to abort the MERGE lock in between.
1635
1482
  */
1636
 
  for (prev= &thd->open_tables; *prev; )
 
1483
  for (prev= &session->open_tables; *prev; )
1637
1484
  {
1638
1485
    list= *prev;
1639
1486
 
1640
1487
    if (list->s->table_cache_key.length == key_length &&
1641
1488
        !memcmp(list->s->table_cache_key.str, key, key_length))
1642
1489
    {
1643
 
      if (unlock && thd->locked_tables)
1644
 
        mysql_lock_remove(thd, thd->locked_tables, list, true);
 
1490
      if (unlock && session->locked_tables)
 
1491
        mysql_lock_remove(session, session->locked_tables, list, true);
1645
1492
 
1646
1493
      /* Remove table from open_tables list. */
1647
1494
      *prev= list->next;
1664
1511
/**
1665
1512
    Auxiliary routine which closes and drops open table.
1666
1513
 
1667
 
    @param  thd         Thread handle
 
1514
    @param  session         Thread handle
1668
1515
    @param  table       Table object for table to be dropped
1669
1516
    @param  db_name     Name of database for this table
1670
1517
    @param  table_name  Name of this table
1680
1527
          table that was locked with LOCK TABLES.
1681
1528
*/
1682
1529
 
1683
 
void drop_open_table(THD *thd, Table *table, const char *db_name,
 
1530
void drop_open_table(Session *session, Table *table, const char *db_name,
1684
1531
                     const char *table_name)
1685
1532
{
1686
1533
  if (table->s->tmp_table)
1687
 
    close_temporary_table(thd, table, 1, 1);
 
1534
    close_temporary_table(session, table, 1, 1);
1688
1535
  else
1689
1536
  {
1690
 
    handlerton *table_type= table->s->db_type();
 
1537
    StorageEngine *table_type= table->s->db_type();
1691
1538
    pthread_mutex_lock(&LOCK_open);
1692
1539
    /*
1693
1540
      unlink_open_table() also tells threads waiting for refresh or close
1694
1541
      that something has happened.
1695
1542
    */
1696
 
    unlink_open_table(thd, table, false);
 
1543
    unlink_open_table(session, table, false);
1697
1544
    quick_rm_table(table_type, db_name, table_name, 0);
1698
1545
    pthread_mutex_unlock(&LOCK_open);
1699
1546
  }
1705
1552
 
1706
1553
   SYNOPSIS
1707
1554
     wait_for_condition()
1708
 
     thd        Thread handler
 
1555
     session    Thread handler
1709
1556
     mutex      mutex that is currently hold that is associated with condition
1710
 
                Will be unlocked on return     
 
1557
                Will be unlocked on return
1711
1558
     cond       Condition to wait for
1712
1559
*/
1713
1560
 
1714
 
void wait_for_condition(THD *thd, pthread_mutex_t *mutex, pthread_cond_t *cond)
 
1561
void wait_for_condition(Session *session, pthread_mutex_t *mutex, pthread_cond_t *cond)
1715
1562
{
1716
1563
  /* Wait until the current table is up to date */
1717
1564
  const char *proc_info;
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)
 
1565
  session->mysys_var->current_mutex= mutex;
 
1566
  session->mysys_var->current_cond= cond;
 
1567
  proc_info=session->get_proc_info();
 
1568
  session->set_proc_info("Waiting for table");
 
1569
  if (!session->killed)
1723
1570
    (void) pthread_cond_wait(cond, mutex);
1724
1571
 
1725
1572
  /*
1732
1579
    condition variables that are guranteed to not disapper (freed) even if this
1733
1580
    mutex is unlocked
1734
1581
  */
1735
 
    
 
1582
 
1736
1583
  pthread_mutex_unlock(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);
 
1584
  pthread_mutex_lock(&session->mysys_var->mutex);
 
1585
  session->mysys_var->current_mutex= 0;
 
1586
  session->mysys_var->current_cond= 0;
 
1587
  session->set_proc_info(proc_info);
 
1588
  pthread_mutex_unlock(&session->mysys_var->mutex);
1742
1589
  return;
1743
1590
}
1744
1591
 
1747
1594
  Exclusively name-lock a table that is already write-locked by the
1748
1595
  current thread.
1749
1596
 
1750
 
  @param thd current thread context
 
1597
  @param session current thread context
1751
1598
  @param tables table list containing one table to open.
1752
1599
 
1753
1600
  @return false on success, true otherwise.
1754
1601
*/
1755
1602
 
1756
 
bool name_lock_locked_table(THD *thd, TableList *tables)
 
1603
bool name_lock_locked_table(Session *session, TableList *tables)
1757
1604
{
1758
1605
  /* Under LOCK TABLES we must only accept write locked tables. */
1759
 
  tables->table= find_locked_table(thd, tables->db, tables->table_name);
 
1606
  tables->table= find_locked_table(session, tables->db, tables->table_name);
1760
1607
 
1761
1608
  if (!tables->table)
1762
1609
    my_error(ER_TABLE_NOT_LOCKED, MYF(0), tables->alias);
1768
1615
      Ensures that table is opened only by this thread and that no
1769
1616
      other statement will open this table.
1770
1617
    */
1771
 
    wait_while_table_is_used(thd, tables->table, HA_EXTRA_FORCE_REOPEN);
 
1618
    wait_while_table_is_used(session, tables->table, HA_EXTRA_FORCE_REOPEN);
1772
1619
    return(false);
1773
1620
  }
1774
1621
 
1781
1628
 
1782
1629
  SYNOPSIS
1783
1630
    reopen_name_locked_table()
1784
 
      thd         Thread handle
 
1631
      session         Thread handle
1785
1632
      table_list  TableList object for table to be open, TableList::table
1786
1633
                  member should point to Table object which was used for
1787
1634
                  name-locking.
1788
1635
      link_in     true  - if Table object for table to be opened should be
1789
 
                          linked into THD::open_tables list.
 
1636
                          linked into Session::open_tables list.
1790
1637
                  false - placeholder used for name-locking is already in
1791
1638
                          this list so we only need to preserve Table::next
1792
1639
                          pointer.
1799
1646
    true  - Error
1800
1647
*/
1801
1648
 
1802
 
bool reopen_name_locked_table(THD* thd, TableList* table_list, bool link_in)
 
1649
bool reopen_name_locked_table(Session* session, TableList* table_list, bool link_in)
1803
1650
{
1804
1651
  Table *table= table_list->table;
1805
1652
  TABLE_SHARE *share;
1808
1655
 
1809
1656
  safe_mutex_assert_owner(&LOCK_open);
1810
1657
 
1811
 
  if (thd->killed || !table)
 
1658
  if (session->killed || !table)
1812
1659
    return(true);
1813
1660
 
1814
1661
  orig_table= *table;
1815
1662
 
1816
 
  if (open_unireg_entry(thd, table, table_list, table_name,
 
1663
  if (open_unireg_entry(session, table, table_list, table_name,
1817
1664
                        table->s->table_cache_key.str,
1818
1665
                        table->s->table_cache_key.length))
1819
1666
  {
1838
1685
    before we will get table-level lock on this table.
1839
1686
  */
1840
1687
  share->version=0;
1841
 
  table->in_use = thd;
 
1688
  table->in_use = session;
1842
1689
 
1843
1690
  if (link_in)
1844
1691
  {
1845
 
    table->next= thd->open_tables;
1846
 
    thd->open_tables= table;
 
1692
    table->next= session->open_tables;
 
1693
    session->open_tables= table;
1847
1694
  }
1848
1695
  else
1849
1696
  {
1850
1697
    /*
1851
 
      Table object should be already in THD::open_tables list so we just
 
1698
      Table object should be already in Session::open_tables list so we just
1852
1699
      need to set Table::next correctly.
1853
1700
    */
1854
1701
    table->next= orig_table.next;
1855
1702
  }
1856
1703
 
1857
 
  table->tablenr=thd->current_tablenr++;
 
1704
  table->tablenr=session->current_tablenr++;
1858
1705
  table->used_fields=0;
1859
1706
  table->const_table=0;
1860
1707
  table->null_row= false;
1870
1717
    which will prevent its opening (or creation) (a.k.a lock
1871
1718
    table name).
1872
1719
 
1873
 
    @param thd         Thread context
 
1720
    @param session         Thread context
1874
1721
    @param key         Table cache key for name to be locked
1875
1722
    @param key_length  Table cache key length
1876
1723
 
1878
1725
            case of failure.
1879
1726
*/
1880
1727
 
1881
 
Table *table_cache_insert_placeholder(THD *thd, const char *key,
 
1728
Table *table_cache_insert_placeholder(Session *session, const char *key,
1882
1729
                                      uint32_t key_length)
1883
1730
{
1884
1731
  Table *table;
1902
1749
  table->s= share;
1903
1750
  share->set_table_cache_key(key_buff, key, key_length);
1904
1751
  share->tmp_table= INTERNAL_TMP_TABLE;  // for intern_close_table
1905
 
  table->in_use= thd;
 
1752
  table->in_use= session;
1906
1753
  table->locked_by_name=1;
1907
1754
 
1908
1755
  if (my_hash_insert(&open_cache, (unsigned char*)table))
1919
1766
    Obtain an exclusive name lock on the table if it is not cached
1920
1767
    in the table cache.
1921
1768
 
1922
 
    @param      thd         Thread context
 
1769
    @param      session         Thread context
1923
1770
    @param      db          Name of database
1924
1771
    @param      table_name  Name of table
1925
1772
    @param[out] table       Out parameter which is either:
1937
1784
    @retval  false  Success. 'table' parameter set according to above rules.
1938
1785
*/
1939
1786
 
1940
 
bool lock_table_name_if_not_cached(THD *thd, const char *db,
 
1787
bool lock_table_name_if_not_cached(Session *session, const char *db,
1941
1788
                                   const char *table_name, Table **table)
1942
1789
{
1943
1790
  char key[MAX_DBKEY_LENGTH];
 
1791
  char *key_pos= key;
1944
1792
  uint32_t key_length;
1945
1793
 
1946
 
  key_length= (uint)(my_stpcpy(my_stpcpy(key, db) + 1, table_name) - key) + 1;
 
1794
  key_pos= strcpy(key_pos, db) + strlen(db);
 
1795
  key_pos= strcpy(key_pos+1, table_name) + strlen(table_name);
 
1796
  key_length= (uint32_t) (key_pos-key)+1;
 
1797
 
1947
1798
  pthread_mutex_lock(&LOCK_open);
1948
1799
 
1949
1800
  if (hash_search(&open_cache, (unsigned char *)key, key_length))
1952
1803
    *table= 0;
1953
1804
    return(false);
1954
1805
  }
1955
 
  if (!(*table= table_cache_insert_placeholder(thd, key, key_length)))
 
1806
  if (!(*table= table_cache_insert_placeholder(session, key, key_length)))
1956
1807
  {
1957
1808
    pthread_mutex_unlock(&LOCK_open);
1958
1809
    return(true);
1959
1810
  }
1960
1811
  (*table)->open_placeholder= 1;
1961
 
  (*table)->next= thd->open_tables;
1962
 
  thd->open_tables= *table;
 
1812
  (*table)->next= session->open_tables;
 
1813
  session->open_tables= *table;
1963
1814
  pthread_mutex_unlock(&LOCK_open);
1964
1815
  return(false);
1965
1816
}
1966
1817
 
1967
 
 
1968
 
/**
1969
 
    Check that table exists in table definition cache, on disk
1970
 
    or in some storage engine.
1971
 
 
1972
 
    @param       thd     Thread context
1973
 
    @param       table   Table list element
1974
 
    @param[out]  exists  Out parameter which is set to true if table
1975
 
                         exists and to false otherwise.
1976
 
 
1977
 
    @note This function assumes that caller owns LOCK_open mutex.
1978
 
          It also assumes that the fact that there are no name-locks
1979
 
          on the table was checked beforehand.
1980
 
 
1981
 
    @note If there is no .FRM file for the table but it exists in one
1982
 
          of engines (e.g. it was created on another node of NDB cluster)
1983
 
          this function will fetch and create proper .FRM file for it.
1984
 
 
1985
 
    @retval  true   Some error occured
1986
 
    @retval  false  No error. 'exists' out parameter set accordingly.
1987
 
*/
1988
 
 
1989
 
bool check_if_table_exists(THD *thd, TableList *table, bool *exists)
1990
 
{
1991
 
  char path[FN_REFLEN];
1992
 
  int rc;
1993
 
 
1994
 
  safe_mutex_assert_owner(&LOCK_open);
1995
 
 
1996
 
  *exists= true;
1997
 
 
1998
 
  if (get_cached_table_share(table->db, table->table_name))
1999
 
    return(false);
2000
 
 
2001
 
  build_table_filename(path, sizeof(path) - 1, table->db, table->table_name,
2002
 
                       reg_ext, 0);
2003
 
 
2004
 
  if (!access(path, F_OK))
2005
 
    return(false);
2006
 
 
2007
 
  /* .FRM file doesn't exist. Check if some engine can provide it. */
2008
 
 
2009
 
  rc= ha_create_table_from_engine(thd, table->db, table->table_name);
2010
 
 
2011
 
  if (rc < 0)
2012
 
  {
2013
 
    /* Table does not exists in engines as well. */
2014
 
    *exists= false;
2015
 
    return(false);
2016
 
  }
2017
 
  else if (!rc)
2018
 
  {
2019
 
    /* Table exists in some engine and .FRM for it was created. */
2020
 
    return(false);
2021
 
  }
2022
 
  else /* (rc > 0) */
2023
 
  {
2024
 
    my_printf_error(ER_UNKNOWN_ERROR, "Failed to open '%-.64s', error while "
2025
 
                    "unpacking from engine", MYF(0), table->table_name);
2026
 
    return(true);
2027
 
  }
2028
 
}
2029
 
 
2030
 
 
2031
1818
/*
2032
1819
  Open a table.
2033
1820
 
2034
1821
  SYNOPSIS
2035
1822
    open_table()
2036
 
    thd                 Thread context.
 
1823
    session                 Thread context.
2037
1824
    table_list          Open first table in list.
2038
1825
    refresh      INOUT  Pointer to memory that will be set to 1 if
2039
1826
                        we need to close all tables and reopen them.
2061
1848
*/
2062
1849
 
2063
1850
 
2064
 
Table *open_table(THD *thd, TableList *table_list, bool *refresh, uint32_t flags)
 
1851
Table *open_table(Session *session, TableList *table_list, bool *refresh, uint32_t flags)
2065
1852
{
2066
1853
  register Table *table;
2067
1854
  char key[MAX_DBKEY_LENGTH];
2069
1856
  char *alias= table_list->alias;
2070
1857
  HASH_SEARCH_STATE state;
2071
1858
 
2072
 
  /* Parsing of partitioning information from .frm needs thd->lex set up. */
2073
 
  assert(thd->lex->is_lex_started);
 
1859
  /* Parsing of partitioning information from .frm needs session->lex set up. */
 
1860
  assert(session->lex->is_lex_started);
2074
1861
 
2075
1862
  /* find a unused table in the open table cache */
2076
1863
  if (refresh)
2077
1864
    *refresh=0;
2078
1865
 
2079
1866
  /* an open table operation needs a lot of the stack space */
2080
 
  if (check_stack_overrun(thd, STACK_MIN_SIZE_FOR_OPEN, (unsigned char *)&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) -
 
1867
  if (check_stack_overrun(session, STACK_MIN_SIZE_FOR_OPEN, (unsigned char *)&alias))
 
1868
    return(0);
 
1869
 
 
1870
  if (session->killed)
 
1871
    return(0);
 
1872
 
 
1873
  key_length= (create_table_def_key(session, key, table_list, 1) -
2087
1874
               TMP_TABLE_KEY_EXTRA);
2088
1875
 
2089
1876
  /*
2094
1881
    TODO: move this block into a separate function.
2095
1882
  */
2096
1883
  {
2097
 
    for (table= thd->temporary_tables; table ; table=table->next)
 
1884
    for (table= session->temporary_tables; table ; table=table->next)
2098
1885
    {
2099
1886
      if (table->s->table_cache_key.length == key_length +
2100
 
          TMP_TABLE_KEY_EXTRA &&
2101
 
          !memcmp(table->s->table_cache_key.str, key,
2102
 
                  key_length + TMP_TABLE_KEY_EXTRA))
 
1887
          TMP_TABLE_KEY_EXTRA && !memcmp(table->s->table_cache_key.str, key,
 
1888
          key_length + TMP_TABLE_KEY_EXTRA))
2103
1889
      {
2104
1890
        /*
2105
1891
          We're trying to use the same temporary table twice in a query.
2106
1892
          Right now we don't support this because a temporary table
2107
 
          is always represented by only one Table object in THD, and
 
1893
          is always represented by only one Table object in Session, and
2108
1894
          it can not be cloned. Emit an error for an unsupported behaviour.
2109
1895
        */
2110
 
        if (table->query_id)
2111
 
        {
2112
 
          my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
2113
 
          return(0);
2114
 
        }
2115
 
        table->query_id= thd->query_id;
2116
 
        thd->thread_specific_used= true;
 
1896
        if (table->query_id)
 
1897
        {
 
1898
          my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
 
1899
          return(0);
 
1900
        }
 
1901
        table->query_id= session->query_id;
 
1902
        session->thread_specific_used= true;
2117
1903
        goto reset;
2118
1904
      }
2119
1905
    }
2132
1918
    open not pre-opened tables in pre-locked/LOCK TABLES mode.
2133
1919
    TODO: move this block into a separate function.
2134
1920
  */
2135
 
  if (thd->locked_tables)
2136
 
  {                                             // Using table locks
 
1921
  if (session->locked_tables)
 
1922
  { // Using table locks
2137
1923
    Table *best_table= 0;
2138
1924
    int best_distance= INT_MIN;
2139
1925
    bool check_if_used= false;
2140
 
    for (table=thd->open_tables; table ; table=table->next)
 
1926
    for (table=session->open_tables; table ; table=table->next)
2141
1927
    {
2142
1928
      if (table->s->table_cache_key.length == key_length &&
2143
 
          !memcmp(table->s->table_cache_key.str, key, key_length))
 
1929
          !memcmp(table->s->table_cache_key.str, key, key_length))
2144
1930
      {
2145
1931
        if (check_if_used && table->query_id &&
2146
 
            table->query_id != thd->query_id)
 
1932
            table->query_id != session->query_id)
2147
1933
        {
2148
1934
          /*
2149
1935
            If we are in stored function or trigger we should ensure that
2160
1946
          belong to their parent and cannot be used explicitly.
2161
1947
        */
2162
1948
        if (!my_strcasecmp(system_charset_info, table->alias, alias) &&
2163
 
            table->query_id != thd->query_id)  /* skip tables already used */
 
1949
            table->query_id != session->query_id)  /* skip tables already used */
2164
1950
        {
2165
1951
          int distance= ((int) table->reginfo.lock_type -
2166
1952
                         (int) table_list->lock_type);
2197
1983
    if (best_table)
2198
1984
    {
2199
1985
      table= best_table;
2200
 
      table->query_id= thd->query_id;
 
1986
      table->query_id= session->query_id;
2201
1987
      goto reset;
2202
1988
    }
2203
1989
    /*
2237
2023
    and try to reopen them.
2238
2024
    Note: refresh_version is currently changed only during FLUSH TABLES.
2239
2025
  */
2240
 
  if (!thd->open_tables)
2241
 
    thd->version=refresh_version;
2242
 
  else if ((thd->version != refresh_version) &&
 
2026
  if (!session->open_tables)
 
2027
    session->version=refresh_version;
 
2028
  else if ((session->version != refresh_version) &&
2243
2029
           ! (flags & DRIZZLE_LOCK_IGNORE_FLUSH))
2244
2030
  {
2245
2031
    /* Someone did a refresh while thread was opening tables */
2250
2036
  }
2251
2037
 
2252
2038
  /*
2253
 
    In order for the back off and re-start process to work properly,
2254
 
    handler tables having old versions (due to FLUSH TABLES or pending
2255
 
    name-lock) MUST be closed. This is specially important if a name-lock
2256
 
    is pending for any table of the handler_tables list, otherwise a
2257
 
    deadlock may occur.
2258
 
  */
2259
 
  if (thd->handler_tables)
2260
 
    mysql_ha_flush(thd);
2261
 
 
2262
 
  /*
2263
2039
    Actually try to find the table in the open_cache.
2264
2040
    The cache may contain several "Table" instances for the same
2265
2041
    physical table. The instances that are currently "in use" by
2288
2064
      need to back off and re-start opening tables.
2289
2065
      If we do not back off now, we may dead lock in case of lock
2290
2066
      order mismatch with some other thread:
2291
 
      c1: name lock t1; -- sort of exclusive lock 
 
2067
      c1: name lock t1; -- sort of exclusive lock
2292
2068
      c2: open t2;      -- sort of shared lock
2293
2069
      c1: name lock t2; -- blocks
2294
2070
      c2: open t1; -- blocks
2298
2074
      if (flags & DRIZZLE_LOCK_IGNORE_FLUSH)
2299
2075
      {
2300
2076
        /* Force close at once after usage */
2301
 
        thd->version= table->s->version;
 
2077
        session->version= table->s->version;
2302
2078
        continue;
2303
2079
      }
2304
2080
 
2305
2081
      /* Avoid self-deadlocks by detecting self-dependencies. */
2306
 
      if (table->open_placeholder && table->in_use == thd)
 
2082
      if (table->open_placeholder && table->in_use == session)
2307
2083
      {
2308
 
        pthread_mutex_unlock(&LOCK_open);
 
2084
        pthread_mutex_unlock(&LOCK_open);
2309
2085
        my_error(ER_UPDATE_TABLE_USED, MYF(0), table->s->table_name.str);
2310
2086
        return(0);
2311
2087
      }
2323
2099
        the earlier call to mysql_ha_flush() in this same critical
2324
2100
        section.
2325
2101
      */
2326
 
      close_old_data_files(thd,thd->open_tables,0,0);
 
2102
      close_old_data_files(session,session->open_tables,0,0);
2327
2103
      /*
2328
2104
        Back-off part 2: try to avoid "busy waiting" on the table:
2329
2105
        if the table is in use by some other thread, we suspend
2339
2115
        after we open first instance but before we open second
2340
2116
        instance.
2341
2117
      */
2342
 
      if (table->in_use != thd)
 
2118
      if (table->in_use != session)
2343
2119
      {
2344
2120
        /* wait_for_conditionwill unlock LOCK_open for us */
2345
 
        wait_for_condition(thd, &LOCK_open, &COND_refresh);
 
2121
        wait_for_condition(session, &LOCK_open, &COND_refresh);
2346
2122
      }
2347
2123
      else
2348
2124
      {
2349
 
        pthread_mutex_unlock(&LOCK_open);
 
2125
        pthread_mutex_unlock(&LOCK_open);
2350
2126
      }
2351
2127
      /*
2352
2128
        There is a refresh in progress for this table.
2353
2129
        Signal the caller that it has to try again.
2354
2130
      */
2355
2131
      if (refresh)
2356
 
        *refresh=1;
 
2132
        *refresh=1;
2357
2133
      return(0);
2358
2134
    }
2359
2135
  }
2361
2137
  {
2362
2138
    /* Unlink the table from "unused_tables" list. */
2363
2139
    if (table == unused_tables)
2364
 
    {                                           // First unused
2365
 
      unused_tables=unused_tables->next;        // Remove from link
 
2140
    {  // First unused
 
2141
      unused_tables=unused_tables->next; // Remove from link
2366
2142
      if (table == unused_tables)
2367
 
        unused_tables=0;
 
2143
        unused_tables=0;
2368
2144
    }
2369
 
    table->prev->next=table->next;              /* Remove from unused list */
 
2145
    table->prev->next=table->next; /* Remove from unused list */
2370
2146
    table->next->prev=table->prev;
2371
 
    table->in_use= thd;
 
2147
    table->in_use= session;
2372
2148
  }
2373
2149
  else
2374
2150
  {
2380
2156
 
2381
2157
    if (table_list->create)
2382
2158
    {
2383
 
      bool exists;
2384
 
 
2385
 
      if (check_if_table_exists(thd, table_list, &exists))
2386
 
      {
2387
 
        pthread_mutex_unlock(&LOCK_open);
2388
 
        return(NULL);
2389
 
      }
2390
 
 
2391
 
      if (!exists)
 
2159
      if(ha_table_exists_in_engine(session, table_list->db,
 
2160
                                   table_list->table_name)
 
2161
         != HA_ERR_TABLE_EXIST)
2392
2162
      {
2393
2163
        /*
2394
2164
          Table to be created, so we need to create placeholder in table-cache.
2395
2165
        */
2396
 
        if (!(table= table_cache_insert_placeholder(thd, key, key_length)))
 
2166
        if (!(table= table_cache_insert_placeholder(session, key, key_length)))
2397
2167
        {
2398
2168
          pthread_mutex_unlock(&LOCK_open);
2399
2169
          return(NULL);
2404
2174
          by other trying to take name-lock.
2405
2175
        */
2406
2176
        table->open_placeholder= 1;
2407
 
        table->next= thd->open_tables;
2408
 
        thd->open_tables= table;
 
2177
        table->next= session->open_tables;
 
2178
        session->open_tables= table;
2409
2179
        pthread_mutex_unlock(&LOCK_open);
2410
2180
        return(table);
2411
2181
      }
2413
2183
    }
2414
2184
 
2415
2185
    /* make a new table */
2416
 
    if (!(table=(Table*) my_malloc(sizeof(*table),MYF(MY_WME))))
 
2186
    table= (Table *) malloc(sizeof(*table));
 
2187
    if (table == NULL)
2417
2188
    {
2418
2189
      pthread_mutex_unlock(&LOCK_open);
2419
2190
      return(NULL);
2420
2191
    }
2421
2192
 
2422
 
    error= open_unireg_entry(thd, table, table_list, alias, key, key_length);
2423
 
    /* Combine the follow two */
2424
 
    if (error > 0)
 
2193
    error= open_unireg_entry(session, table, table_list, alias, key, key_length);
 
2194
    if (error != 0)
2425
2195
    {
2426
 
      free((unsigned char*)table);
 
2196
      free(table);
2427
2197
      pthread_mutex_unlock(&LOCK_open);
2428
2198
      return(NULL);
2429
2199
    }
2430
 
    if (error < 0)
2431
 
    {
2432
 
      free((unsigned char*)table);
2433
 
      pthread_mutex_unlock(&LOCK_open);
2434
 
      return(0); // VIEW
2435
 
    }
2436
2200
    my_hash_insert(&open_cache,(unsigned char*) table);
2437
2201
  }
2438
2202
 
2439
2203
  pthread_mutex_unlock(&LOCK_open);
2440
2204
  if (refresh)
2441
2205
  {
2442
 
    table->next=thd->open_tables;               /* Link into simple list */
2443
 
    thd->open_tables=table;
 
2206
    table->next=session->open_tables; /* Link into simple list */
 
2207
    session->open_tables=table;
2444
2208
  }
2445
 
  table->reginfo.lock_type=TL_READ;             /* Assume read */
 
2209
  table->reginfo.lock_type=TL_READ; /* Assume read */
2446
2210
 
2447
2211
 reset:
2448
2212
  assert(table->s->ref_count > 0 || table->s->tmp_table != NO_TMP_TABLE);
2449
2213
 
2450
 
  if (thd->lex->need_correct_ident())
 
2214
  if (session->lex->need_correct_ident())
2451
2215
    table->alias_name_used= my_strcasecmp(table_alias_charset,
2452
2216
                                          table->s->table_name.str, alias);
2453
2217
  /* Fix alias if table name changes */
2454
2218
  if (strcmp(table->alias, alias))
2455
2219
  {
2456
 
    uint32_t length=(uint) strlen(alias)+1;
2457
 
    table->alias= (char*) my_realloc((char*) table->alias, length,
2458
 
                                     MYF(MY_WME));
 
2220
    uint32_t length=(uint32_t) strlen(alias)+1;
 
2221
    table->alias= (char*) realloc((char*) table->alias, length);
2459
2222
    memcpy((void*) table->alias, alias, length);
2460
2223
  }
2461
2224
  /* These variables are also set in reopen_table() */
2462
 
  table->tablenr=thd->current_tablenr++;
 
2225
  table->tablenr=session->current_tablenr++;
2463
2226
  table->used_fields=0;
2464
2227
  table->const_table=0;
2465
2228
  table->null_row= false;
2479
2242
}
2480
2243
 
2481
2244
 
2482
 
Table *find_locked_table(THD *thd, const char *db,const char *table_name)
 
2245
Table *find_locked_table(Session *session, const char *db,const char *table_name)
2483
2246
{
2484
 
  char  key[MAX_DBKEY_LENGTH];
2485
 
  uint32_t key_length=(uint) (my_stpcpy(my_stpcpy(key,db)+1,table_name)-key)+1;
2486
 
 
2487
 
  for (Table *table=thd->open_tables; table ; table=table->next)
 
2247
  char key[MAX_DBKEY_LENGTH];
 
2248
  char *key_pos= key;
 
2249
  uint32_t key_length;
 
2250
 
 
2251
  key_pos= strcpy(key_pos, db) + strlen(db);
 
2252
  key_pos= strcpy(key_pos+1, table_name) + strlen(table_name);
 
2253
  key_length= (uint32_t)(key_pos-key)+1;
 
2254
 
 
2255
  for (Table *table=session->open_tables; table ; table=table->next)
2488
2256
  {
2489
2257
    if (table->s->table_cache_key.length == key_length &&
2490
 
        !memcmp(table->s->table_cache_key.str, key, key_length))
 
2258
        !memcmp(table->s->table_cache_key.str, key, key_length))
2491
2259
      return table;
2492
2260
  }
2493
2261
  return(0);
2517
2285
  Field **field;
2518
2286
  uint32_t key,part;
2519
2287
  TableList table_list;
2520
 
  THD *thd= table->in_use;
 
2288
  Session *session= table->in_use;
2521
2289
 
2522
2290
  assert(table->s->ref_count == 0);
2523
2291
  assert(!table->sort.io_cache);
2524
2292
 
2525
2293
#ifdef EXTRA_DEBUG
2526
2294
  if (table->db_stat)
2527
 
    sql_print_error(_("Table %s had a open data handler in reopen_table"),
 
2295
    errmsg_printf(ERRMSG_LVL_ERROR, _("Table %s had a open data handler in reopen_table"),
2528
2296
                    table->alias);
2529
2297
#endif
2530
2298
  memset(&table_list, 0, sizeof(TableList));
2532
2300
  table_list.table_name= table->s->table_name.str;
2533
2301
  table_list.table=      table;
2534
2302
 
2535
 
  if (wait_for_locked_table_names(thd, &table_list))
 
2303
  if (wait_for_locked_table_names(session, &table_list))
2536
2304
    return(1);                             // Thread was killed
2537
2305
 
2538
 
  if (open_unireg_entry(thd, &tmp, &table_list,
 
2306
  if (open_unireg_entry(session, &tmp, &table_list,
2539
2307
                        table->alias,
2540
2308
                        table->s->table_cache_key.str,
2541
2309
                        table->s->table_cache_key.length))
2552
2320
  tmp.s->table_map_id=  table->s->table_map_id;
2553
2321
 
2554
2322
  /* Get state */
2555
 
  tmp.in_use=           thd;
 
2323
  tmp.in_use=           session;
2556
2324
  tmp.reginfo.lock_type=table->reginfo.lock_type;
2557
2325
 
2558
2326
  /* Replace table in open list */
2560
2328
  tmp.prev=             table->prev;
2561
2329
 
2562
2330
  if (table->file)
2563
 
    closefrm(table, 1);         // close file, free everything
 
2331
    table->closefrm(true);              // close file, free everything
2564
2332
 
2565
2333
  *table= tmp;
2566
2334
  table->default_column_bitmaps();
2595
2363
    Close all instances of a table open by this thread and replace
2596
2364
    them with exclusive name-locks.
2597
2365
 
2598
 
    @param thd        Thread context
 
2366
    @param session        Thread context
2599
2367
    @param db         Database name for the table to be closed
2600
2368
    @param table_name Name of the table to be closed
2601
2369
 
2608
2376
          the strings are used in a loop even after the share may be freed.
2609
2377
*/
2610
2378
 
2611
 
void close_data_files_and_morph_locks(THD *thd, const char *db,
 
2379
void close_data_files_and_morph_locks(Session *session, const char *db,
2612
2380
                                      const char *table_name)
2613
2381
{
2614
2382
  Table *table;
2615
2383
 
2616
2384
  safe_mutex_assert_owner(&LOCK_open);
2617
2385
 
2618
 
  if (thd->lock)
 
2386
  if (session->lock)
2619
2387
  {
2620
2388
    /*
2621
2389
      If we are not under LOCK TABLES we should have only one table
2622
2390
      open and locked so it makes sense to remove the lock at once.
2623
2391
    */
2624
 
    mysql_unlock_tables(thd, thd->lock);
2625
 
    thd->lock= 0;
 
2392
    mysql_unlock_tables(session, session->lock);
 
2393
    session->lock= 0;
2626
2394
  }
2627
2395
 
2628
2396
  /*
2630
2398
    for target table name if we process ALTER Table ... RENAME.
2631
2399
    So loop below makes sense even if we are not under LOCK TABLES.
2632
2400
  */
2633
 
  for (table=thd->open_tables; table ; table=table->next)
 
2401
  for (table=session->open_tables; table ; table=table->next)
2634
2402
  {
2635
2403
    if (!strcmp(table->s->table_name.str, table_name) &&
2636
2404
        !strcmp(table->s->db.str, db))
2637
2405
    {
2638
 
      if (thd->locked_tables)
 
2406
      if (session->locked_tables)
2639
2407
      {
2640
 
        mysql_lock_remove(thd, thd->locked_tables, table, true);
 
2408
        mysql_lock_remove(session, session->locked_tables, table, true);
2641
2409
      }
2642
2410
      table->open_placeholder= 1;
2643
2411
      close_handle_and_leave_table_as_lock(table);
2650
2418
/**
2651
2419
    Reopen all tables with closed data files.
2652
2420
 
2653
 
    @param thd         Thread context
 
2421
    @param session         Thread context
2654
2422
    @param get_locks   Should we get locks after reopening tables ?
2655
2423
    @param mark_share_as_old  Mark share as old to protect from a impending
2656
2424
                              global read lock.
2667
2435
    @return false in case of success, true - otherwise.
2668
2436
*/
2669
2437
 
2670
 
bool reopen_tables(THD *thd, bool get_locks, bool mark_share_as_old)
 
2438
bool reopen_tables(Session *session, bool get_locks, bool mark_share_as_old)
2671
2439
{
2672
2440
  Table *table,*next,**prev;
2673
2441
  Table **tables,**tables_ptr;                  // For locks
2676
2444
                    DRIZZLE_LOCK_IGNORE_GLOBAL_READ_LOCK |
2677
2445
                    DRIZZLE_LOCK_IGNORE_FLUSH;
2678
2446
 
2679
 
  if (!thd->open_tables)
 
2447
  if (!session->open_tables)
2680
2448
    return(0);
2681
2449
 
2682
2450
  safe_mutex_assert_owner(&LOCK_open);
2687
2455
      Do not handle locks of MERGE children.
2688
2456
    */
2689
2457
    uint32_t opens=0;
2690
 
    for (table= thd->open_tables; table ; table=table->next)
 
2458
    for (table= session->open_tables; table ; table=table->next)
2691
2459
      opens++;
2692
 
    tables= (Table**) my_alloca(sizeof(Table*)*opens);
 
2460
    tables= (Table**) malloc(sizeof(Table*)*opens);
2693
2461
  }
2694
2462
  else
2695
 
    tables= &thd->open_tables;
 
2463
    tables= &session->open_tables;
2696
2464
  tables_ptr =tables;
2697
2465
 
2698
 
  prev= &thd->open_tables;
2699
 
  for (table=thd->open_tables; table ; table=next)
 
2466
  prev= &session->open_tables;
 
2467
  for (table=session->open_tables; table ; table=next)
2700
2468
  {
2701
2469
    uint32_t db_stat=table->db_stat;
2702
2470
    next=table->next;
2729
2497
      wait_for_tables() as it tries to acquire LOCK_open, which is
2730
2498
      already locked.
2731
2499
    */
2732
 
    thd->some_tables_deleted=0;
2733
 
    if ((lock= mysql_lock_tables(thd, tables, (uint) (tables_ptr - tables),
 
2500
    session->some_tables_deleted=0;
 
2501
    if ((lock= mysql_lock_tables(session, tables, (uint32_t) (tables_ptr - tables),
2734
2502
                                 flags, &not_used)))
2735
2503
    {
2736
 
      thd->locked_tables=mysql_lock_merge(thd->locked_tables,lock);
 
2504
      session->locked_tables=mysql_lock_merge(session->locked_tables,lock);
2737
2505
    }
2738
2506
    else
2739
2507
    {
2748
2516
  }
2749
2517
  if (get_locks && tables)
2750
2518
  {
2751
 
    my_afree((unsigned char*) tables);
 
2519
    free((unsigned char*) tables);
2752
2520
  }
2753
2521
  broadcast_refresh();
2754
2522
  return(error);
2759
2527
    Close handlers for tables in list, but leave the Table structure
2760
2528
    intact so that we can re-open these quickly.
2761
2529
 
2762
 
    @param thd           Thread context
 
2530
    @param session           Thread context
2763
2531
    @param table         Head of the list of Table objects
2764
2532
    @param morph_locks   true  - remove locks which we have on tables being closed
2765
2533
                                 but ensure that no DML or DDL will sneak in before
2769
2537
    @param send_refresh  Should we awake waiters even if we didn't close any tables?
2770
2538
*/
2771
2539
 
2772
 
static void close_old_data_files(THD *thd, Table *table, bool morph_locks,
 
2540
static void close_old_data_files(Session *session, Table *table, bool morph_locks,
2773
2541
                                 bool send_refresh)
2774
2542
{
2775
2543
  bool found= send_refresh;
2795
2563
              lock on it. This will also give them a chance to close their
2796
2564
              instances of this table.
2797
2565
            */
2798
 
            mysql_lock_abort(thd, ulcktbl, true);
2799
 
            mysql_lock_remove(thd, thd->locked_tables, ulcktbl, true);
 
2566
            mysql_lock_abort(session, ulcktbl, true);
 
2567
            mysql_lock_remove(session, session->locked_tables, ulcktbl, true);
2800
2568
            ulcktbl->lock_count= 0;
2801
2569
          }
2802
2570
          if ((ulcktbl != table) && ulcktbl->db_stat)
2881
2649
 
2882
2650
/* Wait until all used tables are refreshed */
2883
2651
 
2884
 
bool wait_for_tables(THD *thd)
 
2652
bool wait_for_tables(Session *session)
2885
2653
{
2886
2654
  bool result;
2887
2655
 
2888
 
  thd_proc_info(thd, "Waiting for tables");
 
2656
  session->set_proc_info("Waiting for tables");
2889
2657
  pthread_mutex_lock(&LOCK_open);
2890
 
  while (!thd->killed)
 
2658
  while (!session->killed)
2891
2659
  {
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))
 
2660
    session->some_tables_deleted=0;
 
2661
    close_old_data_files(session,session->open_tables,0,dropping_tables != 0);
 
2662
    if (!table_is_used(session->open_tables,1))
2896
2663
      break;
2897
2664
    (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
2898
2665
  }
2899
 
  if (thd->killed)
 
2666
  if (session->killed)
2900
2667
    result= 1;                                  // aborted
2901
2668
  else
2902
2669
  {
2903
2670
    /* Now we can open all tables without any interference */
2904
 
    thd_proc_info(thd, "Reopen tables");
2905
 
    thd->version= refresh_version;
2906
 
    result=reopen_tables(thd,0,0);
 
2671
    session->set_proc_info("Reopen tables");
 
2672
    session->version= refresh_version;
 
2673
    result=reopen_tables(session,0,0);
2907
2674
  }
2908
2675
  pthread_mutex_unlock(&LOCK_open);
2909
 
  thd_proc_info(thd, 0);
 
2676
  session->set_proc_info(0);
2910
2677
  return(result);
2911
2678
}
2912
2679
 
2916
2683
 
2917
2684
  SYNOPSIS
2918
2685
    drop_locked_tables()
2919
 
    thd                 Thread thandler
 
2686
    session                     Thread thandler
2920
2687
    db                  Database
2921
2688
    table_name          Table name
2922
2689
 
2935
2702
*/
2936
2703
 
2937
2704
 
2938
 
Table *drop_locked_tables(THD *thd,const char *db, const char *table_name)
 
2705
Table *drop_locked_tables(Session *session,const char *db, const char *table_name)
2939
2706
{
2940
2707
  Table *table,*next,**prev, *found= 0;
2941
 
  prev= &thd->open_tables;
 
2708
  prev= &session->open_tables;
2942
2709
 
2943
2710
  /*
2944
2711
    Note that we need to hold LOCK_open while changing the
2947
2714
    Closing a MERGE child before the parent would be fatal if the
2948
2715
    other thread tries to abort the MERGE lock in between.
2949
2716
  */
2950
 
  for (table= thd->open_tables; table ; table=next)
 
2717
  for (table= session->open_tables; table ; table=next)
2951
2718
  {
2952
2719
    next=table->next;
2953
2720
    if (!strcmp(table->s->table_name.str, table_name) &&
2954
2721
        !strcmp(table->s->db.str, db))
2955
2722
    {
2956
 
      mysql_lock_remove(thd, thd->locked_tables, table, true);
 
2723
      mysql_lock_remove(session, session->locked_tables, table, true);
2957
2724
 
2958
2725
      if (!found)
2959
2726
      {
2980
2747
  *prev=0;
2981
2748
  if (found)
2982
2749
    broadcast_refresh();
2983
 
  if (thd->locked_tables && thd->locked_tables->table_count == 0)
 
2750
  if (session->locked_tables && session->locked_tables->table_count == 0)
2984
2751
  {
2985
 
    free((unsigned char*) thd->locked_tables);
2986
 
    thd->locked_tables=0;
 
2752
    free((unsigned char*) session->locked_tables);
 
2753
    session->locked_tables=0;
2987
2754
  }
2988
2755
  return(found);
2989
2756
}
2995
2762
  other threads trying to get the lock.
2996
2763
*/
2997
2764
 
2998
 
void abort_locked_tables(THD *thd,const char *db, const char *table_name)
 
2765
void abort_locked_tables(Session *session,const char *db, const char *table_name)
2999
2766
{
3000
2767
  Table *table;
3001
 
  for (table= thd->open_tables; table ; table= table->next)
 
2768
  for (table= session->open_tables; table ; table= table->next)
3002
2769
  {
3003
2770
    if (!strcmp(table->s->table_name.str, table_name) &&
3004
2771
        !strcmp(table->s->db.str, db))
3005
2772
    {
3006
2773
      /* If MERGE child, forward lock handling to parent. */
3007
 
      mysql_lock_abort(thd, table, true);
 
2774
      mysql_lock_abort(session, table, true);
3008
2775
      break;
3009
2776
    }
3010
2777
  }
3068
2835
 
3069
2836
  SYNOPSIS
3070
2837
    open_unireg_entry()
3071
 
    thd                 Thread handle
 
2838
    session                     Thread handle
3072
2839
    entry               Store open table definition here
3073
2840
    table_list          TableList with db, table_name
3074
2841
    alias               Alias name
3076
2843
    cache_key_length    length of cache_key
3077
2844
 
3078
2845
  NOTES
3079
 
   Extra argument for open is taken from thd->open_options
 
2846
   Extra argument for open is taken from session->open_options
3080
2847
   One must have a lock on LOCK_open when calling this function
3081
2848
 
3082
2849
  RETURN
3084
2851
    #   Error
3085
2852
*/
3086
2853
 
3087
 
static int open_unireg_entry(THD *thd, Table *entry, TableList *table_list,
 
2854
static int open_unireg_entry(Session *session, Table *entry, TableList *table_list,
3088
2855
                             const char *alias,
3089
2856
                             char *cache_key, uint32_t cache_key_length)
3090
2857
{
3094
2861
 
3095
2862
  safe_mutex_assert_owner(&LOCK_open);
3096
2863
retry:
3097
 
  if (!(share= get_table_share_with_create(thd, table_list, cache_key,
3098
 
                                           cache_key_length, 
 
2864
  if (!(share= get_table_share_with_create(session, table_list, cache_key,
 
2865
                                           cache_key_length,
3099
2866
                                           table_list->i_s_requested_object,
3100
2867
                                           &error)))
3101
2868
    return(1);
3102
2869
 
3103
 
  while ((error= open_table_from_share(thd, share, alias,
3104
 
                                       (uint) (HA_OPEN_KEYFILE |
 
2870
  while ((error= open_table_from_share(session, share, alias,
 
2871
                                       (uint32_t) (HA_OPEN_KEYFILE |
3105
2872
                                               HA_OPEN_RNDFILE |
3106
2873
                                               HA_GET_INDEX |
3107
2874
                                               HA_TRY_READ_ONLY),
3108
2875
                                       (EXTRA_RECORD),
3109
 
                                       thd->open_options, entry, OTM_OPEN)))
 
2876
                                       session->open_options, entry, OTM_OPEN)))
3110
2877
  {
3111
2878
    if (error == 7)                             // Table def changed
3112
2879
    {
3119
2886
        Here we should wait until all threads has released the table.
3120
2887
        For now we do one retry. This may cause a deadlock if there
3121
2888
        is other threads waiting for other tables used by this thread.
3122
 
        
 
2889
 
3123
2890
        Proper fix would be to if the second retry failed:
3124
2891
        - Mark that table def changed
3125
2892
        - Return from open table
3127
2894
        - Start waiting that the share is released
3128
2895
        - Retry by opening all tables again
3129
2896
      */
3130
 
      if (ha_create_table_from_engine(thd, table_list->db,
3131
 
                                      table_list->table_name))
3132
 
        goto err;
 
2897
 
3133
2898
      /*
3134
2899
        TO BE FIXED
3135
2900
        To avoid deadlock, only wait for release if no one else is
3139
2904
        goto err;
3140
2905
      /* Free share and wait until it's released by all threads */
3141
2906
      release_table_share(share, RELEASE_WAIT_FOR_DROP);
3142
 
      if (!thd->killed)
 
2907
      if (!session->killed)
3143
2908
      {
3144
 
        drizzle_reset_errors(thd, 1);         // Clear warnings
3145
 
        thd->clear_error();                 // Clear error message
 
2909
        drizzle_reset_errors(session, 1);         // Clear warnings
 
2910
        session->clear_error();                 // Clear error message
3146
2911
        goto retry;
3147
2912
      }
3148
2913
      return(1);
3150
2915
    if (!entry->s || !entry->s->crashed)
3151
2916
      goto err;
3152
2917
     // Code below is for repairing a crashed file
3153
 
     if ((error= lock_table_name(thd, table_list, true)))
 
2918
     if ((error= lock_table_name(session, table_list, true)))
3154
2919
     {
3155
2920
       if (error < 0)
3156
2921
        goto err;
3157
 
       if (wait_for_locked_table_names(thd, table_list))
 
2922
       if (wait_for_locked_table_names(session, table_list))
3158
2923
       {
3159
 
        unlock_table_name(thd, table_list);
 
2924
        unlock_table_name(session, table_list);
3160
2925
        goto err;
3161
2926
       }
3162
2927
     }
3163
2928
     pthread_mutex_unlock(&LOCK_open);
3164
 
     thd->clear_error();                                // Clear error message
 
2929
     session->clear_error();                            // Clear error message
3165
2930
     error= 0;
3166
 
     if (open_table_from_share(thd, share, alias,
3167
 
                               (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
 
2931
     if (open_table_from_share(session, share, alias,
 
2932
                               (uint32_t) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
3168
2933
                                       HA_GET_INDEX |
3169
2934
                                       HA_TRY_READ_ONLY),
3170
2935
                               EXTRA_RECORD,
3171
2936
                               ha_open_options | HA_OPEN_FOR_REPAIR,
3172
2937
                               entry, OTM_OPEN) || ! entry->file ||
3173
 
        (entry->file->is_crashed() && entry->file->ha_check_and_repair(thd)))
 
2938
        (entry->file->is_crashed() && entry->file->ha_check_and_repair(session)))
3174
2939
     {
3175
2940
       /* Give right error message */
3176
 
       thd->clear_error();
 
2941
       session->clear_error();
3177
2942
       my_error(ER_NOT_KEYFILE, MYF(0), share->table_name.str, my_errno);
3178
 
       sql_print_error(_("Couldn't repair table: %s.%s"), share->db.str,
 
2943
       errmsg_printf(ERRMSG_LVL_ERROR, _("Couldn't repair table: %s.%s"), share->db.str,
3179
2944
                       share->table_name.str);
3180
2945
       if (entry->file)
3181
 
        closefrm(entry, 0);
 
2946
        entry->closefrm(false);
3182
2947
       error=1;
3183
2948
     }
3184
2949
     else
3185
 
       thd->clear_error();                      // Clear error message
 
2950
       session->clear_error();                  // Clear error message
3186
2951
     pthread_mutex_lock(&LOCK_open);
3187
 
     unlock_table_name(thd, table_list);
3188
 
 
 
2952
     unlock_table_name(session, table_list);
 
2953
 
3189
2954
     if (error)
3190
2955
       goto err;
3191
2956
     break;
3198
2963
  if (unlikely(entry->file->implicit_emptied))
3199
2964
  {
3200
2965
    entry->file->implicit_emptied= 0;
3201
 
    if (mysql_bin_log.is_open())
3202
2966
    {
3203
2967
      char *query, *end;
3204
2968
      uint32_t query_buf_size= 20 + share->db.length + share->table_name.length +1;
3205
 
      if ((query= (char*) my_malloc(query_buf_size,MYF(MY_WME))))
 
2969
      if ((query= (char*) malloc(query_buf_size)))
3206
2970
      {
3207
 
        /* this DELETE FROM is needed even with row-based binlogging */
3208
 
        end = strxmov(my_stpcpy(query, "DELETE FROM `"),
3209
 
                      share->db.str,"`.`",share->table_name.str,"`", NULL);
3210
 
        thd->binlog_query(THD::STMT_QUERY_TYPE,
3211
 
                          query, (ulong)(end-query), false, false);
 
2971
        /* 
 
2972
          "this DELETE FROM is needed even with row-based binlogging"
 
2973
 
 
2974
          We inherited this from MySQL. TODO: fix it to issue a propper truncate
 
2975
          of the table (though that may not be completely right sematics).
 
2976
        */
 
2977
        end= query;
 
2978
        end+= sprintf(query, "DELETE FROM `%s`.`%s`", share->db.str,
 
2979
                      share->table_name.str);
 
2980
        (void)replicator_statement(session, query, (size_t)(end - query));
3212
2981
        free(query);
3213
2982
      }
3214
2983
      else
3215
2984
      {
3216
 
        /*
3217
 
          As replication is maybe going to be corrupted, we need to warn the
3218
 
          DBA on top of warning the client (which will automatically be done
3219
 
          because of MYF(MY_WME) in my_malloc() above).
3220
 
        */
3221
 
        sql_print_error(_("When opening HEAP table, could not allocate memory "
3222
 
                          "to write 'DELETE FROM `%s`.`%s`' to the binary log"),
3223
 
                        table_list->db, table_list->table_name);
3224
 
        closefrm(entry, 0);
 
2985
        errmsg_printf(ERRMSG_LVL_ERROR, _("When opening HEAP table, could not allocate memory "
 
2986
                                          "to write 'DELETE FROM `%s`.`%s`' to replication"),
 
2987
                      table_list->db, table_list->table_name);
 
2988
        my_error(ER_OUTOFMEMORY, MYF(0), query_buf_size);
 
2989
        entry->closefrm(false);
3225
2990
        goto err;
3226
2991
      }
3227
2992
    }
3239
3004
 
3240
3005
  SYNOPSIS
3241
3006
    open_tables()
3242
 
    thd - thread handler
 
3007
    session - thread handler
3243
3008
    start - list of tables in/out
3244
3009
    counter - number of opened tables will be return using this parameter
3245
3010
    flags   - bitmap of flags to modify how the tables will be open:
3262
3027
    -1 - error
3263
3028
*/
3264
3029
 
3265
 
int open_tables(THD *thd, TableList **start, uint32_t *counter, uint32_t flags)
 
3030
int open_tables(Session *session, TableList **start, uint32_t *counter, uint32_t flags)
3266
3031
{
3267
3032
  TableList *tables= NULL;
3268
3033
  bool refresh;
3277
3042
  */
3278
3043
  init_sql_alloc(&new_frm_mem, 8024, 8024);
3279
3044
 
3280
 
  thd->current_tablenr= 0;
 
3045
  session->current_tablenr= 0;
3281
3046
 restart:
3282
3047
  *counter= 0;
3283
 
  thd_proc_info(thd, "Opening tables");
 
3048
  session->set_proc_info("Opening tables");
3284
3049
 
3285
3050
  /*
3286
3051
    For every table in the list of tables to open, try to find or open
3308
3073
    */
3309
3074
    if (tables->schema_table)
3310
3075
    {
3311
 
      if (!mysql_schema_table(thd, thd->lex, tables))
 
3076
      if (!mysql_schema_table(session, session->lex, tables))
3312
3077
        continue;
3313
3078
      return(-1);
3314
3079
    }
3319
3084
      not opened yet. Try to open the table.
3320
3085
    */
3321
3086
    if (!tables->table)
3322
 
      tables->table= open_table(thd, tables, &refresh, flags);
 
3087
      tables->table= open_table(session, tables, &refresh, flags);
3323
3088
 
3324
3089
    if (!tables->table)
3325
3090
    {
3341
3106
          we pretend that we have finished calculation which we were doing
3342
3107
          currently.
3343
3108
        */
3344
 
        close_tables_for_reopen(thd, start);
 
3109
        close_tables_for_reopen(session, start);
3345
3110
        goto restart;
3346
3111
      }
3347
3112
 
3351
3116
      result= -1;                               // Fatal error
3352
3117
      break;
3353
3118
    }
3354
 
    if (tables->lock_type != TL_UNLOCK && ! thd->locked_tables)
 
3119
    if (tables->lock_type != TL_UNLOCK && ! session->locked_tables)
3355
3120
    {
3356
3121
      if (tables->lock_type == TL_WRITE_DEFAULT)
3357
 
        tables->table->reginfo.lock_type= thd->update_lock_default;
 
3122
        tables->table->reginfo.lock_type= session->update_lock_default;
3358
3123
      else if (tables->table->s->tmp_table == NO_TMP_TABLE)
3359
3124
        tables->table->reginfo.lock_type= tables->lock_type;
3360
3125
    }
3361
3126
  }
3362
3127
 
3363
 
  thd_proc_info(thd, 0);
 
3128
  session->set_proc_info(0);
3364
3129
  free_root(&new_frm_mem, MYF(0));              // Free pre-alloced block
3365
3130
 
3366
3131
  if (result && tables)
3367
3132
  {
3368
3133
    /*
3369
3134
      Some functions determine success as (tables->table != NULL).
3370
 
      tables->table is in thd->open_tables.
 
3135
      tables->table is in session->open_tables.
3371
3136
    */
3372
3137
    tables->table= NULL;
3373
3138
  }
3380
3145
 
3381
3146
  SYNOPSIS
3382
3147
    check_lock_and_start_stmt()
3383
 
    thd                 Thread handle
 
3148
    session                     Thread handle
3384
3149
    table_list          Table to check
3385
3150
    lock_type           Lock used for table
3386
3151
 
3389
3154
  1     error
3390
3155
*/
3391
3156
 
3392
 
static bool check_lock_and_start_stmt(THD *thd, Table *table,
 
3157
static bool check_lock_and_start_stmt(Session *session, Table *table,
3393
3158
                                      thr_lock_type lock_type)
3394
3159
{
3395
3160
  int error;
3400
3165
    my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0),table->alias);
3401
3166
    return(1);
3402
3167
  }
3403
 
  if ((error=table->file->start_stmt(thd, lock_type)))
 
3168
  if ((error=table->file->start_stmt(session, lock_type)))
3404
3169
  {
3405
3170
    table->file->print_error(error,MYF(0));
3406
3171
    return(1);
3412
3177
/**
3413
3178
  @brief Open and lock one table
3414
3179
 
3415
 
  @param[in]    thd             thread handle
 
3180
  @param[in]    session             thread handle
3416
3181
  @param[in]    table_l         table to open is first table in this list
3417
3182
  @param[in]    lock_type       lock to use for table
3418
3183
 
3439
3204
    and locking issues because it does not call lock_tables().
3440
3205
*/
3441
3206
 
3442
 
Table *open_n_lock_single_table(THD *thd, TableList *table_l,
 
3207
Table *open_n_lock_single_table(Session *session, TableList *table_l,
3443
3208
                                thr_lock_type lock_type)
3444
3209
{
3445
3210
  TableList *save_next_global;
3453
3218
  table_l->lock_type= lock_type;
3454
3219
 
3455
3220
  /* Open the table. */
3456
 
  if (simple_open_n_lock_tables(thd, table_l))
 
3221
  if (simple_open_n_lock_tables(session, table_l))
3457
3222
    table_l->table= NULL; /* Just to be sure. */
3458
3223
 
3459
3224
  /* Restore list. */
3468
3233
 
3469
3234
  SYNOPSIS
3470
3235
    open_ltable()
3471
 
    thd                 Thread handler
 
3236
    session                     Thread handler
3472
3237
    table_list          Table to open is first table in this list
3473
3238
    lock_type           Lock to use for open
3474
3239
    lock_flags          Flags passed to mysql_lock_table
3481
3246
  RETURN VALUES
3482
3247
    table               Opened table
3483
3248
    0                   Error
3484
 
  
 
3249
 
3485
3250
    If ok, the following are also set:
3486
3251
      table_list->lock_type     lock_type
3487
3252
      table_list->table         table
3488
3253
*/
3489
3254
 
3490
 
Table *open_ltable(THD *thd, TableList *table_list, thr_lock_type lock_type,
 
3255
Table *open_ltable(Session *session, TableList *table_list, thr_lock_type lock_type,
3491
3256
                   uint32_t lock_flags)
3492
3257
{
3493
3258
  Table *table;
3494
3259
  bool refresh;
3495
3260
 
3496
 
  thd_proc_info(thd, "Opening table");
3497
 
  thd->current_tablenr= 0;
3498
 
  while (!(table= open_table(thd, table_list, &refresh, 0)) &&
 
3261
  session->set_proc_info("Opening table");
 
3262
  session->current_tablenr= 0;
 
3263
  while (!(table= open_table(session, table_list, &refresh, 0)) &&
3499
3264
         refresh)
3500
3265
    ;
3501
3266
 
3503
3268
  {
3504
3269
    table_list->lock_type= lock_type;
3505
3270
    table_list->table=     table;
3506
 
    if (thd->locked_tables)
 
3271
    if (session->locked_tables)
3507
3272
    {
3508
 
      if (check_lock_and_start_stmt(thd, table, lock_type))
 
3273
      if (check_lock_and_start_stmt(session, table, lock_type))
3509
3274
        table= 0;
3510
3275
    }
3511
3276
    else
3512
3277
    {
3513
 
      assert(thd->lock == 0);   // You must lock everything at once
 
3278
      assert(session->lock == 0);       // You must lock everything at once
3514
3279
      if ((table->reginfo.lock_type= lock_type) != TL_UNLOCK)
3515
 
        if (! (thd->lock= mysql_lock_tables(thd, &table_list->table, 1,
 
3280
        if (! (session->lock= mysql_lock_tables(session, &table_list->table, 1,
3516
3281
                                            lock_flags, &refresh)))
3517
3282
          table= 0;
3518
3283
    }
3519
3284
  }
3520
3285
 
3521
 
  thd_proc_info(thd, 0);
 
3286
  session->set_proc_info(0);
3522
3287
  return(table);
3523
3288
}
3524
3289
 
3528
3293
 
3529
3294
  SYNOPSIS
3530
3295
    open_and_lock_tables_derived()
3531
 
    thd         - thread handler
 
3296
    session             - thread handler
3532
3297
    tables      - list of tables for open&locking
3533
3298
    derived     - if to handle derived tables
3534
3299
 
3541
3306
 
3542
3307
  NOTE
3543
3308
    There are two convenience functions:
3544
 
    - simple_open_n_lock_tables(thd, tables)  without derived handling
3545
 
    - open_and_lock_tables(thd, tables)       with derived handling
 
3309
    - simple_open_n_lock_tables(session, tables)  without derived handling
 
3310
    - open_and_lock_tables(session, tables)       with derived handling
3546
3311
    Both inline functions call open_and_lock_tables_derived() with
3547
3312
    the third argument set appropriately.
3548
3313
*/
3549
3314
 
3550
 
int open_and_lock_tables_derived(THD *thd, TableList *tables, bool derived)
 
3315
int open_and_lock_tables_derived(Session *session, TableList *tables, bool derived)
3551
3316
{
3552
3317
  uint32_t counter;
3553
3318
  bool need_reopen;
3554
3319
 
3555
 
  for ( ; ; ) 
 
3320
  for ( ; ; )
3556
3321
  {
3557
 
    if (open_tables(thd, &tables, &counter, 0))
 
3322
    if (open_tables(session, &tables, &counter, 0))
3558
3323
      return(-1);
3559
3324
 
3560
 
    if (!lock_tables(thd, tables, counter, &need_reopen))
 
3325
    if (!lock_tables(session, tables, counter, &need_reopen))
3561
3326
      break;
3562
3327
    if (!need_reopen)
3563
3328
      return(-1);
3564
 
    close_tables_for_reopen(thd, &tables);
 
3329
    close_tables_for_reopen(session, &tables);
3565
3330
  }
3566
3331
  if (derived &&
3567
 
      (mysql_handle_derived(thd->lex, &mysql_derived_prepare) ||
3568
 
       (thd->fill_derived_tables() &&
3569
 
        mysql_handle_derived(thd->lex, &mysql_derived_filling))))
 
3332
      (mysql_handle_derived(session->lex, &mysql_derived_prepare) ||
 
3333
       (session->fill_derived_tables() &&
 
3334
        mysql_handle_derived(session->lex, &mysql_derived_filling))))
3570
3335
    return(true); /* purecov: inspected */
3571
3336
  return(0);
3572
3337
}
3577
3342
 
3578
3343
  SYNOPSIS
3579
3344
    open_normal_and_derived_tables
3580
 
    thd         - thread handler
 
3345
    session             - thread handler
3581
3346
    tables      - list of tables for open
3582
3347
    flags       - bitmap of flags to modify how the tables will be open:
3583
3348
                  DRIZZLE_LOCK_IGNORE_FLUSH - open table even if someone has
3587
3352
    false - ok
3588
3353
    true  - error
3589
3354
 
3590
 
  NOTE 
 
3355
  NOTE
3591
3356
    This is to be used on prepare stage when you don't read any
3592
3357
    data from the tables.
3593
3358
*/
3594
3359
 
3595
 
bool open_normal_and_derived_tables(THD *thd, TableList *tables, uint32_t flags)
 
3360
bool open_normal_and_derived_tables(Session *session, TableList *tables, uint32_t flags)
3596
3361
{
3597
3362
  uint32_t counter;
3598
 
  assert(!thd->fill_derived_tables());
3599
 
  if (open_tables(thd, &tables, &counter, flags) ||
3600
 
      mysql_handle_derived(thd->lex, &mysql_derived_prepare))
 
3363
  assert(!session->fill_derived_tables());
 
3364
  if (open_tables(session, &tables, &counter, flags) ||
 
3365
      mysql_handle_derived(session->lex, &mysql_derived_prepare))
3601
3366
    return(true); /* purecov: inspected */
3602
3367
  return(0);
3603
3368
}
3604
3369
 
3605
 
 
3606
 
/**
3607
 
   Decide on logging format to use for the statement.
3608
 
 
3609
 
   Compute the capabilities vector for the involved storage engines
3610
 
   and mask out the flags for the binary log. Right now, the binlog
3611
 
   flags only include the capabilities of the storage engines, so this
3612
 
   is safe.
3613
 
 
3614
 
   We now have three alternatives that prevent the statement from
3615
 
   being loggable:
3616
 
 
3617
 
   1. If there are no capabilities left (all flags are clear) it is
3618
 
      not possible to log the statement at all, so we roll back the
3619
 
      statement and report an error.
3620
 
 
3621
 
   2. Statement mode is set, but the capabilities indicate that
3622
 
      statement format is not possible.
3623
 
 
3624
 
   3. Row mode is set, but the capabilities indicate that row
3625
 
      format is not possible.
3626
 
 
3627
 
   4. Statement is unsafe, but the capabilities indicate that row
3628
 
      format is not possible.
3629
 
 
3630
 
   If we are in MIXED mode, we then decide what logging format to use:
3631
 
 
3632
 
   1. If the statement is unsafe, row-based logging is used.
3633
 
 
3634
 
   2. If statement-based logging is not possible, row-based logging is
3635
 
      used.
3636
 
 
3637
 
   3. Otherwise, statement-based logging is used.
3638
 
 
3639
 
   @param thd    Client thread
3640
 
   @param tables Tables involved in the query
3641
 
 */
3642
 
 
3643
 
int decide_logging_format(THD *thd, TableList *tables)
3644
 
{
3645
 
  if (mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG))
3646
 
  {
3647
 
    handler::Table_flags flags_some_set= handler::Table_flags();
3648
 
    handler::Table_flags flags_all_set= ~handler::Table_flags();
3649
 
    bool multi_engine= false;
3650
 
    void* prev_ht= NULL;
3651
 
    for (TableList *table= tables; table; table= table->next_global)
3652
 
    {
3653
 
      if (!table->placeholder() && table->lock_type >= TL_WRITE_ALLOW_WRITE)
3654
 
      {
3655
 
        uint64_t const flags= table->table->file->ha_table_flags();
3656
 
        if (prev_ht && prev_ht != table->table->file->ht)
3657
 
          multi_engine= true;
3658
 
        prev_ht= table->table->file->ht;
3659
 
        flags_all_set &= flags;
3660
 
        flags_some_set |= flags;
3661
 
      }
3662
 
    }
3663
 
 
3664
 
    int error= 0;
3665
 
    if (flags_all_set == 0)
3666
 
    {
3667
 
      my_error((error= ER_BINLOG_LOGGING_IMPOSSIBLE), MYF(0),
3668
 
               "Statement cannot be logged to the binary log in"
3669
 
               " row-based nor statement-based format");
3670
 
    }
3671
 
    else if (thd->variables.binlog_format == BINLOG_FORMAT_STMT &&
3672
 
             (flags_all_set & HA_BINLOG_STMT_CAPABLE) == 0)
3673
 
    {
3674
 
      my_error((error= ER_BINLOG_LOGGING_IMPOSSIBLE), MYF(0),
3675
 
                "Statement-based format required for this statement,"
3676
 
                " but not allowed by this combination of engines");
3677
 
    }
3678
 
    else if ((thd->variables.binlog_format == BINLOG_FORMAT_ROW ||
3679
 
              thd->lex->is_stmt_unsafe()) &&
3680
 
             (flags_all_set & HA_BINLOG_ROW_CAPABLE) == 0)
3681
 
    {
3682
 
      my_error((error= ER_BINLOG_LOGGING_IMPOSSIBLE), MYF(0),
3683
 
                "Row-based format required for this statement,"
3684
 
                " but not allowed by this combination of engines");
3685
 
    }
3686
 
 
3687
 
    if (error)
3688
 
      return -1;
3689
 
 
3690
 
    /*
3691
 
      We switch to row-based format if we are in mixed mode and one of
3692
 
      the following are true:
3693
 
 
3694
 
      1. If the statement is unsafe
3695
 
      2. If statement format cannot be used
3696
 
 
3697
 
      Observe that point to cannot be decided before the tables
3698
 
      involved in a statement has been checked, i.e., we cannot put
3699
 
      this code in reset_current_stmt_binlog_row_based(), it has to be
3700
 
      here.
3701
 
    */
3702
 
    if (thd->lex->is_stmt_unsafe() ||
3703
 
        (flags_all_set & HA_BINLOG_STMT_CAPABLE) == 0)
3704
 
    {
3705
 
      thd->set_current_stmt_binlog_row_based_if_mixed();
3706
 
    }
3707
 
  }
3708
 
 
3709
 
  return 0;
3710
 
}
3711
 
 
3712
3370
/*
3713
3371
  Lock all tables in list
3714
3372
 
3715
3373
  SYNOPSIS
3716
3374
    lock_tables()
3717
 
    thd                 Thread handler
 
3375
    session                     Thread handler
3718
3376
    tables              Tables to lock
3719
3377
    count               Number of opened tables
3720
3378
    need_reopen         Out parameter which if true indicates that some
3730
3388
 
3731
3389
    If query for which we are calling this function marked as requring
3732
3390
    prelocking, this function will do implicit LOCK TABLES and change
3733
 
    thd::prelocked_mode accordingly.
 
3391
    session::prelocked_mode accordingly.
3734
3392
 
3735
3393
  RETURN VALUES
3736
3394
   0    ok
3737
3395
   -1   Error
3738
3396
*/
3739
3397
 
3740
 
int lock_tables(THD *thd, TableList *tables, uint32_t count, bool *need_reopen)
 
3398
int lock_tables(Session *session, TableList *tables, uint32_t count, bool *need_reopen)
3741
3399
{
3742
3400
  TableList *table;
3743
3401
 
3748
3406
  *need_reopen= false;
3749
3407
 
3750
3408
  if (!tables)
3751
 
    return(decide_logging_format(thd, tables));
 
3409
    return 0;
3752
3410
 
3753
 
  if (!thd->locked_tables)
 
3411
  if (!session->locked_tables)
3754
3412
  {
3755
 
    assert(thd->lock == 0);     // You must lock everything at once
 
3413
    assert(session->lock == 0); // You must lock everything at once
3756
3414
    Table **start,**ptr;
3757
3415
    uint32_t lock_flag= DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN;
3758
3416
 
3759
 
    if (!(ptr=start=(Table**) thd->alloc(sizeof(Table*)*count)))
 
3417
    if (!(ptr=start=(Table**) session->alloc(sizeof(Table*)*count)))
3760
3418
      return(-1);
3761
3419
    for (table= tables; table; table= table->next_global)
3762
3420
    {
3764
3422
        *(ptr++)= table->table;
3765
3423
    }
3766
3424
 
3767
 
    if (!(thd->lock= mysql_lock_tables(thd, start, (uint) (ptr - start),
 
3425
    if (!(session->lock= mysql_lock_tables(session, start, (uint32_t) (ptr - start),
3768
3426
                                       lock_flag, need_reopen)))
3769
3427
    {
3770
3428
      return(-1);
3772
3430
  }
3773
3431
  else
3774
3432
  {
3775
 
    TableList *first_not_own= thd->lex->first_not_own_table();
 
3433
    TableList *first_not_own= session->lex->first_not_own_table();
3776
3434
    /*
3777
3435
      When open_and_lock_tables() is called for a single table out of
3778
3436
      a table list, the 'next_global' chain is temporarily broken. We
3786
3444
         table= table->next_global)
3787
3445
    {
3788
3446
      if (!table->placeholder() &&
3789
 
          check_lock_and_start_stmt(thd, table->table, table->lock_type))
 
3447
          check_lock_and_start_stmt(session, table->table, table->lock_type))
3790
3448
      {
3791
3449
        return(-1);
3792
3450
      }
3793
3451
    }
3794
3452
  }
3795
3453
 
3796
 
  return(decide_logging_format(thd, tables));
 
3454
  return 0;
3797
3455
}
3798
3456
 
3799
3457
 
3803
3461
 
3804
3462
  SYNOPSIS
3805
3463
    close_tables_for_reopen()
3806
 
      thd    in     Thread context
 
3464
      session    in     Thread context
3807
3465
      tables in/out List of tables which we were trying to open and lock
3808
3466
 
3809
3467
*/
3810
3468
 
3811
 
void close_tables_for_reopen(THD *thd, TableList **tables)
 
3469
void close_tables_for_reopen(Session *session, TableList **tables)
3812
3470
{
3813
3471
  /*
3814
3472
    If table list consists only from tables from prelocking set, table list
3815
3473
    for new attempt should be empty, so we have to update list's root pointer.
3816
3474
  */
3817
 
  if (thd->lex->first_not_own_table() == *tables)
 
3475
  if (session->lex->first_not_own_table() == *tables)
3818
3476
    *tables= 0;
3819
 
  thd->lex->chop_off_not_own_tables();
 
3477
  session->lex->chop_off_not_own_tables();
3820
3478
  for (TableList *tmp= *tables; tmp; tmp= tmp->next_global)
3821
3479
    tmp->table= 0;
3822
 
  close_thread_tables(thd);
 
3480
  close_thread_tables(session);
3823
3481
}
3824
3482
 
3825
3483
 
3828
3486
 
3829
3487
  SYNPOSIS
3830
3488
    open_temporary_table()
3831
 
    thd           Thread object
 
3489
    session               Thread object
3832
3490
    path          Path (without .frm)
3833
3491
    db            database
3834
3492
    table_name    Table name
3835
 
    link_in_list  1 if table should be linked into thd->temporary_tables
 
3493
    link_in_list  1 if table should be linked into session->temporary_tables
3836
3494
 
3837
3495
 NOTES:
3838
3496
    Used by alter_table to open a temporary table and when creating
3843
3501
   #  Table object
3844
3502
*/
3845
3503
 
3846
 
Table *open_temporary_table(THD *thd, const char *path, const char *db,
 
3504
Table *open_temporary_table(Session *session, const char *path, const char *db,
3847
3505
                            const char *table_name, bool link_in_list,
3848
3506
                            open_table_mode open_mode)
3849
3507
{
3850
3508
  Table *tmp_table;
3851
3509
  TABLE_SHARE *share;
3852
3510
  char cache_key[MAX_DBKEY_LENGTH], *saved_cache_key, *tmp_path;
3853
 
  uint32_t key_length;
 
3511
  uint32_t key_length, path_length;
3854
3512
  TableList table_list;
3855
3513
 
3856
3514
  table_list.db=         (char*) db;
3857
3515
  table_list.table_name= (char*) table_name;
3858
3516
  /* Create the cache_key for temporary tables */
3859
 
  key_length= create_table_def_key(thd, cache_key, &table_list, 1);
 
3517
  key_length= create_table_def_key(session, cache_key, &table_list, 1);
 
3518
  path_length= strlen(path);
3860
3519
 
3861
 
  if (!(tmp_table= (Table*) my_malloc(sizeof(*tmp_table) + sizeof(*share) +
3862
 
                                      strlen(path)+1 + key_length,
3863
 
                                      MYF(MY_WME))))
3864
 
    return(0);                          /* purecov: inspected */
 
3520
  if (!(tmp_table= (Table*) malloc(sizeof(*tmp_table) + sizeof(*share) +
 
3521
                                   path_length + 1 + key_length)))
 
3522
    return NULL;
3865
3523
 
3866
3524
  share= (TABLE_SHARE*) (tmp_table+1);
3867
3525
  tmp_path= (char*) (share+1);
3868
 
  saved_cache_key= my_stpcpy(tmp_path, path)+1;
 
3526
  saved_cache_key= strcpy(tmp_path, path)+path_length+1;
3869
3527
  memcpy(saved_cache_key, cache_key, key_length);
3870
3528
 
3871
 
  init_tmp_table_share(thd, share, saved_cache_key, key_length,
 
3529
  init_tmp_table_share(session, share, saved_cache_key, key_length,
3872
3530
                       strchr(saved_cache_key, '\0')+1, tmp_path);
3873
3531
 
3874
 
  if (open_table_def(thd, share, 0) ||
3875
 
      open_table_from_share(thd, share, table_name,
 
3532
  if (open_table_def(session, share, 0) ||
 
3533
      open_table_from_share(session, share, table_name,
3876
3534
                            (open_mode == OTM_ALTER) ? 0 :
3877
 
                            (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
 
3535
                            (uint32_t) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
3878
3536
                                    HA_GET_INDEX),
3879
3537
                            (open_mode == OTM_ALTER) ?
3880
3538
                              (EXTRA_RECORD | OPEN_FRM_FILE_ONLY)
3904
3562
  if (link_in_list)
3905
3563
  {
3906
3564
    /* growing temp list at the head */
3907
 
    tmp_table->next= thd->temporary_tables;
 
3565
    tmp_table->next= session->temporary_tables;
3908
3566
    if (tmp_table->next)
3909
3567
      tmp_table->next->prev= tmp_table;
3910
 
    thd->temporary_tables= tmp_table;
3911
 
    thd->temporary_tables->prev= 0;
3912
 
    if (thd->slave_thread)
3913
 
      slave_open_temp_tables++;
 
3568
    session->temporary_tables= tmp_table;
 
3569
    session->temporary_tables->prev= 0;
3914
3570
  }
3915
3571
  tmp_table->pos_in_table_list= 0;
3916
3572
  return(tmp_table);
3917
3573
}
3918
3574
 
3919
3575
 
3920
 
bool rm_temporary_table(handlerton *base, char *path, bool frm_only)
 
3576
bool rm_temporary_table(StorageEngine *base, char *path)
3921
3577
{
3922
3578
  bool error=0;
3923
3579
  handler *file;
3924
 
  char *ext;
3925
3580
 
3926
 
  my_stpcpy(ext= strchr(path, '\0'), reg_ext);
3927
 
  if (my_delete(path,MYF(0)))
 
3581
  if(delete_table_proto_file(path))
3928
3582
    error=1; /* purecov: inspected */
3929
 
  *ext= 0;                              // remove extension
3930
 
  file= get_new_handler((TABLE_SHARE*) 0, current_thd->mem_root, base);
3931
 
  if (!frm_only && file && file->ha_delete_table(path))
 
3583
 
 
3584
  file= get_new_handler((TABLE_SHARE*) 0, current_session->mem_root, base);
 
3585
  if (file && file->ha_delete_table(path))
3932
3586
  {
3933
3587
    error=1;
3934
 
    sql_print_warning(_("Could not remove temporary table: '%s', error: %d"),
 
3588
    errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
3935
3589
                      path, my_errno);
3936
3590
  }
3937
3591
  delete file;
3950
3604
 
3951
3605
/* Special Field pointers as return values of find_field_in_XXX functions. */
3952
3606
Field *not_found_field= (Field*) 0x1;
3953
 
Field *view_ref_found= (Field*) 0x2; 
 
3607
Field *view_ref_found= (Field*) 0x2;
3954
3608
 
3955
3609
#define WRONG_GRANT (Field*) -1
3956
3610
 
3957
 
static void update_field_dependencies(THD *thd, Field *field, Table *table)
 
3611
static void update_field_dependencies(Session *session, Field *field, Table *table)
3958
3612
{
3959
 
  if (thd->mark_used_columns != MARK_COLUMNS_NONE)
 
3613
  if (session->mark_used_columns != MARK_COLUMNS_NONE)
3960
3614
  {
3961
3615
    MY_BITMAP *current_bitmap, *other_bitmap;
3962
3616
 
3964
3618
      We always want to register the used keys, as the column bitmap may have
3965
3619
      been set for all fields (for example for view).
3966
3620
    */
3967
 
      
 
3621
 
3968
3622
    table->covering_keys.intersect(field->part_of_key);
3969
3623
    table->merge_keys.merge(field->part_of_key);
3970
3624
 
3971
 
    if (thd->mark_used_columns == MARK_COLUMNS_READ)
 
3625
    if (session->mark_used_columns == MARK_COLUMNS_READ)
3972
3626
    {
3973
3627
      current_bitmap= table->read_set;
3974
3628
      other_bitmap=   table->write_set;
3981
3635
 
3982
3636
    if (bitmap_fast_test_and_set(current_bitmap, field->field_index))
3983
3637
    {
3984
 
      if (thd->mark_used_columns == MARK_COLUMNS_WRITE)
3985
 
        thd->dup_field= field;
 
3638
      if (session->mark_used_columns == MARK_COLUMNS_WRITE)
 
3639
        session->dup_field= field;
3986
3640
      return;
3987
3641
    }
3988
3642
    if (table->get_fields_in_item_tree)
4000
3654
 
4001
3655
  SYNOPSIS
4002
3656
    find_field_in_natural_join()
4003
 
    thd                  [in]  thread handler
 
3657
    session                      [in]  thread handler
4004
3658
    table_ref            [in]  table reference to search
4005
3659
    name                 [in]  name of field
4006
3660
    length               [in]  length of name
4025
3679
*/
4026
3680
 
4027
3681
static Field *
4028
 
find_field_in_natural_join(THD *thd, TableList *table_ref, const char *name,
4029
 
                           uint32_t length __attribute__((unused)),
4030
 
                           Item **ref __attribute__((unused)), bool register_tree_change __attribute__((unused)),
4031
 
                           TableList **actual_table)
 
3682
find_field_in_natural_join(Session *session, TableList *table_ref,
 
3683
                           const char *name, uint32_t , Item **,
 
3684
                           bool, TableList **actual_table)
4032
3685
{
4033
3686
  List_iterator_fast<Natural_join_column>
4034
3687
    field_it(*(table_ref->join_columns));
4038
3691
  assert(table_ref->is_natural_join && table_ref->join_columns);
4039
3692
  assert(*actual_table == NULL);
4040
3693
 
4041
 
  for (nj_col= NULL, curr_nj_col= field_it++; curr_nj_col; 
 
3694
  for (nj_col= NULL, curr_nj_col= field_it++; curr_nj_col;
4042
3695
       curr_nj_col= field_it++)
4043
3696
  {
4044
3697
    if (!my_strcasecmp(system_charset_info, curr_nj_col->name(), name))
4045
3698
    {
4046
3699
      if (nj_col)
4047
3700
      {
4048
 
        my_error(ER_NON_UNIQ_ERROR, MYF(0), name, thd->where);
 
3701
        my_error(ER_NON_UNIQ_ERROR, MYF(0), name, session->where);
4049
3702
        return(NULL);
4050
3703
      }
4051
3704
      nj_col= curr_nj_col;
4057
3710
    /* This is a base table. */
4058
3711
    assert(nj_col->table_ref->table == nj_col->table_field->table);
4059
3712
    found_field= nj_col->table_field;
4060
 
    update_field_dependencies(thd, found_field, nj_col->table_ref->table);
 
3713
    update_field_dependencies(session, found_field, nj_col->table_ref->table);
4061
3714
  }
4062
3715
 
4063
3716
  *actual_table= nj_col->table_ref;
4064
 
  
 
3717
 
4065
3718
  return(found_field);
4066
3719
}
4067
3720
 
4071
3724
 
4072
3725
  SYNOPSIS
4073
3726
    find_field_in_table()
4074
 
    thd                         thread handler
 
3727
    session                             thread handler
4075
3728
    table                       table where to search for the field
4076
3729
    name                        name of field
4077
3730
    length                      length of name
4085
3738
*/
4086
3739
 
4087
3740
Field *
4088
 
find_field_in_table(THD *thd, Table *table, const char *name, uint32_t length,
 
3741
find_field_in_table(Session *session, Table *table, const char *name, uint32_t length,
4089
3742
                    bool allow_rowid, uint32_t *cached_field_index_ptr)
4090
3743
{
4091
3744
  Field **field_ptr, *field;
4120
3773
 
4121
3774
  if (field_ptr && *field_ptr)
4122
3775
  {
 
3776
    if ((*field_ptr)->vcol_info)
 
3777
    {
 
3778
      if (session->mark_used_columns != MARK_COLUMNS_NONE)
 
3779
      {
 
3780
        Item *vcol_item= (*field_ptr)->vcol_info->expr_item;
 
3781
        assert(vcol_item);
 
3782
        vcol_item->walk(&Item::register_field_in_read_map, 1, (unsigned char *) 0);
 
3783
        /*
 
3784
          Set the virtual field for write here if
 
3785
          1) this procedure is called for a read-only operation (SELECT), and
 
3786
          2) the virtual column is not phycically stored in the table
 
3787
        */
 
3788
        if ((session->mark_used_columns != MARK_COLUMNS_WRITE) &&
 
3789
            (not (*field_ptr)->is_stored))
 
3790
          bitmap_set_bit((*field_ptr)->table->write_set, (*field_ptr)->field_index);
 
3791
      }
 
3792
    }
4123
3793
    *cached_field_index_ptr= field_ptr - table->field;
4124
3794
    field= *field_ptr;
4125
3795
  }
4132
3802
    field= table->field[table->s->rowid_field_offset-1];
4133
3803
  }
4134
3804
 
4135
 
  update_field_dependencies(thd, field, table);
 
3805
  update_field_dependencies(session, field, table);
4136
3806
 
4137
3807
  return(field);
4138
3808
}
4143
3813
 
4144
3814
  SYNOPSIS
4145
3815
    find_field_in_table_ref()
4146
 
    thd                    [in]  thread handler
 
3816
    session                        [in]  thread handler
4147
3817
    table_list             [in]  table reference to search
4148
3818
    name                   [in]  name of field
4149
3819
    length                 [in]  field length of name
4181
3851
*/
4182
3852
 
4183
3853
Field *
4184
 
find_field_in_table_ref(THD *thd, TableList *table_list,
 
3854
find_field_in_table_ref(Session *session, TableList *table_list,
4185
3855
                        const char *name, uint32_t length,
4186
3856
                        const char *item_name, const char *db_name,
4187
3857
                        const char *table_name, Item **ref,
4213
3883
          something !
4214
3884
  */
4215
3885
  if (/* Exclude nested joins. */
4216
 
      (!table_list->nested_join ||
 
3886
      (!table_list->nested_join) &&
4217
3887
       /* Include merge views and information schema tables. */
4218
 
       table_list->field_translation) &&
4219
3888
      /*
4220
3889
        Test if the field qualifiers match the table reference we plan
4221
3890
        to search.
4228
3897
 
4229
3898
  *actual_table= NULL;
4230
3899
 
4231
 
  if (table_list->field_translation)
4232
 
  {
4233
 
  }
4234
 
  else if (!table_list->nested_join)
 
3900
  if (!table_list->nested_join)
4235
3901
  {
4236
3902
    /* 'table_list' is a stored table. */
4237
3903
    assert(table_list->table);
4238
 
    if ((fld= find_field_in_table(thd, table_list->table, name, length,
 
3904
    if ((fld= find_field_in_table(session, table_list->table, name, length,
4239
3905
                                  allow_rowid,
4240
3906
                                  cached_field_index_ptr)))
4241
3907
      *actual_table= table_list;
4255
3921
      TableList *table;
4256
3922
      while ((table= it++))
4257
3923
      {
4258
 
        if ((fld= find_field_in_table_ref(thd, table, name, length, item_name,
 
3924
        if ((fld= find_field_in_table_ref(session, table, name, length, item_name,
4259
3925
                                          db_name, table_name, ref,
4260
3926
                                          check_privileges, allow_rowid,
4261
3927
                                          cached_field_index_ptr,
4270
3936
      natural join, thus if the field is not qualified, we will search
4271
3937
      directly the top-most NATURAL/USING join.
4272
3938
    */
4273
 
    fld= find_field_in_natural_join(thd, table_list, name, length, ref,
 
3939
    fld= find_field_in_natural_join(session, table_list, name, length, ref,
4274
3940
                                    register_tree_change, actual_table);
4275
3941
  }
4276
3942
 
4277
3943
  if (fld)
4278
3944
  {
4279
 
      if (thd->mark_used_columns != MARK_COLUMNS_NONE)
 
3945
      if (session->mark_used_columns != MARK_COLUMNS_NONE)
4280
3946
      {
4281
3947
        /*
4282
3948
          Get rw_set correct for this field so that the handler
4291
3957
            field_to_set= ((Item_field*)it)->field;
4292
3958
          else
4293
3959
          {
4294
 
            if (thd->mark_used_columns == MARK_COLUMNS_READ)
 
3960
            if (session->mark_used_columns == MARK_COLUMNS_READ)
4295
3961
              it->walk(&Item::register_field_in_read_map, 1, (unsigned char *) 0);
4296
3962
          }
4297
3963
        }
4300
3966
        if (field_to_set)
4301
3967
        {
4302
3968
          Table *table= field_to_set->table;
4303
 
          if (thd->mark_used_columns == MARK_COLUMNS_READ)
 
3969
          if (session->mark_used_columns == MARK_COLUMNS_READ)
4304
3970
            bitmap_set_bit(table->read_set, field_to_set->field_index);
4305
3971
          else
4306
3972
            bitmap_set_bit(table->write_set, field_to_set->field_index);
4362
4028
 
4363
4029
  SYNOPSIS
4364
4030
    find_field_in_tables()
4365
 
    thd                   pointer to current thread structure
 
4031
    session                       pointer to current thread structure
4366
4032
    item                  field item that should be found
4367
4033
    first_table           list of tables to be searched for item
4368
4034
    last_table            end of the list of tables to search for item. If NULL
4392
4058
*/
4393
4059
 
4394
4060
Field *
4395
 
find_field_in_tables(THD *thd, Item_ident *item,
 
4061
find_field_in_tables(Session *session, Item_ident *item,
4396
4062
                     TableList *first_table, TableList *last_table,
4397
4063
                     Item **ref, find_item_error_report_type report_error,
4398
4064
                     bool check_privileges, bool register_tree_change)
4401
4067
  const char *db= item->db_name;
4402
4068
  const char *table_name= item->table_name;
4403
4069
  const char *name= item->field_name;
4404
 
  uint32_t length=(uint) strlen(name);
 
4070
  uint32_t length=(uint32_t) strlen(name);
4405
4071
  char name_buff[NAME_LEN+1];
4406
4072
  TableList *cur_table= first_table;
4407
4073
  TableList *actual_table;
4433
4099
      when table_ref->field_translation != NULL.
4434
4100
      */
4435
4101
    if (table_ref->table)
4436
 
      found= find_field_in_table(thd, table_ref->table, name, length,
 
4102
      found= find_field_in_table(session, table_ref->table, name, length,
4437
4103
                                 true, &(item->cached_field_index));
4438
4104
    else
4439
 
      found= find_field_in_table_ref(thd, table_ref, name, length, item->name,
 
4105
      found= find_field_in_table_ref(session, table_ref, name, length, item->name,
4440
4106
                                     NULL, NULL, ref, check_privileges,
4441
4107
                                     true, &(item->cached_field_index),
4442
4108
                                     register_tree_change,
4451
4117
        fields.
4452
4118
      */
4453
4119
      {
4454
 
        SELECT_LEX *current_sel= thd->lex->current_select;
4455
 
        SELECT_LEX *last_select= table_ref->select_lex;
 
4120
        Select_Lex *current_sel= session->lex->current_select;
 
4121
        Select_Lex *last_select= table_ref->select_lex;
4456
4122
        /*
4457
4123
          If the field was an outer referencee, mark all selects using this
4458
4124
          sub query as dependent on the outer query
4459
4125
        */
4460
4126
        if (current_sel != last_select)
4461
 
          mark_select_range_as_dependent(thd, last_select, current_sel,
 
4127
          mark_select_range_as_dependent(session, last_select, current_sel,
4462
4128
                                         found, *ref, item);
4463
4129
      }
4464
4130
      return found;
4472
4138
      We can't do this in Item_field as this would change the
4473
4139
      'name' of the item which may be used in the select list
4474
4140
    */
4475
 
    strmake(name_buff, db, sizeof(name_buff)-1);
 
4141
    strncpy(name_buff, db, sizeof(name_buff)-1);
4476
4142
    my_casedn_str(files_charset_info, name_buff);
4477
4143
    db= name_buff;
4478
4144
  }
4483
4149
  for (; cur_table != last_table ;
4484
4150
       cur_table= cur_table->next_name_resolution_table)
4485
4151
  {
4486
 
    Field *cur_field= find_field_in_table_ref(thd, cur_table, name, length,
 
4152
    Field *cur_field= find_field_in_table_ref(session, cur_table, name, length,
4487
4153
                                              item->name, db, table_name, ref,
4488
 
                                              (thd->lex->sql_command ==
 
4154
                                              (session->lex->sql_command ==
4489
4155
                                               SQLCOM_SHOW_FIELDS)
4490
4156
                                              ? false : check_privileges,
4491
4157
                                              allow_rowid,
4496
4162
    {
4497
4163
      if (cur_field == WRONG_GRANT)
4498
4164
      {
4499
 
        if (thd->lex->sql_command != SQLCOM_SHOW_FIELDS)
 
4165
        if (session->lex->sql_command != SQLCOM_SHOW_FIELDS)
4500
4166
          return (Field*) 0;
4501
4167
 
4502
 
        thd->clear_error();
4503
 
        cur_field= find_field_in_table_ref(thd, cur_table, name, length,
 
4168
        session->clear_error();
 
4169
        cur_field= find_field_in_table_ref(session, cur_table, name, length,
4504
4170
                                           item->name, db, table_name, ref,
4505
4171
                                           false,
4506
4172
                                           allow_rowid,
4524
4190
      item->cached_table= (!actual_table->cacheable_table || found) ?
4525
4191
                          0 : actual_table;
4526
4192
 
4527
 
      assert(thd->where);
 
4193
      assert(session->where);
4528
4194
      /*
4529
4195
        If we found a fully qualified field we return it directly as it can't
4530
4196
        have duplicates.
4537
4203
        if (report_error == REPORT_ALL_ERRORS ||
4538
4204
            report_error == IGNORE_EXCEPT_NON_UNIQUE)
4539
4205
          my_error(ER_NON_UNIQ_ERROR, MYF(0),
4540
 
                   table_name ? item->full_name() : name, thd->where);
 
4206
                   table_name ? item->full_name() : name, session->where);
4541
4207
        return (Field*) 0;
4542
4208
      }
4543
4209
      found= cur_field;
4561
4227
    char buff[NAME_LEN*2+1];
4562
4228
    if (db && db[0])
4563
4229
    {
4564
 
      strxnmov(buff,sizeof(buff)-1,db,".",table_name,NULL);
 
4230
      /* We're in an error condition, two extra strlen's aren't going
 
4231
       * to kill us */
 
4232
      assert(strlen(db) <= NAME_LEN);
 
4233
      assert(strlen(table_name) <= NAME_LEN);
 
4234
      strcpy(buff, db);
 
4235
      strcat(buff,".");
 
4236
      strcat(buff, table_name);
4565
4237
      table_name=buff;
4566
4238
    }
4567
 
    my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, thd->where);
 
4239
    my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, session->where);
4568
4240
  }
4569
4241
  else
4570
4242
  {
4571
4243
    if (report_error == REPORT_ALL_ERRORS ||
4572
4244
        report_error == REPORT_EXCEPT_NON_UNIQUE)
4573
 
      my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), thd->where);
 
4245
      my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), session->where);
4574
4246
    else
4575
4247
      found= not_found_field;
4576
4248
  }
4595
4267
                                return not_found_item, report other errors,
4596
4268
                                return 0
4597
4269
      IGNORE_ERRORS             Do not report errors, return 0 if error
4598
 
    resolution                  Set to the resolution type if the item is found 
4599
 
                                (it says whether the item is resolved 
 
4270
    resolution                  Set to the resolution type if the item is found
 
4271
                                (it says whether the item is resolved
4600
4272
                                 against an alias name,
4601
4273
                                 or as a field name without alias,
4602
4274
                                 or as a field hidden by alias,
4603
4275
                                 or ignoring alias)
4604
 
                                
 
4276
 
4605
4277
  RETURN VALUES
4606
4278
    0                   Item is not found or item is not unique,
4607
4279
                        error message is reported
4635
4307
 
4636
4308
  *resolution= NOT_RESOLVED;
4637
4309
 
4638
 
  is_ref_by_name= (find->type() == Item::FIELD_ITEM  || 
 
4310
  is_ref_by_name= (find->type() == Item::FIELD_ITEM  ||
4639
4311
                   find->type() == Item::REF_ITEM);
4640
4312
  if (is_ref_by_name)
4641
4313
  {
4652
4324
 
4653
4325
      /*
4654
4326
        In case of group_concat() with ORDER BY condition in the QUERY
4655
 
        item_field can be field of temporary table without item name 
 
4327
        item_field can be field of temporary table without item name
4656
4328
        (if this field created from expression argument of group_concat()),
4657
4329
        => we have to check presence of name before compare
4658
 
      */ 
 
4330
      */
4659
4331
      if (!item_field->name)
4660
4332
        continue;
4661
4333
 
4680
4352
        if (item_field->field_name && item_field->table_name &&
4681
4353
            !my_strcasecmp(system_charset_info, item_field->field_name,
4682
4354
                           field_name) &&
4683
 
            !my_strcasecmp(table_alias_charset, item_field->table_name, 
 
4355
            !my_strcasecmp(table_alias_charset, item_field->table_name,
4684
4356
                           table_name) &&
4685
4357
            (!db_name || (item_field->db_name &&
4686
4358
                          !strcmp(item_field->db_name, db_name))))
4696
4368
            */
4697
4369
            if (report_error != IGNORE_ERRORS)
4698
4370
              my_error(ER_NON_UNIQ_ERROR, MYF(0),
4699
 
                       find->full_name(), current_thd->where);
 
4371
                       find->full_name(), current_session->where);
4700
4372
            return (Item**) 0;
4701
4373
          }
4702
4374
          found_unaliased= li.ref();
4727
4399
              continue;                           // Same field twice
4728
4400
            if (report_error != IGNORE_ERRORS)
4729
4401
              my_error(ER_NON_UNIQ_ERROR, MYF(0),
4730
 
                       find->full_name(), current_thd->where);
 
4402
                       find->full_name(), current_session->where);
4731
4403
            return (Item**) 0;
4732
4404
          }
4733
4405
          found= li.ref();
4755
4427
      }
4756
4428
    }
4757
4429
    else if (!table_name)
4758
 
    { 
 
4430
    {
4759
4431
      if (is_ref_by_name && find->name && item->name &&
4760
4432
          !my_strcasecmp(system_charset_info,item->name,find->name))
4761
4433
      {
4772
4444
        break;
4773
4445
      }
4774
4446
    }
4775
 
    else if (table_name && item->type() == Item::REF_ITEM &&
4776
 
             ((Item_ref *)item)->ref_type() == Item_ref::VIEW_REF)
4777
 
    {
4778
 
      /*
4779
 
        TODO:Here we process prefixed view references only. What we should 
4780
 
        really do is process all types of Item_refs. But this will currently 
4781
 
        lead to a clash with the way references to outer SELECTs (from the 
4782
 
        HAVING clause) are handled in e.g. :
4783
 
        SELECT 1 FROM t1 AS t1_o GROUP BY a
4784
 
          HAVING (SELECT t1_o.a FROM t1 AS t1_i GROUP BY t1_i.a LIMIT 1).
4785
 
        Processing all Item_refs here will cause t1_o.a to resolve to itself.
4786
 
        We still need to process the special case of Item_direct_view_ref 
4787
 
        because in the context of views they have the same meaning as 
4788
 
        Item_field for tables.
4789
 
      */
4790
 
      Item_ident *item_ref= (Item_ident *) item;
4791
 
      if (item_ref->name && item_ref->table_name &&
4792
 
          !my_strcasecmp(system_charset_info, item_ref->name, field_name) &&
4793
 
          !my_strcasecmp(table_alias_charset, item_ref->table_name,
4794
 
                         table_name) &&
4795
 
          (!db_name || (item_ref->db_name && 
4796
 
                        !strcmp (item_ref->db_name, db_name))))
4797
 
      {
4798
 
        found= li.ref();
4799
 
        *counter= i;
4800
 
        *resolution= RESOLVED_IGNORING_ALIAS;
4801
 
        break;
4802
 
      }
4803
 
    }
4804
4447
  }
4805
4448
  if (!found)
4806
4449
  {
4808
4451
    {
4809
4452
      if (report_error != IGNORE_ERRORS)
4810
4453
        my_error(ER_NON_UNIQ_ERROR, MYF(0),
4811
 
                 find->full_name(), current_thd->where);
 
4454
                 find->full_name(), current_session->where);
4812
4455
      return (Item **) 0;
4813
4456
    }
4814
4457
    if (found_unaliased)
4824
4467
  {
4825
4468
    if (report_error == REPORT_ALL_ERRORS)
4826
4469
      my_error(ER_BAD_FIELD_ERROR, MYF(0),
4827
 
               find->full_name(), current_thd->where);
 
4470
               find->full_name(), current_session->where);
4828
4471
    return (Item **) 0;
4829
4472
  }
4830
4473
  else
4872
4515
 
4873
4516
  SYNOPSIS
4874
4517
    set_new_item_local_context()
4875
 
    thd        pointer to current thread
 
4518
    session        pointer to current thread
4876
4519
    item       item for which new context is created and set
4877
4520
    table_ref  table ref where an item showld be resolved
4878
4521
 
4886
4529
*/
4887
4530
 
4888
4531
static bool
4889
 
set_new_item_local_context(THD *thd, Item_ident *item, TableList *table_ref)
 
4532
set_new_item_local_context(Session *session, Item_ident *item, TableList *table_ref)
4890
4533
{
4891
4534
  Name_resolution_context *context;
4892
 
  if (!(context= new (thd->mem_root) Name_resolution_context))
 
4535
  if (!(context= new (session->mem_root) Name_resolution_context))
4893
4536
    return true;
4894
4537
  context->init();
4895
4538
  context->first_name_resolution_table=
4904
4547
 
4905
4548
  SYNOPSIS
4906
4549
    mark_common_columns()
4907
 
    thd                [in] current thread
 
4550
    session                [in] current thread
4908
4551
    table_ref_1        [in] the first (left) join operand
4909
4552
    table_ref_2        [in] the second (right) join operand
4910
4553
    using_fields       [in] if the join is JOIN...USING - the join columns,
4931
4574
*/
4932
4575
 
4933
4576
static bool
4934
 
mark_common_columns(THD *thd, TableList *table_ref_1, TableList *table_ref_2,
 
4577
mark_common_columns(Session *session, TableList *table_ref_1, TableList *table_ref_2,
4935
4578
                    List<String> *using_fields, uint32_t *found_using_fields)
4936
4579
{
4937
4580
  Field_iterator_table_ref it_1, it_2;
4960
4603
    if (!(nj_col_1= it_1.get_or_create_column_ref(leaf_1)))
4961
4604
      goto err;
4962
4605
    field_name_1= nj_col_1->name();
4963
 
    is_using_column_1= using_fields && 
 
4606
    is_using_column_1= using_fields &&
4964
4607
      test_if_string_in_list(field_name_1, using_fields);
4965
4608
 
4966
4609
    /*
4987
4630
        (then cur_nj_col_2->is_common == true).
4988
4631
        Note that it is too early to check the columns outside of the
4989
4632
        USING list for ambiguity because they are not actually "referenced"
4990
 
        here. These columns must be checked only on unqualified reference 
 
4633
        here. These columns must be checked only on unqualified reference
4991
4634
        by name (e.g. in SELECT list).
4992
4635
      */
4993
4636
      if (!my_strcasecmp(system_charset_info, field_name_1, cur_field_name_2))
4995
4638
        if (cur_nj_col_2->is_common ||
4996
4639
            (found && (!using_fields || is_using_column_1)))
4997
4640
        {
4998
 
          my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1, thd->where);
 
4641
          my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1, session->where);
4999
4642
          goto err;
5000
4643
        }
5001
4644
        nj_col_2= cur_nj_col_2;
5021
4664
    */
5022
4665
    if (nj_col_2 && (!using_fields ||is_using_column_1))
5023
4666
    {
5024
 
      Item *item_1=   nj_col_1->create_item(thd);
5025
 
      Item *item_2=   nj_col_2->create_item(thd);
 
4667
      Item *item_1=   nj_col_1->create_item(session);
 
4668
      Item *item_2=   nj_col_2->create_item(session);
5026
4669
      Field *field_1= nj_col_1->field();
5027
4670
      Field *field_2= nj_col_2->field();
5028
4671
      Item_ident *item_ident_1, *item_ident_2;
5052
4695
        resolution of these items, and to enable proper name resolution of
5053
4696
        the items during the execute phase of PS.
5054
4697
      */
5055
 
      if (set_new_item_local_context(thd, item_ident_1, nj_col_1->table_ref) ||
5056
 
          set_new_item_local_context(thd, item_ident_2, nj_col_2->table_ref))
 
4698
      if (set_new_item_local_context(session, item_ident_1, nj_col_1->table_ref) ||
 
4699
          set_new_item_local_context(session, item_ident_2, nj_col_2->table_ref))
5057
4700
        goto err;
5058
4701
 
5059
4702
      if (!(eq_cond= new Item_func_eq(item_ident_1, item_ident_2)))
5114
4757
 
5115
4758
  SYNOPSIS
5116
4759
    store_natural_using_join_columns()
5117
 
    thd                current thread
 
4760
    session                current thread
5118
4761
    natural_using_join the table reference of the NATURAL/USING join
5119
4762
    table_ref_1        the first (left) operand (of a NATURAL/USING join).
5120
4763
    table_ref_2        the second (right) operand (of a NATURAL/USING join).
5145
4788
*/
5146
4789
 
5147
4790
static bool
5148
 
store_natural_using_join_columns(THD *thd __attribute__((unused)),
 
4791
store_natural_using_join_columns(Session *,
5149
4792
                                 TableList *natural_using_join,
5150
4793
                                 TableList *table_ref_1,
5151
4794
                                 TableList *table_ref_2,
5199
4842
        if (!(common_field= it++))
5200
4843
        {
5201
4844
          my_error(ER_BAD_FIELD_ERROR, MYF(0), using_field_name_ptr,
5202
 
                   current_thd->where);
 
4845
                   current_session->where);
5203
4846
          goto err;
5204
4847
        }
5205
4848
        if (!my_strcasecmp(system_charset_info,
5238
4881
 
5239
4882
  SYNOPSIS
5240
4883
    store_top_level_join_columns()
5241
 
    thd            current thread
 
4884
    session            current thread
5242
4885
    table_ref      nested join or table in a FROM clause
5243
4886
    left_neighbor  neighbor table reference to the left of table_ref at the
5244
4887
                   same level in the join tree
5250
4893
    and materializes the row types of NATURAL/USING joins in a
5251
4894
    bottom-up manner until it reaches the TableList elements that
5252
4895
    represent the top-most NATURAL/USING joins. The procedure should be
5253
 
    applied to each element of SELECT_LEX::top_join_list (i.e. to each
 
4896
    applied to each element of Select_Lex::top_join_list (i.e. to each
5254
4897
    top-level element of the FROM clause).
5255
4898
 
5256
4899
  IMPLEMENTATION
5264
4907
*/
5265
4908
 
5266
4909
static bool
5267
 
store_top_level_join_columns(THD *thd, TableList *table_ref,
 
4910
store_top_level_join_columns(Session *session, TableList *table_ref,
5268
4911
                             TableList *left_neighbor,
5269
4912
                             TableList *right_neighbor)
5270
4913
{
5312
4955
                           same_level_right_neighbor : right_neighbor;
5313
4956
 
5314
4957
      if (cur_table_ref->nested_join &&
5315
 
          store_top_level_join_columns(thd, cur_table_ref,
 
4958
          store_top_level_join_columns(session, cur_table_ref,
5316
4959
                                       real_left_neighbor, real_right_neighbor))
5317
4960
        goto err;
5318
4961
      same_level_right_neighbor= cur_table_ref;
5344
4987
    */
5345
4988
    if (table_ref_2->outer_join & JOIN_TYPE_RIGHT)
5346
4989
      std::swap(table_ref_1, table_ref_2);
5347
 
    if (mark_common_columns(thd, table_ref_1, table_ref_2,
 
4990
    if (mark_common_columns(session, table_ref_1, table_ref_2,
5348
4991
                            using_fields, &found_using_fields))
5349
4992
      goto err;
5350
4993
 
5355
4998
    */
5356
4999
    if (table_ref_1->outer_join & JOIN_TYPE_RIGHT)
5357
5000
      std::swap(table_ref_1, table_ref_2);
5358
 
    if (store_natural_using_join_columns(thd, table_ref, table_ref_1,
 
5001
    if (store_natural_using_join_columns(session, table_ref, table_ref_1,
5359
5002
                                         table_ref_2, using_fields,
5360
5003
                                         found_using_fields))
5361
5004
      goto err;
5402
5045
 
5403
5046
  SYNOPSIS
5404
5047
    setup_natural_join_row_types()
5405
 
    thd          current thread
 
5048
    session          current thread
5406
5049
    from_clause  list of top-level table references in a FROM clause
5407
5050
 
5408
5051
  DESCRIPTION
5420
5063
    true   Error
5421
5064
    false  OK
5422
5065
*/
5423
 
static bool setup_natural_join_row_types(THD *thd,
 
5066
static bool setup_natural_join_row_types(Session *session,
5424
5067
                                         List<TableList> *from_clause,
5425
5068
                                         Name_resolution_context *context)
5426
5069
{
5427
 
  thd->where= "from clause";
 
5070
  session->where= "from clause";
5428
5071
  if (from_clause->elements == 0)
5429
5072
    return false; /* We come here in the case of UNIONs. */
5430
5073
 
5440
5083
  {
5441
5084
    table_ref= left_neighbor;
5442
5085
    left_neighbor= table_ref_it++;
5443
 
    if (store_top_level_join_columns(thd, table_ref,
 
5086
    if (store_top_level_join_columns(session, table_ref,
5444
5087
                                     left_neighbor, right_neighbor))
5445
5088
      return true;
5446
5089
    if (left_neighbor)
5470
5113
** Expand all '*' in given fields
5471
5114
****************************************************************************/
5472
5115
 
5473
 
int setup_wild(THD *thd,
5474
 
               TableList *tables __attribute__((unused)),
 
5116
int setup_wild(Session *session,
 
5117
               TableList *,
5475
5118
               List<Item> &fields,
5476
5119
               List<Item> *sum_func_list,
5477
5120
               uint32_t wild_num)
5482
5125
  Item *item;
5483
5126
  List_iterator<Item> it(fields);
5484
5127
 
5485
 
  thd->lex->current_select->cur_pos_in_select_list= 0;
 
5128
  session->lex->current_select->cur_pos_in_select_list= 0;
5486
5129
  while (wild_num && (item= it++))
5487
5130
  {
5488
5131
    if (item->type() == Item::FIELD_ITEM &&
5492
5135
    {
5493
5136
      uint32_t elem= fields.elements;
5494
5137
      bool any_privileges= ((Item_field *) item)->any_privileges;
5495
 
      Item_subselect *subsel= thd->lex->current_select->master_unit()->item;
 
5138
      Item_subselect *subsel= session->lex->current_select->master_unit()->item;
5496
5139
      if (subsel &&
5497
5140
          subsel->substype() == Item_subselect::EXISTS_SUBS)
5498
5141
      {
5504
5147
        it.replace(new Item_int("Not_used", (int64_t) 1,
5505
5148
                                MY_INT64_NUM_DECIMAL_DIGITS));
5506
5149
      }
5507
 
      else if (insert_fields(thd, ((Item_field*) item)->context,
 
5150
      else if (insert_fields(session, ((Item_field*) item)->context,
5508
5151
                             ((Item_field*) item)->db_name,
5509
5152
                             ((Item_field*) item)->table_name, &it,
5510
5153
                             any_privileges))
5523
5166
      wild_num--;
5524
5167
    }
5525
5168
    else
5526
 
      thd->lex->current_select->cur_pos_in_select_list++;
 
5169
      session->lex->current_select->cur_pos_in_select_list++;
5527
5170
  }
5528
 
  thd->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
 
5171
  session->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
5529
5172
  return(0);
5530
5173
}
5531
5174
 
5533
5176
** Check that all given fields exists and fill struct with current data
5534
5177
****************************************************************************/
5535
5178
 
5536
 
bool setup_fields(THD *thd, Item **ref_pointer_array,
 
5179
bool setup_fields(Session *session, Item **ref_pointer_array,
5537
5180
                  List<Item> &fields, enum_mark_columns mark_used_columns,
5538
5181
                  List<Item> *sum_func_list, bool allow_sum_func)
5539
5182
{
5540
5183
  register Item *item;
5541
 
  enum_mark_columns save_mark_used_columns= thd->mark_used_columns;
5542
 
  nesting_map save_allow_sum_func= thd->lex->allow_sum_func;
 
5184
  enum_mark_columns save_mark_used_columns= session->mark_used_columns;
 
5185
  nesting_map save_allow_sum_func= session->lex->allow_sum_func;
5543
5186
  List_iterator<Item> it(fields);
5544
5187
  bool save_is_item_list_lookup;
5545
5188
 
5546
 
  thd->mark_used_columns= mark_used_columns;
 
5189
  session->mark_used_columns= mark_used_columns;
5547
5190
  if (allow_sum_func)
5548
 
    thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
5549
 
  thd->where= THD::DEFAULT_WHERE;
5550
 
  save_is_item_list_lookup= thd->lex->current_select->is_item_list_lookup;
5551
 
  thd->lex->current_select->is_item_list_lookup= 0;
 
5191
    session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
 
5192
  session->where= Session::DEFAULT_WHERE;
 
5193
  save_is_item_list_lookup= session->lex->current_select->is_item_list_lookup;
 
5194
  session->lex->current_select->is_item_list_lookup= 0;
5552
5195
 
5553
5196
  /*
5554
5197
    To prevent fail on forward lookup we fill it with zerows,
5565
5208
    memset(ref_pointer_array, 0, sizeof(Item *) * fields.elements);
5566
5209
 
5567
5210
  Item **ref= ref_pointer_array;
5568
 
  thd->lex->current_select->cur_pos_in_select_list= 0;
 
5211
  session->lex->current_select->cur_pos_in_select_list= 0;
5569
5212
  while ((item= it++))
5570
5213
  {
5571
 
    if ((!item->fixed && item->fix_fields(thd, it.ref())) || (item= *(it.ref()))->check_cols(1))
 
5214
    if ((!item->fixed && item->fix_fields(session, it.ref())) || (item= *(it.ref()))->check_cols(1))
5572
5215
    {
5573
 
      thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
5574
 
      thd->lex->allow_sum_func= save_allow_sum_func;
5575
 
      thd->mark_used_columns= save_mark_used_columns;
 
5216
      session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
 
5217
      session->lex->allow_sum_func= save_allow_sum_func;
 
5218
      session->mark_used_columns= save_mark_used_columns;
5576
5219
      return(true); /* purecov: inspected */
5577
5220
    }
5578
5221
    if (ref)
5579
5222
      *(ref++)= item;
5580
5223
    if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM &&
5581
5224
        sum_func_list)
5582
 
      item->split_sum_func(thd, ref_pointer_array, *sum_func_list);
5583
 
    thd->used_tables|= item->used_tables();
5584
 
    thd->lex->current_select->cur_pos_in_select_list++;
 
5225
      item->split_sum_func(session, ref_pointer_array, *sum_func_list);
 
5226
    session->used_tables|= item->used_tables();
 
5227
    session->lex->current_select->cur_pos_in_select_list++;
5585
5228
  }
5586
 
  thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
5587
 
  thd->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
 
5229
  session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
 
5230
  session->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
5588
5231
 
5589
 
  thd->lex->allow_sum_func= save_allow_sum_func;
5590
 
  thd->mark_used_columns= save_mark_used_columns;
5591
 
  return(test(thd->is_error()));
 
5232
  session->lex->allow_sum_func= save_allow_sum_func;
 
5233
  session->mark_used_columns= save_mark_used_columns;
 
5234
  return(test(session->is_error()));
5592
5235
}
5593
5236
 
5594
5237
 
5620
5263
 
5621
5264
  SYNOPSIS
5622
5265
    setup_tables()
5623
 
    thd           Thread handler
 
5266
    session               Thread handler
5624
5267
    context       name resolution contest to setup table list there
5625
5268
    from_clause   Top-level list of table references in the FROM clause
5626
5269
    tables        Table list (select_lex->table_list)
5643
5286
    true  error
5644
5287
*/
5645
5288
 
5646
 
bool setup_tables(THD *thd, Name_resolution_context *context,
 
5289
bool setup_tables(Session *session, Name_resolution_context *context,
5647
5290
                  List<TableList> *from_clause, TableList *tables,
5648
5291
                  TableList **leaves, bool select_insert)
5649
5292
{
5650
5293
  uint32_t tablenr= 0;
5651
5294
 
5652
 
  assert ((select_insert && !tables->next_name_resolution_table) || !tables || 
 
5295
  assert ((select_insert && !tables->next_name_resolution_table) || !tables ||
5653
5296
               (context->table_list && context->first_name_resolution_table));
5654
5297
  /*
5655
5298
    this is used for INSERT ... SELECT.
5675
5318
      first_select_table= 0;
5676
5319
      tablenr= 0;
5677
5320
    }
5678
 
    setup_table_map(table, table_list, tablenr);
 
5321
    table->setup_table_map(table_list, tablenr);
5679
5322
    if (table_list->process_index_hints(table))
5680
5323
      return(1);
5681
5324
  }
5686
5329
  }
5687
5330
 
5688
5331
  /* Precompute and store the row types of NATURAL/USING joins. */
5689
 
  if (setup_natural_join_row_types(thd, from_clause, context))
 
5332
  if (setup_natural_join_row_types(session, from_clause, context))
5690
5333
    return(1);
5691
5334
 
5692
5335
  return(0);
5698
5341
 
5699
5342
  SYNOPSIS
5700
5343
    setup_tables_and_check_view_access()
5701
 
    thd           Thread handler
 
5344
    session               Thread handler
5702
5345
    context       name resolution contest to setup table list there
5703
5346
    from_clause   Top-level list of table references in the FROM clause
5704
5347
    tables        Table list (select_lex->table_list)
5716
5359
    false ok;  In this case *map will include the chosen index
5717
5360
    true  error
5718
5361
*/
5719
 
bool setup_tables_and_check_access(THD *thd, 
 
5362
bool setup_tables_and_check_access(Session *session,
5720
5363
                                   Name_resolution_context *context,
5721
5364
                                   List<TableList> *from_clause,
5722
5365
                                   TableList *tables,
5726
5369
  TableList *leaves_tmp= NULL;
5727
5370
  bool first_table= true;
5728
5371
 
5729
 
  if (setup_tables(thd, context, from_clause, tables,
 
5372
  if (setup_tables(session, context, from_clause, tables,
5730
5373
                   &leaves_tmp, select_insert))
5731
5374
    return true;
5732
5375
 
5786
5429
 
5787
5430
  SYNOPSIS
5788
5431
    insert_fields()
5789
 
    thd                 Thread handler
 
5432
    session                     Thread handler
5790
5433
    context             Context for name resolution
5791
5434
    db_name             Database name in case of 'database_name.table_name.*'
5792
5435
    table_name          Table name in case of 'table_name.*'
5800
5443
*/
5801
5444
 
5802
5445
bool
5803
 
insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
 
5446
insert_fields(Session *session, Name_resolution_context *context, const char *db_name,
5804
5447
              const char *table_name, List_iterator<Item> *it,
5805
 
              bool any_privileges __attribute__((unused)))
 
5448
              bool )
5806
5449
{
5807
5450
  Field_iterator_table_ref field_iterator;
5808
5451
  bool found;
5815
5458
      We can't do this in Item_field as this would change the
5816
5459
      'name' of the item which may be used in the select list
5817
5460
    */
5818
 
    strmake(name_buff, db_name, sizeof(name_buff)-1);
 
5461
    strncpy(name_buff, db_name, sizeof(name_buff)-1);
5819
5462
    my_casedn_str(files_charset_info, name_buff);
5820
5463
    db_name= name_buff;
5821
5464
  }
5839
5482
 
5840
5483
    assert(tables->is_leaf_for_name_resolution());
5841
5484
 
5842
 
    if ((table_name && my_strcasecmp(table_alias_charset, table_name, tables->alias)) || 
 
5485
    if ((table_name && my_strcasecmp(table_alias_charset, table_name, tables->alias)) ||
5843
5486
        (db_name && strcmp(tables->db,db_name)))
5844
5487
      continue;
5845
5488
 
5848
5491
      views and natural joins this update is performed inside the loop below.
5849
5492
    */
5850
5493
    if (table)
5851
 
      thd->used_tables|= table->map;
 
5494
      session->used_tables|= table->map;
5852
5495
 
5853
5496
    /*
5854
5497
      Initialize a generic field iterator for the current table reference.
5862
5505
    {
5863
5506
      Item *item;
5864
5507
 
5865
 
      if (!(item= field_iterator.create_item(thd)))
 
5508
      if (!(item= field_iterator.create_item(session)))
5866
5509
        return(true);
5867
5510
 
5868
5511
      if (!found)
5877
5520
      {
5878
5521
        /* Mark fields as used to allow storage engine to optimze access */
5879
5522
        bitmap_set_bit(field->table->read_set, field->field_index);
 
5523
        /*
 
5524
          Mark virtual fields for write and others that the virtual fields
 
5525
          depend on for read.
 
5526
        */
 
5527
        if (field->vcol_info)
 
5528
        {
 
5529
          Item *vcol_item= field->vcol_info->expr_item;
 
5530
          assert(vcol_item);
 
5531
          vcol_item->walk(&Item::register_field_in_read_map, 1, (unsigned char *) 0);
 
5532
          bitmap_set_bit(field->table->write_set, field->field_index);
 
5533
        }
5880
5534
        if (table)
5881
5535
        {
5882
5536
          table->covering_keys.intersect(field->part_of_key);
5896
5550
          field_table= nj_col->table_ref->table;
5897
5551
          if (field_table)
5898
5552
          {
5899
 
            thd->used_tables|= field_table->map;
 
5553
            session->used_tables|= field_table->map;
5900
5554
            field_table->covering_keys.intersect(field->part_of_key);
5901
5555
            field_table->merge_keys.merge(field->part_of_key);
5902
5556
            field_table->used_fields++;
5904
5558
        }
5905
5559
      }
5906
5560
      else
5907
 
        thd->used_tables|= item->used_tables();
5908
 
      thd->lex->current_select->cur_pos_in_select_list++;
 
5561
        session->used_tables|= item->used_tables();
 
5562
      session->lex->current_select->cur_pos_in_select_list++;
5909
5563
    }
5910
5564
    /*
5911
5565
      In case of stored tables, all fields are considered as used,
5938
5592
 
5939
5593
  SYNOPSIS
5940
5594
    setup_conds()
5941
 
    thd     thread handler
 
5595
    session     thread handler
5942
5596
    tables  list of tables for name resolving (select_lex->table_list)
5943
5597
    leaves  list of leaves of join table tree (select_lex->leaf_tables)
5944
5598
    conds   WHERE clause
5951
5605
    false if all is OK
5952
5606
*/
5953
5607
 
5954
 
int setup_conds(THD *thd, TableList *tables __attribute__((unused)),
 
5608
int setup_conds(Session *session, TableList *,
5955
5609
                TableList *leaves,
5956
5610
                COND **conds)
5957
5611
{
5958
 
  SELECT_LEX *select_lex= thd->lex->current_select;
 
5612
  Select_Lex *select_lex= session->lex->current_select;
5959
5613
  TableList *table= NULL;       // For HP compilers
5960
 
  void *save_thd_marker= thd->thd_marker;
 
5614
  void *save_session_marker= session->session_marker;
5961
5615
  /*
5962
 
    it_is_update set to true when tables of primary SELECT_LEX (SELECT_LEX
 
5616
    it_is_update set to true when tables of primary Select_Lex (Select_Lex
5963
5617
    which belong to LEX, i.e. most up SELECT) will be updated by
5964
5618
    INSERT/UPDATE/LOAD
5965
5619
    NOTE: using this condition helps to prevent call of prepare_check_option()
5969
5623
  bool save_is_item_list_lookup= select_lex->is_item_list_lookup;
5970
5624
  select_lex->is_item_list_lookup= 0;
5971
5625
 
5972
 
  thd->mark_used_columns= MARK_COLUMNS_READ;
 
5626
  session->mark_used_columns= MARK_COLUMNS_READ;
5973
5627
  select_lex->cond_count= 0;
5974
5628
  select_lex->between_count= 0;
5975
5629
  select_lex->max_equal_elems= 0;
5976
5630
 
5977
 
  thd->thd_marker= (void*)1;
 
5631
  session->session_marker= (void*)1;
5978
5632
  if (*conds)
5979
5633
  {
5980
 
    thd->where="where clause";
5981
 
    if ((!(*conds)->fixed && (*conds)->fix_fields(thd, conds)) ||
 
5634
    session->where="where clause";
 
5635
    if ((!(*conds)->fixed && (*conds)->fix_fields(session, conds)) ||
5982
5636
        (*conds)->check_cols(1))
5983
5637
      goto err_no_arena;
5984
5638
  }
5985
 
  thd->thd_marker= save_thd_marker;
 
5639
  session->session_marker= save_session_marker;
5986
5640
 
5987
5641
  /*
5988
5642
    Apply fix_fields() to all ON clauses at all levels of nesting,
5998
5652
      if (embedded->on_expr)
5999
5653
      {
6000
5654
        /* Make a join an a expression */
6001
 
        thd->thd_marker= (void*)embedded;
6002
 
        thd->where="on clause";
6003
 
        if ((!embedded->on_expr->fixed && embedded->on_expr->fix_fields(thd, &embedded->on_expr)) ||
 
5655
        session->session_marker= (void*)embedded;
 
5656
        session->where="on clause";
 
5657
        if ((!embedded->on_expr->fixed && embedded->on_expr->fix_fields(session, &embedded->on_expr)) ||
6004
5658
            embedded->on_expr->check_cols(1))
6005
5659
          goto err_no_arena;
6006
5660
        select_lex->cond_count++;
6011
5665
           embedding->nested_join->join_list.head() == embedded);
6012
5666
 
6013
5667
  }
6014
 
  thd->thd_marker= save_thd_marker;
 
5668
  session->session_marker= save_session_marker;
6015
5669
 
6016
 
  thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
6017
 
  return(test(thd->is_error()));
 
5670
  session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
 
5671
  return(test(session->is_error()));
6018
5672
 
6019
5673
err_no_arena:
6020
5674
  select_lex->is_item_list_lookup= save_is_item_list_lookup;
6033
5687
 
6034
5688
  SYNOPSIS
6035
5689
    fill_record()
6036
 
    thd           thread handler
 
5690
    session           thread handler
6037
5691
    fields        Item_fields list to be filled
6038
5692
    values        values to fill with
6039
5693
    ignore_errors true if we should ignore errors
6049
5703
*/
6050
5704
 
6051
5705
bool
6052
 
fill_record(THD * thd, List<Item> &fields, List<Item> &values, bool ignore_errors)
 
5706
fill_record(Session * session, List<Item> &fields, List<Item> &values, bool ignore_errors)
6053
5707
{
6054
5708
  List_iterator_fast<Item> f(fields),v(values);
6055
5709
  Item *value, *fld;
6056
5710
  Item_field *field;
6057
5711
  Table *table= 0;
 
5712
  List<Table> tbl_list;
 
5713
  bool abort_on_warning_saved= session->abort_on_warning;
 
5714
  tbl_list.empty();
6058
5715
 
6059
5716
  /*
6060
5717
    Reset the table->auto_increment_field_not_null as it is valid for
6088
5745
    table= rfield->table;
6089
5746
    if (rfield == table->next_number_field)
6090
5747
      table->auto_increment_field_not_null= true;
 
5748
    if (rfield->vcol_info &&
 
5749
        value->type() != Item::DEFAULT_VALUE_ITEM &&
 
5750
        value->type() != Item::NULL_ITEM &&
 
5751
        table->s->table_category != TABLE_CATEGORY_TEMPORARY)
 
5752
    {
 
5753
      session->abort_on_warning= false;
 
5754
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
5755
                          ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN,
 
5756
                          ER(ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN),
 
5757
                          rfield->field_name, table->s->table_name.str);
 
5758
      session->abort_on_warning= abort_on_warning_saved;
 
5759
    }
6091
5760
    if ((value->save_in_field(rfield, 0) < 0) && !ignore_errors)
6092
5761
    {
6093
5762
      my_message(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), MYF(0));
6094
5763
      goto err;
6095
5764
    }
6096
 
  }
6097
 
  return(thd->is_error());
 
5765
    tbl_list.push_back(table);
 
5766
  }
 
5767
  /* Update virtual fields*/
 
5768
  session->abort_on_warning= false;
 
5769
  if (tbl_list.head())
 
5770
  {
 
5771
    List_iterator_fast<Table> t(tbl_list);
 
5772
    Table *prev_table= 0;
 
5773
    while ((table= t++))
 
5774
    {
 
5775
      /*
 
5776
        Do simple optimization to prevent unnecessary re-generating
 
5777
        values for virtual fields
 
5778
      */
 
5779
      if (table != prev_table)
 
5780
      {
 
5781
        prev_table= table;
 
5782
        if (table->vfield)
 
5783
        {
 
5784
          if (update_virtual_fields_marked_for_write(table, false))
 
5785
            goto err;
 
5786
        }
 
5787
      }
 
5788
    }
 
5789
  }
 
5790
  session->abort_on_warning= abort_on_warning_saved;
 
5791
  return(session->is_error());
6098
5792
err:
 
5793
  session->abort_on_warning= abort_on_warning_saved;
6099
5794
  if (table)
6100
5795
    table->auto_increment_field_not_null= false;
6101
5796
  return(true);
6107
5802
 
6108
5803
  SYNOPSIS
6109
5804
    fill_record()
6110
 
    thd           thread handler
 
5805
    session           thread handler
6111
5806
    ptr           pointer on pointer to record
6112
5807
    values        list of fields
6113
5808
    ignore_errors true if we should ignore errors
6123
5818
*/
6124
5819
 
6125
5820
bool
6126
 
fill_record(THD *thd, Field **ptr, List<Item> &values,
6127
 
            bool ignore_errors __attribute__((unused)))
 
5821
fill_record(Session *session, Field **ptr, List<Item> &values,
 
5822
            bool )
6128
5823
{
6129
5824
  List_iterator_fast<Item> v(values);
6130
5825
  Item *value;
6131
5826
  Table *table= 0;
6132
 
 
6133
5827
  Field *field;
 
5828
  List<Table> tbl_list;
 
5829
  bool abort_on_warning_saved= session->abort_on_warning;
 
5830
 
 
5831
  tbl_list.empty();
6134
5832
  /*
6135
5833
    Reset the table->auto_increment_field_not_null as it is valid for
6136
5834
    only one row.
6144
5842
    table= (*ptr)->table;
6145
5843
    table->auto_increment_field_not_null= false;
6146
5844
  }
6147
 
  while ((field = *ptr++) && ! thd->is_error())
 
5845
  while ((field = *ptr++) && ! session->is_error())
6148
5846
  {
6149
5847
    value=v++;
6150
5848
    table= field->table;
6151
5849
    if (field == table->next_number_field)
6152
5850
      table->auto_increment_field_not_null= true;
 
5851
    if (field->vcol_info &&
 
5852
        value->type() != Item::DEFAULT_VALUE_ITEM &&
 
5853
        value->type() != Item::NULL_ITEM &&
 
5854
        table->s->table_category != TABLE_CATEGORY_TEMPORARY)
 
5855
    {
 
5856
      session->abort_on_warning= false;
 
5857
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
5858
                          ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN,
 
5859
                          ER(ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN),
 
5860
                          field->field_name, table->s->table_name.str);
 
5861
      session->abort_on_warning= abort_on_warning_saved;
 
5862
    }
6153
5863
    if (value->save_in_field(field, 0) < 0)
6154
5864
      goto err;
6155
 
  }
6156
 
  return(thd->is_error());
 
5865
    tbl_list.push_back(table);
 
5866
  }
 
5867
  /* Update virtual fields*/
 
5868
  session->abort_on_warning= false;
 
5869
  if (tbl_list.head())
 
5870
  {
 
5871
    List_iterator_fast<Table> t(tbl_list);
 
5872
    Table *prev_table= 0;
 
5873
    while ((table= t++))
 
5874
    {
 
5875
      /*
 
5876
        Do simple optimization to prevent unnecessary re-generating
 
5877
        values for virtual fields
 
5878
      */
 
5879
      if (table != prev_table)
 
5880
      {
 
5881
        prev_table= table;
 
5882
        if (table->vfield)
 
5883
        {
 
5884
          if (update_virtual_fields_marked_for_write(table, false))
 
5885
          {
 
5886
            goto err;
 
5887
          }
 
5888
        }
 
5889
      }
 
5890
    }
 
5891
  }
 
5892
  session->abort_on_warning= abort_on_warning_saved;
 
5893
  return(session->is_error());
6157
5894
 
6158
5895
err:
 
5896
  session->abort_on_warning= abort_on_warning_saved;
6159
5897
  if (table)
6160
5898
    table->auto_increment_field_not_null= false;
6161
5899
  return(true);
6162
5900
}
6163
5901
 
6164
5902
 
6165
 
bool mysql_rm_tmp_tables(void)
 
5903
bool drizzle_rm_tmp_tables(void)
6166
5904
{
6167
 
  uint32_t i, idx;
6168
 
  char  filePath[FN_REFLEN], *tmpdir, filePathCopy[FN_REFLEN];
 
5905
  uint32_t  idx;
 
5906
  char  filePath[FN_REFLEN], filePathCopy[FN_REFLEN];
6169
5907
  MY_DIR *dirp;
6170
5908
  FILEINFO *file;
6171
5909
  TABLE_SHARE share;
6172
 
  THD *thd;
6173
 
 
6174
 
  if (!(thd= new THD))
6175
 
    return(1);
6176
 
  thd->thread_stack= (char*) &thd;
6177
 
  thd->store_globals();
6178
 
 
6179
 
  for (i=0; i<=mysql_tmpdir_list.max; i++)
 
5910
  Session *session;
 
5911
 
 
5912
  assert(drizzle_tmpdir);
 
5913
 
 
5914
  if (!(session= new Session))
 
5915
    return true;
 
5916
  session->thread_stack= (char*) &session;
 
5917
  session->store_globals();
 
5918
 
 
5919
  /* Remove all temp tables in the tmpdir */
 
5920
  /* See if the directory exists */
 
5921
  if ((dirp = my_dir(drizzle_tmpdir ,MYF(MY_WME | MY_DONT_SORT))))
6180
5922
  {
6181
 
    tmpdir=mysql_tmpdir_list.list[i];
6182
 
    /* See if the directory exists */
6183
 
    if (!(dirp = my_dir(tmpdir,MYF(MY_WME | MY_DONT_SORT))))
6184
 
      continue;
6185
 
 
6186
5923
    /* Remove all SQLxxx tables from directory */
6187
 
 
6188
 
    for (idx=0 ; idx < (uint) dirp->number_off_files ; idx++)
 
5924
    for (idx=0 ; idx < (uint32_t) dirp->number_off_files ; idx++)
6189
5925
    {
6190
5926
      file=dirp->dir_entry+idx;
6191
5927
 
6194
5930
                                   (file->name[1] == '.' &&  !file->name[2])))
6195
5931
        continue;
6196
5932
 
6197
 
      if (!memcmp(file->name, tmp_file_prefix, tmp_file_prefix_length))
 
5933
      if (!memcmp(file->name, TMP_FILE_PREFIX, TMP_FILE_PREFIX_LENGTH))
6198
5934
      {
6199
5935
        char *ext= fn_ext(file->name);
6200
5936
        uint32_t ext_len= strlen(ext);
6201
5937
        uint32_t filePath_len= snprintf(filePath, sizeof(filePath),
6202
 
                                    "%s%c%s", tmpdir, FN_LIBCHAR,
6203
 
                                    file->name);
6204
 
        if (!memcmp(reg_ext, ext, ext_len))
 
5938
                                        "%s%c%s", drizzle_tmpdir, FN_LIBCHAR,
 
5939
                                        file->name);
 
5940
        if (!memcmp(".dfe", ext, ext_len))
6205
5941
        {
6206
5942
          handler *handler_file= 0;
6207
5943
          /* We should cut file extention before deleting of table */
6208
5944
          memcpy(filePathCopy, filePath, filePath_len - ext_len);
6209
5945
          filePathCopy[filePath_len - ext_len]= 0;
6210
 
          init_tmp_table_share(thd, &share, "", 0, "", filePathCopy);
6211
 
          if (!open_table_def(thd, &share, 0) &&
6212
 
              ((handler_file= get_new_handler(&share, thd->mem_root,
 
5946
          init_tmp_table_share(session, &share, "", 0, "", filePathCopy);
 
5947
          if (!open_table_def(session, &share, 0) &&
 
5948
              ((handler_file= get_new_handler(&share, session->mem_root,
6213
5949
                                              share.db_type()))))
6214
5950
          {
6215
5951
            handler_file->ha_delete_table(filePathCopy);
6222
5958
          So we hide error messages which happnes during deleting of these
6223
5959
          files(MYF(0)).
6224
5960
        */
6225
 
        my_delete(filePath, MYF(0)); 
 
5961
        my_delete(filePath, MYF(0));
6226
5962
      }
6227
5963
    }
6228
5964
    my_dirend(dirp);
6229
5965
  }
6230
 
  delete thd;
6231
 
  my_pthread_setspecific_ptr(THR_THD,  0);
6232
 
  return(0);
 
5966
 
 
5967
  delete session;
 
5968
 
 
5969
  return false;
6233
5970
}
6234
5971
 
6235
5972
 
6300
6037
    1  Table is in use by another thread
6301
6038
*/
6302
6039
 
6303
 
bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
 
6040
bool remove_table_from_cache(Session *session, const char *db, const char *table_name,
6304
6041
                             uint32_t flags)
6305
6042
{
6306
6043
  char key[MAX_DBKEY_LENGTH];
 
6044
  char *key_pos= key;
6307
6045
  uint32_t key_length;
6308
6046
  Table *table;
6309
6047
  TABLE_SHARE *share;
6310
6048
  bool result= 0, signalled= 0;
6311
6049
 
6312
 
  key_length=(uint) (my_stpcpy(my_stpcpy(key,db)+1,table_name)-key)+1;
 
6050
  key_pos= strcpy(key_pos, db) + strlen(db);
 
6051
  key_pos= strcpy(key_pos+1, table_name) + strlen(table_name);
 
6052
  key_length= (uint32_t) (key_pos-key)+1;
 
6053
 
6313
6054
  for (;;)
6314
6055
  {
6315
6056
    HASH_SEARCH_STATE state;
6321
6062
         table= (Table*) hash_next(&open_cache, (unsigned char*) key, key_length,
6322
6063
                                   &state))
6323
6064
    {
6324
 
      THD *in_use;
 
6065
      Session *in_use;
6325
6066
 
6326
6067
      table->s->version=0L;             /* Free when thread is ready */
6327
6068
      if (!(in_use=table->in_use))
6328
6069
      {
6329
6070
        relink_unused(table);
6330
6071
      }
6331
 
      else if (in_use != thd)
 
6072
      else if (in_use != session)
6332
6073
      {
6333
6074
        /*
6334
6075
          Mark that table is going to be deleted from cache. This will
6349
6090
          open_tables list. Aborting the MERGE lock after a child was
6350
6091
          closed and before the parent is closed would be fatal.
6351
6092
        */
6352
 
        for (Table *thd_table= in_use->open_tables;
6353
 
             thd_table ;
6354
 
             thd_table= thd_table->next)
 
6093
        for (Table *session_table= in_use->open_tables;
 
6094
             session_table ;
 
6095
             session_table= session_table->next)
6355
6096
        {
6356
6097
          /* Do not handle locks of MERGE children. */
6357
 
          if (thd_table->db_stat)       // If table is open
6358
 
            signalled|= mysql_lock_abort_for_thread(thd, thd_table);
 
6098
          if (session_table->db_stat)   // If table is open
 
6099
            signalled|= mysql_lock_abort_for_thread(session, session_table);
6359
6100
        }
6360
6101
      }
6361
6102
      else
6362
 
        result= result || (flags & RTFC_OWNED_BY_THD_FLAG);
 
6103
        result= result || (flags & RTFC_OWNED_BY_Session_FLAG);
6363
6104
    }
6364
6105
    while (unused_tables && !unused_tables->s->version)
6365
6106
      hash_delete(&open_cache,(unsigned char*) unused_tables);
6383
6124
        reopen their tables
6384
6125
      */
6385
6126
      broadcast_refresh();
6386
 
      if (!(flags & RTFC_CHECK_KILLED_FLAG) || !thd->killed)
 
6127
      if (!(flags & RTFC_CHECK_KILLED_FLAG) || !session->killed)
6387
6128
      {
6388
6129
        dropping_tables++;
6389
6130
        if (likely(signalled))
6421
6162
/**
6422
6163
  @} (end of group Data_Dictionary)
6423
6164
*/
 
6165
 
 
6166
void kill_drizzle(void)
 
6167
{
 
6168
  pthread_kill(signal_thread, SIGTERM);
 
6169
  shutdown_in_progress= 1;                      // Safety if kill didn't work
 
6170
}