~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_base.cc

  • Committer: Brian Aker
  • Date: 2009-02-20 22:48:37 UTC
  • Revision ID: brian@tangent.org-20090220224837-fw5wrf46n4ru3e6a
First pass of stripping uint

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
static 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;
55
79
{
56
80
  return hash_init(&open_cache, &my_charset_bin, table_cache_size+16,
57
81
                   0, 0, table_cache_key,
58
 
                   (hash_free_key) free_cache_entry, 0);
 
82
                   free_cache_entry, 0);
59
83
}
60
84
 
61
85
void table_cache_free(void)
79
103
 
80
104
  SYNOPSIS
81
105
    create_table_def_key()
82
 
    thd                 Thread handler
 
106
    session                     Thread handler
83
107
    key                 Create key here (must be of size MAX_DBKEY_LENGTH)
84
108
    table_list          Table definition
85
109
    tmp_table           Set if table is a tmp table
99
123
    Length of key
100
124
*/
101
125
 
102
 
uint32_t create_table_def_key(THD *thd, char *key, TableList *table_list,
 
126
uint32_t create_table_def_key(Session *session, char *key, TableList *table_list,
103
127
                          bool tmp_table)
104
128
{
105
 
  uint32_t key_length= (uint) (my_stpcpy(my_stpcpy(key, table_list->db)+1,
106
 
                                  table_list->table_name)-key)+1;
 
129
  uint32_t key_length;
 
130
  char *key_pos= key;
 
131
  key_pos= strcpy(key_pos, table_list->db) + strlen(table_list->db);
 
132
  key_pos= strcpy(key_pos+1, table_list->table_name) +
 
133
                  strlen(table_list->table_name);
 
134
  key_length= (uint32_t)(key_pos-key)+1;
 
135
 
107
136
  if (tmp_table)
108
137
  {
109
 
    int4store(key + key_length, thd->server_id);
110
 
    int4store(key + key_length + 4, thd->variables.pseudo_thread_id);
 
138
    int4store(key + key_length, session->server_id);
 
139
    int4store(key + key_length + 4, session->variables.pseudo_thread_id);
111
140
    key_length+= TMP_TABLE_KEY_EXTRA;
112
141
  }
113
142
  return key_length;
120
149
*****************************************************************************/
121
150
 
122
151
extern "C" unsigned char *table_def_key(const unsigned char *record, size_t *length,
123
 
                                bool not_used __attribute__((unused)))
 
152
                                bool )
124
153
{
125
154
  TABLE_SHARE *entry=(TABLE_SHARE*) record;
126
155
  *length= entry->table_cache_key.length;
178
207
  Get TABLE_SHARE for a table.
179
208
 
180
209
  get_table_share()
181
 
  thd                   Thread handle
 
210
  session                       Thread handle
182
211
  table_list            Table that should be opened
183
212
  key                   Table cache key
184
213
  key_length            Length of key
199
228
   #  Share for table
200
229
*/
201
230
 
202
 
TABLE_SHARE *get_table_share(THD *thd, TableList *table_list, char *key,
 
231
TABLE_SHARE *get_table_share(Session *session, TableList *table_list, char *key,
203
232
                             uint32_t key_length, uint32_t db_flags, int *error)
204
233
{
205
234
  TABLE_SHARE *share;
242
271
    free_table_share(share);
243
272
    return(0);                          // return error
244
273
  }
245
 
  if (open_table_def(thd, share, db_flags))
 
274
  if (open_table_def(session, share, db_flags))
246
275
  {
247
276
    *error= share->error;
248
277
    (void) hash_delete(&table_def_cache, (unsigned char*) share);
253
282
  return(share);
254
283
 
255
284
found:
256
 
  /* 
 
285
  /*
257
286
     We found an existing table definition. Return it if we didn't get
258
287
     an error when reading the table definition from file.
259
288
  */
302
331
*/
303
332
 
304
333
static TABLE_SHARE
305
 
*get_table_share_with_create(THD *thd, TableList *table_list,
 
334
*get_table_share_with_create(Session *session, TableList *table_list,
306
335
                             char *key, uint32_t key_length,
307
336
                             uint32_t db_flags, int *error)
308
337
{
309
338
  TABLE_SHARE *share;
310
 
  int tmp;
311
339
 
312
 
  share= get_table_share(thd, table_list, key, key_length, db_flags, error);
 
340
  share= get_table_share(session, table_list, key, key_length, db_flags, error);
313
341
  /*
314
342
    If share is not NULL, we found an existing share.
315
343
 
316
344
    If share is NULL, and there is no error, we're inside
317
345
    pre-locking, which silences 'ER_NO_SUCH_TABLE' errors
318
 
    with the intention to silently drop non-existing tables 
 
346
    with the intention to silently drop non-existing tables
319
347
    from the pre-locking list. In this case we still need to try
320
348
    auto-discover before returning a NULL share.
321
349
 
322
350
    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 
 
351
    the same as above, only that the error was not silenced by
324
352
    pre-locking. Once again, we need to try to auto-discover
325
353
    the share.
326
354
 
329
357
 
330
358
    @todo Rework alternative ways to deal with ER_NO_SUCH Table.
331
359
  */
332
 
  if (share || (thd->is_error() && (thd->main_da.sql_errno() != ER_NO_SUCH_TABLE)))
 
360
  if (share || (session->is_error() && (session->main_da.sql_errno() != ER_NO_SUCH_TABLE)))
333
361
 
334
362
    return(share);
335
363
 
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));
 
364
  return 0;
356
365
}
357
366
 
358
367
 
359
 
/* 
 
368
/*
360
369
   Mark that we are not using table share anymore.
361
370
 
362
371
   SYNOPSIS
378
387
*/
379
388
 
380
389
void release_table_share(TABLE_SHARE *share,
381
 
                         enum release_type type __attribute__((unused)))
 
390
                         enum release_type )
382
391
{
383
392
  bool to_be_deleted= 0;
384
393
 
436
445
 
437
446
  table_list.db= (char*) db;
438
447
  table_list.table_name= (char*) table_name;
439
 
  key_length= create_table_def_key((THD*) 0, key, &table_list, 0);
 
448
  key_length= create_table_def_key((Session*) 0, key, &table_list, 0);
440
449
  return (TABLE_SHARE*) hash_search(&table_def_cache,(unsigned char*) key, key_length);
441
 
}  
 
450
}
442
451
 
443
452
 
444
453
/*
452
461
    By leaving the table in the table cache, it disallows any other thread
453
462
    to open the table
454
463
 
455
 
    thd->killed will be set if we run out of memory
 
464
    session->killed will be set if we run out of memory
456
465
 
457
466
    If closing a MERGE child, the calling function has to take care for
458
467
    closing the parent too, if necessary.
499
508
 
500
509
  SYNOPSIS
501
510
    list_open_tables()
502
 
    thd                 Thread THD
503
511
    wild                SQL like expression
504
512
 
505
513
  NOTES
512
520
    #           Pointer to list of names of open tables.
513
521
*/
514
522
 
515
 
OPEN_TableList *list_open_tables(THD *thd __attribute__((unused)),
516
 
                                  const char *db, const char *wild)
 
523
OPEN_TableList *list_open_tables(const char *db, const char *wild)
517
524
{
518
525
  int result = 0;
519
526
  OPEN_TableList **start_list, *open_list;
560
567
      open_list=0;                              // Out of memory
561
568
      break;
562
569
    }
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);
 
570
    strcpy((*start_list)->table=
 
571
           strcpy(((*start_list)->db= (char*) ((*start_list)+1)),
 
572
           share->db.str)+share->db.length+1,
 
573
           share->table_name.str);
567
574
    (*start_list)->in_use= entry->in_use ? 1 : 0;
568
575
    (*start_list)->locked= entry->locked_by_name ? 1 : 0;
569
576
    start_list= &(*start_list)->next;
582
589
{                                               // Free all structures
583
590
  free_io_cache(table);
584
591
  if (table->file)                              // Not true if name lock
585
 
    closefrm(table, 1);                 // close file
 
592
    table->closefrm(true);                      // close file
586
593
  return;
587
594
}
588
595
 
591
598
 
592
599
  SYNOPSIS
593
600
    free_cache_entry()
594
 
    table               Table to remove
 
601
    entry               Table to remove
595
602
 
596
603
  NOTE
597
604
    We need to have a lock on LOCK_open when calling this
598
605
*/
599
606
 
600
 
static void free_cache_entry(Table *table)
 
607
static void free_cache_entry(void *entry)
601
608
{
 
609
  Table *table= static_cast<Table *>(entry);
602
610
  intern_close_table(table);
603
611
  if (!table->in_use)
604
612
  {
611
619
        unused_tables=0;
612
620
    }
613
621
  }
614
 
  free((unsigned char*) table);
 
622
  free(table);
615
623
  return;
616
624
}
617
625
 
622
630
  if (table->sort.io_cache)
623
631
  {
624
632
    close_cached_file(table->sort.io_cache);
625
 
    free((unsigned char*) table->sort.io_cache);
626
 
    table->sort.io_cache=0;
 
633
    delete table->sort.io_cache;
 
634
    table->sort.io_cache= 0;
627
635
  }
628
636
  return;
629
637
}
632
640
/*
633
641
  Close all tables which aren't in use by any thread
634
642
 
635
 
  @param thd Thread context
 
643
  @param session Thread context
636
644
  @param tables List of tables to remove from the cache
637
645
  @param have_lock If LOCK_open is locked
638
646
  @param wait_for_refresh Wait for a impending flush
640
648
         won't proceed while write-locked tables are being reopened by other
641
649
         threads.
642
650
 
643
 
  @remark THD can be NULL, but then wait_for_refresh must be false
 
651
  @remark Session can be NULL, but then wait_for_refresh must be false
644
652
          and tables must be NULL.
645
653
*/
646
654
 
647
 
bool close_cached_tables(THD *thd, TableList *tables, bool have_lock,
 
655
bool close_cached_tables(Session *session, TableList *tables, bool have_lock,
648
656
                         bool wait_for_refresh, bool wait_for_placeholders)
649
657
{
650
658
  bool result=0;
651
 
  assert(thd || (!wait_for_refresh && !tables));
 
659
  assert(session || (!wait_for_refresh && !tables));
652
660
 
653
661
  if (!have_lock)
654
662
    pthread_mutex_lock(&LOCK_open);
722
730
    bool found=0;
723
731
    for (TableList *table= tables; table; table= table->next_local)
724
732
    {
725
 
      if (remove_table_from_cache(thd, table->db, table->table_name,
726
 
                                  RTFC_OWNED_BY_THD_FLAG))
 
733
      if (remove_table_from_cache(session, table->db, table->table_name,
 
734
                                  RTFC_OWNED_BY_Session_FLAG))
727
735
        found=1;
728
736
    }
729
737
    if (!found)
736
744
      If there is any table that has a lower refresh_version, wait until
737
745
      this is closed (or this thread is killed) before returning
738
746
    */
739
 
    thd->mysys_var->current_mutex= &LOCK_open;
740
 
    thd->mysys_var->current_cond= &COND_refresh;
741
 
    thd_proc_info(thd, "Flushing tables");
 
747
    session->mysys_var->current_mutex= &LOCK_open;
 
748
    session->mysys_var->current_cond= &COND_refresh;
 
749
    session->set_proc_info("Flushing tables");
742
750
 
743
 
    close_old_data_files(thd,thd->open_tables,1,1);
744
 
    mysql_ha_flush(thd);
 
751
    close_old_data_files(session,session->open_tables,1,1);
 
752
    mysql_ha_flush(session);
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
 
1541
1390
  handlerton *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
1537
    handlerton *table_type= table->s->db_type();
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
1887
          TMP_TABLE_KEY_EXTRA &&
2104
1891
        /*
2105
1892
          We're trying to use the same temporary table twice in a query.
2106
1893
          Right now we don't support this because a temporary table
2107
 
          is always represented by only one Table object in THD, and
 
1894
          is always represented by only one Table object in Session, and
2108
1895
          it can not be cloned. Emit an error for an unsupported behaviour.
2109
1896
        */
2110
1897
        if (table->query_id)
2112
1899
          my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
2113
1900
          return(0);
2114
1901
        }
2115
 
        table->query_id= thd->query_id;
2116
 
        thd->thread_specific_used= true;
 
1902
        table->query_id= session->query_id;
 
1903
        session->thread_specific_used= true;
2117
1904
        goto reset;
2118
1905
      }
2119
1906
    }
2132
1919
    open not pre-opened tables in pre-locked/LOCK TABLES mode.
2133
1920
    TODO: move this block into a separate function.
2134
1921
  */
2135
 
  if (thd->locked_tables)
 
1922
  if (session->locked_tables)
