diff --git a/mysql-test/main/comment_database.result b/mysql-test/main/comment_database.result index 8e3cf1c904e..d67f0c054ca 100644 --- a/mysql-test/main/comment_database.result +++ b/mysql-test/main/comment_database.result @@ -76,3 +76,16 @@ WHERE schema_name='comment'; CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH SCHEMA_COMMENT def comment latin2 latin2_general_ci NULL comment DROP DATABASE comment; +CREATE DATABASE db1; +# restart +SHOW CREATE DATABASE db1; +Database Create Database +db1 CREATE DATABASE `db1` /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */ +Warnings: +Note 1105 Database 'db1' does not have a db.opt file. You can create one with ALTER DATABASE if needed +SHOW CREATE DATABASE db1; +Database Create Database +db1 CREATE DATABASE `db1` /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */ +Warnings: +Note 1105 Database 'db1' does not have a db.opt file. You can create one with ALTER DATABASE if needed +DROP DATABASE db1; diff --git a/mysql-test/main/comment_database.test b/mysql-test/main/comment_database.test index bf89a57c7b2..a6f43a91e5d 100644 --- a/mysql-test/main/comment_database.test +++ b/mysql-test/main/comment_database.test @@ -63,3 +63,11 @@ SELECT * FROM information_schema.schemata WHERE schema_name='comment'; DROP DATABASE comment; --enable_service_connection + +CREATE DATABASE db1; +--remove_file $MARIADB_DATADIR/db1/db.opt +--source include/restart_mysqld.inc +# We need to call this two times to ensure all code paths are used +SHOW CREATE DATABASE db1; +SHOW CREATE DATABASE db1; +DROP DATABASE db1; diff --git a/mysql-test/main/ctype_utf8_def_upgrade.result b/mysql-test/main/ctype_utf8_def_upgrade.result index d30f8670536..fbe43fb208d 100644 --- a/mysql-test/main/ctype_utf8_def_upgrade.result +++ b/mysql-test/main/ctype_utf8_def_upgrade.result @@ -53,6 +53,8 @@ SET @@character_set_database=DEFAULT; SHOW CREATE DATABASE db1; Database Create Database db1 CREATE DATABASE `db1` /*!40100 DEFAULT CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci */ +Warnings: +Note 1105 Database 'db1' does not have a db.opt file. You can create one with ALTER DATABASE if needed USE db1; SELECT @@character_set_database, 'taken from defaults' AS comment; @@character_set_database comment diff --git a/mysql-test/main/mysql_upgrade-34014.result b/mysql-test/main/mysql_upgrade-34014.result index d53da1c85df..78dd75da8e8 100644 --- a/mysql-test/main/mysql_upgrade-34014.result +++ b/mysql-test/main/mysql_upgrade-34014.result @@ -12,6 +12,8 @@ FLUSH TABLES; SHOW CREATE DATABASE sys; Database Create Database sys CREATE DATABASE `sys` /*!40100 DEFAULT CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci */ +Warnings: +Note 1105 Database 'sys' does not have a db.opt file. You can create one with ALTER DATABASE if needed Phase 1/8: Checking and upgrading mysql database Processing databases mysql diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 44426184497..6b7949ccc41 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -536,36 +536,53 @@ static bool write_db_opt(THD *thd, const char *path, DESCRIPTION + create->default_table_charset is guaranteed to be alway set + Required by some callers + RETURN VALUES 0 File found - 1 No database file or could not open it - + -1 No database file (file was not found or 'empty' file was cached) + 1 Could not open it */ -bool load_db_opt(THD *thd, const char *path, Schema_specification_st *create) +int load_db_opt(THD *thd, const char *path, Schema_specification_st *create) { File file; char buf[256+DATABASE_COMMENT_MAXLEN]; DBUG_ENTER("load_db_opt"); - bool error=1; + int error= 0; size_t nbytes; myf utf8_flag= thd->get_utf8_flag(); bzero((char*) create,sizeof(*create)); - create->default_table_charset= thd->variables.collation_server; /* Check if options for this database are already in the hash */ if (!get_dbopt(thd, path, create)) - DBUG_RETURN(0); + { + if (!create->default_table_charset) + error= -1; // db.opt did not exists + goto err1; + } /* Otherwise, load options from the .opt file */ if ((file= mysql_file_open(key_file_dbopt, path, O_RDONLY | O_SHARE, MYF(0))) < 0) + { + /* + Create an empty entry, to avoid doing an extra file open for every create + table. + */ + put_dbopt(path, create); + error= -1; goto err1; + } IO_CACHE cache; if (init_io_cache(&cache, file, IO_SIZE, READ_CACHE, 0, 0, MYF(0))) - goto err2; + { + error= 1; + goto err2; // Not cached + } while ((int) (nbytes= my_b_gets(&cache, (char*) buf, sizeof(buf))) > 0) { @@ -586,7 +603,7 @@ bool load_db_opt(THD *thd, const char *path, Schema_specification_st *create) default-collation commands. */ if (!(create->default_table_charset= - get_charset_by_csname(pos+1, MY_CS_PRIMARY, MYF(utf8_flag))) && + get_charset_by_csname(pos+1, MY_CS_PRIMARY, MYF(utf8_flag))) && !(create->default_table_charset= get_charset_by_name(pos+1, MYF(utf8_flag)))) { @@ -621,10 +638,11 @@ bool load_db_opt(THD *thd, const char *path, Schema_specification_st *create) err2: mysql_file_close(file, MYF(0)); err1: + if (!create->default_table_charset) // In case of error + create->default_table_charset= thd->variables.collation_server; DBUG_RETURN(error); } - /* Retrieve database options by name. Load database options file or fetch from cache. @@ -651,11 +669,12 @@ err1: db_create_info right after that. RETURN VALUES (read NOTE!) - FALSE Success - TRUE Failed to retrieve options + 0 File found + -1 No database file (file was not found or 'empty' file was cached) + 1 Could not open it */ -bool load_db_opt_by_name(THD *thd, const char *db_name, +int load_db_opt_by_name(THD *thd, const char *db_name, Schema_specification_st *db_create_info) { char db_opt_path[FN_REFLEN + 1]; @@ -1951,8 +1970,7 @@ bool mysql_upgrade_db(THD *thd, const LEX_CSTRING *old_db) build_table_filename(path, sizeof(path)-1, old_db->str, "", MY_DB_OPT_FILE, 0); - if ((load_db_opt(thd, path, &create_info))) - create_info.default_table_charset= thd->variables.collation_server; + load_db_opt(thd, path, &create_info); length= build_table_filename(path, sizeof(path)-1, old_db->str, "", "", 0); if (length && path[length-1] == FN_LIBCHAR) diff --git a/sql/sql_db.h b/sql/sql_db.h index 3c037d668e0..03517dc684e 100644 --- a/sql/sql_db.h +++ b/sql/sql_db.h @@ -37,8 +37,8 @@ bool mysql_opt_change_db(THD *thd, bool my_dboptions_cache_init(void); void my_dboptions_cache_free(void); bool check_db_dir_existence(const char *db_name); -bool load_db_opt(THD *thd, const char *path, Schema_specification_st *create); -bool load_db_opt_by_name(THD *thd, const char *db_name, +int load_db_opt(THD *thd, const char *path, Schema_specification_st *create); +int load_db_opt_by_name(THD *thd, const char *db_name, Schema_specification_st *db_create_info); CHARSET_INFO *get_default_db_collation(THD *thd, const char *db_name); bool my_dbopt_init(void); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index c2186a667a2..d70e20fe0b3 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1435,7 +1435,14 @@ bool mysqld_show_create_db(THD *thd, LEX_CSTRING *dbname, DBUG_RETURN(TRUE); } - load_db_opt_by_name(thd, dbname->str, &create); + if (load_db_opt_by_name(thd, dbname->str, &create) < 0) + { + push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, + ER_UNKNOWN_ERROR, + "Database '%.192s' does not have a db.opt file. " + "You can create one with ALTER DATABASE if needed", + dbname->str); + } } mysqld_show_create_db_get_fields(thd, &field_list);