summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/ctype_create.result32
-rw-r--r--mysql-test/t/ctype_create.test36
-rw-r--r--sql/handler.cc19
-rw-r--r--sql/handler.h27
-rw-r--r--sql/sql_yacc.yy18
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