diff options
-rw-r--r-- | mysql-test/r/ctype_create.result | 32 | ||||
-rw-r--r-- | mysql-test/t/ctype_create.test | 36 | ||||
-rw-r--r-- | sql/handler.cc | 19 | ||||
-rw-r--r-- | sql/handler.h | 27 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 18 |
5 files changed, 117 insertions, 15 deletions
diff --git a/mysql-test/r/ctype_create.result b/mysql-test/r/ctype_create.result index 35461fce45a..4128be82c23 100644 --- a/mysql-test/r/ctype_create.result +++ b/mysql-test/r/ctype_create.result @@ -76,3 +76,35 @@ ALTER DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ERROR 42000: Incorrect database name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' ALTER DATABASE `` DEFAULT CHARACTER SET latin2; ERROR 42000: Incorrect database name '' +USE test; +# +# Start of 10.0 tests +# +# +# MDEV-7387 Alter table xxx CHARACTER SET utf8, CONVERT TO CHARACTER SET latin1 should fail +# +CREATE TABLE t1 (a VARCHAR(10)) CHARACTER SET DEFAULT, CHARACTER SET utf8; +ERROR HY000: Conflicting declarations: 'CHARACTER SET DEFAULT' and 'CHARACTER SET utf8' +CREATE TABLE t1 (a VARCHAR(10)) CHARACTER SET utf8, CHARACTER SET DEFAULT; +ERROR HY000: Conflicting declarations: 'CHARACTER SET utf8' and 'CHARACTER SET DEFAULT' +CREATE TABLE t1 (a VARCHAR(10)) CHARACTER SET utf8, CHARACTER SET utf8; +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(10)) CHARACTER SET DEFAULT, CHARACTER SET DEFAULT; +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET latin1, b VARCHAR(10) CHARACTER SET utf8); +ALTER TABLE t1 CONVERT TO CHARACTER SET utf8, CHARACTER SET latin1; +ERROR HY000: Conflicting declarations: 'CHARACTER SET utf8' and 'CHARACTER SET latin1' +ALTER TABLE t1 CONVERT TO CHARACTER SET utf8, CHARACTER SET DEFAULT; +ERROR HY000: Conflicting declarations: 'CHARACTER SET utf8' and 'CHARACTER SET DEFAULT' +ALTER TABLE t1 CONVERT TO CHARACTER SET latin1, CHARACTER SET utf8; +ERROR HY000: Conflicting declarations: 'CHARACTER SET latin1' and 'CHARACTER SET utf8' +ALTER TABLE t1 CONVERT TO CHARACTER SET latin1, CHARACTER SET DEFAULT; +ERROR HY000: Conflicting declarations: 'CHARACTER SET latin1' and 'CHARACTER SET DEFAULT' +ALTER TABLE t1 CONVERT TO CHARACTER SET DEFAULT, CHARACTER SET utf8; +ERROR HY000: Conflicting declarations: 'CHARACTER SET latin5' and 'CHARACTER SET utf8' +ALTER TABLE t1 CONVERT TO CHARACTER SET DEFAULT, CHARACTER SET latin1; +ERROR HY000: Conflicting declarations: 'CHARACTER SET latin5' and 'CHARACTER SET latin1' +DROP TABLE t1; +# +# End of 10.0 tests +# diff --git a/mysql-test/t/ctype_create.test b/mysql-test/t/ctype_create.test index 060c09a0459..61fc5292094 100644 --- a/mysql-test/t/ctype_create.test +++ b/mysql-test/t/ctype_create.test @@ -105,3 +105,39 @@ ALTER DATABASE DEFAULT CHARACTER SET latin2; ALTER DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa DEFAULT CHARACTER SET latin2; --error 1102 ALTER DATABASE `` DEFAULT CHARACTER SET latin2; +USE test; + +--echo # +--echo # Start of 10.0 tests +--echo # + +--echo # +--echo # MDEV-7387 Alter table xxx CHARACTER SET utf8, CONVERT TO CHARACTER SET latin1 should fail +--echo # +--error ER_CONFLICTING_DECLARATIONS +CREATE TABLE t1 (a VARCHAR(10)) CHARACTER SET DEFAULT, CHARACTER SET utf8; +--error ER_CONFLICTING_DECLARATIONS +CREATE TABLE t1 (a VARCHAR(10)) CHARACTER SET utf8, CHARACTER SET DEFAULT; +CREATE TABLE t1 (a VARCHAR(10)) CHARACTER SET utf8, CHARACTER SET utf8; +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(10)) CHARACTER SET DEFAULT, CHARACTER SET DEFAULT; +DROP TABLE t1; + +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET latin1, b VARCHAR(10) CHARACTER SET utf8); +--error ER_CONFLICTING_DECLARATIONS +ALTER TABLE t1 CONVERT TO CHARACTER SET utf8, CHARACTER SET latin1; +--error ER_CONFLICTING_DECLARATIONS +ALTER TABLE t1 CONVERT TO CHARACTER SET utf8, CHARACTER SET DEFAULT; +--error ER_CONFLICTING_DECLARATIONS +ALTER TABLE t1 CONVERT TO CHARACTER SET latin1, CHARACTER SET utf8; +--error ER_CONFLICTING_DECLARATIONS +ALTER TABLE t1 CONVERT TO CHARACTER SET latin1, CHARACTER SET DEFAULT; +--error ER_CONFLICTING_DECLARATIONS +ALTER TABLE t1 CONVERT TO CHARACTER SET DEFAULT, CHARACTER SET utf8; +--error ER_CONFLICTING_DECLARATIONS +ALTER TABLE t1 CONVERT TO CHARACTER SET DEFAULT, CHARACTER SET latin1; +DROP TABLE t1; + +--echo # +--echo # End of 10.0 tests +--echo # diff --git a/sql/handler.cc b/sql/handler.cc index b92db125cf5..9a2ba6bb732 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -6296,3 +6296,22 @@ fl_create_iterator(enum handler_iterator_type type, } } #endif /*TRANS_LOG_MGM_EXAMPLE_CODE*/ + + +bool HA_CREATE_INFO::check_conflicting_charset_declarations(CHARSET_INFO *cs) +{ + if ((used_fields & HA_CREATE_USED_DEFAULT_CHARSET) && + /* DEFAULT vs explicit, or explicit vs DEFAULT */ + (((default_table_charset == NULL) != (cs == NULL)) || + /* Two different explicit character sets */ + (default_table_charset && cs && + !my_charset_same(default_table_charset, cs)))) + { + my_error(ER_CONFLICTING_DECLARATIONS, MYF(0), + "CHARACTER SET ", default_table_charset ? + default_table_charset->csname : "DEFAULT", + "CHARACTER SET ", cs ? cs->csname : "DEFAULT"); + return true; + } + return false; +} diff --git a/sql/handler.h b/sql/handler.h index 4222270e9c4..2e219d5f3cc 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1637,6 +1637,33 @@ struct HA_CREATE_INFO bool table_was_deleted; bool tmp_table() { return options & HA_LEX_CREATE_TMP_TABLE; } + bool check_conflicting_charset_declarations(CHARSET_INFO *cs); + bool add_table_option_default_charset(CHARSET_INFO *cs) + { + // cs can be NULL, e.g.: CREATE TABLE t1 (..) CHARACTER SET DEFAULT; + if (check_conflicting_charset_declarations(cs)) + return true; + default_table_charset= cs; + used_fields|= HA_CREATE_USED_DEFAULT_CHARSET; + return false; + } + bool add_alter_list_item_convert_to_charset(CHARSET_INFO *cs) + { + /* + cs cannot be NULL, as sql_yacc.yy translates + CONVERT TO CHARACTER SET DEFAULT + to + CONVERT TO CHARACTER SET <character-set-of-the-current-database> + TODO: Should't we postpone resolution of DEFAULT until the + character set of the table owner database is loaded from its db.opt? + */ + DBUG_ASSERT(cs); + if (check_conflicting_charset_declarations(cs)) + return true; + table_charset= default_table_charset= cs; + used_fields|= (HA_CREATE_USED_CHARSET | HA_CREATE_USED_DEFAULT_CHARSET); + return false; + } }; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index bcc74b4a710..a23a88b7559 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -5803,18 +5803,8 @@ create_table_option: default_charset: opt_default charset opt_equal charset_name_or_default { - HA_CREATE_INFO *cinfo= &Lex->create_info; - if ((cinfo->used_fields & HA_CREATE_USED_DEFAULT_CHARSET) && - cinfo->default_table_charset && $4 && - !my_charset_same(cinfo->default_table_charset,$4)) - { - my_error(ER_CONFLICTING_DECLARATIONS, MYF(0), - "CHARACTER SET ", cinfo->default_table_charset->csname, - "CHARACTER SET ", $4->csname); + if (Lex->create_info.add_table_option_default_charset($4)) MYSQL_YYABORT; - } - Lex->create_info.default_table_charset= $4; - Lex->create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET; } ; @@ -7646,10 +7636,8 @@ alter_list_item: MYSQL_YYABORT; } LEX *lex= Lex; - lex->create_info.table_charset= - lex->create_info.default_table_charset= $5; - lex->create_info.used_fields|= (HA_CREATE_USED_CHARSET | - HA_CREATE_USED_DEFAULT_CHARSET); + if (lex->create_info.add_alter_list_item_convert_to_charset($5)) + MYSQL_YYABORT; lex->alter_info.flags|= Alter_info::ALTER_CONVERT; } | create_table_options_space_separated |