Commit e9c6d5a1 authored by Gagan Goel's avatar Gagan Goel Committed by Robert Bindar

MDEV-307 Add functionality for database comments

This commit adds a new feature to the server to add comments at the database
level. 1024 bytes is the maximum comment length allowed. If the comment length
exceeds this limit, a new error/warning code 4144 is thrown, based on whether
thd->is_strict_mode() is true/false. The database comment is also added to the
db.opt file, as well as to the information_schema.schemata table.
parent 9a8d1d84
......@@ -71,6 +71,7 @@
#define COLUMN_COMMENT_MAXLEN 1024
#define INDEX_COMMENT_MAXLEN 1024
#define TABLE_PARTITION_COMMENT_MAXLEN 1024
#define DATABASE_COMMENT_MAXLEN 1024
/*
Maximum length of protocol packet.
......
This diff is collapsed.
--echo #
--echo # MDEV-307: Add functionality for database comments
--echo #
# Check an error state
--error ER_PARSE_ERROR
CREATE DATABASE db1 COMMENT=;
# 1024 bytes
CREATE DATABASE db1
COMMENT='abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcd';
SHOW CREATE DATABASE db1;
SELECT schema_comment, char_length(schema_comment)
FROM information_schema.schemata
WHERE schema_name='db1';
DROP DATABASE db1;
# 1025 bytes (warning)
SET SQL_MODE='';
CREATE DATABASE db1
COMMENT='abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcde';
SHOW CREATE DATABASE db1;
SELECT schema_comment, char_length(schema_comment)
FROM information_schema.schemata
WHERE schema_name='db1';
DROP DATABASE db1;
SET SQL_MODE='TRADITIONAL';
# 1025 bytes (error)
--error ER_TOO_LONG_DATABASE_COMMENT
CREATE DATABASE db1
COMMENT='abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcde';
SELECT schema_comment, char_length(schema_comment)
FROM information_schema.schemata
WHERE schema_name='db1';
CREATE DATABASE db1 COMMENT 'db1';
SHOW CREATE DATABASE db1;
ALTER DATABASE db1 COMMENT = "db1 comment";
SELECT * FROM information_schema.schemata
WHERE schema_name='db1';
DROP DATABASE db1;
CREATE DATABASE db1;
USE db1;
ALTER DATABASE COMMENT 'db1 comment' CHARACTER SET 'utf8';
SHOW CREATE DATABASE db1;
ALTER DATABASE db1 COMMENT 'this is db1 comment';
SHOW CREATE DATABASE db1;
ALTER DATABASE CHARACTER SET 'latin1';
SHOW CREATE DATABASE db1;
DROP DATABASE db1;
# Test the case when the database is named 'comment'
CREATE DATABASE comment COMMENT 'comment' CHARACTER SET 'latin2';
SHOW CREATE DATABASE comment;
ALTER DATABASE comment COMMENT 'comment comment';
SHOW CREATE DATABASE comment;
USE comment;
ALTER DATABASE COMMENT 'comment';
SELECT * FROM information_schema.schemata
WHERE schema_name='comment';
DROP DATABASE comment;
......@@ -10,7 +10,7 @@ grant select, update on test.* to mysqltest_1@localhost;
create user mysqltest_3@localhost;
create user mysqltest_3;
select * from information_schema.SCHEMATA where schema_name > 'm';
CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH
CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH SCHEMA_COMMENT
def mtr latin1 latin1_swedish_ci NULL
def mysql latin1 latin1_swedish_ci NULL
def performance_schema utf8 utf8_general_ci NULL
......@@ -1575,13 +1575,13 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE b ALL NULL NULL NULL NULL NULL Using where; Open_frm_only; Scanned all databases; Using join buffer (flat, BNL join)
SELECT * FROM INFORMATION_SCHEMA.SCHEMATA
WHERE SCHEMA_NAME = 'mysqltest';
CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH
CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH SCHEMA_COMMENT
SELECT * FROM INFORMATION_SCHEMA.SCHEMATA
WHERE SCHEMA_NAME = '';
CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH
CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH SCHEMA_COMMENT
SELECT * FROM INFORMATION_SCHEMA.SCHEMATA
WHERE SCHEMA_NAME = 'test';
CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH
CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH SCHEMA_COMMENT
def test latin1 latin1_swedish_ci NULL
select count(*) from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='mysql' AND TABLE_NAME='nonexisting';
count(*)
......@@ -1627,7 +1627,7 @@ CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME UNIQUE_CONSTRAINT_CATALOG U
select * from `information_schema`.`REFERENTIAL_CONSTRAINTS` where `TABLE_NAME` = NULL;
CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME UNIQUE_CONSTRAINT_CATALOG UNIQUE_CONSTRAINT_SCHEMA UNIQUE_CONSTRAINT_NAME MATCH_OPTION UPDATE_RULE DELETE_RULE TABLE_NAME REFERENCED_TABLE_NAME
select * from information_schema.schemata where schema_name = NULL;
CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH
CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH SCHEMA_COMMENT
select * from `information_schema`.`STATISTICS` where `TABLE_SCHEMA` = NULL;
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME NON_UNIQUE INDEX_SCHEMA INDEX_NAME SEQ_IN_INDEX COLUMN_NAME COLLATION CARDINALITY SUB_PART PACKED NULLABLE INDEX_TYPE COMMENT INDEX_COMMENT
select * from `information_schema`.`STATISTICS` where `TABLE_NAME` = NULL;
......
......@@ -326,6 +326,7 @@ def information_schema ROUTINES SQL_PATH 22 NULL YES varchar 64 192 NULL NULL NU
def information_schema SCHEMATA CATALOG_NAME 1 '' NO varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) select NEVER NULL
def information_schema SCHEMATA DEFAULT_CHARACTER_SET_NAME 3 '' NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select NEVER NULL
def information_schema SCHEMATA DEFAULT_COLLATION_NAME 4 '' NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select NEVER NULL
def information_schema SCHEMATA SCHEMA_COMMENT 6 '' NO varchar 1024 3072 NULL NULL NULL utf8 utf8_general_ci varchar(1024) select NEVER NULL
def information_schema SCHEMATA SCHEMA_NAME 2 '' NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select NEVER NULL
def information_schema SCHEMATA SQL_PATH 5 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) select NEVER NULL
def information_schema SCHEMA_PRIVILEGES GRANTEE 1 '' NO varchar 190 570 NULL NULL NULL utf8 utf8_general_ci varchar(190) select NEVER NULL
......@@ -870,6 +871,7 @@ NULL information_schema ROUTINES LAST_ALTERED datetime NULL NULL NULL NULL datet
3.0000 information_schema SCHEMATA DEFAULT_CHARACTER_SET_NAME varchar 32 96 utf8 utf8_general_ci varchar(32)
3.0000 information_schema SCHEMATA DEFAULT_COLLATION_NAME varchar 32 96 utf8 utf8_general_ci varchar(32)
3.0000 information_schema SCHEMATA SQL_PATH varchar 512 1536 utf8 utf8_general_ci varchar(512)
3.0000 information_schema SCHEMATA SCHEMA_COMMENT varchar 1024 3072 utf8 utf8_general_ci varchar(1024)
3.0000 information_schema SCHEMA_PRIVILEGES GRANTEE varchar 190 570 utf8 utf8_general_ci varchar(190)
3.0000 information_schema SCHEMA_PRIVILEGES TABLE_CATALOG varchar 512 1536 utf8 utf8_general_ci varchar(512)
3.0000 information_schema SCHEMA_PRIVILEGES TABLE_SCHEMA varchar 64 192 utf8 utf8_general_ci varchar(64)
......
......@@ -33,6 +33,7 @@ SCHEMA_NAME varchar(64) NO
DEFAULT_CHARACTER_SET_NAME varchar(32) NO
DEFAULT_COLLATION_NAME varchar(32) NO
SQL_PATH varchar(512) YES NULL
SCHEMA_COMMENT varchar(1024) NO
SHOW CREATE TABLE information_schema.SCHEMATA;
Table Create Table
SCHEMATA CREATE TEMPORARY TABLE `SCHEMATA` (
......@@ -40,7 +41,8 @@ SCHEMATA CREATE TEMPORARY TABLE `SCHEMATA` (
`SCHEMA_NAME` varchar(64) NOT NULL DEFAULT '',
`DEFAULT_CHARACTER_SET_NAME` varchar(32) NOT NULL DEFAULT '',
`DEFAULT_COLLATION_NAME` varchar(32) NOT NULL DEFAULT '',
`SQL_PATH` varchar(512) DEFAULT NULL
`SQL_PATH` varchar(512) DEFAULT NULL,
`SCHEMA_COMMENT` varchar(1024) NOT NULL DEFAULT ''
) ENGINE=MEMORY DEFAULT CHARSET=utf8
SHOW COLUMNS FROM information_schema.SCHEMATA;
Field Type Null Key Default Extra
......@@ -49,6 +51,7 @@ SCHEMA_NAME varchar(64) NO
DEFAULT_CHARACTER_SET_NAME varchar(32) NO
DEFAULT_COLLATION_NAME varchar(32) NO
SQL_PATH varchar(512) YES NULL
SCHEMA_COMMENT varchar(1024) NO
SELECT catalog_name, schema_name, sql_path
FROM information_schema.schemata
WHERE catalog_name IS NOT NULL or sql_path IS NOT NULL
......@@ -77,7 +80,7 @@ GRANT SELECT ON db_datadict_1.* to 'testuser2'@'localhost';
GRANT SELECT ON db_datadict_2.* to 'testuser2'@'localhost';
SELECT * FROM information_schema.schemata
WHERE schema_name LIKE 'db_datadict_%' ORDER BY schema_name;
CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH
CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH SCHEMA_COMMENT
def db_datadict_1 latin1 latin1_swedish_ci NULL
def db_datadict_2 latin1 latin1_swedish_ci NULL
SHOW DATABASES LIKE 'db_datadict_%';
......@@ -87,7 +90,7 @@ db_datadict_2
connect testuser1, localhost, testuser1, , db_datadict_1;
SELECT * FROM information_schema.schemata
WHERE schema_name LIKE 'db_datadict_%' ORDER BY schema_name;
CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH
CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH SCHEMA_COMMENT
def db_datadict_1 latin1 latin1_swedish_ci NULL
SHOW DATABASES LIKE 'db_datadict_%';
Database (db_datadict_%)
......@@ -95,7 +98,7 @@ db_datadict_1
connect testuser2, localhost, testuser2, , db_datadict_2;
SELECT * FROM information_schema.schemata
WHERE schema_name LIKE 'db_datadict_%' ORDER BY schema_name;
CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH
CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH SCHEMA_COMMENT
def db_datadict_1 latin1 latin1_swedish_ci NULL
def db_datadict_2 latin1 latin1_swedish_ci NULL
SHOW DATABASES LIKE 'db_datadict_%';
......@@ -105,7 +108,7 @@ db_datadict_2
connect testuser3, localhost, testuser3, , test;
SELECT * FROM information_schema.schemata
WHERE schema_name LIKE 'db_datadict_%' ORDER BY schema_name;
CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH
CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH SCHEMA_COMMENT
SHOW DATABASES LIKE 'db_datadict_%';
Database (db_datadict_%)
connection default;
......@@ -122,10 +125,10 @@ DROP DATABASE db_datadict_2;
#################################################################################
DROP DATABASE IF EXISTS db_datadict;
SELECT * FROM information_schema.schemata WHERE schema_name = 'db_datadict';
CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH
CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH SCHEMA_COMMENT
CREATE DATABASE db_datadict CHARACTER SET 'latin1' COLLATE 'latin1_swedish_ci';
SELECT * FROM information_schema.schemata WHERE schema_name = 'db_datadict';
CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH
CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH SCHEMA_COMMENT
def db_datadict latin1 latin1_swedish_ci NULL
SELECT schema_name, default_character_set_name
FROM information_schema.schemata WHERE schema_name = 'db_datadict';
......
......@@ -9,7 +9,7 @@ GRANT SELECT ON db_datadict.* TO 'testuser1'@'localhost';
SELECT * FROM information_schema.schemata
WHERE schema_name IN ('information_schema','mysql','test')
ORDER BY schema_name;
CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH
CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH SCHEMA_COMMENT
def information_schema utf8 utf8_general_ci NULL
def mysql latin1 latin1_swedish_ci NULL
def test latin1 latin1_swedish_ci NULL
......@@ -26,7 +26,7 @@ connect testuser1, localhost, testuser1, , db_datadict;
SELECT * FROM information_schema.schemata
WHERE schema_name IN ('information_schema','mysql','test')
ORDER BY schema_name;
CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH
CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH SCHEMA_COMMENT
def information_schema utf8 utf8_general_ci NULL
def test latin1 latin1_swedish_ci NULL
SHOW DATABASES LIKE 'information_schema';
......
......@@ -1945,11 +1945,12 @@ enum enum_stats_auto_recalc { HA_STATS_AUTO_RECALC_DEFAULT= 0,
It stores the "schema_specification" part of the CREATE/ALTER statements and
is passed to mysql_create_db() and mysql_alter_db().
Currently consists only of the schema default character set and collation.
Currently consists of the schema default character set, collation and schema_comment.
*/
struct Schema_specification_st
{
CHARSET_INFO *default_table_charset;
LEX_CSTRING *schema_comment;
void init()
{
bzero(this, sizeof(*this));
......
......@@ -7931,3 +7931,5 @@ ER_PERIOD_CONSTRAINT_DROP
eng "Can't DROP CONSTRAINT `%s`. Use DROP PERIOD `%s` for this"
ER_TOO_LONG_KEYPART 42000 S1009
eng "Specified key part was too long; max key part length is %u bytes"
ER_TOO_LONG_DATABASE_COMMENT
eng "Comment for database '%-.64s' is too long (max = %u)"
......@@ -26,6 +26,7 @@
#include "lock.h" // lock_schema_name
#include "sql_table.h" // build_table_filename,
// filename_to_tablename
// validate_comment_length
#include "sql_rename.h" // mysql_rename_tables
#include "sql_acl.h" // SELECT_ACL, DB_ACLS,
// acl_get, check_grant_db
......@@ -77,6 +78,7 @@ typedef struct my_dbopt_st
char *name; /* Database name */
uint name_length; /* Database length name */
CHARSET_INFO *charset; /* Database default character set */
LEX_STRING comment; /* Database comment */
} my_dbopt_t;
......@@ -235,7 +237,8 @@ void my_dbopt_cleanup(void)
1 on error.
*/
static my_bool get_dbopt(const char *dbname, Schema_specification_st *create)
static my_bool get_dbopt(THD *thd, const char *dbname,
Schema_specification_st *create)
{
my_dbopt_t *opt;
uint length;
......@@ -247,6 +250,11 @@ static my_bool get_dbopt(const char *dbname, Schema_specification_st *create)
if ((opt= (my_dbopt_t*) my_hash_search(&dboptions, (uchar*) dbname, length)))
{
create->default_table_charset= opt->charset;
if (opt->comment.length)
{
create->schema_comment= thd->make_clex_string(const_cast<char*>(opt->comment.str),
opt->comment.length);
}
error= 0;
}
mysql_rwlock_unlock(&LOCK_dboptions);
......@@ -281,8 +289,10 @@ static my_bool put_dbopt(const char *dbname, Schema_specification_st *create)
{
/* Options are not in the hash, insert them */
char *tmp_name;
char *tmp_comment= NULL;
if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
&opt, (uint) sizeof(*opt), &tmp_name, (uint) length+1,
&tmp_comment, (uint) DATABASE_COMMENT_MAXLEN+1,
NullS))
{
error= 1;
......@@ -292,7 +302,7 @@ static my_bool put_dbopt(const char *dbname, Schema_specification_st *create)
opt->name= tmp_name;
strmov(opt->name, dbname);
opt->name_length= length;
opt->comment.str= tmp_comment;
if (unlikely((error= my_hash_insert(&dboptions, (uchar*) opt))))
{
my_free(opt);
......@@ -303,6 +313,12 @@ static my_bool put_dbopt(const char *dbname, Schema_specification_st *create)
/* Update / write options in hash */
opt->charset= create->default_table_charset;
if (create->schema_comment)
{
strmov(opt->comment.str, create->schema_comment->str);
opt->comment.length= create->schema_comment->length;
}
end:
mysql_rwlock_unlock(&LOCK_dboptions);
DBUG_RETURN(error);
......@@ -328,7 +344,7 @@ static void del_dbopt(const char *path)
Create database options file:
DESCRIPTION
Currently database default charset is only stored there.
Currently database default charset, default collation and comment are stored there.
RETURN VALUES
0 ok
......@@ -339,9 +355,31 @@ static bool write_db_opt(THD *thd, const char *path,
Schema_specification_st *create)
{
File file;
char buf[256]; // Should be enough for one option
char buf[256+DATABASE_COMMENT_MAXLEN];
bool error=1;
if (create->schema_comment)
{
if (validate_comment_length(thd, create->schema_comment,
DATABASE_COMMENT_MAXLEN, ER_TOO_LONG_DATABASE_COMMENT,
thd->lex->name.str))
return error;
}
/* Use existing values of schema_comment and charset for ALTER DATABASE queries */
Schema_specification_st tmp;
bzero((char*) &tmp,sizeof(tmp));
if (thd->lex->sql_command == SQLCOM_ALTER_DB)
{
load_db_opt(thd, path, &tmp);
if (!create->schema_comment)
create->schema_comment= tmp.schema_comment;
if (!create->default_table_charset)
create->default_table_charset= tmp.default_table_charset;
}
if (!create->default_table_charset)
create->default_table_charset= thd->variables.collation_server;
......@@ -358,6 +396,11 @@ static bool write_db_opt(THD *thd, const char *path,
create->default_table_charset->name,
"\n", NullS) - buf);
if (create->schema_comment)
length= (ulong) (strxnmov(buf+length, sizeof(buf)-1-length,
"comment=", create->schema_comment->str,
"\n", NullS) - buf);
/* Error is written by mysql_file_write */
if (!mysql_file_write(file, (uchar*) buf, length, MYF(MY_NABP+MY_WME)))
error=0;
......@@ -385,7 +428,7 @@ static bool write_db_opt(THD *thd, const char *path,
bool load_db_opt(THD *thd, const char *path, Schema_specification_st *create)
{
File file;
char buf[256];
char buf[256+DATABASE_COMMENT_MAXLEN];
DBUG_ENTER("load_db_opt");
bool error=1;
size_t nbytes;
......@@ -394,7 +437,7 @@ bool load_db_opt(THD *thd, const char *path, Schema_specification_st *create)
create->default_table_charset= thd->variables.collation_server;
/* Check if options for this database are already in the hash */
if (!get_dbopt(path, create))
if (!get_dbopt(thd, path, create))
DBUG_RETURN(0);
/* Otherwise, load options from the .opt file */
......@@ -444,6 +487,8 @@ bool load_db_opt(THD *thd, const char *path, Schema_specification_st *create)
create->default_table_charset= default_charset_info;
}
}
else if (!strncmp(buf, "comment", (pos-buf)))
create->schema_comment= thd->make_clex_string(pos+1, strlen(pos+1));
}
}
/*
......@@ -544,7 +589,7 @@ CHARSET_INFO *get_default_db_collation(THD *thd, const char *db_name)
Create a database
SYNOPSIS
mysql_create_db_iternal()
mysql_create_db_internal()
thd Thread handler
db Name of database to create
Function assumes that this is already validated.
......
......@@ -1470,7 +1470,7 @@ bool mysqld_show_create_db(THD *thd, LEX_CSTRING *dbname,
LEX_CSTRING *orig_dbname,
const DDL_options_st &options)
{
char buff[2048];
char buff[2048+DATABASE_COMMENT_MAXLEN];
String buffer(buff, sizeof(buff), system_charset_info);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
Security_context *sctx= thd->security_ctx;
......@@ -1506,6 +1506,7 @@ bool mysqld_show_create_db(THD *thd, LEX_CSTRING *dbname,
{
*dbname= INFORMATION_SCHEMA_NAME;
create.default_table_charset= system_charset_info;
create.schema_comment= NULL;
}
else
{
......@@ -1545,6 +1546,13 @@ bool mysqld_show_create_db(THD *thd, LEX_CSTRING *dbname,
}
buffer.append(STRING_WITH_LEN(" */"));
}
if (create.schema_comment)
{
buffer.append(STRING_WITH_LEN(" COMMENT "));
append_unescaped(&buffer, create.schema_comment->str,
create.schema_comment->length);
}
protocol->store(buffer.ptr(), buffer.length(), buffer.charset());
if (protocol->write())
......@@ -5306,14 +5314,16 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
}
bool store_schema_shemata(THD* thd, TABLE *table, LEX_CSTRING *db_name,
CHARSET_INFO *cs)
bool store_schema_schemata(THD* thd, TABLE *table, LEX_CSTRING *db_name,
CHARSET_INFO *cs, LEX_CSTRING *schema_comment= NULL)
{
restore_record(table, s->default_values);
table->field[0]->store(STRING_WITH_LEN("def"), system_charset_info);
table->field[1]->store(db_name->str, db_name->length, system_charset_info);
table->field[2]->store(cs->csname, strlen(cs->csname), system_charset_info);
table->field[3]->store(cs->name, strlen(cs->name), system_charset_info);
if (schema_comment)
table->field[5]->store(schema_comment->str, schema_comment->length, system_charset_info);
return schema_table_store_record(thd, table);
}
......@@ -5366,7 +5376,7 @@ int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond)
DBUG_ASSERT(db_name->length <= NAME_LEN);
if (db_name == &INFORMATION_SCHEMA_NAME)
{
if (store_schema_shemata(thd, table, db_name,
if (store_schema_schemata(thd, table, db_name,
system_charset_info))
DBUG_RETURN(1);
continue;
......@@ -5380,8 +5390,8 @@ int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond)
#endif
{
load_db_opt_by_name(thd, db_name->str, &create);
if (store_schema_shemata(thd, table, db_name,
create.default_table_charset))
if (store_schema_schemata(thd, table, db_name,
create.default_table_charset, create.schema_comment))
DBUG_RETURN(1);
}
}
......@@ -9044,6 +9054,7 @@ ST_FIELD_INFO schema_fields_info[]=
{"DEFAULT_COLLATION_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0,
SKIP_OPEN_TABLE},
{"SQL_PATH", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
{"SCHEMA_COMMENT", DATABASE_COMMENT_MAXLEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
};
......
......@@ -1687,6 +1687,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
*/
%left PREC_BELOW_IDENTIFIER_OPT_SPECIAL_CASE
%left TRANSACTION_SYM TIMESTAMP PERIOD_SYM SYSTEM USER
%left COMMENT_SYM
/*
......@@ -2793,6 +2794,7 @@ create:
| create_or_replace DATABASE opt_if_not_exists ident
{
Lex->create_info.default_table_charset= NULL;
Lex->create_info.schema_comment= NULL;
Lex->create_info.used_fields= 0;
if (Lex->main_select_push())
MYSQL_YYABORT;
......@@ -6043,6 +6045,11 @@ create_database_options:
create_database_option:
default_collation {}
| default_charset {}
| COMMENT_SYM opt_equal TEXT_STRING_sys
{
Lex->create_info.schema_comment= thd->make_clex_string($3);
Lex->create_info.used_fields|= HA_CREATE_USED_COMMENT;
}
;
opt_if_not_exists_table_element:
......@@ -7764,6 +7771,7 @@ alter:
| ALTER DATABASE ident_or_empty
{
Lex->create_info.default_table_charset= NULL;
Lex->create_info.schema_comment= NULL;
Lex->create_info.used_fields= 0;
if (Lex->main_select_push())
MYSQL_YYABORT;
......@@ -7778,6 +7786,22 @@ alter:
MYSQL_YYABORT;
Lex->pop_select(); //main select
}
| ALTER DATABASE COMMENT_SYM opt_equal TEXT_STRING_sys
{
Lex->create_info.default_table_charset= NULL;
Lex->create_info.used_fields= 0;
Lex->create_info.schema_comment= thd->make_clex_string($5);
Lex->create_info.used_fields|= HA_CREATE_USED_COMMENT;
}
opt_create_database_options
{
LEX *lex=Lex;
lex->sql_command=SQLCOM_ALTER_DB;
lex->name= Lex_ident_sys();
if (lex->name.str == NULL &&
unlikely(lex->copy_db_to(&lex->name)))
MYSQL_YYABORT;
}
| ALTER DATABASE ident UPGRADE_SYM DATA_SYM DIRECTORY_SYM NAME_SYM
{
LEX *lex= Lex;
......@@ -8022,7 +8046,7 @@ opt_ev_sql_stmt:
;
ident_or_empty:
/* empty */ { $$= Lex_ident_sys(); }
/* empty */ %prec PREC_BELOW_IDENTIFIER_OPT_SPECIAL_CASE { $$= Lex_ident_sys(); }
| ident
;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment