~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_db.cc

  • Committer: Monty Taylor
  • Date: 2008-09-16 00:00:48 UTC
  • mto: This revision was merged to the branch mainline in revision 391.
  • Revision ID: monty@inaugust.com-20080916000048-3rvrv3gv9l0ad3gs
Fixed copyright headers in drizzled/

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 
16
16
 
17
17
/* create and drop of databases */
18
 
#include <config.h>
19
 
#include CSTDINT_H
20
 
#include CINTTYPES_H
21
18
#include <string>
22
19
#include <fstream>
23
20
#include <drizzled/serialize/serialize.h>
26
23
#include <mysys/mysys_err.h>
27
24
#include <mysys/my_dir.h>
28
25
#include "log.h"
29
 
#include <drizzled/error.h>
30
 
#include <drizzled/gettext.h>
 
26
#include <drizzled/drizzled_error_messages.h>
 
27
#include <libdrizzle/gettext.h>
31
28
 
32
29
 
33
30
#define MAX_DROP_TABLE_Q_LEN      1024
34
31
 
35
 
const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", NULL};
 
32
const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", NullS};
36
33
static TYPELIB deletable_extentions=
37
34
{array_elements(del_exts)-1,"del_exts", del_exts, NULL};
38
35
 
39
 
static long mysql_rm_known_files(Session *session, MY_DIR *dirp,
40
 
                                 const char *db, const char *path, uint32_t level, 
 
36
static long mysql_rm_known_files(THD *thd, MY_DIR *dirp,
 
37
                                 const char *db, const char *path, uint level, 
41
38
                                 TableList **dropped_tables);
42
39
         
43
40
static bool rm_dir_w_symlink(const char *org_path, bool send_error);
44
 
static void mysql_change_db_impl(Session *session,
 
41
static void mysql_change_db_impl(THD *thd,
45
42
                                 LEX_STRING *new_db_name,
46
43
                                 const CHARSET_INFO * const new_db_charset);
47
44
 
56
53
typedef struct my_dblock_st
57
54
{
58
55
  char *name;        /* Database name        */
59
 
  uint32_t name_length;  /* Database length name */
 
56
  uint name_length;  /* Database length name */
60
57
} my_dblock_t;
61
58
 
62
59
 
64
61
  lock_db key.
65
62
*/
66
63
 
67
 
extern "C" unsigned char* lock_db_get_key(my_dblock_t *, size_t *, bool not_used);
 
64
extern "C" uchar* lock_db_get_key(my_dblock_t *, size_t *, bool not_used);
68
65
 
69
 
unsigned char* lock_db_get_key(my_dblock_t *ptr, size_t *length,
 
66
uchar* lock_db_get_key(my_dblock_t *ptr, size_t *length,
70
67
                       bool not_used __attribute__((unused)))
71
68
{
72
69
  *length= ptr->name_length;
73
 
  return (unsigned char*) ptr->name;
 
70
  return (uchar*) ptr->name;
74
71
}
75
72
 
76
73
 
82
79
 
83
80
void lock_db_free_element(void *ptr)
84
81
{
85
 
  free(ptr);
 
82
  my_free(ptr, MYF(0));
86
83
}
87
84
 
88
85
 
90
87
  Delete a database lock entry from hash.
91
88
*/
92
89
 
93
 
void lock_db_delete(const char *name, uint32_t length)
 
90
void lock_db_delete(const char *name, uint length)
94
91
{
95
92
  my_dblock_t *opt;
96
93
  safe_mutex_assert_owner(&LOCK_lock_db);
97
94
  if ((opt= (my_dblock_t *)hash_search(&lock_db_cache,
98
 
                                       (const unsigned char*) name, length)))
99
 
    hash_delete(&lock_db_cache, (unsigned char*) opt);
 
95
                                       (const uchar*) name, length)))
 
96
    hash_delete(&lock_db_cache, (uchar*) opt);
100
97
}
101
98
 
102
99
 
109
106
typedef struct my_dbopt_st
110
107
{
111
108
  char *name;                   /* Database name                  */
112
 
  uint32_t name_length;         /* Database length name           */
 
109
  uint name_length;             /* Database length name           */
113
110
  const CHARSET_INFO *charset;  /* Database default character set */
114
111
} my_dbopt_t;
115
112
 
118
115
  Function we use in the creation of our hash to get key.
119
116
*/
120
117
 
121
 
