1 /*
2    Copyright (c) 2000, 2014, Oracle and/or its affiliates.
3    Copyright (c) 2009, 2016, MariaDB Corporation
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; version 2 of the License.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1335  USA */
17 
18 
19 /* create and drop of databases */
20 
21 #include "mariadb.h"                   /* NO_EMBEDDED_ACCESS_CHECKS */
22 #include "sql_priv.h"
23 #include "unireg.h"
24 #include "sql_db.h"
25 #include "sql_cache.h"                   // query_cache_*
26 #include "lock.h"                        // lock_schema_name
27 #include "sql_table.h"                   // build_table_filename,
28                                          // filename_to_tablename
29 #include "sql_rename.h"                  // mysql_rename_tables
30 #include "sql_acl.h"                     // SELECT_ACL, DB_ACLS,
31                                          // acl_get, check_grant_db
32 #include "log_event.h"                   // Query_log_event
33 #include "sql_base.h"                    // lock_table_names, tdc_remove_table
34 #include "sql_handler.h"                 // mysql_ha_rm_tables
35 #include "sql_class.h"
36 #include <mysys_err.h>
37 #include "sp_head.h"
38 #include "sp.h"
39 #include "events.h"
40 #include "sql_handler.h"
41 #include "sql_statistics.h"
42 #include <my_dir.h>
43 #include <m_ctype.h>
44 #include "log.h"
45 #ifdef __WIN__
46 #include <direct.h>
47 #endif
48 #include "debug_sync.h"
49 
50 #define MAX_DROP_TABLE_Q_LEN      1024
51 
52 const char *del_exts[]= {".BAK", ".opt", NullS};
53 static TYPELIB deletable_extensions=
54 {array_elements(del_exts)-1,"del_exts", del_exts, NULL};
55 
56 static bool find_db_tables_and_rm_known_files(THD *, MY_DIR *, const char *,
57                                               const char *, TABLE_LIST **);
58 
59 long mysql_rm_arc_files(THD *thd, MY_DIR *dirp, const char *org_path);
60 static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error);
61 static void mysql_change_db_impl(THD *thd,
62                                  LEX_CSTRING *new_db_name,
63                                  ulong new_db_access,
64                                  CHARSET_INFO *new_db_charset);
65 static bool mysql_rm_db_internal(THD *thd, const LEX_CSTRING *db,
66                                  bool if_exists, bool silent);
67 
68 
69 /* Database options hash */
70 static HASH dboptions;
71 static my_bool dboptions_init= 0;
72 static mysql_rwlock_t LOCK_dboptions;
73 
74 /* Structure for database options */
75 typedef struct my_dbopt_st
76 {
77   char *name;			/* Database name                  */
78   uint name_length;		/* Database length name           */
79   CHARSET_INFO *charset;	/* Database default character set */
80 } my_dbopt_t;
81 
82 
83 /**
84   Return TRUE if db1_name is equal to db2_name, FALSE otherwise.
85 
86   The function allows to compare database names according to the MariaDB
87   rules. The database names db1 and db2 are equal if:
88      - db1 is NULL and db2 is NULL;
89      or
90      - db1 is not-NULL, db2 is not-NULL, db1 is equal to db2 in
91      table_alias_charset
92 
93   This is the same rules as we use for filenames.
94 */
95 
96 static inline bool
97 cmp_db_names(LEX_CSTRING *db1_name, const LEX_CSTRING *db2_name)
98 {
99   return (db1_name->length == db2_name->length &&
100           (db1_name->length == 0 ||
101            my_strcasecmp(table_alias_charset,
102                          db1_name->str, db2_name->str) == 0));
103 }
104 
105 
106 /*
107   Function we use in the creation of our hash to get key.
108 */
109 
110 extern "C" uchar* dboptions_get_key(my_dbopt_t *opt, size_t *length,
111                                     my_bool not_used);
112 
113 uchar* dboptions_get_key(my_dbopt_t *opt, size_t *length,
114                          my_bool not_used __attribute__((unused)))
115 {
116   *length= opt->name_length;
117   return (uchar*) opt->name;
118 }
119 
120 
121 /*
122   Helper function to write a query to binlog used by mysql_rm_db()
123 */
124 
125 static inline int write_to_binlog(THD *thd, const char *query, size_t q_len,
126                                   const char *db, size_t db_len)
127 {
128   Query_log_event qinfo(thd, query, q_len, FALSE, TRUE, FALSE, 0);
129   qinfo.db= db;
130   qinfo.db_len= (uint32)db_len;
131   return mysql_bin_log.write(&qinfo);
132 }
133 
134 
135 /*
136   Function to free dboptions hash element
137 */
138 
139 extern "C" void free_dbopt(void *dbopt);
140 
141 void free_dbopt(void *dbopt)
142 {
143   my_free(dbopt);
144 }
145 
146 #ifdef HAVE_PSI_INTERFACE
147 static PSI_rwlock_key key_rwlock_LOCK_dboptions;
148 
149 static PSI_rwlock_info all_database_names_rwlocks[]=
150 {
151   { &key_rwlock_LOCK_dboptions, "LOCK_dboptions", PSI_FLAG_GLOBAL}
152 };
153 
154 static void init_database_names_psi_keys(void)
155 {
156   const char* category= "sql";
157   int count;
158 
159   if (PSI_server == NULL)
160     return;
161 
162   count= array_elements(all_database_names_rwlocks);
163   PSI_server->register_rwlock(category, all_database_names_rwlocks, count);
164 }
165 #endif
166 
167 /**
168   Initialize database option cache.
169 
170   @note Must be called before any other database function is called.
171 
172   @retval  0	ok
173   @retval  1	Fatal error
174 */
175 
176 bool my_dboptions_cache_init(void)
177 {
178 #ifdef HAVE_PSI_INTERFACE
179   init_database_names_psi_keys();
180 #endif
181 
182   bool error= 0;
183   mysql_rwlock_init(key_rwlock_LOCK_dboptions, &LOCK_dboptions);
184   if (!dboptions_init)
185   {
186     dboptions_init= 1;
187     error= my_hash_init(&dboptions, table_alias_charset,
188                         32, 0, 0, (my_hash_get_key) dboptions_get_key,
189                         free_dbopt,0);
190   }
191   return error;
192 }
193 
194 
195 
196 /**
197   Free database option hash and locked databases hash.
198 */
199 
200 void my_dboptions_cache_free(void)
201 {
202   if (dboptions_init)
203   {
204     dboptions_init= 0;
205     my_hash_free(&dboptions);
206     mysql_rwlock_destroy(&LOCK_dboptions);
207   }
208 }
209 
210 
211 /**
212   Cleanup cached options.
213 */
214 
215 void my_dbopt_cleanup(void)
216 {
217   mysql_rwlock_wrlock(&LOCK_dboptions);
218   my_hash_free(&dboptions);
219   my_hash_init(&dboptions, table_alias_charset,
220                32, 0, 0, (my_hash_get_key) dboptions_get_key,
221                free_dbopt,0);
222   mysql_rwlock_unlock(&LOCK_dboptions);
223 }
224 
225 
226 /*
227   Find database options in the hash.
228 
229   DESCRIPTION
230     Search a database options in the hash, usings its path.
231     Fills "create" on success.
232 
233   RETURN VALUES
234     0 on success.
235     1 on error.
236 */
237 
238 static my_bool get_dbopt(const char *dbname, Schema_specification_st *create)
239 {
240   my_dbopt_t *opt;
241   uint length;
242   my_bool error= 1;
243 
244   length= (uint) strlen(dbname);
245 
246   mysql_rwlock_rdlock(&LOCK_dboptions);
247   if ((opt= (my_dbopt_t*) my_hash_search(&dboptions, (uchar*) dbname, length)))
248   {
249     create->default_table_charset= opt->charset;
250     error= 0;
251   }
252   mysql_rwlock_unlock(&LOCK_dboptions);
253   return error;
254 }
255 
256 
257 /*
258   Writes database options into the hash.
259 
260   DESCRIPTION
261     Inserts database options into the hash, or updates
262     options if they are already in the hash.
263 
264   RETURN VALUES
265     0 on success.
266     1 on error.
267 */
268 
269 static my_bool put_dbopt(const char *dbname, Schema_specification_st *create)
270 {
271   my_dbopt_t *opt;
272   uint length;
273   my_bool error= 0;
274   DBUG_ENTER("put_dbopt");
275 
276   length= (uint) strlen(dbname);
277 
278   mysql_rwlock_wrlock(&LOCK_dboptions);
279   if (!(opt= (my_dbopt_t*) my_hash_search(&dboptions, (uchar*) dbname,
280                                           length)))
281   {
282     /* Options are not in the hash, insert them */
283     char *tmp_name;
284     if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
285                          &opt, (uint) sizeof(*opt), &tmp_name, (uint) length+1,
286                          NullS))
287     {
288       error= 1;
289       goto end;
290     }
291 
292     opt->name= tmp_name;
293     strmov(opt->name, dbname);
294     opt->name_length= length;
295 
296     if (unlikely((error= my_hash_insert(&dboptions, (uchar*) opt))))
297     {
298       my_free(opt);
299       goto end;
300     }
301   }
302 
303   /* Update / write options in hash */
304   opt->charset= create->default_table_charset;
305 
306 end:
307   mysql_rwlock_unlock(&LOCK_dboptions);
308   DBUG_RETURN(error);
309 }
310 
311 
312 /*
313   Deletes database options from the hash.
314 */
315 
316 static void del_dbopt(const char *path)
317 {
318   my_dbopt_t *opt;
319   mysql_rwlock_wrlock(&LOCK_dboptions);
320   if ((opt= (my_dbopt_t *)my_hash_search(&dboptions, (const uchar*) path,
321                                          strlen(path))))
322     my_hash_delete(&dboptions, (uchar*) opt);
323   mysql_rwlock_unlock(&LOCK_dboptions);
324 }
325 
326 
327 /*
328   Create database options file:
329 
330   DESCRIPTION
331     Currently database default charset is only stored there.
332 
333   RETURN VALUES
334   0	ok
335   1	Could not create file or write to it.  Error sent through my_error()
336 */
337 
338 static bool write_db_opt(THD *thd, const char *path,
339                          Schema_specification_st *create)
340 {
341   File file;
342   char buf[256]; // Should be enough for one option
343   bool error=1;
344 
345   if (!create->default_table_charset)
346     create->default_table_charset= thd->variables.collation_server;
347 
348   if (put_dbopt(path, create))
349     return 1;
350 
351   if ((file= mysql_file_create(key_file_dbopt, path, CREATE_MODE,
352                                O_RDWR | O_TRUNC, MYF(MY_WME))) >= 0)
353   {
354     ulong length;
355     length= (ulong) (strxnmov(buf, sizeof(buf)-1, "default-character-set=",
356                               create->default_table_charset->csname,
357                               "\ndefault-collation=",
358                               create->default_table_charset->name,
359                               "\n", NullS) - buf);
360 
361     /* Error is written by mysql_file_write */
362     if (!mysql_file_write(file, (uchar*) buf, length, MYF(MY_NABP+MY_WME)))
363       error=0;
364     mysql_file_close(file, MYF(0));
365   }
366   return error;
367 }
368 
369 
370 /*
371   Load database options file
372 
373   load_db_opt()
374   path		Path for option file
375   create	Where to store the read options
376 
377   DESCRIPTION
378 
379   RETURN VALUES
380   0	File found
381   1	No database file or could not open it
382 
383 */
384 
385 bool load_db_opt(THD *thd, const char *path, Schema_specification_st *create)
386 {
387   File file;
388   char buf[256];
389   DBUG_ENTER("load_db_opt");
390   bool error=1;
391   size_t nbytes;
392 
393   bzero((char*) create,sizeof(*create));
394   create->default_table_charset= thd->variables.collation_server;
395 
396   /* Check if options for this database are already in the hash */
397   if (!get_dbopt(path, create))
398     DBUG_RETURN(0);
399 
400   /* Otherwise, load options from the .opt file */
401   if ((file= mysql_file_open(key_file_dbopt,
402                              path, O_RDONLY | O_SHARE, MYF(0))) < 0)
403     goto err1;
404 
405   IO_CACHE cache;
406   if (init_io_cache(&cache, file, IO_SIZE, READ_CACHE, 0, 0, MYF(0)))
407     goto err2;
408 
409   while ((int) (nbytes= my_b_gets(&cache, (char*) buf, sizeof(buf))) > 0)
410   {
411     char *pos= buf+nbytes-1;
412     /* Remove end space and control characters */
413     while (pos > buf && !my_isgraph(&my_charset_latin1, pos[-1]))
414       pos--;
415     *pos=0;
416     if ((pos= strchr(buf, '=')))
417     {
418       if (!strncmp(buf,"default-character-set", (pos-buf)))
419       {
420         /*
421            Try character set name, and if it fails
422            try collation name, probably it's an old
423            4.1.0 db.opt file, which didn't have
424            separate default-character-set and
425            default-collation commands.
426         */
427         if (!(create->default_table_charset=
428         get_charset_by_csname(pos+1, MY_CS_PRIMARY, MYF(0))) &&
429             !(create->default_table_charset=
430               get_charset_by_name(pos+1, MYF(0))))
431         {
432           sql_print_error("Error while loading database options: '%s':",path);
433           sql_print_error(ER_THD(thd, ER_UNKNOWN_CHARACTER_SET),pos+1);
434           create->default_table_charset= default_charset_info;
435         }
436       }
437       else if (!strncmp(buf,"default-collation", (pos-buf)))
438       {
439         if (!(create->default_table_charset= get_charset_by_name(pos+1,
440                                                            MYF(0))))
441         {
442           sql_print_error("Error while loading database options: '%s':",path);
443           sql_print_error(ER_THD(thd, ER_UNKNOWN_COLLATION),pos+1);
444           create->default_table_charset= default_charset_info;
445         }
446       }
447     }
448   }
449   /*
450     Put the loaded value into the hash.
451     Note that another thread could've added the same
452     entry to the hash after we called get_dbopt(),
453     but it's not an error, as put_dbopt() takes this
454     possibility into account.
455   */
456   error= put_dbopt(path, create);
457 
458   end_io_cache(&cache);
459 err2:
460   mysql_file_close(file, MYF(0));
461 err1:
462   DBUG_RETURN(error);
463 }
464 
465 
466 /*
467   Retrieve database options by name. Load database options file or fetch from
468   cache.
469 
470   SYNOPSIS
471     load_db_opt_by_name()
472     db_name         Database name
473     db_create_info  Where to store the database options
474 
475   DESCRIPTION
476     load_db_opt_by_name() is a shortcut for load_db_opt().
477 
478   NOTE
479     Although load_db_opt_by_name() (and load_db_opt()) returns status of
480     the operation, it is useless usually and should be ignored. The problem
481     is that there are 1) system databases ("mysql") and 2) virtual
482     databases ("information_schema"), which do not contain options file.
483     So, load_db_opt[_by_name]() returns FALSE for these databases, but this
484     is not an error.
485 
486     load_db_opt[_by_name]() clears db_create_info structure in any case, so
487     even on failure it contains valid data. So, common use case is just
488     call load_db_opt[_by_name]() without checking return value and use
489     db_create_info right after that.
490 
491   RETURN VALUES (read NOTE!)
492     FALSE   Success
493     TRUE    Failed to retrieve options
494 */
495 
496 bool load_db_opt_by_name(THD *thd, const char *db_name,
497                          Schema_specification_st *db_create_info)
498 {
499   char db_opt_path[FN_REFLEN + 1];
500 
501   /*
502     Pass an empty file name, and the database options file name as extension
503     to avoid table name to file name encoding.
504   */
505   (void) build_table_filename(db_opt_path, sizeof(db_opt_path) - 1,
506                               db_name, "", MY_DB_OPT_FILE, 0);
507 
508   return load_db_opt(thd, db_opt_path, db_create_info);
509 }
510 
511 
512 /**
513   Return default database collation.
514 
515   @param thd     Thread context.
516   @param db_name Database name.
517 
518   @return CHARSET_INFO object. The operation always return valid character
519     set, even if the database does not exist.
520 */
521 
522 CHARSET_INFO *get_default_db_collation(THD *thd, const char *db_name)
523 {
524   Schema_specification_st db_info;
525 
526   if (thd->db.str != NULL && strcmp(db_name, thd->db.str) == 0)
527     return thd->db_charset;
528 
529   load_db_opt_by_name(thd, db_name, &db_info);
530 
531   /*
532     NOTE: even if load_db_opt_by_name() fails,
533     db_info.default_table_charset contains valid character set
534     (collation_server). We should not fail if load_db_opt_by_name() fails,
535     because it is valid case. If a database has been created just by
536     "mkdir", it does not contain db.opt file, but it is valid database.
537   */
538 
539   return db_info.default_table_charset;
540 }
541 
542 
543 /*
544   Create a database
545 
546   SYNOPSIS
547   mysql_create_db_iternal()
548   thd		Thread handler
549   db		Name of database to create
550 		Function assumes that this is already validated.
551   options       DDL options, e.g. IF NOT EXISTS
552   create_info	Database create options (like character set)
553   silent	Used by replication when internally creating a database.
554 		In this case the entry should not be logged.
555 
556   SIDE-EFFECTS
557    1. Report back to client that command succeeded (my_ok)
558    2. Report errors to client
559    3. Log event to binary log
560    (The 'silent' flags turns off 1 and 3.)
561 
562   RETURN VALUES
563   FALSE ok
564   TRUE  Error
565 
566 */
567 
568 static int
569 mysql_create_db_internal(THD *thd, const LEX_CSTRING *db,
570                          const DDL_options_st &options,
571                          Schema_specification_st *create_info,
572                          bool silent)
573 {
574   char	 path[FN_REFLEN+16];
575   MY_STAT stat_info;
576   uint path_len;
577   DBUG_ENTER("mysql_create_db");
578 
579   /* do not create 'information_schema' db */
580   if (is_infoschema_db(db))
581   {
582     my_error(ER_DB_CREATE_EXISTS, MYF(0), db->str);
583     DBUG_RETURN(-1);
584   }
585 
586   char db_tmp[SAFE_NAME_LEN+1];
587   const char *dbnorm= normalize_db_name(db->str, db_tmp, sizeof(db_tmp));
588 
589   if (lock_schema_name(thd, dbnorm))
590     DBUG_RETURN(-1);
591 
592   /* Check directory */
593   path_len= build_table_filename(path, sizeof(path) - 1, db->str, "", "", 0);
594   path[path_len-1]= 0;                    // Remove last '/' from path
595 
596   long affected_rows= 1;
597   if (!mysql_file_stat(key_file_misc, path, &stat_info, MYF(0)))
598   {
599     // The database directory does not exist, or my_file_stat() failed
600     if (my_errno != ENOENT)
601     {
602       my_error(EE_STAT, MYF(0), path, my_errno);
603       DBUG_RETURN(1);
604     }
605   }
606   else if (options.or_replace())
607   {
608     if (mysql_rm_db_internal(thd, db, 0, true)) // Removing the old database
609       DBUG_RETURN(1);
610     /*
611       Reset the diagnostics m_status.
612       It might be set ot DA_OK in mysql_rm_db.
613     */
614     thd->get_stmt_da()->reset_diagnostics_area();
615     affected_rows= 2;
616   }
617   else if (options.if_not_exists())
618   {
619     push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
620                         ER_DB_CREATE_EXISTS, ER_THD(thd, ER_DB_CREATE_EXISTS),
621                         db->str);
622     affected_rows= 0;
623     goto not_silent;
624   }
625   else
626   {
627     my_error(ER_DB_CREATE_EXISTS, MYF(0), db->str);
628     DBUG_RETURN(-1);
629   }
630 
631 
632   if (my_mkdir(path, 0777, MYF(0)) < 0)
633   {
634     my_error(ER_CANT_CREATE_DB, MYF(0), db->str, my_errno);
635     DBUG_RETURN(-1);
636   }
637 
638   path[path_len-1]= FN_LIBCHAR;
639   strmake(path+path_len, MY_DB_OPT_FILE, sizeof(path)-path_len-1);
640   if (write_db_opt(thd, path, create_info))
641   {
642     /*
643       Could not create options file.
644       Restore things to beginning.
645     */
646     path[path_len]= 0;
647     if (rmdir(path) >= 0)
648       DBUG_RETURN(-1);
649     /*
650       We come here when we managed to create the database, but not the option
651       file.  In this case it's best to just continue as if nothing has
652       happened.  (This is a very unlikely senario)
653     */
654     thd->clear_error();
655   }
656 
657 not_silent:
658   if (!silent)
659   {
660     char *query;
661     uint query_length;
662 
663     query=        thd->query();
664     query_length= thd->query_length();
665     DBUG_ASSERT(query);
666 
667     if (mysql_bin_log.is_open())
668     {
669       int errcode= query_error_code(thd, TRUE);
670       Query_log_event qinfo(thd, query, query_length, FALSE, TRUE,
671 			    /* suppress_use */ TRUE, errcode);
672 
673       /*
674 	Write should use the database being created as the "current
675         database" and not the threads current database, which is the
676         default. If we do not change the "current database" to the
677         database being created, the CREATE statement will not be
678         replicated when using --binlog-do-db to select databases to be
679         replicated.
680 
681 	An example (--binlog-do-db=sisyfos):
682 
683           CREATE DATABASE bob;        # Not replicated
684           USE bob;                    # 'bob' is the current database
685           CREATE DATABASE sisyfos;    # Not replicated since 'bob' is
686                                       # current database.
687           USE sisyfos;                # Will give error on slave since
688                                       # database does not exist.
689       */
690       qinfo.db     = db->str;
691       qinfo.db_len = (uint32)db->length;
692 
693       /*
694         These DDL methods and logging are protected with the exclusive
695         metadata lock on the schema
696       */
697       if (mysql_bin_log.write(&qinfo))
698         DBUG_RETURN(-1);
699     }
700     my_ok(thd, affected_rows);
701   }
702 
703   DBUG_RETURN(0);
704 }
705 
706 
707 /* db-name is already validated when we come here */
708 
709 static bool
710 mysql_alter_db_internal(THD *thd, const LEX_CSTRING *db,
711                         Schema_specification_st *create_info)
712 {
713   char path[FN_REFLEN+16];
714   long result=1;
715   int error= 0;
716   DBUG_ENTER("mysql_alter_db");
717 
718   if (lock_schema_name(thd, db->str))
719     DBUG_RETURN(TRUE);
720 
721   /*
722      Recreate db options file: /dbpath/.db.opt
723      We pass MY_DB_OPT_FILE as "extension" to avoid
724      "table name to file name" encoding.
725   */
726   build_table_filename(path, sizeof(path) - 1, db->str, "", MY_DB_OPT_FILE, 0);
727   if (unlikely((error=write_db_opt(thd, path, create_info))))
728     goto exit;
729 
730   /* Change options if current database is being altered. */
731 
732   if (thd->db.str && !cmp(&thd->db, db))
733   {
734     thd->db_charset= create_info->default_table_charset ?
735 		     create_info->default_table_charset :
736 		     thd->variables.collation_server;
737     thd->variables.collation_database= thd->db_charset;
738   }
739 
740   if (mysql_bin_log.is_open())
741   {
742     int errcode= query_error_code(thd, TRUE);
743     Query_log_event qinfo(thd, thd->query(), thd->query_length(), FALSE, TRUE,
744 			  /* suppress_use */ TRUE, errcode);
745     /*
746       Write should use the database being created as the "current
747       database" and not the threads current database, which is the
748       default.
749     */
750     qinfo.db=     db->str;
751     qinfo.db_len= (uint)db->length;
752 
753     /*
754       These DDL methods and logging are protected with the exclusive
755       metadata lock on the schema.
756     */
757     if (unlikely((error= mysql_bin_log.write(&qinfo))))
758       goto exit;
759   }
760   my_ok(thd, result);
761 
762 exit:
763   DBUG_RETURN(error);
764 }
765 
766 
767 int mysql_create_db(THD *thd, const LEX_CSTRING *db, DDL_options_st options,
768                     const Schema_specification_st *create_info)
769 {
770   /*
771     As mysql_create_db_internal() may modify Db_create_info structure passed
772     to it, we need to use a copy to make execution prepared statement- safe.
773   */
774   Schema_specification_st tmp(*create_info);
775   if (thd->slave_thread &&
776       slave_ddl_exec_mode_options == SLAVE_EXEC_MODE_IDEMPOTENT)
777     options.add(DDL_options::OPT_IF_NOT_EXISTS);
778   return mysql_create_db_internal(thd, db, options, &tmp, false);
779 }
780 
781 
782 bool mysql_alter_db(THD *thd, const LEX_CSTRING *db,
783                     const Schema_specification_st *create_info)
784 {
785   /*
786     As mysql_alter_db_internal() may modify Db_create_info structure passed
787     to it, we need to use a copy to make execution prepared statement- safe.
788   */
789   Schema_specification_st tmp(*create_info);
790   return mysql_alter_db_internal(thd, db, &tmp);
791 }
792 
793 
794 /**
795   Drop all tables, routines and events in a database and the database itself.
796 
797   @param  thd        Thread handle
798   @param  db         Database name in the case given by user
799                      It's already validated and set to lower case
800                      (if needed) when we come here
801   @param  if_exists  Don't give error if database doesn't exists
802   @param  silent     Don't write the statement to the binary log and don't
803                      send ok packet to the client
804 
805   @retval  false  OK (Database dropped)
806   @retval  true   Error
807 */
808 
809 static bool
810 mysql_rm_db_internal(THD *thd, const LEX_CSTRING *db, bool if_exists, bool silent)
811 {
812   ulong deleted_tables= 0;
813   bool error= true, rm_mysql_schema;
814   char	path[FN_REFLEN + 16];
815   MY_DIR *dirp;
816   uint length;
817   TABLE_LIST *tables= NULL;
818   TABLE_LIST *table;
819   Drop_table_error_handler err_handler;
820   DBUG_ENTER("mysql_rm_db");
821 
822   char db_tmp[SAFE_NAME_LEN+1];
823   const char *dbnorm= normalize_db_name(db->str, db_tmp, sizeof(db_tmp));
824 
825   if (lock_schema_name(thd, dbnorm))
826     DBUG_RETURN(true);
827 
828   length= build_table_filename(path, sizeof(path) - 1, db->str, "", "", 0);
829   strmov(path+length, MY_DB_OPT_FILE);		// Append db option file name
830   del_dbopt(path);				// Remove dboption hash entry
831   /*
832      Now remove the db.opt file.
833      The 'find_db_tables_and_rm_known_files' doesn't remove this file
834      if there exists a table with the name 'db', so let's just do it
835      separately. We know this file exists and needs to be deleted anyway.
836   */
837   if (mysql_file_delete_with_symlink(key_file_misc, path, "", MYF(0)) &&
838       my_errno != ENOENT)
839   {
840     my_error(EE_DELETE, MYF(0), path, my_errno);
841     DBUG_RETURN(true);
842   }
843 
844   path[length]= '\0';				// Remove file name
845 
846   /* See if the directory exists */
847   if (!(dirp= my_dir(path,MYF(MY_DONT_SORT))))
848   {
849     if (!if_exists)
850     {
851       my_error(ER_DB_DROP_EXISTS, MYF(0), db->str);
852       DBUG_RETURN(true);
853     }
854     else
855     {
856       push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
857 			  ER_DB_DROP_EXISTS, ER_THD(thd, ER_DB_DROP_EXISTS),
858                           db->str);
859       error= false;
860       goto update_binlog;
861     }
862   }
863 
864   if (find_db_tables_and_rm_known_files(thd, dirp, dbnorm, path, &tables))
865     goto exit;
866 
867   /*
868     Disable drop of enabled log tables, must be done before name locking.
869     This check is only needed if we are dropping the "mysql" database.
870   */
871   if ((rm_mysql_schema=
872         (my_strcasecmp(system_charset_info, MYSQL_SCHEMA_NAME.str, db->str) == 0)))
873   {
874     for (table= tables; table; table= table->next_local)
875       if (check_if_log_table(table, TRUE, "DROP"))
876         goto exit;
877   }
878 
879   /* Lock all tables and stored routines about to be dropped. */
880   if (lock_table_names(thd, tables, NULL, thd->variables.lock_wait_timeout,
881                        0) ||
882       lock_db_routines(thd, dbnorm))
883     goto exit;
884 
885   if (!in_bootstrap && !rm_mysql_schema)
886   {
887     for (table= tables; table; table= table->next_local)
888     {
889       if (table->open_type == OT_BASE_ONLY ||
890           !thd->find_temporary_table(table))
891         (void) delete_statistics_for_table(thd, &table->db, &table->table_name);
892     }
893   }
894 
895   /* mysql_ha_rm_tables() requires a non-null TABLE_LIST. */
896   if (tables)
897     mysql_ha_rm_tables(thd, tables);
898 
899   for (table= tables; table; table= table->next_local)
900     deleted_tables++;
901 
902   thd->push_internal_handler(&err_handler);
903   if (!thd->killed &&
904       !(tables &&
905         mysql_rm_table_no_locks(thd, tables, true, false, true, false, true,
906                                 false)))
907   {
908     /*
909       We temporarily disable the binary log while dropping the objects
910       in the database. Since the DROP DATABASE statement is always
911       replicated as a statement, execution of it will drop all objects
912       in the database on the slave as well, so there is no need to
913       replicate the removal of the individual objects in the database
914       as well.
915 
916       This is more of a safety precaution, since normally no objects
917       should be dropped while the database is being cleaned, but in
918       the event that a change in the code to remove other objects is
919       made, these drops should still not be logged.
920     */
921 
922     ha_drop_database(path);
923     tmp_disable_binlog(thd);
924     query_cache_invalidate1(thd, dbnorm);
925     if (!rm_mysql_schema)
926     {
927       (void) sp_drop_db_routines(thd, dbnorm); /* @todo Do not ignore errors */
928 #ifdef HAVE_EVENT_SCHEDULER
929       Events::drop_schema_events(thd, dbnorm);
930 #endif
931     }
932     reenable_binlog(thd);
933 
934     /*
935       If the directory is a symbolic link, remove the link first, then
936       remove the directory the symbolic link pointed at
937     */
938     error= rm_dir_w_symlink(path, true);
939   }
940   thd->pop_internal_handler();
941 
942 update_binlog:
943   if (!silent && likely(!error))
944   {
945     const char *query;
946     ulong query_length;
947 
948     query= thd->query();
949     query_length= thd->query_length();
950     DBUG_ASSERT(query);
951 
952     if (mysql_bin_log.is_open())
953     {
954       int errcode= query_error_code(thd, TRUE);
955       Query_log_event qinfo(thd, query, query_length, FALSE, TRUE,
956 			    /* suppress_use */ TRUE, errcode);
957       /*
958         Write should use the database being created as the "current
959         database" and not the threads current database, which is the
960         default.
961       */
962       qinfo.db     = db->str;
963       qinfo.db_len = (uint32)db->length;
964 
965       /*
966         These DDL methods and logging are protected with the exclusive
967         metadata lock on the schema.
968       */
969       if (mysql_bin_log.write(&qinfo))
970       {
971         error= true;
972         goto exit;
973       }
974     }
975     thd->clear_error();
976     thd->server_status|= SERVER_STATUS_DB_DROPPED;
977     my_ok(thd, deleted_tables);
978   }
979   else if (mysql_bin_log.is_open() && !silent)
980   {
981     char *query, *query_pos, *query_end, *query_data_start;
982     TABLE_LIST *tbl;
983 
984     if (!(query= (char*) thd->alloc(MAX_DROP_TABLE_Q_LEN)))
985       goto exit; /* not much else we can do */
986     query_pos= query_data_start= strmov(query,"DROP TABLE IF EXISTS ");
987     query_end= query + MAX_DROP_TABLE_Q_LEN;
988 
989     for (tbl= tables; tbl; tbl= tbl->next_local)
990     {
991       size_t tbl_name_len;
992       char quoted_name[FN_REFLEN+3];
993 
994       // Only write drop table to the binlog for tables that no longer exist.
995       if (ha_table_exists(thd, &tbl->db, &tbl->table_name))
996         continue;
997 
998       tbl_name_len= my_snprintf(quoted_name, sizeof(quoted_name), "%`s",
999                                 tbl->table_name.str);
1000       tbl_name_len++;                           /* +1 for the comma */
1001       if (query_pos + tbl_name_len + 1 >= query_end)
1002       {
1003         /*
1004           These DDL methods and logging are protected with the exclusive
1005           metadata lock on the schema.
1006         */
1007         if (write_to_binlog(thd, query, (uint)(query_pos -1 - query), db->str, db->length))
1008         {
1009           error= true;
1010           goto exit;
1011         }
1012         query_pos= query_data_start;
1013       }
1014 
1015       query_pos= strmov(query_pos, quoted_name);
1016       *query_pos++ = ',';
1017     }
1018 
1019     if (query_pos != query_data_start)
1020     {
1021       /*
1022         These DDL methods and logging are protected with the exclusive
1023         metadata lock on the schema.
1024       */
1025       if (write_to_binlog(thd, query, (uint)(query_pos -1 - query), db->str, db->length))
1026       {
1027         error= true;
1028         goto exit;
1029       }
1030     }
1031   }
1032 
1033 exit:
1034   /*
1035     If this database was the client's selected database, we silently
1036     change the client's selected database to nothing (to have an empty
1037     SELECT DATABASE() in the future). For this we free() thd->db and set
1038     it to 0.
1039   */
1040   if (unlikely(thd->db.str && cmp_db_names(&thd->db, db) && !error))
1041   {
1042     mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server);
1043     SESSION_TRACKER_CHANGED(thd, CURRENT_SCHEMA_TRACKER, NULL);
1044   }
1045   my_dirend(dirp);
1046   DBUG_RETURN(error);
1047 }
1048 
1049 
1050 bool mysql_rm_db(THD *thd, const LEX_CSTRING *db, bool if_exists)
1051 {
1052   if (thd->slave_thread &&
1053       slave_ddl_exec_mode_options == SLAVE_EXEC_MODE_IDEMPOTENT)
1054     if_exists= true;
1055   return mysql_rm_db_internal(thd, db, if_exists, false);
1056 }
1057 
1058 
1059 static bool find_db_tables_and_rm_known_files(THD *thd, MY_DIR *dirp,
1060                                               const char *dbname,
1061                                               const char *path,
1062                                               TABLE_LIST **tables)
1063 {
1064   char filePath[FN_REFLEN];
1065   LEX_CSTRING db= { dbname, strlen(dbname) };
1066   TABLE_LIST *tot_list=0, **tot_list_next_local, **tot_list_next_global;
1067   DBUG_ENTER("find_db_tables_and_rm_known_files");
1068   DBUG_PRINT("enter",("path: %s", path));
1069 
1070   /* first, get the list of tables */
1071   Dynamic_array<LEX_CSTRING*> files(dirp->number_of_files);
1072   Discovered_table_list tl(thd, &files);
1073   if (ha_discover_table_names(thd, &db, dirp, &tl, true))
1074     DBUG_RETURN(1);
1075 
1076   /* Now put the tables in the list */
1077   tot_list_next_local= tot_list_next_global= &tot_list;
1078 
1079   for (size_t idx=0; idx < files.elements(); idx++)
1080   {
1081     LEX_CSTRING *table= files.at(idx);
1082 
1083     /* Drop the table nicely */
1084     TABLE_LIST *table_list=(TABLE_LIST*)thd->calloc(sizeof(*table_list));
1085 
1086     if (!table_list)
1087       DBUG_RETURN(true);
1088     table_list->db= db;
1089     table_list->table_name= *table;
1090     table_list->open_type= OT_BASE_ONLY;
1091 
1092     /*
1093       On the case-insensitive file systems table is opened
1094       with the lowercased file name. So we should lowercase
1095       as well to look up the cache properly.
1096     */
1097     if (lower_case_file_system)
1098       table_list->table_name.length= my_casedn_str(files_charset_info,
1099                                                    (char*) table_list->table_name.str);
1100 
1101     table_list->alias= table_list->table_name;	// If lower_case_table_names=2
1102     table_list->mdl_request.init(MDL_key::TABLE, table_list->db.str,
1103                                  table_list->table_name.str, MDL_EXCLUSIVE,
1104                                  MDL_TRANSACTION);
1105     /* Link into list */
1106     (*tot_list_next_local)= table_list;
1107     (*tot_list_next_global)= table_list;
1108     tot_list_next_local= &table_list->next_local;
1109     tot_list_next_global= &table_list->next_global;
1110   }
1111   *tables= tot_list;
1112 
1113   /* and at last delete all non-table files */
1114   for (uint idx=0 ;
1115        idx < (uint) dirp->number_of_files && !thd->killed ;
1116        idx++)
1117   {
1118     FILEINFO *file=dirp->dir_entry+idx;
1119     char *extension;
1120     DBUG_PRINT("info",("Examining: %s", file->name));
1121 
1122     if (file->name[0] == 'a' && file->name[1] == 'r' &&
1123              file->name[2] == 'c' && file->name[3] == '\0')
1124     {
1125       /* .frm archive:
1126         Those archives are obsolete, but following code should
1127         exist to remove existent "arc" directories.
1128       */
1129       char newpath[FN_REFLEN];
1130       MY_DIR *new_dirp;
1131       strxmov(newpath, path, "/", "arc", NullS);
1132       (void) unpack_filename(newpath, newpath);
1133       if ((new_dirp = my_dir(newpath, MYF(MY_DONT_SORT))))
1134       {
1135 	DBUG_PRINT("my",("Archive subdir found: %s", newpath));
1136 	if ((mysql_rm_arc_files(thd, new_dirp, newpath)) < 0)
1137 	  DBUG_RETURN(true);
1138       }
1139       continue;
1140     }
1141     if (!(extension= strrchr(file->name, '.')))
1142       extension= strend(file->name);
1143     if (find_type(extension, &deletable_extensions, FIND_TYPE_NO_PREFIX) > 0)
1144     {
1145       strxmov(filePath, path, "/", file->name, NullS);
1146       /*
1147         We ignore ENOENT error in order to skip files that was deleted
1148         by concurrently running statement like REPAIR TABLE ...
1149       */
1150       if (mysql_file_delete_with_symlink(key_file_misc, filePath, "", MYF(0)) &&
1151           my_errno != ENOENT)
1152       {
1153         my_error(EE_DELETE, MYF(0), filePath, my_errno);
1154         DBUG_RETURN(true);
1155       }
1156     }
1157   }
1158 
1159   DBUG_RETURN(false);
1160 }
1161 
1162 
1163 /*
1164   Remove directory with symlink
1165 
1166   SYNOPSIS
1167     rm_dir_w_symlink()
1168     org_path    path of derictory
1169     send_error  send errors
1170   RETURN
1171     0 OK
1172     1 ERROR
1173 */
1174 
1175 static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error)
1176 {
1177   char tmp_path[FN_REFLEN], *pos;
1178   char *path= tmp_path;
1179   DBUG_ENTER("rm_dir_w_symlink");
1180   unpack_filename(tmp_path, org_path);
1181 #ifdef HAVE_READLINK
1182   int error;
1183   char tmp2_path[FN_REFLEN];
1184 
1185   /* Remove end FN_LIBCHAR as this causes problem on Linux in readlink */
1186   pos= strend(path);
1187   if (pos > path && pos[-1] == FN_LIBCHAR)
1188     *--pos=0;
1189 
1190   if (unlikely((error= my_readlink(tmp2_path, path, MYF(MY_WME))) < 0))
1191     DBUG_RETURN(1);
1192   if (likely(!error))
1193   {
1194     if (mysql_file_delete(key_file_misc, path, MYF(send_error ? MY_WME : 0)))
1195     {
1196       DBUG_RETURN(send_error);
1197     }
1198     /* Delete directory symbolic link pointed at */
1199     path= tmp2_path;
1200   }
1201 #endif
1202   /* Remove last FN_LIBCHAR to not cause a problem on OS/2 */
1203   pos= strend(path);
1204 
1205   if (pos > path && pos[-1] == FN_LIBCHAR)
1206     *--pos=0;
1207   if (unlikely(rmdir(path) < 0 && send_error))
1208   {
1209     my_error(ER_DB_DROP_RMDIR, MYF(0), path, errno);
1210     DBUG_RETURN(1);
1211   }
1212   DBUG_RETURN(0);
1213 }
1214 
1215 
1216 /*
1217   Remove .frm archives from directory
1218 
1219   SYNOPSIS
1220     thd       thread handler
1221     dirp      list of files in archive directory
1222     db        data base name
1223     org_path  path of archive directory
1224 
1225   RETURN
1226     > 0 number of removed files
1227     -1  error
1228 
1229   NOTE
1230     A support of "arc" directories is obsolete, however this
1231     function should exist to remove existent "arc" directories.
1232 */
1233 long mysql_rm_arc_files(THD *thd, MY_DIR *dirp, const char *org_path)
1234 {
1235   long deleted= 0;
1236   ulong found_other_files= 0;
1237   char filePath[FN_REFLEN];
1238   DBUG_ENTER("mysql_rm_arc_files");
1239   DBUG_PRINT("enter", ("path: %s", org_path));
1240 
1241   for (uint idx=0 ;
1242        idx < (uint) dirp->number_of_files && !thd->killed ;
1243        idx++)
1244   {
1245     FILEINFO *file=dirp->dir_entry+idx;
1246     char *extension, *revision;
1247     DBUG_PRINT("info",("Examining: %s", file->name));
1248 
1249     extension= fn_ext(file->name);
1250     if (extension[0] != '.' ||
1251         extension[1] != 'f' || extension[2] != 'r' ||
1252         extension[3] != 'm' || extension[4] != '-')
1253     {
1254       found_other_files++;
1255       continue;
1256     }
1257     revision= extension+5;
1258     while (*revision && my_isdigit(system_charset_info, *revision))
1259       revision++;
1260     if (*revision)
1261     {
1262       found_other_files++;
1263       continue;
1264     }
1265     strxmov(filePath, org_path, "/", file->name, NullS);
1266     if (mysql_file_delete_with_symlink(key_file_misc, filePath, "", MYF(MY_WME)))
1267     {
1268       goto err;
1269     }
1270     deleted++;
1271   }
1272   if (thd->killed)
1273     goto err;
1274 
1275   my_dirend(dirp);
1276 
1277   /*
1278     If the directory is a symbolic link, remove the link first, then
1279     remove the directory the symbolic link pointed at
1280   */
1281   if (!found_other_files &&
1282       rm_dir_w_symlink(org_path, 0))
1283     DBUG_RETURN(-1);
1284   DBUG_RETURN(deleted);
1285 
1286 err:
1287   my_dirend(dirp);
1288   DBUG_RETURN(-1);
1289 }
1290 
1291 
1292 /**
1293   @brief Internal implementation: switch current database to a valid one.
1294 
1295   @param thd            Thread context.
1296   @param new_db_name    Name of the database to switch to. The function will
1297                         take ownership of the name (the caller must not free
1298                         the allocated memory). If the name is NULL, we're
1299                         going to switch to NULL db.
1300   @param new_db_access  Privileges of the new database.
1301   @param new_db_charset Character set of the new database.
1302 */
1303 
1304 static void mysql_change_db_impl(THD *thd,
1305                                  LEX_CSTRING *new_db_name,
1306                                  ulong new_db_access,
1307                                  CHARSET_INFO *new_db_charset)
1308 {
1309   /* 1. Change current database in THD. */
1310 
1311   if (new_db_name == NULL)
1312   {
1313     /*
1314       THD::set_db() does all the job -- it frees previous database name and
1315       sets the new one.
1316     */
1317 
1318     thd->set_db(&null_clex_str);
1319   }
1320   else if (new_db_name->str == INFORMATION_SCHEMA_NAME.str)
1321   {
1322     /*
1323       Here we must use THD::set_db(), because we want to copy
1324       INFORMATION_SCHEMA_NAME constant.
1325     */
1326 
1327     thd->set_db(&INFORMATION_SCHEMA_NAME);
1328   }
1329   else
1330   {
1331     /*
1332       Here we already have a copy of database name to be used in THD. So,
1333       we just call THD::reset_db(). Since THD::reset_db() does not releases
1334       the previous database name, we should do it explicitly.
1335     */
1336     thd->set_db(&null_clex_str);
1337     thd->reset_db(new_db_name);
1338   }
1339 
1340   /* 2. Update security context. */
1341 
1342 #ifndef NO_EMBEDDED_ACCESS_CHECKS
1343   thd->security_ctx->db_access= new_db_access;
1344 #endif
1345 
1346   /* 3. Update db-charset environment variables. */
1347 
1348   thd->db_charset= new_db_charset;
1349   thd->variables.collation_database= new_db_charset;
1350 }
1351 
1352 
1353 
1354 /**
1355   Backup the current database name before switch.
1356 
1357   @param[in]      thd             thread handle
1358   @param[in, out] saved_db_name   IN: "str" points to a buffer where to store
1359                                   the old database name, "length" contains the
1360                                   buffer size
1361                                   OUT: if the current (default) database is
1362                                   not NULL, its name is copied to the
1363                                   buffer pointed at by "str"
1364                                   and "length" is updated accordingly.
1365                                   Otherwise "str" is set to NULL and
1366                                   "length" is set to 0.
1367 */
1368 
1369 static void backup_current_db_name(THD *thd,
1370                                    LEX_STRING *saved_db_name)
1371 {
1372   DBUG_ASSERT(saved_db_name->length >= SAFE_NAME_LEN +1);
1373   if (!thd->db.str)
1374   {
1375     /* No current (default) database selected. */
1376     saved_db_name->str= 0;
1377     saved_db_name->length= 0;
1378   }
1379   else
1380   {
1381     memcpy(saved_db_name->str, thd->db.str, thd->db.length + 1);
1382     saved_db_name->length= thd->db.length;
1383   }
1384 }
1385 
1386 
1387 /**
1388   @brief Change the current database and its attributes unconditionally.
1389 
1390   @param thd          thread handle
1391   @param new_db_name  database name
1392   @param force_switch if force_switch is FALSE, then the operation will fail if
1393 
1394                         - new_db_name is NULL or empty;
1395 
1396                         - OR new database name is invalid
1397                           (check_db_name() failed);
1398 
1399                         - OR user has no privilege on the new database;
1400 
1401                         - OR new database does not exist;
1402 
1403                       if force_switch is TRUE, then
1404 
1405                         - if new_db_name is NULL or empty, the current
1406                           database will be NULL, @@collation_database will
1407                           be set to @@collation_server, the operation will
1408                           succeed.
1409 
1410                         - if new database name is invalid
1411                           (check_db_name() failed), the current database
1412                           will be NULL, @@collation_database will be set to
1413                           @@collation_server, but the operation will fail;
1414 
1415                         - user privileges will not be checked
1416                           (THD::db_access however is updated);
1417 
1418                           TODO: is this really the intention?
1419                                 (see sp-security.test).
1420 
1421                         - if new database does not exist,the current database
1422                           will be NULL, @@collation_database will be set to
1423                           @@collation_server, a warning will be thrown, the
1424                           operation will succeed.
1425 
1426   @details The function checks that the database name corresponds to a
1427   valid and existent database, checks access rights and changes the current
1428   database with database attributes (@@collation_database session variable,
1429   THD::db_access).
1430 
1431   This function is not the only way to switch the database that is
1432   currently employed. When the replication slave thread switches the
1433   database before executing a query, it calls thd->set_db directly.
1434   However, if the query, in turn, uses a stored routine, the stored routine
1435   will use this function, even if it's run on the slave.
1436 
1437   This function allocates the name of the database on the system heap: this
1438   is necessary to be able to uniformly change the database from any module
1439   of the server. Up to 5.0 different modules were using different memory to
1440   store the name of the database, and this led to memory corruption:
1441   a stack pointer set by Stored Procedures was used by replication after
1442   the stack address was long gone.
1443 
1444   @return error code (ER_XXX)
1445     @retval 0 Success
1446     @retval >0  Error
1447 */
1448 
1449 uint mysql_change_db(THD *thd, const LEX_CSTRING *new_db_name,
1450                      bool force_switch)
1451 {
1452   LEX_CSTRING new_db_file_name;
1453 
1454   Security_context *sctx= thd->security_ctx;
1455   ulong db_access= sctx->db_access;
1456   CHARSET_INFO *db_default_cl;
1457   DBUG_ENTER("mysql_change_db");
1458 
1459   if (new_db_name->length == 0)
1460   {
1461     if (force_switch)
1462     {
1463       /*
1464         This can happen only if we're switching the current database back
1465         after loading stored program. The thing is that loading of stored
1466         program can happen when there is no current database.
1467 
1468         In case of stored program, new_db_name->str == "" and
1469         new_db_name->length == 0.
1470       */
1471 
1472       mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server);
1473 
1474       goto done;
1475     }
1476     else
1477     {
1478       my_message(ER_NO_DB_ERROR, ER_THD(thd, ER_NO_DB_ERROR), MYF(0));
1479 
1480       DBUG_RETURN(ER_NO_DB_ERROR);
1481     }
1482   }
1483   DBUG_PRINT("enter",("name: '%s'", new_db_name->str));
1484 
1485   if (is_infoschema_db(new_db_name))
1486   {
1487     /* Switch the current database to INFORMATION_SCHEMA. */
1488 
1489     mysql_change_db_impl(thd, &INFORMATION_SCHEMA_NAME, SELECT_ACL,
1490                          system_charset_info);
1491     goto done;
1492   }
1493 
1494   /*
1495     Now we need to make a copy because check_db_name requires a
1496     non-constant argument. Actually, it takes database file name.
1497 
1498     TODO: fix check_db_name().
1499   */
1500 
1501   new_db_file_name.str= my_strndup(new_db_name->str, new_db_name->length,
1502                                    MYF(MY_WME));
1503   new_db_file_name.length= new_db_name->length;
1504 
1505   if (new_db_file_name.str == NULL)
1506     DBUG_RETURN(ER_OUT_OF_RESOURCES);                             /* the error is set */
1507 
1508   /*
1509     NOTE: if check_db_name() fails, we should throw an error in any case,
1510     even if we are called from sp_head::execute().
1511 
1512     It's next to impossible however to get this error when we are called
1513     from sp_head::execute(). But let's switch the current database to NULL
1514     in this case to be sure.
1515     The cast below ok here as new_db_file_name was just allocated
1516   */
1517 
1518   if (check_db_name((LEX_STRING*) &new_db_file_name))
1519   {
1520     my_error(ER_WRONG_DB_NAME, MYF(0), new_db_file_name.str);
1521     my_free(const_cast<char*>(new_db_file_name.str));
1522 
1523     if (force_switch)
1524       mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server);
1525 
1526     DBUG_RETURN(ER_WRONG_DB_NAME);
1527   }
1528 
1529   DBUG_PRINT("info",("Use database: %s", new_db_file_name.str));
1530 
1531 #ifndef NO_EMBEDDED_ACCESS_CHECKS
1532   if (test_all_bits(sctx->master_access, DB_ACLS))
1533     db_access= DB_ACLS;
1534   else
1535   {
1536     db_access= acl_get(sctx->host, sctx->ip, sctx->priv_user,
1537                         new_db_file_name.str, FALSE) | sctx->master_access;
1538     if (sctx->priv_role[0])
1539     {
1540       /* include a possible currently set role for access */
1541       db_access|= acl_get("", "", sctx->priv_role, new_db_file_name.str, FALSE);
1542     }
1543   }
1544 
1545   if (!force_switch &&
1546       !(db_access & DB_ACLS) &&
1547       check_grant_db(thd, new_db_file_name.str))
1548   {
1549     my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
1550              sctx->priv_user,
1551              sctx->priv_host,
1552              new_db_file_name.str);
1553     general_log_print(thd, COM_INIT_DB, ER_THD(thd, ER_DBACCESS_DENIED_ERROR),
1554                       sctx->priv_user, sctx->priv_host, new_db_file_name.str);
1555     my_free(const_cast<char*>(new_db_file_name.str));
1556     DBUG_RETURN(ER_DBACCESS_DENIED_ERROR);
1557   }
1558 #endif
1559 
1560   DEBUG_SYNC(thd, "before_db_dir_check");
1561 
1562   if (check_db_dir_existence(new_db_file_name.str))
1563   {
1564     if (force_switch)
1565     {
1566       /* Throw a warning and free new_db_file_name. */
1567 
1568       push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
1569                           ER_BAD_DB_ERROR, ER_THD(thd, ER_BAD_DB_ERROR),
1570                           new_db_file_name.str);
1571 
1572       my_free(const_cast<char*>(new_db_file_name.str));
1573 
1574       /* Change db to NULL. */
1575 
1576       mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server);
1577 
1578       /* The operation succeed. */
1579       goto done;
1580     }
1581     else
1582     {
1583       /* Report an error and free new_db_file_name. */
1584 
1585       my_error(ER_BAD_DB_ERROR, MYF(0), new_db_file_name.str);
1586       my_free(const_cast<char*>(new_db_file_name.str));
1587 
1588       /* The operation failed. */
1589 
1590       DBUG_RETURN(ER_BAD_DB_ERROR);
1591     }
1592   }
1593 
1594   /*
1595     NOTE: in mysql_change_db_impl() new_db_file_name is assigned to THD
1596     attributes and will be freed in THD::~THD().
1597   */
1598 
1599   db_default_cl= get_default_db_collation(thd, new_db_file_name.str);
1600 
1601   mysql_change_db_impl(thd, &new_db_file_name, db_access, db_default_cl);
1602 
1603 done:
1604   SESSION_TRACKER_CHANGED(thd, CURRENT_SCHEMA_TRACKER, NULL);
1605   SESSION_TRACKER_CHANGED(thd, SESSION_STATE_CHANGE_TRACKER, NULL);
1606   DBUG_RETURN(0);
1607 }
1608 
1609 
1610 /**
1611   Change the current database and its attributes if needed.
1612 
1613   @param          thd             thread handle
1614   @param          new_db_name     database name
1615   @param[in, out] saved_db_name   IN: "str" points to a buffer where to store
1616                                   the old database name, "length" contains the
1617                                   buffer size
1618                                   OUT: if the current (default) database is
1619                                   not NULL, its name is copied to the
1620                                   buffer pointed at by "str"
1621                                   and "length" is updated accordingly.
1622                                   Otherwise "str" is set to NULL and
1623                                   "length" is set to 0.
1624   @param          force_switch    @see mysql_change_db()
1625   @param[out]     cur_db_changed  out-flag to indicate whether the current
1626                                   database has been changed (valid only if
1627                                   the function suceeded)
1628 */
1629 
1630 bool mysql_opt_change_db(THD *thd,
1631                          const LEX_CSTRING *new_db_name,
1632                          LEX_STRING *saved_db_name,
1633                          bool force_switch,
1634                          bool *cur_db_changed)
1635 {
1636   *cur_db_changed= !cmp_db_names(&thd->db, new_db_name);
1637 
1638   if (!*cur_db_changed)
1639     return FALSE;
1640 
1641   backup_current_db_name(thd, saved_db_name);
1642 
1643   return mysql_change_db(thd, new_db_name, force_switch);
1644 }
1645 
1646 
1647 /**
1648   Upgrade a 5.0 database.
1649   This function is invoked whenever an ALTER DATABASE UPGRADE query is executed:
1650     ALTER DATABASE 'olddb' UPGRADE DATA DIRECTORY NAME.
1651 
1652   If we have managed to rename (move) tables to the new database
1653   but something failed on a later step, then we store the
1654   RENAME DATABASE event in the log. mysql_rename_db() is atomic in
1655   the sense that it will rename all or none of the tables.
1656 
1657   @param thd Current thread
1658   @param old_db 5.0 database name, in #mysql50#name format
1659   @return 0 on success, 1 on error
1660 */
1661 
1662 bool mysql_upgrade_db(THD *thd, const LEX_CSTRING *old_db)
1663 {
1664   bool error= 0, change_to_newdb= 0;
1665   char path[FN_REFLEN+16];
1666   uint length;
1667   Schema_specification_st create_info;
1668   MY_DIR *dirp;
1669   TABLE_LIST *table_list;
1670   SELECT_LEX *sl= thd->lex->current_select;
1671   LEX_CSTRING new_db;
1672   DBUG_ENTER("mysql_upgrade_db");
1673 
1674   if ((old_db->length <= MYSQL50_TABLE_NAME_PREFIX_LENGTH) ||
1675       (strncmp(old_db->str,
1676               MYSQL50_TABLE_NAME_PREFIX,
1677               MYSQL50_TABLE_NAME_PREFIX_LENGTH) != 0))
1678   {
1679     my_error(ER_WRONG_USAGE, MYF(0),
1680              "ALTER DATABASE UPGRADE DATA DIRECTORY NAME",
1681              "name");
1682     DBUG_RETURN(1);
1683   }
1684 
1685   /* `#mysql50#<name>` converted to encoded `<name>` */
1686   new_db.str= old_db->str + MYSQL50_TABLE_NAME_PREFIX_LENGTH;
1687   new_db.length= old_db->length - MYSQL50_TABLE_NAME_PREFIX_LENGTH;
1688 
1689   /* Lock the old name, the new name will be locked by mysql_create_db().*/
1690   if (lock_schema_name(thd, old_db->str))
1691     DBUG_RETURN(1);
1692 
1693   /*
1694     Let's remember if we should do "USE newdb" afterwards.
1695     thd->db will be cleared in mysql_rename_db()
1696   */
1697   if (thd->db.str && !cmp(&thd->db, old_db))
1698     change_to_newdb= 1;
1699 
1700   build_table_filename(path, sizeof(path)-1,
1701                        old_db->str, "", MY_DB_OPT_FILE, 0);
1702   if ((load_db_opt(thd, path, &create_info)))
1703     create_info.default_table_charset= thd->variables.collation_server;
1704 
1705   length= build_table_filename(path, sizeof(path)-1, old_db->str, "", "", 0);
1706   if (length && path[length-1] == FN_LIBCHAR)
1707     path[length-1]=0;                            // remove ending '\'
1708   if (unlikely((error= my_access(path,F_OK))))
1709   {
1710     my_error(ER_BAD_DB_ERROR, MYF(0), old_db->str);
1711     goto exit;
1712   }
1713 
1714   /* Step1: Create the new database */
1715   if (unlikely((error= mysql_create_db_internal(thd, &new_db,
1716                                                 DDL_options(), &create_info,
1717                                                 1))))
1718     goto exit;
1719 
1720   /* Step2: Move tables to the new database */
1721   if ((dirp = my_dir(path,MYF(MY_DONT_SORT))))
1722   {
1723     uint nfiles= (uint) dirp->number_of_files;
1724     for (uint idx=0 ; idx < nfiles && !thd->killed ; idx++)
1725     {
1726       FILEINFO *file= dirp->dir_entry + idx;
1727       char *extension, tname[FN_REFLEN + 1];
1728       LEX_CSTRING table_str;
1729       DBUG_PRINT("info",("Examining: %s", file->name));
1730 
1731       /* skiping non-FRM files */
1732       if (!(extension= (char*) fn_frm_ext(file->name)))
1733         continue;
1734 
1735       /* A frm file found, add the table info rename list */
1736       *extension= '\0';
1737 
1738       table_str.length= filename_to_tablename(file->name,
1739                                               tname, sizeof(tname)-1);
1740       table_str.str= (char*) thd->memdup(tname, table_str.length + 1);
1741       Table_ident *old_ident= new Table_ident(thd, old_db, &table_str, 0);
1742       Table_ident *new_ident= new Table_ident(thd, &new_db, &table_str, 0);
1743       if (!old_ident || !new_ident ||
1744           !sl->add_table_to_list(thd, old_ident, NULL,
1745                                  TL_OPTION_UPDATING, TL_IGNORE,
1746                                  MDL_EXCLUSIVE) ||
1747           !sl->add_table_to_list(thd, new_ident, NULL,
1748                                  TL_OPTION_UPDATING, TL_IGNORE,
1749                                  MDL_EXCLUSIVE))
1750       {
1751         error= 1;
1752         my_dirend(dirp);
1753         goto exit;
1754       }
1755     }
1756     my_dirend(dirp);
1757   }
1758 
1759   if ((table_list= thd->lex->query_tables) &&
1760       (error= mysql_rename_tables(thd, table_list, 1)))
1761   {
1762     /*
1763       Failed to move all tables from the old database to the new one.
1764       In the best case mysql_rename_tables() moved all tables back to the old
1765       database. In the worst case mysql_rename_tables() moved some tables
1766       to the new database, then failed, then started to move the tables back,
1767       and then failed again. In this situation we have some tables in the
1768       old database and some tables in the new database.
1769       Let's delete the option file, and then the new database directory.
1770       If some tables were left in the new directory, rmdir() will fail.
1771       It garantees we never loose any tables.
1772     */
1773     build_table_filename(path, sizeof(path)-1,
1774                          new_db.str,"",MY_DB_OPT_FILE, 0);
1775     mysql_file_delete(key_file_dbopt, path, MYF(MY_WME));
1776     length= build_table_filename(path, sizeof(path)-1, new_db.str, "", "", 0);
1777     if (length && path[length-1] == FN_LIBCHAR)
1778       path[length-1]=0;                            // remove ending '\'
1779     rmdir(path);
1780     goto exit;
1781   }
1782 
1783 
1784   /*
1785     Step3: move all remaining files to the new db's directory.
1786     Skip db opt file: it's been created by mysql_create_db() in
1787     the new directory, and will be dropped by mysql_rm_db() in the old one.
1788     Trigger TRN and TRG files are be moved as regular files at the moment,
1789     without any special treatment.
1790 
1791     Triggers without explicit database qualifiers in table names work fine:
1792       use d1;
1793       create trigger trg1 before insert on t2 for each row set @a:=1
1794       rename database d1 to d2;
1795 
1796     TODO: Triggers, having the renamed database explicitly written
1797     in the table qualifiers.
1798     1. when the same database is renamed:
1799         create trigger d1.trg1 before insert on d1.t1 for each row set @a:=1;
1800         rename database d1 to d2;
1801       Problem: After database renaming, the trigger's body
1802                still points to the old database d1.
1803     2. when another database is renamed:
1804         create trigger d3.trg1 before insert on d3.t1 for each row
1805           insert into d1.t1 values (...);
1806         rename database d1 to d2;
1807       Problem: After renaming d1 to d2, the trigger's body
1808                in the database d3 still points to database d1.
1809   */
1810 
1811   if ((dirp = my_dir(path,MYF(MY_DONT_SORT))))
1812   {
1813     uint nfiles= (uint) dirp->number_of_files;
1814     for (uint idx=0 ; idx < nfiles ; idx++)
1815     {
1816       FILEINFO *file= dirp->dir_entry + idx;
1817       char oldname[FN_REFLEN + 1], newname[FN_REFLEN + 1];
1818       DBUG_PRINT("info",("Examining: %s", file->name));
1819 
1820       /* skiping MY_DB_OPT_FILE */
1821       if (!my_strcasecmp(files_charset_info, file->name, MY_DB_OPT_FILE))
1822         continue;
1823 
1824       /* pass empty file name, and file->name as extension to avoid encoding */
1825       build_table_filename(oldname, sizeof(oldname)-1,
1826                            old_db->str, "", file->name, 0);
1827       build_table_filename(newname, sizeof(newname)-1,
1828                            new_db.str, "", file->name, 0);
1829       mysql_file_rename(key_file_misc, oldname, newname, MYF(MY_WME));
1830     }
1831     my_dirend(dirp);
1832   }
1833 
1834   /*
1835     Step7: drop the old database.
1836     query_cache_invalidate(olddb) is done inside mysql_rm_db(), no need
1837     to execute them again.
1838     mysql_rm_db() also "unuses" if we drop the current database.
1839   */
1840   error= mysql_rm_db_internal(thd, old_db, 0, true);
1841 
1842   /* Step8: logging */
1843   if (mysql_bin_log.is_open())
1844   {
1845     int errcode= query_error_code(thd, TRUE);
1846     Query_log_event qinfo(thd, thd->query(), thd->query_length(),
1847                           FALSE, TRUE, TRUE, errcode);
1848     thd->clear_error();
1849     error|= mysql_bin_log.write(&qinfo);
1850   }
1851 
1852   /* Step9: Let's do "use newdb" if we renamed the current database */
1853   if (change_to_newdb)
1854     error|= mysql_change_db(thd, & new_db, FALSE) != 0;
1855 
1856 exit:
1857   DBUG_RETURN(error);
1858 }
1859 
1860 
1861 
1862 /*
1863   Check if there is directory for the database name.
1864 
1865   SYNOPSIS
1866     check_db_dir_existence()
1867     db_name   database name
1868 
1869   RETURN VALUES
1870     FALSE   There is directory for the specified database name.
1871     TRUE    The directory does not exist.
1872 */
1873 
1874 bool check_db_dir_existence(const char *db_name)
1875 {
1876   char db_dir_path[FN_REFLEN + 1];
1877   uint db_dir_path_len;
1878 
1879   db_dir_path_len= build_table_filename(db_dir_path, sizeof(db_dir_path) - 1,
1880                                         db_name, "", "", 0);
1881 
1882   if (db_dir_path_len && db_dir_path[db_dir_path_len - 1] == FN_LIBCHAR)
1883     db_dir_path[db_dir_path_len - 1]= 0;
1884 
1885   /* Check access. */
1886 
1887   return my_access(db_dir_path, F_OK);
1888 }
1889 
1890 
1891 const char *normalize_db_name(const char *db, char *buffer, size_t buffer_size)
1892 {
1893   DBUG_ASSERT(buffer_size > 1);
1894   if (!lower_case_table_names)
1895     return db;
1896   strmake(buffer, db, buffer_size - 1);
1897   my_casedn_str(system_charset_info, buffer);
1898   return buffer;
1899 }
1900