2136
1923
  {                                             // Using table locks
2137
1924
    Table *best_table= 0;
2138
1925
    int best_distance= INT_MIN;
2139
1926
    bool check_if_used= false;
2140
 
    for (table=thd->open_tables; table ; table=table->next)
 
1927
    for (table=session->open_tables; table ; table=table->next)
2141
1928
    {
2142
1929
      if (table->s->table_cache_key.length == key_length &&
2143
1930
          !memcmp(table->s->table_cache_key.str, key, key_length))
2144
1931
      {
2145
1932
        if (check_if_used && table->query_id &&
2146
 
            table->query_id != thd->query_id)
 
1933
            table->query_id != session->query_id)
2147
1934
        {
2148
1935
          /*
2149
1936
            If we are in stored function or trigger we should ensure that
2160
1947
          belong to their parent and cannot be used explicitly.
2161
1948
        */
2162
1949
        if (!my_strcasecmp(system_charset_info, table->alias, alias) &&
2163
 
            table->query_id != thd->query_id)  /* skip tables already used */
 
1950
            table->query_id != session->query_id)  /* skip tables already used */
2164
1951
        {
2165
1952
          int distance= ((int) table->reginfo.lock_type -
2166
1953
                         (int) table_list->lock_type);
2197
1984
    if (best_table)
2198
1985
    {
2199
1986
      table= best_table;
2200
 
      table->query_id= thd->query_id;
 
1987
      table->query_id= session->query_id;
2201
1988
      goto reset;
2202
1989
    }
2203
1990
    /*
2237
2024
    and try to reopen them.
2238
2025
    Note: refresh_version is currently changed only during FLUSH TABLES.
2239
2026
  */
2240
 
  if (!thd->open_tables)
2241
 
    thd->version=refresh_version;
2242
 
  else if ((thd->version != refresh_version) &&
 
2027
  if (!session->open_tables)
 
2028
    session->version=refresh_version;
 
2029
  else if ((session->version != refresh_version) &&
2243
2030
           ! (flags & DRIZZLE_LOCK_IGNORE_FLUSH))
2244
2031
  {
2245
2032
    /* Someone did a refresh while thread was opening tables */
2256
2043
    is pending for any table of the handler_tables list, otherwise a
2257
2044
    deadlock may occur.
2258
2045
  */
2259
 
  if (thd->handler_tables)
2260
 
    mysql_ha_flush(thd);
 
2046
  if (session->handler_tables)
 
2047
    mysql_ha_flush(session);
2261
2048
 
2262
2049
  /*
2263
2050
    Actually try to find the table in the open_cache.
2288
2075
      need to back off and re-start opening tables.
2289
2076
      If we do not back off now, we may dead lock in case of lock
2290
2077
      order mismatch with some other thread:
2291
 
      c1: name lock t1; -- sort of exclusive lock 
 
2078
      c1: name lock t1; -- sort of exclusive lock
2292
2079
      c2: open t2;      -- sort of shared lock
2293
2080
      c1: name lock t2; -- blocks
2294
2081
      c2: open t1; -- blocks
2298
2085
      if (flags & DRIZZLE_LOCK_IGNORE_FLUSH)
2299
2086
      {
2300
2087
        /* Force close at once after usage */
2301
 
        thd->version= table->s->version;
 
2088
        session->version= table->s->version;
2302
2089
        continue;
2303
2090
      }
2304
2091
 
2305
2092
      /* Avoid self-deadlocks by detecting self-dependencies. */
2306
 
      if (table->open_placeholder && table->in_use == thd)
 
2093
      if (table->open_placeholder && table->in_use == session)
2307
2094
      {
2308
2095
        pthread_mutex_unlock(&LOCK_open);
2309
2096
        my_error(ER_UPDATE_TABLE_USED, MYF(0), table->s->table_name.str);
2323
2110
        the earlier call to mysql_ha_flush() in this same critical
2324
2111
        section.
2325
2112
      */
2326
 
      close_old_data_files(thd,thd->open_tables,0,0);
 
2113
      close_old_data_files(session,session->open_tables,0,0);
2327
2114
      /*
2328
2115
        Back-off part 2: try to avoid "busy waiting" on the table:
2329
2116
        if the table is in use by some other thread, we suspend
2339
2126
        after we open first instance but before we open second
2340
2127
        instance.
2341
2128
      */
2342
 
      if (table->in_use != thd)
 
2129
      if (table->in_use != session)
2343
2130
      {
2344
2131
        /* wait_for_conditionwill unlock LOCK_open for us */
2345
 
        wait_for_condition(thd, &LOCK_open, &COND_refresh);
 
2132
        wait_for_condition(session, &LOCK_open, &COND_refresh);
2346
2133
      }
2347
2134
      else
2348
2135
      {
2368
2155
    }
2369
2156
    table->prev->next=table->next;              /* Remove from unused list */
2370
2157
    table->next->prev=table->prev;
2371
 
    table->in_use= thd;
 
2158
    table->in_use= session;
2372
2159
  }
2373
2160
  else
2374
2161
  {
2380
2167
 
2381
2168
    if (table_list->create)
2382
2169
    {
2383
 
      bool exists;
2384
 
 
2385
 
      if (check_if_table_exists(thd, table_list, &exists))
 
2170
      if(ha_table_exists_in_engine(session, table_list->db,
 
2171
                                   table_list->table_name)
 
2172
         == HA_ERR_TABLE_EXIST)
2386
2173
      {
2387
2174
        pthread_mutex_unlock(&LOCK_open);
2388
2175
        return(NULL);
2389
2176
      }
2390
 
 
2391
 
      if (!exists)
 
2177
      else
2392
2178
      {
2393
2179
        /*
2394
2180
          Table to be created, so we need to create placeholder in table-cache.
2395
2181
        */
2396
 
        if (!(table= table_cache_insert_placeholder(thd, key, key_length)))
 
2182
        if (!(table= table_cache_insert_placeholder(session, key, key_length)))
2397
2183
        {
2398
2184
          pthread_mutex_unlock(&LOCK_open);
2399
2185
          return(NULL);
2404
2190
          by other trying to take name-lock.
2405
2191
        */
2406
2192
        table->open_placeholder= 1;
2407
 
        table->next= thd->open_tables;
2408
 
        thd->open_tables= table;
 
2193
        table->next= session->open_tables;
 
2194
        session->open_tables= table;
2409
2195
        pthread_mutex_unlock(&LOCK_open);
2410
2196
        return(table);
2411
2197
      }
2413
2199
    }
2414
2200
 
2415
2201
    /* make a new table */
2416
 
    if (!(table=(Table*) my_malloc(sizeof(*table),MYF(MY_WME))))
 
2202
    table= (Table *) malloc(sizeof(*table));
 
2203
    if (table == NULL)
2417
2204
    {
2418
2205
      pthread_mutex_unlock(&LOCK_open);
2419
2206
      return(NULL);
2420
2207
    }
2421
2208
 
2422
 
    error= open_unireg_entry(thd, table, table_list, alias, key, key_length);
2423
 
    /* Combine the follow two */
2424
 
    if (error > 0)
 
2209
    error= open_unireg_entry(session, table, table_list, alias, key, key_length);
 
2210
    if (error != 0)
2425
2211
    {
2426
 
      free((unsigned char*)table);
 
2212
      free(table);
2427
2213
      pthread_mutex_unlock(&LOCK_open);
2428
2214
      return(NULL);
2429
2215
    }
2430
 
    if (error < 0)
2431
 
    {
2432
 
      free((unsigned char*)table);
2433
 
      pthread_mutex_unlock(&LOCK_open);
2434
 
      return(0); // VIEW
2435
 
    }
2436
2216
    my_hash_insert(&open_cache,(unsigned char*) table);
2437
2217
  }
2438
2218
 
2439
2219
  pthread_mutex_unlock(&LOCK_open);
2440
2220
  if (refresh)
2441
2221
  {
2442
 
    table->next=thd->open_tables;               /* Link into simple list */
2443
 
    thd->open_tables=table;
 
2222
    table->next=session->open_tables;           /* Link into simple list */
 
2223
    session->open_tables=table;
2444
2224
  }
2445
2225
  table->reginfo.lock_type=TL_READ;             /* Assume read */
2446
2226
 
2447
2227
 reset:
2448
2228
  assert(table->s->ref_count > 0 || table->s->tmp_table != NO_TMP_TABLE);
2449
2229
 
2450
 
  if (thd->lex->need_correct_ident())
 
2230
  if (session->lex->need_correct_ident())
2451
2231
    table->alias_name_used= my_strcasecmp(table_alias_charset,
2452
2232
                                          table->s->table_name.str, alias);
2453
2233
  /* Fix alias if table name changes */
2454
2234
  if (strcmp(table->alias, alias))
2455
2235
  {
2456
2236
    uint32_t length=(uint) strlen(alias)+1;
2457
 
    table->alias= (char*) my_realloc((char*) table->alias, length,
2458
 
                                     MYF(MY_WME));
 
2237
    table->alias= (char*) realloc((char*) table->alias, length);
2459
2238
    memcpy((void*) table->alias, alias, length);
2460
2239
  }
2461
2240
  /* These variables are also set in reopen_table() */
2462
 
  table->tablenr=thd->current_tablenr++;
 
2241
  table->tablenr=session->current_tablenr++;
2463
2242
  table->used_fields=0;
2464
2243
  table->const_table=0;
2465
2244
  table->null_row= false;
2479
2258
}
2480
2259
 
2481
2260
 
2482
 
Table *find_locked_table(THD *thd, const char *db,const char *table_name)
 
2261
Table *find_locked_table(Session *session, const char *db,const char *table_name)
2483
2262
{
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)
 
2263
  char key[MAX_DBKEY_LENGTH];
 
2264
  char *key_pos= key;
 
2265
  uint32_t key_length;
 
2266
 
 
2267
  key_pos= strcpy(key_pos, db) + strlen(db);
 
2268
  key_pos= strcpy(key_pos+1, table_name) + strlen(table_name);
 
2269
  key_length= (uint32_t)(key_pos-key)+1;
 
2270
 
 
2271
  for (Table *table=session->open_tables; table ; table=table->next)
2488
2272
  {
2489
2273
    if (table->s->table_cache_key.length == key_length &&
2490
2274
        !memcmp(table->s->table_cache_key.str, key, key_length))
2517
2301
  Field **field;
2518
2302
  uint32_t key,part;
2519
2303
  TableList table_list;
2520
 
  THD *thd= table->in_use;
 
2304
  Session *session= table->in_use;
2521
2305
 
2522
2306
  assert(table->s->ref_count == 0);
2523
2307
  assert(!table->sort.io_cache);
2524
2308
 
2525
2309
#ifdef EXTRA_DEBUG
2526
2310
  if (table->db_stat)
2527
 
    sql_print_error(_("Table %s had a open data handler in reopen_table"),
 
2311
    errmsg_printf(ERRMSG_LVL_ERROR, _("Table %s had a open data handler in reopen_table"),
2528
2312
                    table->alias);
2529
2313
#endif
2530
2314
  memset(&table_list, 0, sizeof(TableList));
2532
2316
  table_list.table_name= table->s->table_name.str;
2533
2317
  table_list.table=      table;
2534
2318
 
2535
 
  if (wait_for_locked_table_names(thd, &table_list))
 
2319
  if (wait_for_locked_table_names(session, &table_list))
2536
2320
    return(1);                             // Thread was killed
2537
2321
 
2538
 
  if (open_unireg_entry(thd, &tmp, &table_list,
 
2322
  if (open_unireg_entry(session, &tmp, &table_list,
2539
2323
                        table->alias,
2540
2324
                        table->s->table_cache_key.str,
2541
2325
                        table->s->table_cache_key.length))
2552
2336
  tmp.s->table_map_id=  table->s->table_map_id;
2553
2337
 
2554
2338
  /* Get state */
2555
 
  tmp.in_use=           thd;
 
2339
  tmp.in_use=           session;
2556
2340
  tmp.reginfo.lock_type=table->reginfo.lock_type;
2557
2341
 
2558
2342
  /* Replace table in open list */
2560
2344
  tmp.prev=             table->prev;
2561
2345
 
2562
2346
  if (table->file)
2563
 
    closefrm(table, 1);         // close file, free everything
 
2347
    table->closefrm(true);              // close file, free everything
2564
2348
 
2565
2349
  *table= tmp;
2566
2350
  table->default_column_bitmaps();
2595
2379
    Close all instances of a table open by this thread and replace
2596
2380
    them with exclusive name-locks.
2597
2381
 
2598
 
    @param thd        Thread context
 
2382
    @param session        Thread context
2599
2383
    @param db         Database name for the table to be closed
2600
2384
    @param table_name Name of the table to be closed
2601
2385
 
2608
2392
          the strings are used in a loop even after the share may be freed.
2609
2393
*/
2610
2394
 
2611
 
void close_data_files_and_morph_locks(THD *thd, const char *db,
 
2395
void close_data_files_and_morph_locks(Session *session, const char *db,
2612
2396
                                      const char *table_name)
2613
2397
{
2614
2398
  Table *table;
2615
2399
 
2616
2400
  safe_mutex_assert_owner(&LOCK_open);
2617
2401
 
2618
 
  if (thd->lock)
 
2402
  if (session->lock)
2619
2403
  {
2620
2404
    /*
2621
2405
      If we are not under LOCK TABLES we should have only one table
2622
2406
      open and locked so it makes sense to remove the lock at once.
2623
2407
    */
2624
 
    mysql_unlock_tables(thd, thd->lock);
2625
 
    thd->lock= 0;
 
2408
    mysql_unlock_tables(session, session->lock);
 
2409
    session->lock= 0;
2626
2410
  }
2627
2411
 
2628
2412
  /*
2630
2414
    for target table name if we process ALTER Table ... RENAME.
2631
2415
    So loop below makes sense even if we are not under LOCK TABLES.
2632
2416
  */
2633
 
  for (table=thd->open_tables; table ; table=table->next)
 
2417
  for (table=session->open_tables; table ; table=table->next)
2634
2418
  {
2635
2419
    if (!strcmp(table->s->table_name.str, table_name) &&
2636
2420
        !strcmp(table->s->db.str, db))
2637
2421
    {
2638
 
      if (thd->locked_tables)
 
2422
      if (session->locked_tables)
2639
2423
      {
2640
 
        mysql_lock_remove(thd, thd->locked_tables, table, true);
 
2424
        mysql_lock_remove(session, session->locked_tables, table, true);
2641
2425
      }
2642
2426
      table->open_placeholder= 1;
2643
2427
      close_handle_and_leave_table_as_lock(table);
2650
2434
/**
2651
2435
    Reopen all tables with closed data files.
2652
2436
 
2653
 
    @param thd         Thread context
 
2437
    @param session         Thread context
2654
2438
    @param get_locks   Should we get locks after reopening tables ?
2655
2439
    @param mark_share_as_old  Mark share as old to protect from a impending
2656
2440
                              global read lock.
2667
2451
    @return false in case of success, true - otherwise.
2668
2452
*/
2669
2453
 
2670
 
bool reopen_tables(THD *thd, bool get_locks, bool mark_share_as_old)
 
2454
bool reopen_tables(Session *session, bool get_locks, bool mark_share_as_old)
2671
2455
{
2672
2456
  Table *table,*next,**prev;
2673
2457
  Table **tables,**tables_ptr;                  // For locks
2676
2460
                    DRIZZLE_LOCK_IGNORE_GLOBAL_READ_LOCK |
2677
2461
                    DRIZZLE_LOCK_IGNORE_FLUSH;
2678
2462
 
2679
 
  if (!thd->open_tables)
 
2463
  if (!session->open_tables)
2680
2464
    return(0);
2681
2465
 
2682
2466
  safe_mutex_assert_owner(&LOCK_open);
2687
2471
      Do not handle locks of MERGE children.
2688
2472
    */
2689
2473
    uint32_t opens=0;
2690
 
    for (table= thd->open_tables; table ; table=table->next)
 
2474
    for (table= session->open_tables; table ; table=table->next)
2691
2475
      opens++;
2692
 
    tables= (Table**) my_alloca(sizeof(Table*)*opens);
 
2476
    tables= (Table**) malloc(sizeof(Table*)*opens);
2693
2477
  }
2694
2478
  else
2695
 
    tables= &thd->open_tables;
 
2479
    tables= &session->open_tables;
2696
2480
  tables_ptr =tables;
2697
2481
 
2698
 
  prev= &thd->open_tables;
2699
 
  for (table=thd->open_tables; table ; table=next)
 
2482
  prev= &session->open_tables;
 
2483
  for (table=session->open_tables; table ; table=next)
2700
2484
  {
2701
2485
    uint32_t db_stat=table->db_stat;
2702
2486
    next=table->next;
2729
2513
      wait_for_tables() as it tries to acquire LOCK_open, which is
2730
2514
      already locked.
2731
2515
    */
2732
 
    thd->some_tables_deleted=0;
2733
 
    if ((lock= mysql_lock_tables(thd, tables, (uint) (tables_ptr - tables),
 
2516
    session->some_tables_deleted=0;
 
2517
    if ((lock= mysql_lock_tables(session, tables, (uint) (tables_ptr - tables),
2734
2518
                                 flags, &not_used)))
2735
2519
    {
2736
 
      thd->locked_tables=mysql_lock_merge(thd->locked_tables,lock);
 
2520
      session->locked_tables=mysql_lock_merge(session->locked_tables,lock);
2737
2521
    }
2738
2522
    else
2739
2523
    {
2748
2532
  }
2749
2533
  if (get_locks && tables)
2750
2534
  {
2751
 
    my_afree((unsigned char*) tables);
 
2535
    free((unsigned char*) tables);
2752
2536
  }
2753
2537
  broadcast_refresh();
2754
2538
  return(error);
2759
2543
    Close handlers for tables in list, but leave the Table structure
2760
2544
    intact so that we can re-open these quickly.
2761
2545
 
2762
 
    @param thd           Thread context
 
2546
    @param session           Thread context
2763
2547
    @param table         Head of the list of Table objects
2764
2548
    @param morph_locks   true  - remove locks which we have on tables being closed
2765
2549
                                 but ensure that no DML or DDL will sneak in before
2769
2553
    @param send_refresh  Should we awake waiters even if we didn't close any tables?
2770
2554
*/
2771
2555
 
2772
 
static void close_old_data_files(THD *thd, Table *table, bool morph_locks,
 
2556
static void close_old_data_files(Session *session, Table *table, bool morph_locks,
2773
2557
                                 bool send_refresh)
2774
2558
{
2775
2559
  bool found= send_refresh;
2795
2579
              lock on it. This will also give them a chance to close their
2796
2580
              instances of this table.
2797
2581
            */
2798
 
            mysql_lock_abort(thd, ulcktbl, true);
2799
 
            mysql_lock_remove(thd, thd->locked_tables, ulcktbl, true);
 
2582
            mysql_lock_abort(session, ulcktbl, true);
 
2583
            mysql_lock_remove(session, session->locked_tables, ulcktbl, true);
2800
2584
            ulcktbl->lock_count= 0;
2801
2585
          }
2802
2586
          if ((ulcktbl != table) && ulcktbl->db_stat)
2881
2665
 
2882
2666
/* Wait until all used tables are refreshed */
2883
2667
 
2884
 
bool wait_for_tables(THD *thd)
 
2668
bool wait_for_tables(Session *session)
2885
2669
{
2886
2670
  bool result;
2887
2671
 
2888
 
  thd_proc_info(thd, "Waiting for tables");
 
2672
  session->set_proc_info("Waiting for tables");
2889
2673
  pthread_mutex_lock(&LOCK_open);
2890
 
  while (!thd->killed)
 
2674
  while (!session->killed)
2891
2675
  {
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))
 
2676
    session->some_tables_deleted=0;
 
2677
    close_old_data_files(session,session->open_tables,0,dropping_tables != 0);
 
2678
    mysql_ha_flush(session);
 
2679
    if (!table_is_used(session->open_tables,1))
2896
2680
      break;
2897
2681
    (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
2898
2682
  }
2899
 
  if (thd->killed)
 
2683
  if (session->killed)
2900
2684
    result= 1;                                  // aborted
2901
2685
  else
2902
2686
  {
2903
2687
    /* 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);
 
2688
    session->set_proc_info("Reopen tables");
 
2689
    session->version= refresh_version;
 
2690
    result=reopen_tables(session,0,0);
2907
2691
  }
2908
2692
  pthread_mutex_unlock(&LOCK_open);
2909
 
  thd_proc_info(thd, 0);
 
2693
  session->set_proc_info(0);
2910
2694
  return(result);
2911
2695
}
2912
2696
 
2916
2700
 
2917
2701
  SYNOPSIS
2918
2702
    drop_locked_tables()
2919
 
    thd                 Thread thandler
 
2703
    session                     Thread thandler
2920
2704
    db                  Database
2921
2705
    table_name          Table name
2922
2706
 
2935
2719
*/
2936
2720
 
2937
2721
 
2938
 
Table *drop_locked_tables(THD *thd,const char *db, const char *table_name)
 
2722
Table *drop_locked_tables(Session *session,const char *db, const char *table_name)
2939
2723
{
2940
2724
  Table *table,*next,**prev, *found= 0;
2941
 
  prev= &thd->open_tables;
 
2725
  prev= &session->open_tables;
2942
2726
 
2943
2727
  /*
2944
2728
    Note that we need to hold LOCK_open while changing the
2947
2731
    Closing a MERGE child before the parent would be fatal if the
2948
2732
    other thread tries to abort the MERGE lock in between.
2949
2733
  */
2950
 
  for (table= thd->open_tables; table ; table=next)
 
2734
  for (table= session->open_tables; table ; table=next)
2951
2735
  {
2952
2736
    next=table->next;
2953
2737
    if (!strcmp(table->s->table_name.str, table_name) &&
2954
2738
        !strcmp(table->s->db.str, db))
2955
2739
    {
2956
 
      mysql_lock_remove(thd, thd->locked_tables, table, true);
 
2740
      mysql_lock_remove(session, session->locked_tables, table, true);
2957
2741
 
2958
2742
      if (!found)
2959
2743
      {
2980
2764
  *prev=0;
2981
2765
  if (found)
2982
2766
    broadcast_refresh();
2983
 
  if (thd->locked_tables && thd->locked_tables->table_count == 0)
 
2767
  if (session->locked_tables && session->locked_tables->table_count == 0)
2984
2768
  {
2985
 
    free((unsigned char*) thd->locked_tables);
2986
 
    thd->locked_tables=0;
 
2769
    free((unsigned char*) session->locked_tables);
 
2770
    session->locked_tables=0;
2987
2771
  }
2988
2772
  return(found);
2989
2773
}
2995
2779
  other threads trying to get the lock.
2996
2780
*/
2997
2781
 
2998
 
void abort_locked_tables(THD *thd,const char *db, const char *table_name)
 
2782
void abort_locked_tables(Session *session,const char *db, const char *table_name)
2999
2783
{
3000
2784
  Table *table;
3001
 
  for (table= thd->open_tables; table ; table= table->next)
 
2785
  for (table= session->open_tables; table ; table= table->next)
3002
2786
  {
3003
2787
    if (!strcmp(table->s->table_name.str, table_name) &&
3004
2788
        !strcmp(table->s->db.str, db))
3005
2789
    {
3006
2790
      /* If MERGE child, forward lock handling to parent. */
3007
 
      mysql_lock_abort(thd, table, true);
 
2791
      mysql_lock_abort(session, table, true);
3008
2792
      break;
3009
2793
    }
3010
2794
  }
3068
2852
 
3069
2853
  SYNOPSIS
3070
2854
    open_unireg_entry()
3071
 
    thd                 Thread handle
 
2855
    session                     Thread handle
3072
2856
    entry               Store open table definition here
3073
2857
    table_list          TableList with db, table_name
3074
2858
    alias               Alias name
3076
2860
    cache_key_length    length of cache_key
3077
2861
 
3078
2862
  NOTES
3079
 
   Extra argument for open is taken from thd->open_options
 
2863
   Extra argument for open is taken from session->open_options
3080
2864
   One must have a lock on LOCK_open when calling this function
3081
2865
 
3082
2866
  RETURN
3084
2868
    #   Error
3085
2869
*/
3086
2870
 
3087
 
static int open_unireg_entry(THD *thd, Table *entry, TableList *table_list,
 
2871
static int open_unireg_entry(Session *session, Table *entry, TableList *table_list,
3088
2872
                             const char *alias,
3089
2873
                             char *cache_key, uint32_t cache_key_length)
3090
2874
{
3094
2878
 
3095
2879
  safe_mutex_assert_owner(&LOCK_open);
3096
2880
retry:
3097
 
  if (!(share= get_table_share_with_create(thd, table_list, cache_key,
3098
 
                                           cache_key_length, 
 
2881
  if (!(share= get_table_share_with_create(session, table_list, cache_key,
 
2882
                                           cache_key_length,
3099
2883
                                           table_list->i_s_requested_object,
3100
2884
                                           &error)))
3101
2885
    return(1);
3102
2886
 
3103
 
  while ((error= open_table_from_share(thd, share, alias,
 
2887
  while ((error= open_table_from_share(session, share, alias,
3104
2888
                                       (uint) (HA_OPEN_KEYFILE |
3105
2889
                                               HA_OPEN_RNDFILE |
3106
2890
                                               HA_GET_INDEX |
3107
2891
                                               HA_TRY_READ_ONLY),
3108
2892
                                       (EXTRA_RECORD),
3109
 
                                       thd->open_options, entry, OTM_OPEN)))
 
2893
                                       session->open_options, entry, OTM_OPEN)))
3110
2894
  {
3111
2895
    if (error == 7)                             // Table def changed
3112
2896
    {
3119
2903
        Here we should wait until all threads has released the table.
3120
2904
        For now we do one retry. This may cause a deadlock if there
3121
2905
        is other threads waiting for other tables used by this thread.
3122
 
        
 
2906
 
3123
2907
        Proper fix would be to if the second retry failed:
3124
2908
        - Mark that table def changed
3125
2909
        - Return from open table
3127
2911
        - Start waiting that the share is released
3128
2912
        - Retry by opening all tables again
3129
2913
      */
3130
 
      if (ha_create_table_from_engine(thd, table_list->db,
3131
 
                                      table_list->table_name))
3132
 
        goto err;
 
2914
 
3133
2915
      /*
3134
2916
        TO BE FIXED
3135
2917
        To avoid deadlock, only wait for release if no one else is
3139
2921
        goto err;
3140
2922
      /* Free share and wait until it's released by all threads */
3141
2923
      release_table_share(share, RELEASE_WAIT_FOR_DROP);
3142
 
      if (!thd->killed)
 
2924
      if (!session->killed)
3143
2925
      {
3144
 
        drizzle_reset_errors(thd, 1);         // Clear warnings
3145
 
        thd->clear_error();                 // Clear error message
 
2926
        drizzle_reset_errors(session, 1);         // Clear warnings
 
2927
        session->clear_error();                 // Clear error message
3146
2928
        goto retry;
3147
2929
      }
3148
2930
      return(1);
3150
2932
    if (!entry->s || !entry->s->crashed)
3151
2933
      goto err;
3152
2934
     // Code below is for repairing a crashed file
3153
 
     if ((error= lock_table_name(thd, table_list, true)))
 
2935
     if ((error= lock_table_name(session, table_list, true)))
3154
2936
     {
3155
2937
       if (error < 0)
3156
2938
        goto err;
3157
 
       if (wait_for_locked_table_names(thd, table_list))
 
2939
       if (wait_for_locked_table_names(session, table_list))
3158
2940
       {
3159
 
        unlock_table_name(thd, table_list);
 
2941
        unlock_table_name(session, table_list);
3160
2942
        goto err;
3161
2943
       }
3162
2944
     }
3163
2945
     pthread_mutex_unlock(&LOCK_open);
3164
 
     thd->clear_error();                                // Clear error message
 
2946
     session->clear_error();                            // Clear error message
3165
2947
     error= 0;
3166
 
     if (open_table_from_share(thd, share, alias,
 
2948
     if (open_table_from_share(session, share, alias,
3167
2949
                               (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
3168
2950
                                       HA_GET_INDEX |
3169
2951
                                       HA_TRY_READ_ONLY),
3170
2952
                               EXTRA_RECORD,
3171
2953
                               ha_open_options | HA_OPEN_FOR_REPAIR,
3172
2954
                               entry, OTM_OPEN) || ! entry->file ||
3173
 
        (entry->file->is_crashed() && entry->file->ha_check_and_repair(thd)))
 
2955
        (entry->file->is_crashed() && entry->file->ha_check_and_repair(session)))
3174
2956
     {
3175
2957
       /* Give right error message */
3176
 
       thd->clear_error();
 
2958
       session->clear_error();
3177
2959
       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,
 
2960
       errmsg_printf(ERRMSG_LVL_ERROR, _("Couldn't repair table: %s.%s"), share->db.str,
3179
2961
                       share->table_name.str);
3180
2962
       if (entry->file)
3181
 
        closefrm(entry, 0);
 
2963
        entry->closefrm(false);
3182
2964
       error=1;
3183
2965
     }
3184
2966
     else
3185
 
       thd->clear_error();                      // Clear error message
 
2967
       session->clear_error();                  // Clear error message
3186
2968
     pthread_mutex_lock(&LOCK_open);
3187
 
     unlock_table_name(thd, table_list);
3188
 
 
 
2969
     unlock_table_name(session, table_list);
 
2970
 
3189
2971
     if (error)
3190
2972
       goto err;
3191
2973
     break;
3198
2980
  if (unlikely(entry->file->implicit_emptied))
3199
2981
  {
3200
2982
    entry->file->implicit_emptied= 0;
3201
 
    if (mysql_bin_log.is_open())
3202
2983
    {
3203
2984
      char *query, *end;
3204
2985
      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))))
 
2986
      if ((query= (char*) malloc(query_buf_size)))
3206
2987
      {
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);
 
2988
        /* 
 
2989
          "this DELETE FROM is needed even with row-based binlogging"
 
2990
 
 
2991
          We inherited this from MySQL. TODO: fix it to issue a propper truncate
 
2992
          of the table (though that may not be completely right sematics).
 
2993
        */
 
2994
        end= query;
 
2995
        end+= sprintf(query, "DELETE FROM `%s`.`%s`", share->db.str,
 
2996
                      share->table_name.str);
 
2997
        (void)replicator_statement(session, query, (size_t)(end - query));
3212
2998
        free(query);
3213
2999
      }
3214
3000
      else
3215
3001
      {
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);
 
3002
        errmsg_printf(ERRMSG_LVL_ERROR, _("When opening HEAP table, could not allocate memory "
 
3003
                                          "to write 'DELETE FROM `%s`.`%s`' to replication"),
 
3004
                      table_list->db, table_list->table_name);
 
3005
        my_error(ER_OUTOFMEMORY, MYF(0), query_buf_size);
 
3006
        entry->closefrm(false);
3225
3007
        goto err;
3226
3008
      }
3227
3009
    }
3239
3021
 
3240
3022
  SYNOPSIS
3241
3023
    open_tables()
3242
 
    thd - thread handler
 
3024
    session - thread handler
3243
3025
    start - list of tables in/out
3244
3026
    counter - number of opened tables will be return using this parameter
3245
3027
    flags   - bitmap of flags to modify how the tables will be open:
3262
3044
    -1 - error
3263
3045
*/
3264
3046
 
3265
 
int open_tables(THD *thd, TableList **start, uint32_t *counter, uint32_t flags)
 
3047
int open_tables(Session *session, TableList **start, uint32_t *counter, uint32_t flags)
3266
3048
{
3267
3049
  TableList *tables= NULL;
3268
3050
  bool refresh;
3277
3059
  */
3278
3060
  init_sql_alloc(&new_frm_mem, 8024, 8024);
3279
3061
 
3280
 
  thd->current_tablenr= 0;
 
3062
  session->current_tablenr= 0;
3281
3063
 restart:
3282
3064
  *counter= 0;
3283
 
  thd_proc_info(thd, "Opening tables");
 
3065
  session->set_proc_info("Opening tables");
3284
3066
 
3285
3067
  /*
3286
3068
    For every table in the list of tables to open, try to find or open
3308
3090
    */
3309
3091
    if (tables->schema_table)
3310
3092
    {
3311
 
      if (!mysql_schema_table(thd, thd->lex, tables))
 
3093
      if (!mysql_schema_table(session, session->lex, tables))
3312
3094
        continue;
3313
3095
      return(-1);
3314
3096
    }
3319
3101
      not opened yet. Try to open the table.
3320
3102
    */
3321
3103
    if (!tables->table)
3322
 
      tables->table= open_table(thd, tables, &refresh, flags);
 
3104
      tables->table= open_table(session, tables, &refresh, flags);
3323
3105
 
3324
3106
    if (!tables->table)
3325
3107
    {
3341
3123
          we pretend that we have finished calculation which we were doing
3342
3124
          currently.
3343
3125
        */
3344
 
        close_tables_for_reopen(thd, start);
 
3126
        close_tables_for_reopen(session, start);
3345
3127
        goto restart;
3346
3128
      }
3347
3129
 
3351
3133
      result= -1;                               // Fatal error
3352
3134
      break;
3353
3135
    }
3354
 
    if (tables->lock_type != TL_UNLOCK && ! thd->locked_tables)
 
3136
    if (tables->lock_type != TL_UNLOCK && ! session->locked_tables)
3355
3137
    {
3356
3138
      if (tables->lock_type == TL_WRITE_DEFAULT)
3357
 
        tables->table->reginfo.lock_type= thd->update_lock_default;
 
3139
        tables->table->reginfo.lock_type= session->update_lock_default;
3358
3140
      else if (tables->table->s->tmp_table == NO_TMP_TABLE)
3359
3141
        tables->table->reginfo.lock_type= tables->lock_type;
3360
3142
    }
3361
3143
  }
3362
3144
 
3363
 
  thd_proc_info(thd, 0);
 
3145
  session->set_proc_info(0);
3364
3146
  free_root(&new_frm_mem, MYF(0));              // Free pre-alloced block
3365
3147
 
3366
3148
  if (result && tables)
3367
3149
  {
3368
3150
    /*
3369
3151
      Some functions determine success as (tables->table != NULL).
3370
 
      tables->table is in thd->open_tables.
 
3152
      tables->table is in session->open_tables.
3371
3153
    */
3372
3154
    tables->table= NULL;
3373
3155
  }
3380
3162
 
3381
3163
  SYNOPSIS
3382
3164
    check_lock_and_start_stmt()
3383
 
    thd                 Thread handle
 
3165
    session                     Thread handle
3384
3166
    table_list          Table to check
3385
3167
    lock_type           Lock used for table
3386
3168
 
3389
3171
  1     error
3390
3172
*/
3391
3173
 
3392
 
static bool check_lock_and_start_stmt(THD *thd, Table *table,
 
3174
static bool check_lock_and_start_stmt(Session *session, Table *table,
3393
3175
                                      thr_lock_type lock_type)
3394
3176
{
3395
3177
  int error;
3400
3182
    my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0),table->alias);
3401
3183
    return(1);
3402
3184
  }
3403
 
  if ((error=table->file->start_stmt(thd, lock_type)))
 
3185
  if ((error=table->file->start_stmt(session, lock_type)))
3404
3186
  {
3405
3187
    table->file->print_error(error,MYF(0));
3406
3188
    return(1);
3412
3194
/**
3413
3195
  @brief Open and lock one table
3414
3196
 
3415
 
  @param[in]    thd             thread handle
 
3197
  @param[in]    session             thread handle
3416
3198
  @param[in]    table_l         table to open is first table in this list
3417
3199
  @param[in]    lock_type       lock to use for table
3418
3200
 
3439
3221
    and locking issues because it does not call lock_tables().
3440
3222
*/
3441
3223
 
3442
 
Table *open_n_lock_single_table(THD *thd, TableList *table_l,
 
3224
Table *open_n_lock_single_table(Session *session, TableList *table_l,
3443
3225
                                thr_lock_type lock_type)
3444
3226
{
3445
3227
  TableList *save_next_global;
3453
3235
  table_l->lock_type= lock_type;
3454
3236
 
3455
3237
  /* Open the table. */
3456
 
  if (simple_open_n_lock_tables(thd, table_l))
 
3238
  if (simple_open_n_lock_tables(session, table_l))
3457
3239
    table_l->table= NULL; /* Just to be sure. */
3458
3240
 
3459
3241
  /* Restore list. */
3468
3250
 
3469
3251
  SYNOPSIS
3470
3252
    open_ltable()
3471
 
    thd                 Thread handler
 
3253
    session                     Thread handler
3472
3254
    table_list          Table to open is first table in this list
3473
3255
    lock_type           Lock to use for open
3474
3256
    lock_flags          Flags passed to mysql_lock_table
3481
3263
  RETURN VALUES
3482
3264
    table               Opened table
3483
3265
    0                   Error
3484
 
  
 
3266
 
3485
3267
    If ok, the following are also set:
3486
3268
      table_list->lock_type     lock_type
3487
3269
      table_list->table         table
3488
3270
*/
3489
3271
 
3490
 
Table *open_ltable(THD *thd, TableList *table_list, thr_lock_type lock_type,
 
3272
Table *open_ltable(Session *session, TableList *table_list, thr_lock_type lock_type,
3491
3273
                   uint32_t lock_flags)
3492
3274
{
3493
3275
  Table *table;
3494
3276
  bool refresh;
3495
3277
 
3496
 
  thd_proc_info(thd, "Opening table");
3497
 
  thd->current_tablenr= 0;
3498
 
  while (!(table= open_table(thd, table_list, &refresh, 0)) &&
 
3278
  session->set_proc_info("Opening table");
 
3279
  session->current_tablenr= 0;
 
3280
  while (!(table= open_table(session, table_list, &refresh, 0)) &&
3499
3281
         refresh)
3500
3282
    ;
3501
3283
 
3503
3285
  {
3504
3286
    table_list->lock_type= lock_type;
3505
3287
    table_list->table=     table;
3506
 
    if (thd->locked_tables)
 
3288
    if (session->locked_tables)
3507
3289
    {
3508
 
      if (check_lock_and_start_stmt(thd, table, lock_type))
 
3290
      if (check_lock_and_start_stmt(session, table, lock_type))
3509
3291
        table= 0;
3510
3292
    }
3511
3293
    else
3512
3294
    {
3513
 
      assert(thd->lock == 0);   // You must lock everything at once
 
3295
      assert(session->lock == 0);       // You must lock everything at once
3514
3296
      if ((table->reginfo.lock_type= lock_type) != TL_UNLOCK)
3515
 
        if (! (thd->lock= mysql_lock_tables(thd, &table_list->table, 1,
 
3297
        if (! (session->lock= mysql_lock_tables(session, &table_list->table, 1,
3516
3298
                                            lock_flags, &refresh)))
3517
3299
          table= 0;
3518
3300
    }
3519
3301
  }
3520
3302
 
3521
 
  thd_proc_info(thd, 0);
 
3303
  session->set_proc_info(0);
3522
3304
  return(table);
3523
3305
}
3524
3306
 
3528
3310
 
3529
3311
  SYNOPSIS
3530
3312
    open_and_lock_tables_derived()
3531
 
    thd         - thread handler
 
3313
    session             - thread handler
3532
3314
    tables      - list of tables for open&locking
3533
3315
    derived     - if to handle derived tables
3534
3316
 
3541
3323
 
3542
3324
  NOTE
3543
3325
    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
 
3326
    - simple_open_n_lock_tables(session, tables)  without derived handling
 
3327
    - open_and_lock_tables(session, tables)       with derived handling
3546
3328
    Both inline functions call open_and_lock_tables_derived() with
3547
3329
    the third argument set appropriately.
3548
3330
*/
3549
3331
 
3550
 
int open_and_lock_tables_derived(THD *thd, TableList *tables, bool derived)
 
3332
int open_and_lock_tables_derived(Session *session, TableList *tables, bool derived)
3551
3333
{
3552
3334
  uint32_t counter;
3553
3335
  bool need_reopen;
3554
3336
 
3555
 
  for ( ; ; ) 
 
3337
  for ( ; ; )
3556
3338
  {
3557
 
    if (open_tables(thd, &tables, &counter, 0))
 
3339
    if (open_tables(session, &tables, &counter, 0))
3558
3340
      return(-1);
3559
3341
 
3560
 
    if (!lock_tables(thd, tables, counter, &need_reopen))
 
3342
    if (!lock_tables(session, tables, counter, &need_reopen))
3561
3343
      break;
3562
3344
    if (!need_reopen)
3563
3345
      return(-1);
3564
 
    close_tables_for_reopen(thd, &tables);
 
3346
    close_tables_for_reopen(session, &tables);
3565
3347
  }
3566
3348
  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))))
 
3349
      (mysql_handle_derived(session->lex, &mysql_derived_prepare) ||
 
3350
       (session->fill_derived_tables() &&
 
3351
        mysql_handle_derived(session->lex, &mysql_derived_filling))))
3570
3352
    return(true); /* purecov: inspected */
3571
3353
  return(0);
3572
3354
}
3577
3359
 
3578
3360
  SYNOPSIS
3579
3361
    open_normal_and_derived_tables
3580
 
    thd         - thread handler
 
3362
    session             - thread handler
3581
3363
    tables      - list of tables for open
3582
3364
    flags       - bitmap of flags to modify how the tables will be open:
3583
3365
                  DRIZZLE_LOCK_IGNORE_FLUSH - open table even if someone has
3587
3369
    false - ok
3588
3370
    true  - error
3589
3371
 
3590
 
  NOTE 
 
3372
  NOTE
3591
3373
    This is to be used on prepare stage when you don't read any
3592
3374
    data from the tables.
3593
3375
*/
3594
3376
 
3595
 
bool open_normal_and_derived_tables(THD *thd, TableList *tables, uint32_t flags)
 
3377
bool open_normal_and_derived_tables(Session *session, TableList *tables, uint32_t flags)
3596
3378
{
3597
3379
  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))
 
3380
  assert(!session->fill_derived_tables());
 
3381
  if (open_tables(session, &tables, &counter, flags) ||
 
3382
      mysql_handle_derived(session->lex, &mysql_derived_prepare))
3601
3383
    return(true); /* purecov: inspected */
3602
3384
  return(0);
3603
3385
}
3604
3386
 
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
3387
/*
3713
3388
  Lock all tables in list
3714
3389
 
3715
3390
  SYNOPSIS
3716
3391
    lock_tables()
3717
 
    thd                 Thread handler
 
3392
    session                     Thread handler
3718
3393
    tables              Tables to lock
3719
3394
    count               Number of opened tables
3720
3395
    need_reopen         Out parameter which if true indicates that some
3730
3405
 
3731
3406
    If query for which we are calling this function marked as requring
3732
3407
    prelocking, this function will do implicit LOCK TABLES and change
3733
 
    thd::prelocked_mode accordingly.
 
3408
    session::prelocked_mode accordingly.
3734
3409
 
3735
3410
  RETURN VALUES
3736
3411
   0    ok
3737
3412
   -1   Error
3738
3413
*/
3739
3414
 
3740
 
int lock_tables(THD *thd, TableList *tables, uint32_t count, bool *need_reopen)
 
3415
int lock_tables(Session *session, TableList *tables, uint32_t count, bool *need_reopen)
3741
3416
{
3742
3417
  TableList *table;
3743
3418
 
3748
3423
  *need_reopen= false;
3749
3424
 
3750
3425
  if (!tables)
3751
 
    return(decide_logging_format(thd, tables));
 
3426
    return 0;
3752
3427
 
3753
 
  if (!thd->locked_tables)
 
3428
  if (!session->locked_tables)
3754
3429
  {
3755
 
    assert(thd->lock == 0);     // You must lock everything at once
 
3430
    assert(session->lock == 0); // You must lock everything at once
3756
3431
    Table **start,**ptr;
3757
3432
    uint32_t lock_flag= DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN;
3758
3433
 
3759
 
    if (!(ptr=start=(Table**) thd->alloc(sizeof(Table*)*count)))
 
3434
    if (!(ptr=start=(Table**) session->alloc(sizeof(Table*)*count)))
3760
3435
      return(-1);
3761
3436
    for (table= tables; table; table= table->next_global)
3762
3437
    {
3764
3439
        *(ptr++)= table->table;
3765
3440
    }
3766
3441
 
3767
 
    if (!(thd->lock= mysql_lock_tables(thd, start, (uint) (ptr - start),
 
3442
    if (!(session->lock= mysql_lock_tables(session, start, (uint) (ptr - start),
3768
3443
                                       lock_flag, need_reopen)))
3769
3444
    {
3770
3445
      return(-1);
3772
3447
  }
3773
3448
  else
3774
3449
  {
3775
 
    TableList *first_not_own= thd->lex->first_not_own_table();
 
3450
    TableList *first_not_own= session->lex->first_not_own_table();
3776
3451
    /*
3777
3452
      When open_and_lock_tables() is called for a single table out of
3778
3453
      a table list, the 'next_global' chain is temporarily broken. We
3786
3461
         table= table->next_global)
3787
3462
    {
3788
3463
      if (!table->placeholder() &&
3789
 
          check_lock_and_start_stmt(thd, table->table, table->lock_type))
 
3464
          check_lock_and_start_stmt(session, table->table, table->lock_type))
3790
3465
      {
3791
3466
        return(-1);
3792
3467
      }
3793
3468
    }
3794
3469
  }
3795
3470
 
3796
 
  return(decide_logging_format(thd, tables));
 
3471
  return 0;
3797
3472
}
3798
3473
 
3799
3474
 
3803
3478
 
3804
3479
  SYNOPSIS
3805
3480
    close_tables_for_reopen()
3806
 
      thd    in     Thread context
 
3481
      session    in     Thread context
3807
3482
      tables in/out List of tables which we were trying to open and lock
3808
3483
 
3809
3484
*/
3810
3485
 
3811
 
void close_tables_for_reopen(THD *thd, TableList **tables)
 
3486
void close_tables_for_reopen(Session *session, TableList **tables)
3812
3487
{
3813
3488
  /*
3814
3489
    If table list consists only from tables from prelocking set, table list
3815
3490
    for new attempt should be empty, so we have to update list's root pointer.
3816
3491
  */
3817
 
  if (thd->lex->first_not_own_table() == *tables)
 
3492
  if (session->lex->first_not_own_table() == *tables)
3818
3493
    *tables= 0;
3819
 
  thd->lex->chop_off_not_own_tables();
 
3494
  session->lex->chop_off_not_own_tables();
3820
3495
  for (TableList *tmp= *tables; tmp; tmp= tmp->next_global)
3821
3496
    tmp->table= 0;
3822
 
  close_thread_tables(thd);
 
3497
  close_thread_tables(session);
3823
3498
}
3824
3499
 
3825
3500
 
3828
3503
 
3829
3504
  SYNPOSIS
3830
3505
    open_temporary_table()
3831
 
    thd           Thread object
 
3506
    session               Thread object
3832
3507
    path          Path (without .frm)
3833
3508
    db            database
3834
3509
    table_name    Table name
3835
 
    link_in_list  1 if table should be linked into thd->temporary_tables
 
3510
    link_in_list  1 if table should be linked into session->temporary_tables
3836
3511
 
3837
3512
 NOTES:
3838
3513
    Used by alter_table to open a temporary table and when creating
3843
3518
   #  Table object
3844
3519
*/
3845
3520
 
3846
 
Table *open_temporary_table(THD *thd, const char *path, const char *db,
 
3521
Table *open_temporary_table(Session *session, const char *path, const char *db,
3847
3522
                            const char *table_name, bool link_in_list,
3848
3523
                            open_table_mode open_mode)
3849
3524
{
3850
3525
  Table *tmp_table;
3851
3526
  TABLE_SHARE *share;
3852
3527
  char cache_key[MAX_DBKEY_LENGTH], *saved_cache_key, *tmp_path;
3853
 
  uint32_t key_length;
 
3528
  uint32_t key_length, path_length;
3854
3529
  TableList table_list;
3855
3530
 
3856
3531
  table_list.db=         (char*) db;
3857
3532
  table_list.table_name= (char*) table_name;
3858
3533
  /* Create the cache_key for temporary tables */
3859
 
  key_length= create_table_def_key(thd, cache_key, &table_list, 1);
 
3534
  key_length= create_table_def_key(session, cache_key, &table_list, 1);
 
3535
  path_length= strlen(path);
3860
3536
 
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 */
 
3537
  if (!(tmp_table= (Table*) malloc(sizeof(*tmp_table) + sizeof(*share) +
 
3538
                                   path_length + 1 + key_length)))
 
3539
    return NULL;
3865
3540
 
3866
3541
  share= (TABLE_SHARE*) (tmp_table+1);
3867
3542
  tmp_path= (char*) (share+1);
3868
 
  saved_cache_key= my_stpcpy(tmp_path, path)+1;
 
3543
  saved_cache_key= strcpy(tmp_path, path)+path_length+1;
3869
3544
  memcpy(saved_cache_key, cache_key, key_length);
3870
3545
 
3871
 
  init_tmp_table_share(thd, share, saved_cache_key, key_length,
 
3546
  init_tmp_table_share(session, share, saved_cache_key, key_length,
3872
3547
                       strchr(saved_cache_key, '\0')+1, tmp_path);
3873
3548
 
3874
 
  if (open_table_def(thd, share, 0) ||
3875
 
      open_table_from_share(thd, share, table_name,
 
3549
  if (open_table_def(session, share, 0) ||
 
3550
      open_table_from_share(session, share, table_name,
3876
3551
                            (open_mode == OTM_ALTER) ? 0 :
3877
3552
                            (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
3878
3553
                                    HA_GET_INDEX),
3904
3579
  if (link_in_list)
3905
3580
  {
3906
3581
    /* growing temp list at the head */
3907
 
    tmp_table->next= thd->temporary_tables;
 
3582
    tmp_table->next= session->temporary_tables;
3908
3583
    if (tmp_table->next)
3909
3584
      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++;
 
3585
    session->temporary_tables= tmp_table;
 
3586
    session->temporary_tables->prev= 0;
3914
3587
  }
3915
3588
  tmp_table->pos_in_table_list= 0;
3916
3589
  return(tmp_table);
3917
3590
}
3918
3591
 
3919
3592
 
3920
 
bool rm_temporary_table(handlerton *base, char *path, bool frm_only)
 
3593
bool rm_temporary_table(handlerton *base, char *path)
3921
3594
{
3922
3595
  bool error=0;
3923
3596
  handler *file;
3924
3597
  char *ext;
3925
3598
 
3926
 
  my_stpcpy(ext= strchr(path, '\0'), reg_ext);
 
3599
  delete_table_proto_file(path);
 
3600
 
 
3601
  strcpy(ext= strchr(path, '\0'), reg_ext);
3927
3602
  if (my_delete(path,MYF(0)))
3928
3603
    error=1; /* purecov: inspected */
3929
3604
  *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))
 
3605
  file= get_new_handler((TABLE_SHARE*) 0, current_session->mem_root, base);
 
3606
  if (file && file->ha_delete_table(path))
3932
3607
  {
3933
3608
    error=1;
3934
 
    sql_print_warning(_("Could not remove temporary table: '%s', error: %d"),
 
3609
    errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
3935
3610
                      path, my_errno);
3936
3611
  }
3937
3612
  delete file;
3950
3625
 
3951
3626
/* Special Field pointers as return values of find_field_in_XXX functions. */
3952
3627
Field *not_found_field= (Field*) 0x1;
3953
 
Field *view_ref_found= (Field*) 0x2; 
 
3628
Field *view_ref_found= (Field*) 0x2;
3954
3629
 
3955
3630
#define WRONG_GRANT (Field*) -1
3956
3631
 
3957
 
static void update_field_dependencies(THD *thd, Field *field, Table *table)
 
3632
static void update_field_dependencies(Session *session, Field *field, Table *table)
3958
3633
{
3959
 
  if (thd->mark_used_columns != MARK_COLUMNS_NONE)
 
3634
  if (session->mark_used_columns != MARK_COLUMNS_NONE)
3960
3635
  {
3961
3636
    MY_BITMAP *current_bitmap, *other_bitmap;
3962
3637
 
3964
3639
      We always want to register the used keys, as the column bitmap may have
3965
3640
      been set for all fields (for example for view).
3966
3641
    */
3967
 
      
 
3642
 
3968
3643
    table->covering_keys.intersect(field->part_of_key);
3969
3644
    table->merge_keys.merge(field->part_of_key);
3970
3645
 
3971
 
    if (thd->mark_used_columns == MARK_COLUMNS_READ)
 
3646
    if (session->mark_used_columns == MARK_COLUMNS_READ)
3972
3647
    {
3973
3648
      current_bitmap= table->read_set;
3974
3649
      other_bitmap=   table->write_set;
3981
3656
 
3982
3657
    if (bitmap_fast_test_and_set(current_bitmap, field->field_index))
3983
3658
    {
3984
 
      if (thd->mark_used_columns == MARK_COLUMNS_WRITE)
3985
 
        thd->dup_field= field;
 
3659
      if (session->mark_used_columns == MARK_COLUMNS_WRITE)
 
3660
        session->dup_field= field;
3986
3661
      return;
3987
3662
    }
3988
3663
    if (table->get_fields_in_item_tree)
4000
3675
 
4001
3676
  SYNOPSIS
4002
3677
    find_field_in_natural_join()
4003
 
    thd                  [in]  thread handler
 
3678
    session                      [in]  thread handler
4004
3679
    table_ref            [in]  table reference to search
4005
3680
    name                 [in]  name of field
4006
3681
    length               [in]  length of name
4025
3700
*/
4026
3701
 
4027
3702
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)
 
3703
find_field_in_natural_join(Session *session, TableList *table_ref,
 
3704
                           const char *name, uint32_t , Item **,
 
3705
                           bool, TableList **actual_table)
4032
3706
{
4033
3707
  List_iterator_fast<Natural_join_column>
4034
3708
    field_it(*(table_ref->join_columns));
4038
3712
  assert(table_ref->is_natural_join && table_ref->join_columns);
4039
3713
  assert(*actual_table == NULL);
4040
3714
 
4041
 
  for (nj_col= NULL, curr_nj_col= field_it++; curr_nj_col; 
 
3715
  for (nj_col= NULL, curr_nj_col= field_it++; curr_nj_col;
4042
3716
       curr_nj_col= field_it++)
4043
3717
  {
4044
3718
    if (!my_strcasecmp(system_charset_info, curr_nj_col->name(), name))
4045
3719
    {
4046
3720
      if (nj_col)
4047
3721
      {
4048
 
        my_error(ER_NON_UNIQ_ERROR, MYF(0), name, thd->where);
 
3722
        my_error(ER_NON_UNIQ_ERROR, MYF(0), name, session->where);
4049
3723
        return(NULL);
4050
3724
      }
4051
3725
      nj_col= curr_nj_col;
4057
3731
    /* This is a base table. */
4058
3732
    assert(nj_col->table_ref->table == nj_col->table_field->table);
4059
3733
    found_field= nj_col->table_field;
4060
 
    update_field_dependencies(thd, found_field, nj_col->table_ref->table);
 
3734
    update_field_dependencies(session, found_field, nj_col->table_ref->table);
4061
3735
  }
4062
3736
 
4063
3737
  *actual_table= nj_col->table_ref;
4064
 
  
 
3738
 
4065
3739
  return(found_field);
4066
3740
}
4067
3741
 
4071
3745
 
4072
3746
  SYNOPSIS
4073
3747
    find_field_in_table()
4074
 
    thd                         thread handler
 
3748
    session                             thread handler
4075
3749
    table                       table where to search for the field
4076
3750
    name                        name of field
4077
3751
    length                      length of name
4085
3759
*/
4086
3760
 
4087
3761
Field *
4088
 
find_field_in_table(THD *thd, Table *table, const char *name, uint32_t length,
 
3762
find_field_in_table(Session *session, Table *table, const char *name, uint32_t length,
4089
3763
                    bool allow_rowid, uint32_t *cached_field_index_ptr)
4090
3764
{
4091
3765
  Field **field_ptr, *field;
4120
3794
 
4121
3795
  if (field_ptr && *field_ptr)
4122
3796
  {
 
3797
    if ((*field_ptr)->vcol_info)
 
3798
    {
 
3799
      if (session->mark_used_columns != MARK_COLUMNS_NONE)
 
3800
      {
 
3801
        Item *vcol_item= (*field_ptr)->vcol_info->expr_item;
 
3802
        assert(vcol_item);
 
3803
        vcol_item->walk(&Item::register_field_in_read_map, 1, (unsigned char *) 0);
 
3804
        /*
 
3805
          Set the virtual field for write here if
 
3806
          1) this procedure is called for a read-only operation (SELECT), and
 
3807
          2) the virtual column is not phycically stored in the table
 
3808
        */
 
3809
        if ((session->mark_used_columns != MARK_COLUMNS_WRITE) &&
 
3810
            (not (*field_ptr)->is_stored))
 
3811
          bitmap_set_bit((*field_ptr)->table->write_set, (*field_ptr)->field_index);
 
3812
      }
 
3813
    }
4123
3814
    *cached_field_index_ptr= field_ptr - table->field;
4124
3815
    field= *field_ptr;
4125
3816
  }
4132
3823
    field= table->field[table->s->rowid_field_offset-1];
4133
3824
  }
4134
3825
 
4135
 
  update_field_dependencies(thd, field, table);
 
3826
  update_field_dependencies(session, field, table);
4136
3827
 
4137
3828
  return(field);
4138
3829
}
4143
3834
 
4144
3835
  SYNOPSIS
4145
3836
    find_field_in_table_ref()
4146
 
    thd                    [in]  thread handler
 
3837
    session                        [in]  thread handler
4147
3838
    table_list             [in]  table reference to search
4148
3839
    name                   [in]  name of field
4149
3840
    length                 [in]  field length of name
4181
3872
*/
4182
3873
 
4183
3874
Field *
4184
 
find_field_in_table_ref(THD *thd, TableList *table_list,
 
3875
find_field_in_table_ref(Session *session, TableList *table_list,
4185
3876
                        const char *name, uint32_t length,
4186
3877
                        const char *item_name, const char *db_name,
4187
3878
                        const char *table_name, Item **ref,
4213
3904
          something !
4214
3905
  */
4215
3906
  if (/* Exclude nested joins. */
4216
 
      (!table_list->nested_join ||
 
3907
      (!table_list->nested_join) &&
4217
3908
       /* Include merge views and information schema tables. */
4218
 
       table_list->field_translation) &&
4219
3909
      /*
4220
3910
        Test if the field qualifiers match the table reference we plan
4221
3911
        to search.
4228
3918
 
4229
3919
  *actual_table= NULL;
4230
3920
 
4231
 
  if (table_list->field_translation)
4232
 
  {
4233
 
  }
4234
 
  else if (!table_list->nested_join)
 
3921
  if (!table_list->nested_join)
4235
3922
  {
4236
3923
    /* 'table_list' is a stored table. */
4237
3924
    assert(table_list->table);
4238
 
    if ((fld= find_field_in_table(thd, table_list->table, name, length,
 
3925
    if ((fld= find_field_in_table(session, table_list->table, name, length,
4239
3926
                                  allow_rowid,
4240
3927
                                  cached_field_index_ptr)))
4241
3928
      *actual_table= table_list;
4255
3942
      TableList *table;
4256
3943
      while ((table= it++))
4257
3944
      {
4258
 
        if ((fld= find_field_in_table_ref(thd, table, name, length, item_name,
 
3945
        if ((fld= find_field_in_table_ref(session, table, name, length, item_name,
4259
3946
                                          db_name, table_name, ref,
4260
3947
                                          check_privileges, allow_rowid,
4261
3948
                                          cached_field_index_ptr,
4270
3957
      natural join, thus if the field is not qualified, we will search
4271
3958
      directly the top-most NATURAL/USING join.
4272
3959
    */
4273
 
    fld= find_field_in_natural_join(thd, table_list, name, length, ref,
 
3960
    fld= find_field_in_natural_join(session, table_list, name, length, ref,
4274
3961
                                    register_tree_change, actual_table);
4275
3962
  }
4276
3963
 
4277
3964
  if (fld)
4278
3965
  {
4279
 
      if (thd->mark_used_columns != MARK_COLUMNS_NONE)
 
3966
      if (session->mark_used_columns != MARK_COLUMNS_NONE)
4280
3967
      {
4281
3968
        /*
4282
3969
          Get rw_set correct for this field so that the handler
4291
3978
            field_to_set= ((Item_field*)it)->field;
4292
3979
          else
4293
3980
          {
4294
 
            if (thd->mark_used_columns == MARK_COLUMNS_READ)
 
3981
            if (session->mark_used_columns == MARK_COLUMNS_READ)
4295
3982
              it->walk(&Item::register_field_in_read_map, 1, (unsigned char *) 0);
4296
3983
          }
4297
3984
        }
4300
3987
        if (field_to_set)
4301
3988
        {
4302
3989
          Table *table= field_to_set->table;
4303
 
          if (thd->mark_used_columns == MARK_COLUMNS_READ)
 
3990
          if (session->mark_used_columns == MARK_COLUMNS_READ)
4304
3991
            bitmap_set_bit(table->read_set, field_to_set->field_index);
4305
3992
          else
4306
3993
            bitmap_set_bit(table->write_set, field_to_set->field_index);
4362
4049
 
4363
4050
  SYNOPSIS
4364
4051
    find_field_in_tables()
4365
 
    thd                   pointer to current thread structure
 
4052
    session                       pointer to current thread structure
4366
4053
    item                  field item that should be found
4367
4054
    first_table           list of tables to be searched for item
4368
4055
    last_table            end of the list of tables to search for item. If NULL
4392
4079
*/
4393
4080
 
4394
4081
Field *
4395
 
find_field_in_tables(THD *thd, Item_ident *item,
 
4082
find_field_in_tables(Session *session, Item_ident *item,
4396
4083
                     TableList *first_table, TableList *last_table,
4397
4084
                     Item **ref, find_item_error_report_type report_error,
4398
4085
                     bool check_privileges, bool register_tree_change)
4433
4120
      when table_ref->field_translation != NULL.
4434
4121
      */
4435
4122
    if (table_ref->table)
4436
 
      found= find_field_in_table(thd, table_ref->table, name, length,
 
4123
      found= find_field_in_table(session, table_ref->table, name, length,
4437
4124
                                 true, &(item->cached_field_index));
4438
4125
    else
4439
 
      found= find_field_in_table_ref(thd, table_ref, name, length, item->name,
 
4126
      found= find_field_in_table_ref(session, table_ref, name, length, item->name,
4440
4127
                                     NULL, NULL, ref, check_privileges,
4441
4128
                                     true, &(item->cached_field_index),
4442
4129
                                     register_tree_change,
4451
4138
        fields.
4452
4139
      */
4453
4140
      {
4454
 
        SELECT_LEX *current_sel= thd->lex->current_select;
4455
 
        SELECT_LEX *last_select= table_ref->select_lex;
 
4141
        Select_Lex *current_sel= session->lex->current_select;
 
4142
        Select_Lex *last_select= table_ref->select_lex;
4456
4143
        /*
4457
4144
          If the field was an outer referencee, mark all selects using this
4458
4145
          sub query as dependent on the outer query
4459
4146
        */
4460
4147
        if (current_sel != last_select)
4461
 
          mark_select_range_as_dependent(thd, last_select, current_sel,
 
4148
          mark_select_range_as_dependent(session, last_select, current_sel,
4462
4149
                                         found, *ref, item);
4463
4150
      }
4464
4151
      return found;
4472
4159
      We can't do this in Item_field as this would change the
4473
4160
      'name' of the item which may be used in the select list
4474
4161
    */
4475
 
    strmake(name_buff, db, sizeof(name_buff)-1);
 
4162
    strncpy(name_buff, db, sizeof(name_buff)-1);
4476
4163
    my_casedn_str(files_charset_info, name_buff);
4477
4164
    db= name_buff;
4478
4165
  }
4483
4170
  for (; cur_table != last_table ;
4484
4171
       cur_table= cur_table->next_name_resolution_table)
4485
4172
  {
4486
 
    Field *cur_field= find_field_in_table_ref(thd, cur_table, name, length,
 
4173
    Field *cur_field= find_field_in_table_ref(session, cur_table, name, length,
4487
4174
                                              item->name, db, table_name, ref,
4488
 
                                              (thd->lex->sql_command ==
 
4175
                                              (session->lex->sql_command ==
4489
4176
                                               SQLCOM_SHOW_FIELDS)
4490
4177
                                              ? false : check_privileges,
4491
4178
                                              allow_rowid,
4496
4183
    {
4497
4184
      if (cur_field == WRONG_GRANT)
4498
4185
      {
4499
 
        if (thd->lex->sql_command != SQLCOM_SHOW_FIELDS)
 
4186
        if (session->lex->sql_command != SQLCOM_SHOW_FIELDS)
4500
4187
          return (Field*) 0;
4501
4188
 
4502
 
        thd->clear_error();
4503
 
        cur_field= find_field_in_table_ref(thd, cur_table, name, length,
 
4189
        session->clear_error();
 
4190
        cur_field= find_field_in_table_ref(session, cur_table, name, length,
4504
4191
                                           item->name, db, table_name, ref,
4505
4192
                                           false,
4506
4193
                                           allow_rowid,
4524
4211
      item->cached_table= (!actual_table->cacheable_table || found) ?
4525
4212
                          0 : actual_table;
4526
4213
 
4527
 
      assert(thd->where);
 
4214
      assert(session->where);
4528
4215
      /*
4529
4216
        If we found a fully qualified field we return it directly as it can't
4530
4217
        have duplicates.
4537
4224
        if (report_error == REPORT_ALL_ERRORS ||
4538
4225
            report_error == IGNORE_EXCEPT_NON_UNIQUE)
4539
4226
          my_error(ER_NON_UNIQ_ERROR, MYF(0),
4540
 
                   table_name ? item->full_name() : name, thd->where);
 
4227
                   table_name ? item->full_name() : name, session->where);
4541
4228
        return (Field*) 0;
4542
4229
      }
4543
4230
      found= cur_field;
4561
4248
    char buff[NAME_LEN*2+1];
4562
4249
    if (db && db[0])
4563
4250
    {
4564
 
      strxnmov(buff,sizeof(buff)-1,db,".",table_name,NULL);
 
4251
      /* We're in an error condition, two extra strlen's aren't going
 
4252
       * to kill us */
 
4253
      assert(strlen(db) <= NAME_LEN);
 
4254
      assert(strlen(table_name) <= NAME_LEN);
 
4255
      strcpy(buff, db);
 
4256
      strcat(buff,".");
 
4257
      strcat(buff, table_name);
4565
4258
      table_name=buff;
4566
4259
    }
4567
 
    my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, thd->where);
 
4260
    my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, session->where);
4568
4261
  }
4569
4262
  else
4570
4263
  {
4571
4264
    if (report_error == REPORT_ALL_ERRORS ||
4572
4265
        report_error == REPORT_EXCEPT_NON_UNIQUE)
4573
 
      my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), thd->where);
 
4266
      my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), session->where);
4574
4267
    else
4575
4268
      found= not_found_field;
4576
4269
  }
4595
4288
                                return not_found_item, report other errors,
4596
4289
                                return 0
4597
4290
      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 
 
4291
    resolution                  Set to the resolution type if the item is found
 
4292
                                (it says whether the item is resolved
4600
4293
                                 against an alias name,
4601
4294
                                 or as a field name without alias,
4602
4295
                                 or as a field hidden by alias,
4603
4296
                                 or ignoring alias)
4604
 
                                
 
4297
 
4605
4298
  RETURN VALUES
4606
4299
    0                   Item is not found or item is not unique,
4607
4300
                        error message is reported
4635
4328
 
4636
4329
  *resolution= NOT_RESOLVED;
4637
4330
 
4638
 
  is_ref_by_name= (find->type() == Item::FIELD_ITEM  || 
 
4331
  is_ref_by_name= (find->type() == Item::FIELD_ITEM  ||
4639
4332
                   find->type() == Item::REF_ITEM);
4640
4333
  if (is_ref_by_name)
4641
4334
  {
4652
4345
 
4653
4346
      /*
4654
4347
        In case of group_concat() with ORDER BY condition in the QUERY
4655
 
        item_field can be field of temporary table without item name 
 
4348
        item_field can be field of temporary table without item name
4656
4349
        (if this field created from expression argument of group_concat()),
4657
4350
        => we have to check presence of name before compare
4658
 
      */ 
 
4351
      */
4659
4352
      if (!item_field->name)
4660
4353
        continue;
4661
4354
 
4680
4373
        if (item_field->field_name && item_field->table_name &&
4681
4374
            !my_strcasecmp(system_charset_info, item_field->field_name,
4682
4375
                           field_name) &&
4683
 
            !my_strcasecmp(table_alias_charset, item_field->table_name, 
 
4376
            !my_strcasecmp(table_alias_charset, item_field->table_name,
4684
4377
                           table_name) &&
4685
4378
            (!db_name || (item_field->db_name &&
4686
4379
                          !strcmp(item_field->db_name, db_name))))
4696
4389
            */
4697
4390
            if (report_error != IGNORE_ERRORS)
4698
4391
              my_error(ER_NON_UNIQ_ERROR, MYF(0),
4699
 
                       find->full_name(), current_thd->where);
 
4392
                       find->full_name(), current_session->where);
4700
4393
            return (Item**) 0;
4701
4394
          }
4702
4395
          found_unaliased= li.ref();
4727
4420
              continue;                           // Same field twice
4728
4421
            if (report_error != IGNORE_ERRORS)
4729
4422
              my_error(ER_NON_UNIQ_ERROR, MYF(0),
4730
 
                       find->full_name(), current_thd->where);
 
4423
                       find->full_name(), current_session->where);
4731
4424
            return (Item**) 0;
4732
4425
          }
4733
4426
          found= li.ref();
4755
4448
      }
4756
4449
    }
4757
4450
    else if (!table_name)
4758
 
    { 
 
4451
    {
4759
4452
      if (is_ref_by_name && find->name && item->name &&
4760
4453
          !my_strcasecmp(system_charset_info,item->name,find->name))
4761
4454
      {
4772
4465
        break;
4773
4466
      }
4774
4467
    }
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
4468
  }
4805
4469
  if (!found)
4806
4470
  {
4808
4472
    {
4809
4473
      if (report_error != IGNORE_ERRORS)
4810
4474
        my_error(ER_NON_UNIQ_ERROR, MYF(0),
4811
 
                 find->full_name(), current_thd->where);
 
4475
                 find->full_name(), current_session->where);
4812
4476
      return (Item **) 0;
4813
4477
    }
4814
4478
    if (found_unaliased)
4824
4488
  {
4825
4489
    if (report_error == REPORT_ALL_ERRORS)
4826
4490
      my_error(ER_BAD_FIELD_ERROR, MYF(0),
4827
 
               find->full_name(), current_thd->where);
 
4491
               find->full_name(), current_session->where);
4828
4492
    return (Item **) 0;
4829
4493
  }
4830
4494
  else
4872
4536
 
4873
4537
  SYNOPSIS
4874
4538
    set_new_item_local_context()
4875
 
    thd        pointer to current thread
 
4539
    session        pointer to current thread
4876
4540
    item       item for which new context is created and set
4877
4541
    table_ref  table ref where an item showld be resolved
4878
4542
 
4886
4550
*/
4887
4551
 
4888
4552
static bool
4889
 
set_new_item_local_context(THD *thd, Item_ident *item, TableList *table_ref)
 
4553
set_new_item_local_context(Session *session, Item_ident *item, TableList *table_ref)
4890
4554
{
4891
4555
  Name_resolution_context *context;
4892
 
  if (!(context= new (thd->mem_root) Name_resolution_context))
 
4556
  if (!(context= new (session->mem_root) Name_resolution_context))
4893
4557
    return true;
4894
4558
  context->init();
4895
4559
  context->first_name_resolution_table=
4904
4568
 
4905
4569
  SYNOPSIS
4906
4570
    mark_common_columns()
4907
 
    thd                [in] current thread
 
4571
    session                [in] current thread
4908
4572
    table_ref_1        [in] the first (left) join operand
4909
4573
    table_ref_2        [in] the second (right) join operand
4910
4574
    using_fields       [in] if the join is JOIN...USING - the join columns,
4931
4595
*/
4932
4596
 
4933
4597
static bool
4934
 
mark_common_columns(THD *thd, TableList *table_ref_1, TableList *table_ref_2,
 
4598
mark_common_columns(Session *session, TableList *table_ref_1, TableList *table_ref_2,
4935
4599
                    List<String> *using_fields, uint32_t *found_using_fields)
4936
4600
{
4937
4601
  Field_iterator_table_ref it_1, it_2;
4960
4624
    if (!(nj_col_1= it_1.get_or_create_column_ref(leaf_1)))
4961
4625
      goto err;
4962
4626
    field_name_1= nj_col_1->name();
4963
 
    is_using_column_1= using_fields && 
 
4627
    is_using_column_1= using_fields &&
4964
4628
      test_if_string_in_list(field_name_1, using_fields);
4965
4629
 
4966
4630
    /*
4987
4651
        (then cur_nj_col_2->is_common == true).
4988
4652
        Note that it is too early to check the columns outside of the
4989
4653
        USING list for ambiguity because they are not actually "referenced"
4990
 
        here. These columns must be checked only on unqualified reference 
 
4654
        here. These columns must be checked only on unqualified reference
4991
4655
        by name (e.g. in SELECT list).
4992
4656
      */
4993
4657
      if (!my_strcasecmp(system_charset_info, field_name_1, cur_field_name_2))
4995
4659
        if (cur_nj_col_2->is_common ||
4996
4660
            (found && (!using_fields || is_using_column_1)))
4997
4661
        {
4998
 
          my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1, thd->where);
 
4662
          my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1, session->where);
4999
4663
          goto err;
5000
4664
        }
5001
4665
        nj_col_2= cur_nj_col_2;
5021
4685
    */
5022
4686
    if (nj_col_2 && (!using_fields ||is_using_column_1))
5023
4687
    {
5024
 
      Item *item_1=   nj_col_1->create_item(thd);
5025
 
      Item *item_2=   nj_col_2->create_item(thd);
 
4688
      Item *item_1=   nj_col_1->create_item(session);
 
4689
      Item *item_2=   nj_col_2->create_item(session);
5026
4690
      Field *field_1= nj_col_1->field();
5027
4691
      Field *field_2= nj_col_2->field();
5028
4692
      Item_ident *item_ident_1, *item_ident_2;
5052
4716
        resolution of these items, and to enable proper name resolution of
5053
4717
        the items during the execute phase of PS.
5054
4718
      */
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))
 
4719
      if (set_new_item_local_context(session, item_ident_1, nj_col_1->table_ref) ||
 
4720
          set_new_item_local_context(session, item_ident_2, nj_col_2->table_ref))
5057
4721
        goto err;
5058
4722
 
5059
4723
      if (!(eq_cond= new Item_func_eq(item_ident_1, item_ident_2)))
5114
4778
 
5115
4779
  SYNOPSIS
5116
4780
    store_natural_using_join_columns()
5117
 
    thd                current thread
 
4781
    session                current thread
5118
4782
    natural_using_join the table reference of the NATURAL/USING join
5119
4783
    table_ref_1        the first (left) operand (of a NATURAL/USING join).
5120
4784
    table_ref_2        the second (right) operand (of a NATURAL/USING join).
5145
4809
*/
5146
4810
 
5147
4811
static bool
5148
 
store_natural_using_join_columns(THD *thd __attribute__((unused)),
 
4812
store_natural_using_join_columns(Session *,
5149
4813
                                 TableList *natural_using_join,
5150
4814
                                 TableList *table_ref_1,
5151
4815
                                 TableList *table_ref_2,
5199
4863
        if (!(common_field= it++))
5200
4864
        {
5201
4865
          my_error(ER_BAD_FIELD_ERROR, MYF(0), using_field_name_ptr,
5202
 
                   current_thd->where);
 
4866
                   current_session->where);
5203
4867
          goto err;
5204
4868
        }
5205
4869
        if (!my_strcasecmp(system_charset_info,
5238
4902
 
5239
4903
  SYNOPSIS
5240
4904
    store_top_level_join_columns()
5241
 
    thd            current thread
 
4905
    session            current thread
5242
4906
    table_ref      nested join or table in a FROM clause
5243
4907
    left_neighbor  neighbor table reference to the left of table_ref at the
5244
4908
                   same level in the join tree
5250
4914
    and materializes the row types of NATURAL/USING joins in a
5251
4915
    bottom-up manner until it reaches the TableList elements that
5252
4916
    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
 
4917
    applied to each element of Select_Lex::top_join_list (i.e. to each
5254
4918
    top-level element of the FROM clause).
5255
4919
 
5256
4920
  IMPLEMENTATION
5264
4928
*/
5265
4929
 
5266
4930
static bool
5267
 
store_top_level_join_columns(THD *thd, TableList *table_ref,
 
4931
store_top_level_join_columns(Session *session, TableList *table_ref,
5268
4932
                             TableList *left_neighbor,
5269
4933
                             TableList *right_neighbor)
5270
4934
{
5312
4976
                           same_level_right_neighbor : right_neighbor;
5313
4977
 
5314
4978
      if (cur_table_ref->nested_join &&
5315
 
          store_top_level_join_columns(thd, cur_table_ref,
 
4979
          store_top_level_join_columns(session, cur_table_ref,
5316
4980
                                       real_left_neighbor, real_right_neighbor))
5317
4981
        goto err;
5318
4982
      same_level_right_neighbor= cur_table_ref;
5344
5008
    */
5345
5009
    if (table_ref_2->outer_join & JOIN_TYPE_RIGHT)
5346
5010
      std::swap(table_ref_1, table_ref_2);
5347
 
    if (mark_common_columns(thd, table_ref_1, table_ref_2,
 
5011
    if (mark_common_columns(session, table_ref_1, table_ref_2,
5348
5012
                            using_fields, &found_using_fields))
5349
5013
      goto err;
5350
5014
 
5355
5019
    */
5356
5020
    if (table_ref_1->outer_join & JOIN_TYPE_RIGHT)
5357
5021
      std::swap(table_ref_1, table_ref_2);
5358
 
    if (store_natural_using_join_columns(thd, table_ref, table_ref_1,
 
5022
    if (store_natural_using_join_columns(session, table_ref, table_ref_1,
5359
5023
                                         table_ref_2, using_fields,
5360
5024
                                         found_using_fields))
5361
5025
      goto err;
5402
5066
 
5403
5067
  SYNOPSIS
5404
5068
    setup_natural_join_row_types()
5405
 
    thd          current thread
 
5069
    session          current thread
5406
5070
    from_clause  list of top-level table references in a FROM clause
5407
5071
 
5408
5072
  DESCRIPTION
5420
5084
    true   Error
5421
5085
    false  OK
5422
5086
*/
5423
 
static bool setup_natural_join_row_types(THD *thd,
 
5087
static bool setup_natural_join_row_types(Session *session,
5424
5088
                                         List<TableList> *from_clause,
5425
5089
                                         Name_resolution_context *context)
5426
5090
{
5427
 
  thd->where= "from clause";
 
5091
  session->where= "from clause";
5428
5092
  if (from_clause->elements == 0)
5429
5093
    return false; /* We come here in the case of UNIONs. */
5430
5094
 
5440
5104
  {
5441
5105
    table_ref= left_neighbor;
5442
5106
    left_neighbor= table_ref_it++;
5443
 
    if (store_top_level_join_columns(thd, table_ref,
 
5107
    if (store_top_level_join_columns(session, table_ref,
5444
5108
                                     left_neighbor, right_neighbor))
5445
5109
      return true;
5446
5110
    if (left_neighbor)
5470
5134
** Expand all '*' in given fields
5471
5135
****************************************************************************/
5472
5136
 
5473
 
int setup_wild(THD *thd,
5474
 
               TableList *tables __attribute__((unused)),
 
5137
int setup_wild(Session *session,
 
5138
               TableList *,
5475
5139
               List<Item> &fields,
5476
5140
               List<Item> *sum_func_list,
5477
5141
               uint32_t wild_num)
5482
5146
  Item *item;
5483
5147
  List_iterator<Item> it(fields);
5484
5148
 
5485
 
  thd->lex->current_select->cur_pos_in_select_list= 0;
 
5149
  session->lex->current_select->cur_pos_in_select_list= 0;
5486
5150
  while (wild_num && (item= it++))
5487
5151
  {
5488
5152
    if (item->type() == Item::FIELD_ITEM &&
5492
5156
    {
5493
5157
      uint32_t elem= fields.elements;
5494
5158
      bool any_privileges= ((Item_field *) item)->any_privileges;
5495
 
      Item_subselect *subsel= thd->lex->current_select->master_unit()->item;
 
5159
      Item_subselect *subsel= session->lex->current_select->master_unit()->item;
5496
5160
      if (subsel &&
5497
5161
          subsel->substype() == Item_subselect::EXISTS_SUBS)
5498
5162
      {
5504
5168
        it.replace(new Item_int("Not_used", (int64_t) 1,
5505
5169
                                MY_INT64_NUM_DECIMAL_DIGITS));
5506
5170
      }
5507
 
      else if (insert_fields(thd, ((Item_field*) item)->context,
 
5171
      else if (insert_fields(session, ((Item_field*) item)->context,
5508
5172
                             ((Item_field*) item)->db_name,
5509
5173
                             ((Item_field*) item)->table_name, &it,
5510
5174
                             any_privileges))
5523
5187
      wild_num--;
5524
5188
    }
5525
5189
    else
5526
 
      thd->lex->current_select->cur_pos_in_select_list++;
 
5190
      session->lex->current_select->cur_pos_in_select_list++;
5527
5191
  }
5528
 
  thd->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
 
5192
  session->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
5529
5193
  return(0);
5530
5194
}
5531
5195
 
5533
5197
** Check that all given fields exists and fill struct with current data
5534
5198
****************************************************************************/
5535
5199
 
5536
 
bool setup_fields(THD *thd, Item **ref_pointer_array,
 
5200
bool setup_fields(Session *session, Item **ref_pointer_array,
5537
5201
                  List<Item> &fields, enum_mark_columns mark_used_columns,
5538
5202
                  List<Item> *sum_func_list, bool allow_sum_func)
5539
5203
{
5540
5204
  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;
 
5205
  enum_mark_columns save_mark_used_columns= session->mark_used_columns;
 
5206
  nesting_map save_allow_sum_func= session->lex->allow_sum_func;
5543
5207
  List_iterator<Item> it(fields);
5544
5208
  bool save_is_item_list_lookup;
5545
5209
 
5546
 
  thd->mark_used_columns= mark_used_columns;
 
5210
  session->mark_used_columns= mark_used_columns;
5547
5211
  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;
 
5212
    session->lex->allow_sum_func|= 1 << session->lex->current_select->nest_level;
 
5213
  session->where= Session::DEFAULT_WHERE;
 
5214
  save_is_item_list_lookup= session->lex->current_select->is_item_list_lookup;
 
5215
  session->lex->current_select->is_item_list_lookup= 0;
5552
5216
 
5553
5217
  /*
5554
5218
    To prevent fail on forward lookup we fill it with zerows,
5565
5229
    memset(ref_pointer_array, 0, sizeof(Item *) * fields.elements);
5566
5230
 
5567
5231
  Item **ref= ref_pointer_array;
5568
 
  thd->lex->current_select->cur_pos_in_select_list= 0;
 
5232
  session->lex->current_select->cur_pos_in_select_list= 0;
5569
5233
  while ((item= it++))
5570
5234
  {
5571
 
    if ((!item->fixed && item->fix_fields(thd, it.ref())) || (item= *(it.ref()))->check_cols(1))
 
5235
    if ((!item->fixed && item->fix_fields(session, it.ref())) || (item= *(it.ref()))->check_cols(1))
5572
5236
    {
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;
 
5237
      session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
 
5238
      session->lex->allow_sum_func= save_allow_sum_func;
 
5239
      session->mark_used_columns= save_mark_used_columns;
5576
5240
      return(true); /* purecov: inspected */
5577
5241
    }
5578
5242
    if (ref)
5579
5243
      *(ref++)= item;
5580
5244
    if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM &&
5581
5245
        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++;
 
5246
      item->split_sum_func(session, ref_pointer_array, *sum_func_list);
 
5247
    session->used_tables|= item->used_tables();
 
5248
    session->lex->current_select->cur_pos_in_select_list++;
5585
5249
  }
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;
 
5250
  session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
 
5251
  session->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
5588
5252
 
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()));
 
5253
  session->lex->allow_sum_func= save_allow_sum_func;
 
5254
  session->mark_used_columns= save_mark_used_columns;
 
5255
  return(test(session->is_error()));
5592
5256
}
5593
5257
 
5594
5258
 
5620
5284
 
5621
5285
  SYNOPSIS
5622
5286
    setup_tables()
5623
 
    thd           Thread handler
 
5287
    session               Thread handler
5624
5288
    context       name resolution contest to setup table list there
5625
5289
    from_clause   Top-level list of table references in the FROM clause
5626
5290
    tables        Table list (select_lex->table_list)
5643
5307
    true  error
5644
5308
*/
5645
5309
 
5646
 
bool setup_tables(THD *thd, Name_resolution_context *context,
 
5310
bool setup_tables(Session *session, Name_resolution_context *context,
5647
5311
                  List<TableList> *from_clause, TableList *tables,
5648
5312
                  TableList **leaves, bool select_insert)
5649
5313
{
5650
5314
  uint32_t tablenr= 0;
5651
5315
 
5652
 
  assert ((select_insert && !tables->next_name_resolution_table) || !tables || 
 
5316
  assert ((select_insert && !tables->next_name_resolution_table) || !tables ||
5653
5317
               (context->table_list && context->first_name_resolution_table));
5654
5318
  /*
5655
5319
    this is used for INSERT ... SELECT.
5686
5350
  }
5687
5351
 
5688
5352
  /* Precompute and store the row types of NATURAL/USING joins. */
5689
 
  if (setup_natural_join_row_types(thd, from_clause, context))
 
5353
  if (setup_natural_join_row_types(session, from_clause, context))
5690
5354
    return(1);
5691
5355
 
5692
5356
  return(0);
5698
5362
 
5699
5363
  SYNOPSIS
5700
5364
    setup_tables_and_check_view_access()
5701
 
    thd           Thread handler
 
5365
    session               Thread handler
5702
5366
    context       name resolution contest to setup table list there
5703
5367
    from_clause   Top-level list of table references in the FROM clause
5704
5368
    tables        Table list (select_lex->table_list)
5716
5380
    false ok;  In this case *map will include the chosen index
5717
5381
    true  error
5718
5382
*/
5719
 
bool setup_tables_and_check_access(THD *thd, 
 
5383
bool setup_tables_and_check_access(Session *session,
5720
5384
                                   Name_resolution_context *context,
5721
5385
                                   List<TableList> *from_clause,
5722
5386
                                   TableList *tables,
5726
5390
  TableList *leaves_tmp= NULL;
5727
5391
  bool first_table= true;
5728
5392
 
5729
 
  if (setup_tables(thd, context, from_clause, tables,
 
5393
  if (setup_tables(session, context, from_clause, tables,
5730
5394
                   &leaves_tmp, select_insert))
5731
5395
    return true;
5732
5396
 
5786
5450
 
5787
5451
  SYNOPSIS
5788
5452
    insert_fields()
5789
 
    thd                 Thread handler
 
5453
    session                     Thread handler
5790
5454
    context             Context for name resolution
5791
5455
    db_name             Database name in case of 'database_name.table_name.*'
5792
5456
    table_name          Table name in case of 'table_name.*'
5800
5464
*/
5801
5465
 
5802
5466
bool
5803
 
insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
 
5467
insert_fields(Session *session, Name_resolution_context *context, const char *db_name,
5804
5468
              const char *table_name, List_iterator<Item> *it,
5805
 
              bool any_privileges __attribute__((unused)))
 
5469
              bool )
5806
5470
{
5807
5471
  Field_iterator_table_ref field_iterator;
5808
5472
  bool found;
5815
5479
      We can't do this in Item_field as this would change the
5816
5480
      'name' of the item which may be used in the select list
5817
5481
    */
5818
 
    strmake(name_buff, db_name, sizeof(name_buff)-1);
 
5482
    strncpy(name_buff, db_name, sizeof(name_buff)-1);
5819
5483
    my_casedn_str(files_charset_info, name_buff);
5820
5484
    db_name= name_buff;
5821
5485
  }
5839
5503
 
5840
5504
    assert(tables->is_leaf_for_name_resolution());
5841
5505
 
5842
 
    if ((table_name && my_strcasecmp(table_alias_charset, table_name, tables->alias)) || 
 
5506
    if ((table_name && my_strcasecmp(table_alias_charset, table_name, tables->alias)) ||
5843
5507
        (db_name && strcmp(tables->db,db_name)))
5844
5508
      continue;
5845
5509
 
5848
5512
      views and natural joins this update is performed inside the loop below.
5849
5513
    */
5850
5514
    if (table)
5851
 
      thd->used_tables|= table->map;
 
5515
      session->used_tables|= table->map;
5852
5516
 
5853
5517
    /*
5854
5518
      Initialize a generic field iterator for the current table reference.
5862
5526
    {
5863
5527
      Item *item;
5864
5528
 
5865
 
      if (!(item= field_iterator.create_item(thd)))
 
5529
      if (!(item= field_iterator.create_item(session)))
5866
5530
        return(true);
5867
5531
 
5868
5532
      if (!found)
5877
5541
      {
5878
5542
        /* Mark fields as used to allow storage engine to optimze access */
5879
5543
        bitmap_set_bit(field->table->read_set, field->field_index);
 
5544
        /*
 
5545
          Mark virtual fields for write and others that the virtual fields
 
5546
          depend on for read.
 
5547
        */
 
5548
        if (field->vcol_info)
 
5549
        {
 
5550
          Item *vcol_item= field->vcol_info->expr_item;
 
5551
          assert(vcol_item);
 
5552
          vcol_item->walk(&Item::register_field_in_read_map, 1, (unsigned char *) 0);
 
5553
          bitmap_set_bit(field->table->write_set, field->field_index);
 
5554
        }
5880
5555
        if (table)
5881
5556
        {
5882
5557
          table->covering_keys.intersect(field->part_of_key);
5896
5571
          field_table= nj_col->table_ref->table;
5897
5572
          if (field_table)
5898
5573
          {
5899
 
            thd->used_tables|= field_table->map;
 
5574
            session->used_tables|= field_table->map;
5900
5575
            field_table->covering_keys.intersect(field->part_of_key);
5901
5576
            field_table->merge_keys.merge(field->part_of_key);
5902
5577
            field_table->used_fields++;
5904
5579
        }
5905
5580
      }
5906
5581
      else
5907
 
        thd->used_tables|= item->used_tables();
5908
 
      thd->lex->current_select->cur_pos_in_select_list++;
 
5582
        session->used_tables|= item->used_tables();
 
5583
      session->lex->current_select->cur_pos_in_select_list++;
5909
5584
    }
5910
5585
    /*
5911
5586
      In case of stored tables, all fields are considered as used,
5938
5613
 
5939
5614
  SYNOPSIS
5940
5615
    setup_conds()
5941
 
    thd     thread handler
 
5616
    session     thread handler
5942
5617
    tables  list of tables for name resolving (select_lex->table_list)
5943
5618
    leaves  list of leaves of join table tree (select_lex->leaf_tables)
5944
5619
    conds   WHERE clause
5951
5626
    false if all is OK
5952
5627
*/
5953
5628
 
5954
 
int setup_conds(THD *thd, TableList *tables __attribute__((unused)),
 
5629
int setup_conds(Session *session, TableList *,
5955
5630
                TableList *leaves,
5956
5631
                COND **conds)
5957
5632
{
5958
 
  SELECT_LEX *select_lex= thd->lex->current_select;
 
5633
  Select_Lex *select_lex= session->lex->current_select;
5959
5634
  TableList *table= NULL;       // For HP compilers
5960
 
  void *save_thd_marker= thd->thd_marker;
 
5635
  void *save_session_marker= session->session_marker;
5961
5636
  /*
5962
 
    it_is_update set to true when tables of primary SELECT_LEX (SELECT_LEX
 
5637
    it_is_update set to true when tables of primary Select_Lex (Select_Lex
5963
5638
    which belong to LEX, i.e. most up SELECT) will be updated by
5964
5639
    INSERT/UPDATE/LOAD
5965
5640
    NOTE: using this condition helps to prevent call of prepare_check_option()
5969
5644
  bool save_is_item_list_lookup= select_lex->is_item_list_lookup;
5970
5645
  select_lex->is_item_list_lookup= 0;
5971
5646
 
5972
 
  thd->mark_used_columns= MARK_COLUMNS_READ;
 
5647
  session->mark_used_columns= MARK_COLUMNS_READ;
5973
5648
  select_lex->cond_count= 0;
5974
5649
  select_lex->between_count= 0;
5975
5650
  select_lex->max_equal_elems= 0;
5976
5651
 
5977
 
  thd->thd_marker= (void*)1;
 
5652
  session->session_marker= (void*)1;
5978
5653
  if (*conds)
5979
5654
  {
5980
 
    thd->where="where clause";
5981
 
    if ((!(*conds)->fixed && (*conds)->fix_fields(thd, conds)) ||
 
5655
    session->where="where clause";
 
5656
    if ((!(*conds)->fixed && (*conds)->fix_fields(session, conds)) ||
5982
5657
        (*conds)->check_cols(1))
5983
5658
      goto err_no_arena;
5984
5659
  }
5985
 
  thd->thd_marker= save_thd_marker;
 
5660
  session->session_marker= save_session_marker;
5986
5661
 
5987
5662
  /*
5988
5663
    Apply fix_fields() to all ON clauses at all levels of nesting,
5998
5673
      if (embedded->on_expr)
5999
5674
      {
6000
5675
        /* 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)) ||
 
5676
        session->session_marker= (void*)embedded;
 
5677
        session->where="on clause";
 
5678
        if ((!embedded->on_expr->fixed && embedded->on_expr->fix_fields(session, &embedded->on_expr)) ||
6004
5679
            embedded->on_expr->check_cols(1))
6005
5680
          goto err_no_arena;
6006
5681
        select_lex->cond_count++;
6011
5686
           embedding->nested_join->join_list.head() == embedded);
6012
5687
 
6013
5688
  }
6014
 
  thd->thd_marker= save_thd_marker;
 
5689
  session->session_marker= save_session_marker;
6015
5690
 
6016
 
  thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
6017
 
  return(test(thd->is_error()));
 
5691
  session->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
 
5692
  return(test(session->is_error()));
6018
5693
 
6019
5694
err_no_arena:
6020
5695
  select_lex->is_item_list_lookup= save_is_item_list_lookup;
6033
5708
 
6034
5709
  SYNOPSIS
6035
5710
    fill_record()
6036
 
    thd           thread handler
 
5711
    session           thread handler
6037
5712
    fields        Item_fields list to be filled
6038
5713
    values        values to fill with
6039
5714
    ignore_errors true if we should ignore errors
6049
5724
*/
6050
5725
 
6051
5726
bool
6052
 
fill_record(THD * thd, List<Item> &fields, List<Item> &values, bool ignore_errors)
 
5727
fill_record(Session * session, List<Item> &fields, List<Item> &values, bool ignore_errors)
6053
5728
{
6054
5729
  List_iterator_fast<Item> f(fields),v(values);
6055
5730
  Item *value, *fld;
6056
5731
  Item_field *field;
6057
5732
  Table *table= 0;
 
5733
  List<Table> tbl_list;
 
5734
  bool abort_on_warning_saved= session->abort_on_warning;
 
5735
  tbl_list.empty();
6058
5736
 
6059
5737
  /*
6060
5738
    Reset the table->auto_increment_field_not_null as it is valid for
6088
5766
    table= rfield->table;
6089
5767
    if (rfield == table->next_number_field)
6090
5768
      table->auto_increment_field_not_null= true;
 
5769
    if (rfield->vcol_info &&
 
5770
        value->type() != Item::DEFAULT_VALUE_ITEM &&
 
5771
        value->type() != Item::NULL_ITEM &&
 
5772
        table->s->table_category != TABLE_CATEGORY_TEMPORARY)
 
5773
    {
 
5774
      session->abort_on_warning= false;
 
5775
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
5776
                          ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN,
 
5777
                          ER(ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN),
 
5778
                          rfield->field_name, table->s->table_name.str);
 
5779
      session->abort_on_warning= abort_on_warning_saved;
 
5780
    }
6091
5781
    if ((value->save_in_field(rfield, 0) < 0) && !ignore_errors)
6092
5782
    {
6093
5783
      my_message(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), MYF(0));
6094
5784
      goto err;
6095
5785
    }
6096
 
  }
6097
 
  return(thd->is_error());
 
5786
    tbl_list.push_back(table);
 
5787
  }
 
5788
  /* Update virtual fields*/
 
5789
  session->abort_on_warning= false;
 
5790
  if (tbl_list.head())
 
5791
  {
 
5792
    List_iterator_fast<Table> t(tbl_list);
 
5793
    Table *prev_table= 0;
 
5794
    while ((table= t++))
 
5795
    {
 
5796
      /*
 
5797
        Do simple optimization to prevent unnecessary re-generating
 
5798
        values for virtual fields
 
5799
      */
 
5800
      if (table != prev_table)
 
5801
      {
 
5802
        prev_table= table;
 
5803
        if (table->vfield)
 
5804
        {
 
5805
          if (update_virtual_fields_marked_for_write(table, false))
 
5806
            goto err;
 
5807
        }
 
5808
      }
 
5809
    }
 
5810
  }
 
5811
  session->abort_on_warning= abort_on_warning_saved;
 
5812
  return(session->is_error());
6098
5813
err:
 
5814
  session->abort_on_warning= abort_on_warning_saved;
6099
5815
  if (table)
6100
5816
    table->auto_increment_field_not_null= false;
6101
5817
  return(true);
6107
5823
 
6108
5824
  SYNOPSIS
6109
5825
    fill_record()
6110
 
    thd           thread handler
 
5826
    session           thread handler
6111
5827
    ptr           pointer on pointer to record
6112
5828
    values        list of fields
6113
5829
    ignore_errors true if we should ignore errors
6123
5839
*/
6124
5840
 
6125
5841
bool
6126
 
fill_record(THD *thd, Field **ptr, List<Item> &values,
6127
 
            bool ignore_errors __attribute__((unused)))
 
5842
fill_record(Session *session, Field **ptr, List<Item> &values,
 
5843
            bool )
6128
5844
{
6129
5845
  List_iterator_fast<Item> v(values);
6130
5846
  Item *value;
6131
5847
  Table *table= 0;
6132
 
 
6133
5848
  Field *field;
 
5849
  List<Table> tbl_list;
 
5850
  bool abort_on_warning_saved= session->abort_on_warning;
 
5851
 
 
5852
  tbl_list.empty();
6134
5853
  /*
6135
5854
    Reset the table->auto_increment_field_not_null as it is valid for
6136
5855
    only one row.
6144
5863
    table= (*ptr)->table;
6145
5864
    table->auto_increment_field_not_null= false;
6146
5865
  }
6147
 
  while ((field = *ptr++) && ! thd->is_error())
 
5866
  while ((field = *ptr++) && ! session->is_error())
6148
5867
  {
6149
5868
    value=v++;
6150
5869
    table= field->table;
6151
5870
    if (field == table->next_number_field)
6152
5871
      table->auto_increment_field_not_null= true;
 
5872
    if (field->vcol_info &&
 
5873
        value->type() != Item::DEFAULT_VALUE_ITEM &&
 
5874
        value->type() != Item::NULL_ITEM &&
 
5875
        table->s->table_category != TABLE_CATEGORY_TEMPORARY)
 
5876
    {
 
5877
      session->abort_on_warning= false;
 
5878
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
5879
                          ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN,
 
5880
                          ER(ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN),
 
5881
                          field->field_name, table->s->table_name.str);
 
5882
      session->abort_on_warning= abort_on_warning_saved;
 
5883
    }
6153
5884
    if (value->save_in_field(field, 0) < 0)
6154
5885
      goto err;
6155
 
  }
6156
 
  return(thd->is_error());
 
5886
    tbl_list.push_back(table);
 
5887
  }
 
5888
  /* Update virtual fields*/
 
5889
  session->abort_on_warning= false;
 
5890
  if (tbl_list.head())
 
5891
  {
 
5892
    List_iterator_fast<Table> t(tbl_list);
 
5893
    Table *prev_table= 0;
 
5894
    while ((table= t++))
 
5895
    {
 
5896
      /*
 
5897
        Do simple optimization to prevent unnecessary re-generating
 
5898
        values for virtual fields
 
5899
      */
 
5900
      if (table != prev_table)
 
5901
      {
 
5902
        prev_table= table;
 
5903
        if (table->vfield)
 
5904
        {
 
5905
          if (update_virtual_fields_marked_for_write(table, false))
 
5906
          {
 
5907
            goto err;
 
5908
          }
 
5909
        }
 
5910
      }
 
5911
    }
 
5912
  }
 
5913
  session->abort_on_warning= abort_on_warning_saved;
 
5914
  return(session->is_error());
6157
5915
 
6158
5916
err:
 
5917
  session->abort_on_warning= abort_on_warning_saved;
6159
5918
  if (table)
6160
5919
    table->auto_increment_field_not_null= false;
6161
5920
  return(true);
6162
5921
}
6163
5922
 
6164
5923
 
6165
 
bool mysql_rm_tmp_tables(void)
 
5924
bool drizzle_rm_tmp_tables(void)
6166
5925
{
6167
 
  uint32_t i, idx;
6168
 
  char  filePath[FN_REFLEN], *tmpdir, filePathCopy[FN_REFLEN];
 
5926
  uint32_t  idx;
 
5927
  char  filePath[FN_REFLEN], filePathCopy[FN_REFLEN];
6169
5928
  MY_DIR *dirp;
6170
5929
  FILEINFO *file;
6171
5930
  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++)
 
5931
  Session *session;
 
5932
 
 
5933
  assert(drizzle_tmpdir);
 
5934
 
 
5935
  if (!(session= new Session))
 
5936
    return true;
 
5937
  session->thread_stack= (char*) &session;
 
5938
  session->store_globals();
 
5939
 
 
5940
  /* Remove all temp tables in the tmpdir */
 
5941
  /* See if the directory exists */
 
5942
  if ((dirp = my_dir(drizzle_tmpdir ,MYF(MY_WME | MY_DONT_SORT))))
6180
5943
  {
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
5944
    /* Remove all SQLxxx tables from directory */
6187
 
 
6188
5945
    for (idx=0 ; idx < (uint) dirp->number_off_files ; idx++)
6189
5946
    {
6190
5947
      file=dirp->dir_entry+idx;
6194
5951
                                   (file->name[1] == '.' &&  !file->name[2])))
6195
5952
        continue;
6196
5953
 
6197
 
      if (!memcmp(file->name, tmp_file_prefix, tmp_file_prefix_length))
 
5954
      if (!memcmp(file->name, TMP_FILE_PREFIX, TMP_FILE_PREFIX_LENGTH))
6198
5955
      {
6199
5956
        char *ext= fn_ext(file->name);
6200
5957
        uint32_t ext_len= strlen(ext);
6201
5958
        uint32_t filePath_len= snprintf(filePath, sizeof(filePath),
6202
 
                                    "%s%c%s", tmpdir, FN_LIBCHAR,
6203
 
                                    file->name);
 
5959
                                        "%s%c%s", drizzle_tmpdir, FN_LIBCHAR,
 
5960
                                        file->name);
6204
5961
        if (!memcmp(reg_ext, ext, ext_len))
6205
5962
        {
6206
5963
          handler *handler_file= 0;
6207
5964
          /* We should cut file extention before deleting of table */
6208
5965
          memcpy(filePathCopy, filePath, filePath_len - ext_len);
6209
5966
          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,
 
5967
          init_tmp_table_share(session, &share, "", 0, "", filePathCopy);
 
5968
          if (!open_table_def(session, &share, 0) &&
 
5969
              ((handler_file= get_new_handler(&share, session->mem_root,
6213
5970
                                              share.db_type()))))
6214
5971
          {
6215
5972
            handler_file->ha_delete_table(filePathCopy);
6222
5979
          So we hide error messages which happnes during deleting of these
6223
5980
          files(MYF(0)).
6224
5981
        */
6225
 
        my_delete(filePath, MYF(0)); 
 
5982
        my_delete(filePath, MYF(0));
6226
5983
      }
6227
5984
    }
6228
5985
    my_dirend(dirp);
6229
5986
  }
6230
 
  delete thd;
6231
 
  my_pthread_setspecific_ptr(THR_THD,  0);
6232
 
  return(0);
 
5987
 
 
5988
  delete session;
 
5989
 
 
5990
  return false;
6233
5991
}
6234
5992
 
6235
5993
 
6300
6058
    1  Table is in use by another thread
6301
6059
*/
6302
6060
 
6303
 
bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
 
6061
bool remove_table_from_cache(Session *session, const char *db, const char *table_name,
6304
6062
                             uint32_t flags)
6305
6063
{
6306
6064
  char key[MAX_DBKEY_LENGTH];
 
6065
  char *key_pos= key;
6307
6066
  uint32_t key_length;
6308
6067
  Table *table;
6309
6068
  TABLE_SHARE *share;
6310
6069
  bool result= 0, signalled= 0;
6311
6070
 
6312
 
  key_length=(uint) (my_stpcpy(my_stpcpy(key,db)+1,table_name)-key)+1;
 
6071
  key_pos= strcpy(key_pos, db) + strlen(db);
 
6072
  key_pos= strcpy(key_pos+1, table_name) + strlen(table_name);
 
6073
  key_length= (uint32_t) (key_pos-key)+1;
 
6074
 
6313
6075
  for (;;)
6314
6076
  {
6315
6077
    HASH_SEARCH_STATE state;
6321
6083
         table= (Table*) hash_next(&open_cache, (unsigned char*) key, key_length,
6322
6084
                                   &state))
6323
6085
    {
6324
 
      THD *in_use;
 
6086
      Session *in_use;
6325
6087
 
6326
6088
      table->s->version=0L;             /* Free when thread is ready */
6327
6089
      if (!(in_use=table->in_use))
6328
6090
      {
6329
6091
        relink_unused(table);
6330
6092
      }
6331
 
      else if (in_use != thd)
 
6093
      else if (in_use != session)
6332
6094
      {
6333
6095
        /*
6334
6096
          Mark that table is going to be deleted from cache. This will
6349
6111
          open_tables list. Aborting the MERGE lock after a child was
6350
6112
          closed and before the parent is closed would be fatal.
6351
6113
        */
6352
 
        for (Table *thd_table= in_use->open_tables;
6353
 
             thd_table ;
6354
 
             thd_table= thd_table->next)
 
6114
        for (Table *session_table= in_use->open_tables;
 
6115
             session_table ;
 
6116
             session_table= session_table->next)
6355
6117
        {
6356
6118
          /* 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);
 
6119
          if (session_table->db_stat)   // If table is open
 
6120
            signalled|= mysql_lock_abort_for_thread(session, session_table);
6359
6121
        }
6360
6122
      }
6361
6123
      else
6362
 
        result= result || (flags & RTFC_OWNED_BY_THD_FLAG);
 
6124
        result= result || (flags & RTFC_OWNED_BY_Session_FLAG);
6363
6125
    }
6364
6126
    while (unused_tables && !unused_tables->s->version)
6365
6127
      hash_delete(&open_cache,(unsigned char*) unused_tables);
6383
6145
        reopen their tables
6384
6146
      */
6385
6147
      broadcast_refresh();
6386
 
      if (!(flags & RTFC_CHECK_KILLED_FLAG) || !thd->killed)
 
6148
      if (!(flags & RTFC_CHECK_KILLED_FLAG) || !session->killed)
6387
6149
      {
6388
6150
        dropping_tables++;
6389
6151
        if (likely(signalled))
6421
6183
/**
6422
6184
  @} (end of group Data_Dictionary)
6423
6185
*/
 
6186
 
 
6187
void kill_drizzle(void)
 
6188
{
 
6189
 
 
6190
#if defined(SIGNALS_DONT_BREAK_READ)
 
6191
  abort_loop=1;                                 // Break connection loops
 
6192
  close_server_sock();                          // Force accept to wake up
 
6193
#endif
 
6194
 
 
6195
#if defined(HAVE_PTHREAD_KILL)
 
6196
  pthread_kill(signal_thread, SIGTERM);
 
6197
#elif !defined(SIGNALS_DONT_BREAK_READ)
 
6198
  kill(current_pid, SIGTERM);
 
6199
#endif
 
6200
  shutdown_in_progress=1;                       // Safety if kill didn't work
 
6201
#ifdef SIGNALS_DONT_BREAK_READ
 
6202
  if (!kill_in_progress)
 
6203
  {
 
6204
    pthread_t tmp;
 
6205
    abort_loop=1;
 
6206
    if (pthread_create(&tmp,&connection_attrib, kill_server_thread,
 
6207
                           (void*) 0))
 
6208
      errmsg_printf(ERRMSG_LVL_ERROR, _("Can't create thread to kill server"));
 
6209
  }
 
6210
#endif
 
6211
  return;;
 
6212
}