extern "C" unsigned char* dboptions_get_key(my_dbopt_t *opt, size_t *length,
 
118
extern "C" uchar* dboptions_get_key(my_dbopt_t *opt, size_t *length,
122
119
                                    bool not_used);
123
120
 
124
 
unsigned char* dboptions_get_key(my_dbopt_t *opt, size_t *length,
 
121
uchar* dboptions_get_key(my_dbopt_t *opt, size_t *length,
125
122
                         bool not_used __attribute__((unused)))
126
123
{
127
124
  *length= opt->name_length;
128
 
  return (unsigned char*) opt->name;
 
125
  return (uchar*) opt->name;
129
126
}
130
127
 
131
128
 
133
130
  Helper function to write a query to binlog used by mysql_rm_db()
134
131
*/
135
132
 
136
 
static inline void write_to_binlog(Session *session, char *query, uint32_t q_len,
137
 
                                   char *db, uint32_t db_len)
 
133
static inline void write_to_binlog(THD *thd, char *query, uint q_len,
 
134
                                   char *db, uint db_len)
138
135
{
139
 
  Query_log_event qinfo(session, query, q_len, 0, 0);
 
136
  Query_log_event qinfo(thd, query, q_len, 0, 0);
140
137
  qinfo.error_code= 0;
141
138
  qinfo.db= db;
142
139
  qinfo.db_len= db_len;
152
149
 
153
150
void free_dbopt(void *dbopt)
154
151
{
155
 
  free((unsigned char*) dbopt);
 
152
  my_free((uchar*) dbopt, MYF(0));
156
153
}
157
154
 
158
155
 
239
236
static bool get_dbopt(const char *dbname, HA_CREATE_INFO *create)
240
237
{
241
238
  my_dbopt_t *opt;
242
 
  uint32_t length;
 
239
  uint length;
243
240
  bool error= true;
244
241
  
245
242
  length= (uint) strlen(dbname);
246
243
  
247
244
  rw_rdlock(&LOCK_dboptions);
248
 
  if ((opt= (my_dbopt_t*) hash_search(&dboptions, (unsigned char*) dbname, length)))
 
245
  if ((opt= (my_dbopt_t*) hash_search(&dboptions, (uchar*) dbname, length)))
249
246
  {
250
247
    create->default_table_charset= opt->charset;
251
248
    error= true;
270
267
static bool put_dbopt(const char *dbname, HA_CREATE_INFO *create)
271
268
{
272
269
  my_dbopt_t *opt;
273
 
  uint32_t length;
 
270
  uint length;
274
271
  bool error= false;
275
272
 
276
273
  length= (uint) strlen(dbname);
277
274
  
278
275
  rw_wrlock(&LOCK_dboptions);
279
 
  if (!(opt= (my_dbopt_t*) hash_search(&dboptions, (unsigned char*) dbname, length)))
 
276
  if (!(opt= (my_dbopt_t*) hash_search(&dboptions, (uchar*) dbname, length)))
280
277
  { 
281
278
    /* Options are not in the hash, insert them */
282
279
    char *tmp_name;
283
280
    if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
284
281
                         &opt, (uint) sizeof(*opt), &tmp_name, (uint) length+1,
285
 
                         NULL))
 
282
                         NullS))
286
283
    {
287
284
      error= true;
288
285
      goto end;
289
286
    }
290
287
    
291
288
    opt->name= tmp_name;
292
 
    my_stpcpy(opt->name, dbname);
 
289
    stpcpy(opt->name, dbname);
293
290
    opt->name_length= length;
294
291
    
295
 
    if ((error= my_hash_insert(&dboptions, (unsigned char*) opt)))
 
292
    if ((error= my_hash_insert(&dboptions, (uchar*) opt)))
296
293
    {
297
 
      free(opt);
 
294
      my_free(opt, MYF(0));
298
295
      goto end;
299
296
    }
300
297
  }
316
313
{
317
314
  my_dbopt_t *opt;
318
315
  rw_wrlock(&LOCK_dboptions);
319
 
  if ((opt= (my_dbopt_t *)hash_search(&dboptions, (const unsigned char*) path,
 
316
  if ((opt= (my_dbopt_t *)hash_search(&dboptions, (const uchar*) path,
320
317
                                      strlen(path))))
321
 
    hash_delete(&dboptions, (unsigned char*) opt);
 
318
    hash_delete(&dboptions, (uchar*) opt);
322
319
  rw_unlock(&LOCK_dboptions);
323
320
}
324
321
 
334
331
  1     Could not create file or write to it.  Error sent through my_error()
335
332
*/
336
333
 
337
 
static bool write_db_opt(Session *session, const char *path, const char *name, HA_CREATE_INFO *create)
 
334
static bool write_db_opt(THD *thd, const char *path, const char *name, HA_CREATE_INFO *create)
338
335
{
339
336
  bool error= true;
340
337
  drizzle::Schema db;
342
339
  assert(name);
343
340
 
344
341
  if (!create->default_table_charset)
345
 
    create->default_table_charset= session->variables.collation_server;
 
342
    create->default_table_charset= thd->variables.collation_server;
346
343
 
347
344
  if (put_dbopt(path, create))
348
345
    return 1;
374
371
 
375
372
*/
376
373
 
377
 
bool load_db_opt(Session *session, const char *path, HA_CREATE_INFO *create)
 
374
bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create)
378
375
{
379
376
  bool error=1;
380
377
  drizzle::Schema db;
381
378
  string buffer;
382
379
 
383
380
  memset(create, 0, sizeof(*create));
384
 
  create->default_table_charset= session->variables.collation_server;
 
381
  create->default_table_charset= thd->variables.collation_server;
385
382
 
386
383
  /* Check if options for this database are already in the hash */
387
384
  if (!get_dbopt(path, create))
453
450
    true    Failed to retrieve options
454
451
*/
455
452
 
456
 
bool load_db_opt_by_name(Session *session, const char *db_name,
 
453
bool load_db_opt_by_name(THD *thd, const char *db_name,
457
454
                         HA_CREATE_INFO *db_create_info)
458
455
{
459
456
  char db_opt_path[FN_REFLEN];
465
462
  (void) build_table_filename(db_opt_path, sizeof(db_opt_path),
466
463
                              db_name, "", MY_DB_OPT_FILE, 0);
467
464
 
468
 
  return load_db_opt(session, db_opt_path, db_create_info);
 
465
  return load_db_opt(thd, db_opt_path, db_create_info);
469
466
}
470
467
 
471
468
 
472
469
/**
473
470
  Return default database collation.
474
471
 
475
 
  @param session     Thread context.
 
472
  @param thd     Thread context.
476
473
  @param db_name Database name.
477
474
 
478
475
  @return CHARSET_INFO object. The operation always return valid character
479
476
    set, even if the database does not exist.
480
477
*/
481
478
 
482
 
const CHARSET_INFO *get_default_db_collation(Session *session, const char *db_name)
 
479
const CHARSET_INFO *get_default_db_collation(THD *thd, const char *db_name)
483
480
{
484
481
  HA_CREATE_INFO db_info;
485
482
 
486
 
  if (session->db != NULL && strcmp(db_name, session->db) == 0)
487
 
    return session->db_charset;
 
483
  if (thd->db != NULL && strcmp(db_name, thd->db) == 0)
 
484
    return thd->db_charset;
488
485
 
489
 
  load_db_opt_by_name(session, db_name, &db_info);
 
486
  load_db_opt_by_name(thd, db_name, &db_info);
490
487
 
491
488
  /*
492
489
    NOTE: even if load_db_opt_by_name() fails,
505
502
 
506
503
  SYNOPSIS
507
504
  mysql_create_db()
508
 
  session               Thread handler
 
505
  thd           Thread handler
509
506
  db            Name of database to create
510
507
                Function assumes that this is already validated.
511
508
  create_info   Database create options (like character set)
524
521
 
525
522
*/
526
523
 
527
 
int mysql_create_db(Session *session, char *db, HA_CREATE_INFO *create_info, bool silent)
 
524
int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent)
528
525
{
529
526
  char   path[FN_REFLEN+16];
530
527
  char   tmp_query[FN_REFLEN+16];
531
528
  long result= 1;
532
529
  int error= 0;
533
530
  struct stat stat_info;
534
 
  uint32_t create_options= create_info ? create_info->options : 0;
535
 
  uint32_t path_len;
 
531
  uint create_options= create_info ? create_info->options : 0;
 
532
  uint path_len;
536
533
 
537
534
  /* do not create 'information_schema' db */
538
535
  if (!my_strcasecmp(system_charset_info, db, INFORMATION_SCHEMA_NAME.str))
553
550
    has the global read lock and refuses the operation with
554
551
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
555
552
  */
556
 
  if (wait_if_global_read_lock(session, 0, 1))
 
553
  if (wait_if_global_read_lock(thd, 0, 1))
557
554
  {
558
555
    error= -1;
559
556
    goto exit2;
560
557
  }
561
558
 
562
 
  pthread_mutex_lock(&LOCK_mysql_create_db);
 
559
  VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
563
560
 
564
561
  /* Check directory */
565
562
  path_len= build_table_filename(path, sizeof(path), db, "", "", 0);
573
570
      error= -1;
574
571
      goto exit;
575
572
    }
576
 
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
573
    push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
577
574
                        ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS), db);
578
575
    if (!silent)
579
 
      my_ok(session);
 
576
      my_ok(thd);
580
577
    error= 0;
581
578
    goto exit;
582
579
  }
597
594
 
598
595
  path[path_len-1]= FN_LIBCHAR;
599
596
  strmake(path+path_len, MY_DB_OPT_FILE, sizeof(path)-path_len-1);
600
 
  if (write_db_opt(session, path, db, create_info))
 
597
  if (write_db_opt(thd, path, db, create_info))
601
598
  {
602
599
    /*
603
600
      Could not create options file.
619
616
  if (!silent)
620
617
  {
621
618
    char *query;
622
 
    uint32_t query_length;
 
619
    uint query_length;
623
620
 
624
 
    if (!session->query)                                // Only in replication
 
621
    if (!thd->query)                            // Only in replication
625
622
    {
626
623
      query=         tmp_query;
627
624
      query_length= (uint) (strxmov(tmp_query,"create database `",
628
 
                                    db, "`", NULL) - tmp_query);
 
625
                                    db, "`", NullS) - tmp_query);
629
626
    }
630
627
    else
631
628
    {
632
 
      query=        session->query;
633
 
      query_length= session->query_length;
 
629
      query=        thd->query;
 
630
      query_length= thd->query_length;
634
631
    }
635
632
 
 
633
    ha_binlog_log_query(thd, 0, LOGCOM_CREATE_DB,
 
634
                        query, query_length,
 
635
                        db, "");
 
636
 
636
637
    if (mysql_bin_log.is_open())
637
638
    {
638
 
      Query_log_event qinfo(session, query, query_length, 0, 
 
639
      Query_log_event qinfo(thd, query, query_length, 0, 
639
640
                            /* suppress_use */ true);
640
641
 
641
642
      /*
661
662
      /* These DDL methods and logging protected with LOCK_mysql_create_db */
662
663
      mysql_bin_log.write(&qinfo);
663
664
    }
664
 
    my_ok(session, result);
 
665
    my_ok(thd, result);
665
666
  }
666
667
 
667
668
exit:
668
 
  pthread_mutex_unlock(&LOCK_mysql_create_db);
669
 
  start_waiting_global_read_lock(session);
 
669
  VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
 
670
  start_waiting_global_read_lock(thd);
670
671
exit2:
671
672
  return(error);
672
673
}
674
675
 
675
676
/* db-name is already validated when we come here */
676
677
 
677
 
bool mysql_alter_db(Session *session, const char *db, HA_CREATE_INFO *create_info)
 
678
bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info)
678
679
{
679
680
  char path[FN_REFLEN+16];
680
681
  long result=1;
692
693
    has the global read lock and refuses the operation with
693
694
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
694
695
  */
695
 
  if ((error=wait_if_global_read_lock(session,0,1)))
 
696
  if ((error=wait_if_global_read_lock(thd,0,1)))
696
697
    goto exit2;
697
698
 
698
 
  pthread_mutex_lock(&LOCK_mysql_create_db);
 
699
  VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
699
700
 
700
701
  /* 
701
702
     Recreate db options file: /dbpath/.db.opt
703
704
     "table name to file name" encoding.
704
705
  */
705
706
  build_table_filename(path, sizeof(path), db, "", MY_DB_OPT_FILE, 0);
706
 
  if ((error=write_db_opt(session, path, db, create_info)))
 
707
  if ((error=write_db_opt(thd, path, db, create_info)))
707
708
    goto exit;
708
709
 
709
710
  /* Change options if current database is being altered. */
710
711
 
711
 
  if (session->db && !strcmp(session->db,db))
 
712
  if (thd->db && !strcmp(thd->db,db))
712
713
  {
713
 
    session->db_charset= create_info->default_table_charset ?
 
714
    thd->db_charset= create_info->default_table_charset ?
714
715
                     create_info->default_table_charset :
715
 
                     session->variables.collation_server;
716
 
    session->variables.collation_database= session->db_charset;
 
716
                     thd->variables.collation_server;
 
717
    thd->variables.collation_database= thd->db_charset;
717
718
  }
718
719
 
 
720
  ha_binlog_log_query(thd, 0, LOGCOM_ALTER_DB,
 
721
                      thd->query, thd->query_length,
 
722
                      db, "");
 
723
 
719
724
  if (mysql_bin_log.is_open())
720
725
  {
721
 
    Query_log_event qinfo(session, session->query, session->query_length, 0,
 
726
    Query_log_event qinfo(thd, thd->query, thd->query_length, 0,
722
727
                          /* suppress_use */ true);
723
728
 
724
729
    /*
729
734
    qinfo.db     = db;
730
735
    qinfo.db_len = strlen(db);
731
736
 
732
 
    session->clear_error();
 
737
    thd->clear_error();
733
738
    /* These DDL methods and logging protected with LOCK_mysql_create_db */
734
739
    mysql_bin_log.write(&qinfo);
735
740
  }
736
 
  my_ok(session, result);
 
741
  my_ok(thd, result);
737
742
 
738
743
exit:
739
 
  pthread_mutex_unlock(&LOCK_mysql_create_db);
740
 
  start_waiting_global_read_lock(session);
 
744
  VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
 
745
  start_waiting_global_read_lock(thd);
741
746
exit2:
742
747
  return(error);
743
748
}
748
753
 
749
754
  SYNOPSIS
750
755
    mysql_rm_db()
751
 
    session                     Thread handle
 
756
    thd                 Thread handle
752
757
    db                  Database name in the case given by user
753
758
                        It's already validated and set to lower case
754
759
                        (if needed) when we come here
760
765
    ERROR Error
761
766
*/
762
767
 
763
 
bool mysql_rm_db(Session *session,char *db,bool if_exists, bool silent)
 
768
bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
764
769
{
765
770
  long deleted=0;
766
771
  int error= false;
767
772
  char  path[FN_REFLEN+16];
768
773
  MY_DIR *dirp;
769
 
  uint32_t length;
 
774
  uint length;
770
775
  TableList* dropped_tables= 0;
771
776
 
772
777
  if (db && (strcmp(db, "information_schema") == 0))
787
792
    has the global read lock and refuses the operation with
788
793
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
789
794
  */
790
 
  if (wait_if_global_read_lock(session, 0, 1))
 
795
  if (wait_if_global_read_lock(thd, 0, 1))
791
796
  {
792
797
    error= -1;
793
798
    goto exit2;
794
799
  }
795
800
 
796
 
  pthread_mutex_lock(&LOCK_mysql_create_db);
 
801
  VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
797
802
 
798
803
  /*
799
804
    This statement will be replicated as a statement, even when using
800
805
    row-based replication. The flag will be reset at the end of the
801
806
    statement.
802
807
  */
803
 
  session->clear_current_stmt_binlog_row_based();
 
808
  thd->clear_current_stmt_binlog_row_based();
804
809
 
805
810
  length= build_table_filename(path, sizeof(path), db, "", "", 0);
806
 
  my_stpcpy(path+length, MY_DB_OPT_FILE);               // Append db option file name
 
811
  stpcpy(path+length, MY_DB_OPT_FILE);          // Append db option file name
807
812
  del_dbopt(path);                              // Remove dboption hash entry
808
813
  path[length]= '\0';                           // Remove file name
809
814
 
817
822
      goto exit;
818
823
    }
819
824
    else
820
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
825
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
821
826
                          ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS), db);
822
827
  }
823
828
  else
828
833
 
829
834
    
830
835
    error= -1;
831
 
    if ((deleted= mysql_rm_known_files(session, dirp, db, path, 0,
 
836
    if ((deleted= mysql_rm_known_files(thd, dirp, db, path, 0,
832
837
                                       &dropped_tables)) >= 0)
833
838
    {
834
839
      ha_drop_database(path);
839
844
  {
840
845
    const char *query;
841
846
    uint32_t query_length;
842
 
    if (!session->query)
 
847
    if (!thd->query)
843
848
    {
844
849
      /* The client used the old obsolete mysql_drop_db() call */
845
850
      query= path;
846
851
      query_length= (uint) (strxmov(path, "drop database `", db, "`",
847
 
                                     NULL) - path);
 
852
                                     NullS) - path);
848
853
    }
849
854
    else
850
855
    {
851
 
      query =session->query;
852
 
      query_length= session->query_length;
 
856
      query =thd->query;
 
857
      query_length= thd->query_length;
853
858
    }
854
859
    if (mysql_bin_log.is_open())
855
860
    {
856
 
      Query_log_event qinfo(session, query, query_length, 0, 
 
861
      Query_log_event qinfo(thd, query, query_length, 0, 
857
862
                            /* suppress_use */ true);
858
863
      /*
859
864
        Write should use the database being created as the "current
863
868
      qinfo.db     = db;
864
869
      qinfo.db_len = strlen(db);
865
870
 
866
 
      session->clear_error();
 
871
      thd->clear_error();
867
872
      /* These DDL methods and logging protected with LOCK_mysql_create_db */
868
873
      mysql_bin_log.write(&qinfo);
869
874
    }
870
 
    session->clear_error();
871
 
    session->server_status|= SERVER_STATUS_DB_DROPPED;
872
 
    my_ok(session, (uint32_t) deleted);
873
 
    session->server_status&= ~SERVER_STATUS_DB_DROPPED;
 
875
    thd->clear_error();
 
876
    thd->server_status|= SERVER_STATUS_DB_DROPPED;
 
877
    my_ok(thd, (uint32_t) deleted);
 
878
    thd->server_status&= ~SERVER_STATUS_DB_DROPPED;
874
879
  }
875
880
  else if (mysql_bin_log.is_open())
876
881
  {
877
882
    char *query, *query_pos, *query_end, *query_data_start;
878
883
    TableList *tbl;
879
 
    uint32_t db_len;
 
884
    uint db_len;
880
885
 
881
 
    if (!(query= (char*) session->alloc(MAX_DROP_TABLE_Q_LEN)))
 
886
    if (!(query= (char*) thd->alloc(MAX_DROP_TABLE_Q_LEN)))
882
887
      goto exit; /* not much else we can do */
883
 
    query_pos= query_data_start= my_stpcpy(query,"drop table ");
 
888
    query_pos= query_data_start= stpcpy(query,"drop table ");
884
889
    query_end= query + MAX_DROP_TABLE_Q_LEN;
885
890
    db_len= strlen(db);
886
891
 
887
892
    for (tbl= dropped_tables; tbl; tbl= tbl->next_local)
888
893
    {
889
 
      uint32_t tbl_name_len;
 
894
      uint tbl_name_len;
890
895
 
891
896
      /* 3 for the quotes and the comma*/
892
897
      tbl_name_len= strlen(tbl->table_name) + 3;
893
898
      if (query_pos + tbl_name_len + 1 >= query_end)
894
899
      {
895
900
        /* These DDL methods and logging protected with LOCK_mysql_create_db */
896
 
        write_to_binlog(session, query, query_pos -1 - query, db, db_len);
 
901
        write_to_binlog(thd, query, query_pos -1 - query, db, db_len);
897
902
        query_pos= query_data_start;
898
903
      }
899
904
 
900
905
      *query_pos++ = '`';
901
 
      query_pos= my_stpcpy(query_pos,tbl->table_name);
 
906
      query_pos= stpcpy(query_pos,tbl->table_name);
902
907
      *query_pos++ = '`';
903
908
      *query_pos++ = ',';
904
909
    }
906
911
    if (query_pos != query_data_start)
907
912
    {
908
913
      /* These DDL methods and logging protected with LOCK_mysql_create_db */
909
 
      write_to_binlog(session, query, query_pos -1 - query, db, db_len);
 
914
      write_to_binlog(thd, query, query_pos -1 - query, db, db_len);
910
915
    }
911
916
  }
912
917
 
914
919
  /*
915
920
    If this database was the client's selected database, we silently
916
921
    change the client's selected database to nothing (to have an empty
917
 
    SELECT DATABASE() in the future). For this we free() session->db and set
 
922
    SELECT DATABASE() in the future). For this we free() thd->db and set
918
923
    it to 0.
919
924
  */
920
 
  if (session->db && !strcmp(session->db, db))
921
 
    mysql_change_db_impl(session, NULL, session->variables.collation_server);
922
 
  pthread_mutex_unlock(&LOCK_mysql_create_db);
923
 
  start_waiting_global_read_lock(session);
 
925
  if (thd->db && !strcmp(thd->db, db))
 
926
    mysql_change_db_impl(thd, NULL, thd->variables.collation_server);
 
927
  VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
 
928
  start_waiting_global_read_lock(thd);
924
929
exit2:
925
930
  return(error);
926
931
}
927
932
 
928
933
/*
929
934
  Removes files with known extensions plus.
930
 
  session MUST be set when calling this function!
 
935
  thd MUST be set when calling this function!
931
936
*/
932
937
 
933
 
static long mysql_rm_known_files(Session *session, MY_DIR *dirp, const char *db,
934
 
                                 const char *org_path, uint32_t level,
 
938
static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db,
 
939
                                 const char *org_path, uint level,
935
940
                                 TableList **dropped_tables)
936
941
{
937
942
  long deleted=0;
941
946
 
942
947
  tot_list_next= &tot_list;
943
948
 
944
 
  for (uint32_t idx=0 ;
945
 
       idx < (uint) dirp->number_off_files && !session->killed ;
 
949
  for (uint idx=0 ;
 
950
       idx < (uint) dirp->number_off_files && !thd->killed ;
946
951
       idx++)
947
952
  {
948
953
    FILEINFO *file=dirp->dir_entry+idx;
968
973
      /* Drop the table nicely */
969
974
      *extension= 0;                    // Remove extension
970
975
      TableList *table_list=(TableList*)
971
 
                              session->calloc(sizeof(*table_list) + 
 
976
                              thd->calloc(sizeof(*table_list) + 
972
977
                                          strlen(db) + 1 +
973
978
                                          MYSQL50_TABLE_NAME_PREFIX_LENGTH + 
974
979
                                          strlen(file->name) + 1);
976
981
      if (!table_list)
977
982
        goto err;
978
983
      table_list->db= (char*) (table_list+1);
979
 
      table_list->table_name= my_stpcpy(table_list->db, db) + 1;
980
 
      filename_to_tablename(file->name, table_list->table_name,
981
 
                            MYSQL50_TABLE_NAME_PREFIX_LENGTH +
982
 
                            strlen(file->name) + 1);
 
984
      table_list->table_name= stpcpy(table_list->db, db) + 1;
 
985
      VOID(filename_to_tablename(file->name, table_list->table_name,
 
986
                                 MYSQL50_TABLE_NAME_PREFIX_LENGTH +
 
987
                                 strlen(file->name) + 1));
983
988
      table_list->alias= table_list->table_name;        // If lower_case_table_names=2
984
989
      table_list->internal_tmp_table= is_prefix(file->name, tmp_file_prefix);
985
990
      /* Link into list */
989
994
    }
990
995
    else
991
996
    {
992
 
      strxmov(filePath, org_path, "/", file->name, NULL);
 
997
      strxmov(filePath, org_path, "/", file->name, NullS);
993
998
      if (my_delete_with_symlink(filePath,MYF(MY_WME)))
994
999
      {
995
1000
        goto err;
996
1001
      }
997
1002
    }
998
1003
  }
999
 
  if (session->killed ||
1000
 
      (tot_list && mysql_rm_table_part2(session, tot_list, 1, 0, 1, 1)))
 
1004
  if (thd->killed ||
 
1005
      (tot_list && mysql_rm_table_part2(thd, tot_list, 1, 0, 1, 1)))
1001
1006
    goto err;
1002
1007
 
1003
1008
  my_dirend(dirp);  
1084
1089
/**
1085
1090
  @brief Internal implementation: switch current database to a valid one.
1086
1091
 
1087
 
  @param session            Thread context.
 
1092
  @param thd            Thread context.
1088
1093
  @param new_db_name    Name of the database to switch to. The function will
1089
1094
                        take ownership of the name (the caller must not free
1090
1095
                        the allocated memory). If the name is NULL, we're
1092
1097
  @param new_db_charset Character set of the new database.
1093
1098
*/
1094
1099
 
1095
 
static void mysql_change_db_impl(Session *session,
 
1100
static void mysql_change_db_impl(THD *thd,
1096
1101
                                 LEX_STRING *new_db_name,
1097
1102
                                 const CHARSET_INFO * const new_db_charset)
1098
1103
{
1099
 
  /* 1. Change current database in Session. */
 
1104
  /* 1. Change current database in THD. */
1100
1105
 
1101
1106
  if (new_db_name == NULL)
1102
1107
  {
1103
1108
    /*
1104
 
      Session::set_db() does all the job -- it frees previous database name and
 
1109
      THD::set_db() does all the job -- it frees previous database name and
1105
1110
      sets the new one.
1106
1111
    */
1107
1112
 
1108
 
    session->set_db(NULL, 0);
 
1113
    thd->set_db(NULL, 0);
1109
1114
  }
1110
1115
  else if (new_db_name == &INFORMATION_SCHEMA_NAME)
1111
1116
  {
1112
1117
    /*
1113
 
      Here we must use Session::set_db(), because we want to copy
 
1118
      Here we must use THD::set_db(), because we want to copy
1114
1119
      INFORMATION_SCHEMA_NAME constant.
1115
1120
    */
1116
1121
 
1117
 
    session->set_db(INFORMATION_SCHEMA_NAME.str, INFORMATION_SCHEMA_NAME.length);
 
1122
    thd->set_db(INFORMATION_SCHEMA_NAME.str, INFORMATION_SCHEMA_NAME.length);
1118
1123
  }
1119
1124
  else
1120
1125
  {
1121
1126
    /*
1122
 
      Here we already have a copy of database name to be used in Session. So,
1123
 
      we just call Session::reset_db(). Since Session::reset_db() does not releases
 
1127
      Here we already have a copy of database name to be used in THD. So,
 
1128
      we just call THD::reset_db(). Since THD::reset_db() does not releases
1124
1129
      the previous database name, we should do it explicitly.
1125
1130
    */
1126
1131
 
1127
 
    if (session->db)
1128
 
      free(session->db);
 
1132
    x_free(thd->db);
1129
1133
 
1130
 
    session->reset_db(new_db_name->str, new_db_name->length);
 
1134
    thd->reset_db(new_db_name->str, new_db_name->length);
1131
1135
  }
1132
1136
 
1133
1137
  /* 3. Update db-charset environment variables. */
1134
1138
 
1135
 
  session->db_charset= new_db_charset;
1136
 
  session->variables.collation_database= new_db_charset;
 
1139
  thd->db_charset= new_db_charset;
 
1140
  thd->variables.collation_database= new_db_charset;
1137
1141
}
1138
1142
 
1139
1143
 
1141
1145
/**
1142
1146
  Backup the current database name before switch.
1143
1147
 
1144
 
  @param[in]      session             thread handle
 
1148
  @param[in]      thd             thread handle
1145
1149
  @param[in, out] saved_db_name   IN: "str" points to a buffer where to store
1146
1150
                                  the old database name, "length" contains the
1147
1151
                                  buffer size
1153
1157
                                  "length" is set to 0.
1154
1158
*/
1155
1159
 
1156
 
static void backup_current_db_name(Session *session,
 
1160
static void backup_current_db_name(THD *thd,
1157
1161
                                   LEX_STRING *saved_db_name)
1158
1162
{
1159
 
  if (!session->db)
 
1163
  if (!thd->db)
1160
1164
  {
1161
1165
    /* No current (default) database selected. */
1162
1166
 
1165
1169
  }
1166
1170
  else
1167
1171
  {
1168
 
    strmake(saved_db_name->str, session->db, saved_db_name->length - 1);
1169
 
    saved_db_name->length= session->db_length;
 
1172
    strmake(saved_db_name->str, thd->db, saved_db_name->length - 1);
 
1173
    saved_db_name->length= thd->db_length;
1170
1174
  }
1171
1175
}
1172
1176
 
1198
1202
/**
1199
1203
  @brief Change the current database and its attributes unconditionally.
1200
1204
 
1201
 
  @param session          thread handle
 
1205
  @param thd          thread handle
1202
1206
  @param new_db_name  database name
1203
1207
  @param force_switch if force_switch is false, then the operation will fail if
1204
1208
 
1224
1228
                          @@collation_server, but the operation will fail;
1225
1229
 
1226
1230
                        - user privileges will not be checked
1227
 
                          (Session::db_access however is updated);
 
1231
                          (THD::db_access however is updated);
1228
1232
 
1229
1233
                          TODO: is this really the intention?
1230
1234
                                (see sp-security.test).
1237
1241
  @details The function checks that the database name corresponds to a
1238
1242
  valid and existent database, checks access rights and changes the current
1239
1243
  database with database attributes (@@collation_database session variable,
1240
 
  Session::db_access).
 
1244
  THD::db_access).
1241
1245
 
1242
1246
  This function is not the only way to switch the database that is
1243
1247
  currently employed. When the replication slave thread switches the
1244
 
  database before executing a query, it calls session->set_db directly.
 
1248
  database before executing a query, it calls thd->set_db directly.
1245
1249
  However, if the query, in turn, uses a stored routine, the stored routine
1246
1250
  will use this function, even if it's run on the slave.
1247
1251
 
1257
1261
    @retval true  Error
1258
1262
*/
1259
1263
 
1260
 
bool mysql_change_db(Session *session, const LEX_STRING *new_db_name, bool force_switch)
 
1264
bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch)
1261
1265
{
1262
1266
  LEX_STRING new_db_file_name;
1263
1267
  const CHARSET_INFO *db_default_cl;
1277
1281
        new_db_name->length == 0.
1278
1282
      */
1279
1283
 
1280
 
      mysql_change_db_impl(session, NULL, session->variables.collation_server);
 
1284
      mysql_change_db_impl(thd, NULL, thd->variables.collation_server);
1281
1285
 
1282
1286
      return(false);
1283
1287
    }
1294
1298
  {
1295
1299
    /* Switch the current database to INFORMATION_SCHEMA. */
1296
1300
 
1297
 
    mysql_change_db_impl(session, &INFORMATION_SCHEMA_NAME, system_charset_info);
 
1301
    mysql_change_db_impl(thd, &INFORMATION_SCHEMA_NAME, system_charset_info);
1298
1302
 
1299
1303
    return(false);
1300
1304
  }
1325
1329
  if (check_db_name(&new_db_file_name))
1326
1330
  {
1327
1331
    my_error(ER_WRONG_DB_NAME, MYF(0), new_db_file_name.str);
1328
 
    free(new_db_file_name.str);
 
1332
    my_free(new_db_file_name.str, MYF(0));
1329
1333
 
1330
1334
    if (force_switch)
1331
 
      mysql_change_db_impl(session, NULL, session->variables.collation_server);
 
1335
      mysql_change_db_impl(thd, NULL, thd->variables.collation_server);
1332
1336
 
1333
1337
    return(true);
1334
1338
  }
1339
1343
    {
1340
1344
      /* Throw a warning and free new_db_file_name. */
1341
1345
 
1342
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
1346
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1343
1347
                          ER_BAD_DB_ERROR, ER(ER_BAD_DB_ERROR),
1344
1348
                          new_db_file_name.str);
1345
1349
 
1346
 
      free(new_db_file_name.str);
 
1350
      my_free(new_db_file_name.str, MYF(0));
1347
1351
 
1348
1352
      /* Change db to NULL. */
1349
1353
 
1350
 
      mysql_change_db_impl(session, NULL, session->variables.collation_server);
 
1354
      mysql_change_db_impl(thd, NULL, thd->variables.collation_server);
1351
1355
 
1352
1356
      /* The operation succeed. */
1353
1357
 
1358
1362
      /* Report an error and free new_db_file_name. */
1359
1363
 
1360
1364
      my_error(ER_BAD_DB_ERROR, MYF(0), new_db_file_name.str);
1361
 
      free(new_db_file_name.str);
 
1365
      my_free(new_db_file_name.str, MYF(0));
1362
1366
 
1363
1367
      /* The operation failed. */
1364
1368
 
1367
1371
  }
1368
1372
 
1369
1373
  /*
1370
 
    NOTE: in mysql_change_db_impl() new_db_file_name is assigned to Session
1371
 
    attributes and will be freed in Session::~Session().
 
1374
    NOTE: in mysql_change_db_impl() new_db_file_name is assigned to THD
 
1375
    attributes and will be freed in THD::~THD().
1372
1376
  */
1373
1377
 
1374
 
  db_default_cl= get_default_db_collation(session, new_db_file_name.str);
 
1378
  db_default_cl= get_default_db_collation(thd, new_db_file_name.str);
1375
1379
 
1376
 
  mysql_change_db_impl(session, &new_db_file_name, db_default_cl);
 
1380
  mysql_change_db_impl(thd, &new_db_file_name, db_default_cl);
1377
1381
 
1378
1382
  return(false);
1379
1383
}
1382
1386
/**
1383
1387
  Change the current database and its attributes if needed.
1384
1388
 
1385
 
  @param          session             thread handle
 
1389
  @param          thd             thread handle
1386
1390
  @param          new_db_name     database name
1387
1391
  @param[in, out] saved_db_name   IN: "str" points to a buffer where to store
1388
1392
                                  the old database name, "length" contains the
1399
1403
                                  the function suceeded)
1400
1404
*/
1401
1405
 
1402
 
bool mysql_opt_change_db(Session *session,
 
1406
bool mysql_opt_change_db(THD *thd,
1403
1407
                         const LEX_STRING *new_db_name,
1404
1408
                         LEX_STRING *saved_db_name,
1405
1409
                         bool force_switch,
1406
1410
                         bool *cur_db_changed)
1407
1411
{
1408
 
  *cur_db_changed= !cmp_db_names(session->db, new_db_name->str);
 
1412
  *cur_db_changed= !cmp_db_names(thd->db, new_db_name->str);
1409
1413
 
1410
1414
  if (!*cur_db_changed)
1411
1415
    return false;
1412
1416
 
1413
 
  backup_current_db_name(session, saved_db_name);
 
1417
  backup_current_db_name(thd, saved_db_name);
1414
1418
 
1415
 
  return mysql_change_db(session, new_db_name, force_switch);
 
1419
  return mysql_change_db(thd, new_db_name, force_switch);
1416
1420
}
1417
1421
 
1418
1422
 
1431
1435
bool check_db_dir_existence(const char *db_name)
1432
1436
{
1433
1437
  char db_dir_path[FN_REFLEN];
1434
 
  uint32_t db_dir_path_len;
 
1438
  uint db_dir_path_len;
1435
1439
 
1436
1440
  db_dir_path_len= build_table_filename(db_dir_path, sizeof(db_dir_path),
1437
1441
                                        db_name, "", "", 0);