From 68baa2ac2e6e72b0b36ffa4e5c36c0965fdfc6d1 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 31 Jan 2005 18:22:52 -0800 Subject: [PATCH 01/19] Fix bug in bundled GNU readline library, based on similar report for GNU bash (http://lists.gnu.org/archive/html/bug-bash/2002-08/msg00042.html) and current code from GNU readline 5.0. (Bug #5672) cmd-line-utils/readline/bind.c: Import fix from readline-5.0 for endless recursion problem with some misunderstood key codes --- cmd-line-utils/readline/bind.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd-line-utils/readline/bind.c b/cmd-line-utils/readline/bind.c index 7e8ca04e0d6..fd01049f09f 100644 --- a/cmd-line-utils/readline/bind.c +++ b/cmd-line-utils/readline/bind.c @@ -311,7 +311,7 @@ rl_generic_bind (type, keyseq, data, map) mapped to something, `abc' to be mapped to something else, and the function bound to `a' to be executed when the user types `abx', leaving `bx' in the input queue. */ - if (k.function /* && k.type == ISFUNC */) + if (k.function && ((k.type == ISFUNC && k.function != rl_do_lowercase_version) || k.type == ISMACR)) { map[ANYOTHERKEY] = k; k.function = 0; From d41473f3c63c4f770f1bb28f1729331d4f780ada Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Feb 2005 16:07:32 -0800 Subject: [PATCH 02/19] Fix error in parsing string literals containing a backslash followed by a multi-byte character with a second byte of 0x5c (\). (Bug #8903) sql/sql_lex.cc: Fix lex error when multi-byte character containing 0x5c (\) follows a backslash mysql-test/t/ctype_sjis.test: Add regression test for Bug #8303 mysql-test/r/ctype_sjis.result: Add test results --- mysql-test/r/ctype_sjis.result | 4 ++++ mysql-test/t/ctype_sjis.test | 7 +++++++ sql/sql_lex.cc | 32 ++++++++++++++++++++++++++------ 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/ctype_sjis.result b/mysql-test/r/ctype_sjis.result index 1f414f89e20..98e5992f374 100644 --- a/mysql-test/r/ctype_sjis.result +++ b/mysql-test/r/ctype_sjis.result @@ -91,3 +91,7 @@ sjis_bin 6109 sjis_bin 61 sjis_bin 6120 drop table t1; +SET NAMES sjis; +SELECT HEX('@\\') FROM DUAL; +HEX('@_\') +8DB2939181408C5C diff --git a/mysql-test/t/ctype_sjis.test b/mysql-test/t/ctype_sjis.test index 58ca3c6a997..50d286f28b9 100644 --- a/mysql-test/t/ctype_sjis.test +++ b/mysql-test/t/ctype_sjis.test @@ -68,3 +68,10 @@ SET collation_connection='sjis_japanese_ci'; -- source include/ctype_filesort.inc SET collation_connection='sjis_bin'; -- source include/ctype_filesort.inc + +# Check parsing of string literals in SJIS with multibyte characters that +# have an embedded \ in them. (Bug #8303) + +--character_set sjis +SET NAMES sjis; +SELECT HEX('@\\') FROM DUAL; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index ed974a48ad3..d6dcd9ce9ae 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -295,7 +295,18 @@ static char *get_text(LEX *lex) found_escape=1; if (lex->ptr == lex->end_of_query) return 0; - yySkip(); +#ifdef USE_MB + int l; + if (use_mb(cs) && + (l = my_ismbchar(cs, + (const char *)lex->ptr, + (const char *)lex->end_of_query))) { + lex->ptr += l; + continue; + } + else +#endif + yySkip(); } else if (c == sep) { @@ -323,6 +334,10 @@ static char *get_text(LEX *lex) else { uchar *to; + + /* Re-use found_escape for tracking state of escapes */ + found_escape= 0; + for (to=start ; str != end ; str++) { #ifdef USE_MB @@ -336,7 +351,7 @@ static char *get_text(LEX *lex) continue; } #endif - if (*str == '\\' && str+1 != end) + if (!found_escape && *str == '\\' && str+1 != end) { switch(*++str) { case 'n': @@ -362,15 +377,20 @@ static char *get_text(LEX *lex) *to++= '\\'; // remember prefix for wildcard /* Fall through */ default: - *to++ = *str; + found_escape= 1; + str--; break; } } - else if (*str == sep) - *to++= *str++; // Two ' or " + else if (!found_escape && *str == sep) + { + found_escape= 1; + } else + { *to++ = *str; - + found_escape= 0; + } } *to=0; lex->yytoklen=(uint) (to-start); From 1de817e9c467178b82690618223cf320d48a4b0b Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 8 Feb 2005 15:14:14 -0800 Subject: [PATCH 03/19] Fix removal of tables from cache when the database they are contained within is dropped and lower_case_table_names is set. (Bug #8355) mysql-test/t/lowercase_table2.test: Add new regression test mysql-test/r/lowercase_table2.result: Add results for regression test sql/mysql_priv.h: Change remove_db_from_cache() to use char* instead of my_string sql/sql_base.cc: Lowercase database name in remove_db_from_cache so that all of the correct entries are removed. --- mysql-test/r/lowercase_table2.result | 18 ++++++++++++++++++ mysql-test/t/lowercase_table2.test | 17 +++++++++++++++++ sql/mysql_priv.h | 2 +- sql/sql_base.cc | 12 +++++++++++- 4 files changed, 47 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/lowercase_table2.result b/mysql-test/r/lowercase_table2.result index a79b6b04063..8361b66817a 100644 --- a/mysql-test/r/lowercase_table2.result +++ b/mysql-test/r/lowercase_table2.result @@ -141,3 +141,21 @@ select * from T1; a b 1 abc drop table T1; +create database mysqltest_LC2; +use mysqltest_LC2; +create table myUC (i int); +insert into myUC values (1),(2),(3); +select * from myUC; +i +1 +2 +3 +use test; +drop database mysqltest_LC2; +create database mysqltest_LC2; +use mysqltest_LC2; +create table myUC (i int); +select * from myUC; +i +use test; +drop database mysqltest_LC2; diff --git a/mysql-test/t/lowercase_table2.test b/mysql-test/t/lowercase_table2.test index a766e39abab..eff5f2a99ec 100644 --- a/mysql-test/t/lowercase_table2.test +++ b/mysql-test/t/lowercase_table2.test @@ -111,3 +111,20 @@ select * from T1; alter table T1 add index (a); select * from T1; drop table T1; + +# +# Bug #8355: Tables not dropped from table cache on drop db +# +create database mysqltest_LC2; +use mysqltest_LC2; +create table myUC (i int); +insert into myUC values (1),(2),(3); +select * from myUC; +use test; +drop database mysqltest_LC2; +create database mysqltest_LC2; +use mysqltest_LC2; +create table myUC (i int); +select * from myUC; +use test; +drop database mysqltest_LC2; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 6218bc49f53..f851e36dcad 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -750,7 +750,7 @@ bool close_temporary_table(THD *thd, const char *db, const char *table_name); void close_temporary(TABLE *table, bool delete_table=1); bool rename_temporary_table(THD* thd, TABLE *table, const char *new_db, const char *table_name); -void remove_db_from_cache(const my_string db); +void remove_db_from_cache(const char *db); void flush_tables(); bool remove_table_from_cache(THD *thd, const char *db, const char *table, bool return_if_owned_by_thd=0); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index fe1f268e277..7ff5a02f05a 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2864,8 +2864,18 @@ static void mysql_rm_tmp_tables(void) ** and afterwards delete those marked unused. */ -void remove_db_from_cache(const my_string db) +void remove_db_from_cache(const char *db) { + char name_buff[NAME_LEN+1]; + if (db && lower_case_table_names) + { + /* + convert database to lower case for comparision. + */ + strmake(name_buff, db, sizeof(name_buff)-1); + my_casedn_str(files_charset_info, name_buff); + db= name_buff; + } for (uint idx=0 ; idx < open_cache.records ; idx++) { TABLE *table=(TABLE*) hash_element(&open_cache,idx); From ae14393e7487f3c8a97f3dc44cab7a2c19cdd0a9 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 9 Feb 2005 16:14:13 -0800 Subject: [PATCH 04/19] When escaping a string in a multi-byte character set, escape all bytes of a character that appears to be a multi-byte character based on its first byte, but is not actually a valid multi-byte character. (Bug #8378) tests/mysql_client_test.c: Add test for Bug #8317 mysys/charset.c: Properly escape invalid multibyte characters. --- mysys/charset.c | 20 ++++++++++++++++ tests/mysql_client_test.c | 49 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/mysys/charset.c b/mysys/charset.c index cb2379f8723..934125ead4a 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -581,6 +581,26 @@ ulong escape_string_for_mysql(CHARSET_INFO *charset_info, char *to, from--; continue; } + /* + If the next character appears to begin a multi-byte character, we + escape all of the bytes of that apparent character. (The character just + looks like a multi-byte character -- if it were actually a multi-byte + character, it would have been passed through in the test above.) + + Without this check, we can create a problem by converting an invalid + multi-byte character into a valid one. For example, 0xbf27 is not + a valid GBK character, but 0xbf5c is. (0x27 = ', 0x5c = \) + */ + if (use_mb_flag && (l= my_mbcharlen(charset_info, *from)) > 1) + { + while (l--) + { + *to++= '\\'; + *to++= *from++; + } + from--; + continue; + } #endif switch (*from) { case 0: /* Must be escaped for 'mysql' */ diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 83f8f6ab143..b7e3e1b3469 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -11532,6 +11532,54 @@ static void test_bug6761(void) myquery(rc); } +/* + Test mysql_real_escape_string() with gbk charset + + The important part is that 0x27 (') is the second-byte in a invvalid + two-byte GBK character here. But 0xbf5c is a valid GBK character, so + it needs to be escaped as 0x5cbf5c27 +*/ +#define TEST_BUG8317_IN "\xef\xbb\xbf\x27" +#define TEST_BUG8317_OUT "\xef\xbb\x5c\xbf\x5c\x27" + +static void test_bug8317() +{ + MYSQL *lmysql; + char out[9]; /* strlen(TEST_BUG8317)*2+1 */ + int len; + + myheader("test_bug8317"); + + if (!opt_silent) + fprintf(stdout, "\n Establishing a test connection ..."); + if (!(lmysql= mysql_init(NULL))) + { + myerror("mysql_init() failed"); + exit(1); + } + if (mysql_options(lmysql, MYSQL_SET_CHARSET_NAME, "gbk")) + { + myerror("mysql_options() failed"); + exit(1); + } + if (!(mysql_real_connect(lmysql, opt_host, opt_user, + opt_password, current_db, opt_port, + opt_unix_socket, 0))) + { + myerror("connection failed"); + exit(1); + } + if (!opt_silent) + fprintf(stdout, " OK"); + + len= mysql_real_escape_string(lmysql, out, TEST_BUG8317_IN, 4); + + /* No escaping should have actually happened. */ + DIE_UNLESS(memcmp(out, TEST_BUG8317_OUT, len) == 0); + + mysql_close(lmysql); +} + /* Read and parse arguments and MySQL options from my.cnf */ @@ -11739,6 +11787,7 @@ static struct my_tests_st my_tests[]= { { "test_conversion", test_conversion }, { "test_rewind", test_rewind }, { "test_bug6761", test_bug6761 }, + { "test_bug8317", test_bug8317 }, { 0, 0 } }; From 2a9b8f589ee332908065a4750e9363afd0bc4b22 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 10 Feb 2005 20:25:14 -0800 Subject: [PATCH 05/19] Fix all of the enum and set columns in privilege tables to be case-insensitive. (Bug #7989) mysql-test/r/system_mysql_db.result: Update results scripts/mysql_create_system_tables.sh: Need to create enum and set columns with case-insensitive collation scripts/mysql_fix_privilege_tables.sql: Modify all enum and set columns to be case-insensitive (and re-order some of the fix-ups to make it all happen smoothly). --- mysql-test/r/system_mysql_db.result | 100 +++++++------- scripts/mysql_create_system_tables.sh | 102 +++++++------- scripts/mysql_fix_privilege_tables.sql | 178 +++++++++++++++++-------- 3 files changed, 224 insertions(+), 156 deletions(-) diff --git a/mysql-test/r/system_mysql_db.result b/mysql-test/r/system_mysql_db.result index ebb24159373..141878a7bf6 100644 --- a/mysql-test/r/system_mysql_db.result +++ b/mysql-test/r/system_mysql_db.result @@ -21,18 +21,18 @@ db CREATE TABLE `db` ( `Host` char(60) collate utf8_bin NOT NULL default '', `Db` char(64) collate utf8_bin NOT NULL default '', `User` char(16) collate utf8_bin NOT NULL default '', - `Select_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Insert_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Update_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Delete_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Create_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Drop_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Grant_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `References_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Index_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Alter_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Create_tmp_table_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Lock_tables_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', + `Select_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Insert_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Update_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Delete_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Create_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Drop_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Grant_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `References_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Index_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Alter_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Create_tmp_table_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Lock_tables_priv` enum('N','Y') character set utf8 NOT NULL default 'N', PRIMARY KEY (`Host`,`Db`,`User`), KEY `User` (`User`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Database privileges' @@ -41,18 +41,18 @@ Table Create Table host CREATE TABLE `host` ( `Host` char(60) collate utf8_bin NOT NULL default '', `Db` char(64) collate utf8_bin NOT NULL default '', - `Select_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Insert_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Update_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Delete_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Create_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Drop_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Grant_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `References_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Index_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Alter_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Create_tmp_table_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Lock_tables_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', + `Select_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Insert_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Update_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Delete_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Create_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Drop_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Grant_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `References_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Index_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Alter_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Create_tmp_table_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Lock_tables_priv` enum('N','Y') character set utf8 NOT NULL default 'N', PRIMARY KEY (`Host`,`Db`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Host privileges; Merged with database privileges' show create table user; @@ -61,28 +61,28 @@ user CREATE TABLE `user` ( `Host` varchar(60) collate utf8_bin NOT NULL default '', `User` varchar(16) collate utf8_bin NOT NULL default '', `Password` varchar(41) collate utf8_bin NOT NULL default '', - `Select_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Insert_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Update_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Delete_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Create_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Drop_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Reload_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Shutdown_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Process_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `File_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Grant_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `References_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Index_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Alter_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Show_db_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Super_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Create_tmp_table_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Lock_tables_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Execute_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Repl_slave_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Repl_client_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `ssl_type` enum('','ANY','X509','SPECIFIED') collate utf8_bin NOT NULL default '', + `Select_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Insert_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Update_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Delete_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Create_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Drop_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Reload_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Shutdown_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Process_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `File_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Grant_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `References_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Index_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Alter_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Show_db_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Super_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Create_tmp_table_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Lock_tables_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Execute_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Repl_slave_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Repl_client_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `ssl_type` enum('','ANY','X509','SPECIFIED') character set utf8 NOT NULL default '', `ssl_cipher` blob NOT NULL, `x509_issuer` blob NOT NULL, `x509_subject` blob NOT NULL, @@ -97,7 +97,7 @@ func CREATE TABLE `func` ( `name` char(64) collate utf8_bin NOT NULL default '', `ret` tinyint(1) NOT NULL default '0', `dl` char(128) collate utf8_bin NOT NULL default '', - `type` enum('function','aggregate') collate utf8_bin NOT NULL default 'function', + `type` enum('function','aggregate') character set utf8 NOT NULL default 'function', PRIMARY KEY (`name`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='User defined functions' show create table tables_priv; @@ -109,8 +109,8 @@ tables_priv CREATE TABLE `tables_priv` ( `Table_name` char(64) collate utf8_bin NOT NULL default '', `Grantor` char(77) collate utf8_bin NOT NULL default '', `Timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, - `Table_priv` set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter') collate utf8_bin NOT NULL default '', - `Column_priv` set('Select','Insert','Update','References') collate utf8_bin NOT NULL default '', + `Table_priv` set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter') character set utf8 NOT NULL default '', + `Column_priv` set('Select','Insert','Update','References') character set utf8 NOT NULL default '', PRIMARY KEY (`Host`,`Db`,`User`,`Table_name`), KEY `Grantor` (`Grantor`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Table privileges' @@ -123,7 +123,7 @@ columns_priv CREATE TABLE `columns_priv` ( `Table_name` char(64) collate utf8_bin NOT NULL default '', `Column_name` char(64) collate utf8_bin NOT NULL default '', `Timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, - `Column_priv` set('Select','Insert','Update','References') collate utf8_bin NOT NULL default '', + `Column_priv` set('Select','Insert','Update','References') character set utf8 NOT NULL default '', PRIMARY KEY (`Host`,`Db`,`User`,`Table_name`,`Column_name`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Column privileges' show tables; diff --git a/scripts/mysql_create_system_tables.sh b/scripts/mysql_create_system_tables.sh index f524b322388..7f4a1105201 100644 --- a/scripts/mysql_create_system_tables.sh +++ b/scripts/mysql_create_system_tables.sh @@ -54,18 +54,18 @@ then c_d="$c_d Host char(60) binary DEFAULT '' NOT NULL," c_d="$c_d Db char(64) binary DEFAULT '' NOT NULL," c_d="$c_d User char(16) binary DEFAULT '' NOT NULL," - c_d="$c_d Select_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_d="$c_d Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_d="$c_d Update_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_d="$c_d Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_d="$c_d Create_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_d="$c_d Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_d="$c_d Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_d="$c_d References_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_d="$c_d Index_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_d="$c_d Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_d="$c_d Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_d="$c_d Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL," + c_d="$c_d Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_d="$c_d Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_d="$c_d Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_d="$c_d Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_d="$c_d Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_d="$c_d Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_d="$c_d Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_d="$c_d References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_d="$c_d Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_d="$c_d Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_d="$c_d Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_d="$c_d Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," c_d="$c_d PRIMARY KEY Host (Host,Db,User)," c_d="$c_d KEY User (User)" c_d="$c_d ) engine=MyISAM" @@ -85,18 +85,18 @@ then c_h="$c_h CREATE TABLE host (" c_h="$c_h Host char(60) binary DEFAULT '' NOT NULL," c_h="$c_h Db char(64) binary DEFAULT '' NOT NULL," - c_h="$c_h Select_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_h="$c_h Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_h="$c_h Update_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_h="$c_h Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_h="$c_h Create_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_h="$c_h Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_h="$c_h Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_h="$c_h References_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_h="$c_h Index_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_h="$c_h Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_h="$c_h Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_h="$c_h Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL," + c_h="$c_h Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_h="$c_h Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_h="$c_h Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_h="$c_h Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_h="$c_h Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_h="$c_h Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_h="$c_h Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_h="$c_h References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_h="$c_h Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_h="$c_h Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_h="$c_h Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_h="$c_h Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," c_h="$c_h PRIMARY KEY Host (Host,Db)" c_h="$c_h ) engine=MyISAM" c_h="$c_h CHARACTER SET utf8 COLLATE utf8_bin" @@ -113,28 +113,28 @@ then c_u="$c_u Host char(60) binary DEFAULT '' NOT NULL," c_u="$c_u User char(16) binary DEFAULT '' NOT NULL," c_u="$c_u Password char(41) binary DEFAULT '' NOT NULL," - c_u="$c_u Select_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_u="$c_u Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_u="$c_u Update_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_u="$c_u Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_u="$c_u Create_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_u="$c_u Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_u="$c_u Reload_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_u="$c_u Shutdown_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_u="$c_u Process_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_u="$c_u File_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_u="$c_u Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_u="$c_u References_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_u="$c_u Index_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_u="$c_u Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_u="$c_u Show_db_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_u="$c_u Super_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_u="$c_u Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_u="$c_u Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_u="$c_u Execute_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_u="$c_u Repl_slave_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_u="$c_u Repl_client_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_u="$c_u ssl_type enum('','ANY','X509', 'SPECIFIED') DEFAULT '' NOT NULL," + c_u="$c_u Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_u="$c_u Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_u="$c_u Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_u="$c_u Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_u="$c_u Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_u="$c_u Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_u="$c_u Reload_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_u="$c_u Shutdown_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_u="$c_u Process_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_u="$c_u File_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_u="$c_u Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_u="$c_u References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_u="$c_u Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_u="$c_u Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_u="$c_u Show_db_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_u="$c_u Super_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_u="$c_u Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_u="$c_u Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_u="$c_u Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_u="$c_u Repl_slave_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_u="$c_u Repl_client_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_u="$c_u ssl_type enum('','ANY','X509', 'SPECIFIED') COLLATE utf8_general_ci DEFAULT '' NOT NULL," c_u="$c_u ssl_cipher BLOB NOT NULL," c_u="$c_u x509_issuer BLOB NOT NULL," c_u="$c_u x509_subject BLOB NOT NULL," @@ -180,7 +180,7 @@ then c_f="$c_f name char(64) binary DEFAULT '' NOT NULL," c_f="$c_f ret tinyint(1) DEFAULT '0' NOT NULL," c_f="$c_f dl char(128) DEFAULT '' NOT NULL," - c_f="$c_f type enum ('function','aggregate') NOT NULL," + c_f="$c_f type enum ('function','aggregate') COLLATE utf8_general_ci NOT NULL," c_f="$c_f PRIMARY KEY (name)" c_f="$c_f ) engine=MyISAM" c_f="$c_f CHARACTER SET utf8 COLLATE utf8_bin" @@ -200,8 +200,8 @@ then c_t="$c_t Table_name char(64) binary DEFAULT '' NOT NULL," c_t="$c_t Grantor char(77) DEFAULT '' NOT NULL," c_t="$c_t Timestamp timestamp(14)," - c_t="$c_t Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter') DEFAULT '' NOT NULL," - c_t="$c_t Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL," + c_t="$c_t Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter') COLLATE utf8_general_ci DEFAULT '' NOT NULL," + c_t="$c_t Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL," c_t="$c_t PRIMARY KEY (Host,Db,User,Table_name)," c_t="$c_t KEY Grantor (Grantor)" c_t="$c_t ) engine=MyISAM" @@ -222,7 +222,7 @@ then c_c="$c_c Table_name char(64) binary DEFAULT '' NOT NULL," c_c="$c_c Column_name char(64) binary DEFAULT '' NOT NULL," c_c="$c_c Timestamp timestamp(14)," - c_c="$c_c Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL," + c_c="$c_c Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL," c_c="$c_c PRIMARY KEY (Host,Db,User,Table_name,Column_name)" c_c="$c_c ) engine=MyISAM" c_c="$c_c CHARACTER SET utf8 COLLATE utf8_bin" @@ -330,7 +330,7 @@ then c_tz="$c_tz CREATE TABLE time_zone (" c_tz="$c_tz Time_zone_id int unsigned NOT NULL auto_increment," - c_tz="$c_tz Use_leap_seconds enum('Y','N') DEFAULT 'N' NOT NULL," + c_tz="$c_tz Use_leap_seconds enum('Y','N') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," c_tz="$c_tz PRIMARY KEY TzId (Time_zone_id)" c_tz="$c_tz ) engine=MyISAM CHARACTER SET utf8" c_tz="$c_tz comment='Time zones';" diff --git a/scripts/mysql_fix_privilege_tables.sql b/scripts/mysql_fix_privilege_tables.sql index 536b263f7bd..8f398689bd9 100644 --- a/scripts/mysql_fix_privilege_tables.sql +++ b/scripts/mysql_fix_privilege_tables.sql @@ -9,54 +9,23 @@ -- this sql script. -- On windows you should do 'mysql --force mysql < mysql_fix_privilege_tables.sql' --- Convert all tables to UTF-8 with binary collation --- and reset all char columns to correct width -ALTER TABLE user - MODIFY Host char(60) NOT NULL default '', - MODIFY User char(16) NOT NULL default '', - MODIFY Password char(41) NOT NULL default '', - ENGINE=MyISAM, CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; -ALTER TABLE db - MODIFY Host char(60) NOT NULL default '', - MODIFY Db char(64) NOT NULL default '', - MODIFY User char(16) NOT NULL default '', - ENGINE=MyISAM, CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; -ALTER TABLE host - MODIFY Host char(60) NOT NULL default '', - MODIFY Db char(64) NOT NULL default '', - ENGINE=MyISAM, CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; -ALTER TABLE func - ENGINE=MyISAM, CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; -ALTER TABLE columns_priv - MODIFY Host char(60) NOT NULL default '', - MODIFY Db char(64) NOT NULL default '', - MODIFY User char(16) NOT NULL default '', - MODIFY Table_name char(64) NOT NULL default '', - MODIFY Column_name char(64) NOT NULL default '', - ENGINE=MyISAM, CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; -ALTER TABLE tables_priv - MODIFY Host char(60) NOT NULL default '', - MODIFY Db char(64) NOT NULL default '', - MODIFY User char(16) NOT NULL default '', - MODIFY Table_name char(64) NOT NULL default '', - MODIFY Grantor char(77) NOT NULL default '', - ENGINE=MyISAM, CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; -ALTER TABLE user add File_priv enum('N','Y') NOT NULL; CREATE TABLE IF NOT EXISTS func ( name char(64) binary DEFAULT '' NOT NULL, ret tinyint(1) DEFAULT '0' NOT NULL, dl char(128) DEFAULT '' NOT NULL, - type enum ('function','aggregate') NOT NULL, + type enum ('function','aggregate') COLLATE utf8_general_ci NOT NULL, PRIMARY KEY (name) ) CHARACTER SET utf8 COLLATE utf8_bin; +ALTER TABLE user add File_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL; + -- Detect whether or not we had the Grant_priv column SET @hadGrantPriv:=0; SELECT @hadGrantPriv:=1 FROM user WHERE Grant_priv LIKE '%'; -ALTER TABLE user add Grant_priv enum('N','Y') NOT NULL,add References_priv enum('N','Y') NOT NULL,add Index_priv enum('N','Y') NOT NULL,add Alter_priv enum('N','Y') NOT NULL; -ALTER TABLE host add Grant_priv enum('N','Y') NOT NULL,add References_priv enum('N','Y') NOT NULL,add Index_priv enum('N','Y') NOT NULL,add Alter_priv enum('N','Y') NOT NULL; -ALTER TABLE db add Grant_priv enum('N','Y') NOT NULL,add References_priv enum('N','Y') NOT NULL,add Index_priv enum('N','Y') NOT NULL,add Alter_priv enum('N','Y') NOT NULL; +ALTER TABLE user add Grant_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add References_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add Index_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add Alter_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL; +ALTER TABLE host add Grant_priv enum('N','Y') NOT NULL,add References_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add Index_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add Alter_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL; +ALTER TABLE db add Grant_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add References_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add Index_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add Alter_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL; --- Fix privileges for old tables UPDATE user SET Grant_priv=File_priv,References_priv=Create_priv,Index_priv=Create_priv,Alter_priv=Create_priv WHERE @hadGrantPriv = 0; @@ -68,7 +37,7 @@ UPDATE host SET References_priv=Create_priv,Index_priv=Create_priv,Alter_priv=Cr -- Adding columns needed by GRANT .. REQUIRE (openssl)" ALTER TABLE user -ADD ssl_type enum('','ANY','X509', 'SPECIFIED') NOT NULL, +ADD ssl_type enum('','ANY','X509', 'SPECIFIED') COLLATE utf8_general_ci NOT NULL, ADD ssl_cipher BLOB NOT NULL, ADD x509_issuer BLOB NOT NULL, ADD x509_subject BLOB NOT NULL; @@ -85,10 +54,14 @@ CREATE TABLE IF NOT EXISTS tables_priv ( Table_name char(64) binary DEFAULT '' NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Timestamp timestamp(14), - Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter') DEFAULT '' NOT NULL, - Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL, + Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter') COLLATE utf8_general_ci DEFAULT '' NOT NULL, + Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name) ) CHARACTER SET utf8 COLLATE utf8_bin; +-- Fix collation of set fields +ALTER TABLE tables_priv + modify Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter') COLLATE utf8_general_ci DEFAULT '' NOT NULL, + modify Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL; CREATE TABLE IF NOT EXISTS columns_priv ( Host char(60) DEFAULT '' NOT NULL, @@ -97,22 +70,25 @@ CREATE TABLE IF NOT EXISTS columns_priv ( Table_name char(60) DEFAULT '' NOT NULL, Column_name char(59) DEFAULT '' NOT NULL, Timestamp timestamp(14), - Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL, + Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name,Column_name) ) CHARACTER SET utf8 COLLATE utf8_bin; +-- Fix collation of set fields +ALTER TABLE columns_priv + MODIFY Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL; -- -- Name change of Type -> Column_priv from MySQL 3.22.12 -- -ALTER TABLE columns_priv change Type Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL; +ALTER TABLE columns_priv change Type Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL; -- -- Add the new 'type' column to the func table. -- -ALTER TABLE func add type enum ('function','aggregate') NOT NULL; +ALTER TABLE func add type enum ('function','aggregate') COLLATE utf8_general_ci NOT NULL; -- -- Change the user,db and host tables to MySQL 4.0 format @@ -123,13 +99,13 @@ SET @hadShowDbPriv:=0; SELECT @hadShowDbPriv:=1 FROM user WHERE Show_db_priv LIKE '%'; ALTER TABLE user -ADD Show_db_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Alter_priv, -ADD Super_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Show_db_priv, -ADD Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Super_priv, -ADD Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Create_tmp_table_priv, -ADD Execute_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Lock_tables_priv, -ADD Repl_slave_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Execute_priv, -ADD Repl_client_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Repl_slave_priv; +ADD Show_db_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Alter_priv, +ADD Super_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Show_db_priv, +ADD Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Super_priv, +ADD Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Create_tmp_table_priv, +ADD Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Lock_tables_priv, +ADD Repl_slave_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Execute_priv, +ADD Repl_client_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Repl_slave_priv; -- Convert privileges so that users have similar privileges as before @@ -150,11 +126,11 @@ ADD max_connections int(11) unsigned NOT NULL AFTER max_updates; -- ALTER TABLE db -ADD Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, -ADD Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL; +ADD Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, +ADD Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; ALTER TABLE host -ADD Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, -ADD Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL; +ADD Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, +ADD Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; alter table db change Db Db char(64) binary DEFAULT '' NOT NULL; alter table host change Db Db char(64) binary DEFAULT '' NOT NULL; @@ -170,6 +146,95 @@ alter table func comment='User defined functions'; alter table tables_priv comment='Table privileges'; alter table columns_priv comment='Column privileges'; +-- Convert all tables to UTF-8 with binary collation +-- and reset all char columns to correct width +ALTER TABLE user + MODIFY Host char(60) NOT NULL default '', + MODIFY User char(16) NOT NULL default '', + MODIFY Password char(41) NOT NULL default '', + ENGINE=MyISAM, CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; +ALTER TABLE user + MODIFY Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Reload_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Shutdown_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Process_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY File_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Show_db_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Super_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Repl_slave_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Repl_client_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY ssl_type enum('','ANY','X509', 'SPECIFIED') COLLATE utf8_general_ci DEFAULT '' NOT NULL; +ALTER TABLE db + MODIFY Host char(60) NOT NULL default '', + MODIFY Db char(64) NOT NULL default '', + MODIFY User char(16) NOT NULL default '', + ENGINE=MyISAM, CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; +ALTER TABLE db + MODIFY Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; +ALTER TABLE host + MODIFY Host char(60) NOT NULL default '', + MODIFY Db char(64) NOT NULL default '', + ENGINE=MyISAM, CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; +ALTER TABLE host + MODIFY Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + MODIFY Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; +ALTER TABLE func + ENGINE=MyISAM, CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; +ALTER TABLE func + MODIFY type enum ('function','aggregate') COLLATE utf8_general_ci NOT NULL; +ALTER TABLE columns_priv + MODIFY Host char(60) NOT NULL default '', + MODIFY Db char(64) NOT NULL default '', + MODIFY User char(16) NOT NULL default '', + MODIFY Table_name char(64) NOT NULL default '', + MODIFY Column_name char(64) NOT NULL default '', + ENGINE=MyISAM, CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; +ALTER TABLE columns_priv + MODIFY Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL; +ALTER TABLE tables_priv + MODIFY Host char(60) NOT NULL default '', + MODIFY Db char(64) NOT NULL default '', + MODIFY User char(16) NOT NULL default '', + MODIFY Table_name char(64) NOT NULL default '', + MODIFY Grantor char(77) NOT NULL default '', + ENGINE=MyISAM, CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; +ALTER TABLE tables_priv + MODIFY Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter') COLLATE utf8_general_ci DEFAULT '' NOT NULL, + MODIFY Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL; + # # Create some possible missing tables # @@ -217,9 +282,12 @@ PRIMARY KEY Name (Name) CREATE TABLE IF NOT EXISTS time_zone ( Time_zone_id int unsigned NOT NULL auto_increment, -Use_leap_seconds enum('Y','N') DEFAULT 'N' NOT NULL, +Use_leap_seconds enum('Y','N') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, PRIMARY KEY TzId (Time_zone_id) ) CHARACTER SET utf8 comment='Time zones'; +-- Make enum field case-insensitive +ALTER TABLE time_zone + MODIFY Use_leap_seconds enum('Y','N') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; CREATE TABLE IF NOT EXISTS time_zone_transition ( Time_zone_id int unsigned NOT NULL, From ddcb947ff73d89233093fb696212a8f788c952df Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 14 Feb 2005 20:33:14 -0800 Subject: [PATCH 06/19] Allow hostnames that are IP addresses with a netmask even when running with --skip-name-resolve. (Bug #8471) sql/sql_acl.cc: Add '/' to list of characters that doesn't trigger a need for resolving the hostname, so that the IP mask syntax works with skip-name-resolve. --- mysql-test/r/skip_name_resolve.result | 7 +++++++ mysql-test/t/skip_name_resolve-master.opt | 1 + mysql-test/t/skip_name_resolve.test | 5 +++++ sql/sql_acl.cc | 2 +- 4 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 mysql-test/r/skip_name_resolve.result create mode 100644 mysql-test/t/skip_name_resolve-master.opt create mode 100644 mysql-test/t/skip_name_resolve.test diff --git a/mysql-test/r/skip_name_resolve.result b/mysql-test/r/skip_name_resolve.result new file mode 100644 index 00000000000..d8d873699a5 --- /dev/null +++ b/mysql-test/r/skip_name_resolve.result @@ -0,0 +1,7 @@ +GRANT ALL ON test.* TO mysqltest_1@'127.0.0.1/255.255.255.255'; +SHOW GRANTS FOR mysqltest_1@'127.0.0.1/255.255.255.255'; +Grants for mysqltest_1@127.0.0.1/255.255.255.255 +GRANT USAGE ON *.* TO 'mysqltest_1'@'127.0.0.1/255.255.255.255' +GRANT ALL PRIVILEGES ON `test`.* TO 'mysqltest_1'@'127.0.0.1/255.255.255.255' +REVOKE ALL ON test.* FROM mysqltest_1@'127.0.0.1/255.255.255.255'; +DROP USER mysqltest_1@'127.0.0.1/255.255.255.255'; diff --git a/mysql-test/t/skip_name_resolve-master.opt b/mysql-test/t/skip_name_resolve-master.opt new file mode 100644 index 00000000000..ab6ca1731f5 --- /dev/null +++ b/mysql-test/t/skip_name_resolve-master.opt @@ -0,0 +1 @@ +--skip-name-resolve diff --git a/mysql-test/t/skip_name_resolve.test b/mysql-test/t/skip_name_resolve.test new file mode 100644 index 00000000000..68dcf329427 --- /dev/null +++ b/mysql-test/t/skip_name_resolve.test @@ -0,0 +1,5 @@ +# Bug #8471: IP address with mask fail when skip-name-resolve is on +GRANT ALL ON test.* TO mysqltest_1@'127.0.0.1/255.255.255.255'; +SHOW GRANTS FOR mysqltest_1@'127.0.0.1/255.255.255.255'; +REVOKE ALL ON test.* FROM mysqltest_1@'127.0.0.1/255.255.255.255'; +DROP USER mysqltest_1@'127.0.0.1/255.255.255.255'; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 7c17a4ef275..f437a432921 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1339,7 +1339,7 @@ bool hostname_requires_resolving(const char *hostname) return FALSE; for (; (cur=*hostname); hostname++) { - if ((cur != '%') && (cur != '_') && (cur != '.') && + if ((cur != '%') && (cur != '_') && (cur != '.') && (cur != '/') && ((cur < '0') || (cur > '9'))) return TRUE; } From 9dad64a129a18e8b9d64edcd5947e9eba88f3c41 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 15 Feb 2005 11:31:01 -0800 Subject: [PATCH 07/19] Only escape the first character in a sequence of bytes that appears to be a multibyte character, but was not a valid multibyte character. Refinement of fix for Bug #8378. tests/mysql_client_test.c: Fix test (and fix number) for Bug #8378 mysys/charset.c: Fix to only escape the first character in a sequence that appears to be a multibyte character, but was not a valid one. --- mysys/charset.c | 15 ++++++--------- tests/mysql_client_test.c | 20 ++++++++++---------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/mysys/charset.c b/mysys/charset.c index 934125ead4a..5587a6d685f 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -583,9 +583,10 @@ ulong escape_string_for_mysql(CHARSET_INFO *charset_info, char *to, } /* If the next character appears to begin a multi-byte character, we - escape all of the bytes of that apparent character. (The character just - looks like a multi-byte character -- if it were actually a multi-byte - character, it would have been passed through in the test above.) + escape that first byte of that apparent multi-byte character. (The + character just looks like a multi-byte character -- if it were actually + a multi-byte character, it would have been passed through in the test + above.) Without this check, we can create a problem by converting an invalid multi-byte character into a valid one. For example, 0xbf27 is not @@ -593,12 +594,8 @@ ulong escape_string_for_mysql(CHARSET_INFO *charset_info, char *to, */ if (use_mb_flag && (l= my_mbcharlen(charset_info, *from)) > 1) { - while (l--) - { - *to++= '\\'; - *to++= *from++; - } - from--; + *to++= '\\'; + *to++= *from; continue; } #endif diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index b7e3e1b3469..7886e0c1884 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -11535,20 +11535,20 @@ static void test_bug6761(void) /* Test mysql_real_escape_string() with gbk charset - The important part is that 0x27 (') is the second-byte in a invvalid + The important part is that 0x27 (') is the second-byte in a invalid two-byte GBK character here. But 0xbf5c is a valid GBK character, so - it needs to be escaped as 0x5cbf5c27 + it needs to be escaped as 0x5cbf27 */ -#define TEST_BUG8317_IN "\xef\xbb\xbf\x27" -#define TEST_BUG8317_OUT "\xef\xbb\x5c\xbf\x5c\x27" +#define TEST_BUG8378_IN "\xef\xbb\xbf\x27\xbf\x10" +#define TEST_BUG8378_OUT "\xef\xbb\x5c\xbf\x5c\x27\x5c\xbf\x10" -static void test_bug8317() +static void test_bug8378() { MYSQL *lmysql; - char out[9]; /* strlen(TEST_BUG8317)*2+1 */ + char out[9]; /* strlen(TEST_BUG8378)*2+1 */ int len; - myheader("test_bug8317"); + myheader("test_bug8378"); if (!opt_silent) fprintf(stdout, "\n Establishing a test connection ..."); @@ -11572,10 +11572,10 @@ static void test_bug8317() if (!opt_silent) fprintf(stdout, " OK"); - len= mysql_real_escape_string(lmysql, out, TEST_BUG8317_IN, 4); + len= mysql_real_escape_string(lmysql, out, TEST_BUG8378_IN, 4); /* No escaping should have actually happened. */ - DIE_UNLESS(memcmp(out, TEST_BUG8317_OUT, len) == 0); + DIE_UNLESS(memcmp(out, TEST_BUG8378_OUT, len) == 0); mysql_close(lmysql); } @@ -11787,7 +11787,7 @@ static struct my_tests_st my_tests[]= { { "test_conversion", test_conversion }, { "test_rewind", test_rewind }, { "test_bug6761", test_bug6761 }, - { "test_bug8317", test_bug8317 }, + { "test_bug8378", test_bug8378 }, { 0, 0 } }; From 2d2d4df7d28bc1826858b69d93a60cad76fe80d3 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 15 Feb 2005 13:36:46 -0800 Subject: [PATCH 08/19] Always lowercase database names from 'host' and 'db' grant tables when they are loaded and lower_case_table_names is set, but issue a warning when it is done. (Bug #7989) sql/sql_acl.cc: Lowercase database names in 'host' and 'db' grant tables when loading, but issue a warning to the log about them. --- mysql-test/r/lowercase_table_grant.result | 23 ++++++++++++ mysql-test/t/lowercase_table_grant-master.opt | 1 + mysql-test/t/lowercase_table_grant.test | 25 +++++++++++++ sql/sql_acl.cc | 37 +++++++++++++++++++ 4 files changed, 86 insertions(+) create mode 100644 mysql-test/r/lowercase_table_grant.result create mode 100644 mysql-test/t/lowercase_table_grant-master.opt create mode 100644 mysql-test/t/lowercase_table_grant.test diff --git a/mysql-test/r/lowercase_table_grant.result b/mysql-test/r/lowercase_table_grant.result new file mode 100644 index 00000000000..3889bd418db --- /dev/null +++ b/mysql-test/r/lowercase_table_grant.result @@ -0,0 +1,23 @@ +use mysql; +create database MYSQLtest; +grant all on MySQLtest.* to mysqltest_1@localhost; +show grants for mysqltest_1@localhost; +Grants for mysqltest_1@localhost +GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' +GRANT ALL PRIVILEGES ON `mysqltest`.* TO 'mysqltest_1'@'localhost' +select * from db where user = 'mysqltest_1'; +Host Db User Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Grant_priv References_priv Index_priv Alter_priv Create_tmp_table_priv Lock_tables_priv +localhost mysqltest mysqltest_1 Y Y Y Y Y Y N Y Y Y Y Y +update db set db = 'MYSQLtest' where db = 'mysqltest' and user = 'mysqltest_1' and host = 'localhost'; +flush privileges; +show grants for mysqltest_1@localhost; +Grants for mysqltest_1@localhost +GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' +GRANT ALL PRIVILEGES ON `mysqltest`.* TO 'mysqltest_1'@'localhost' +select * from db where user = 'mysqltest_1'; +Host Db User Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Grant_priv References_priv Index_priv Alter_priv Create_tmp_table_priv Lock_tables_priv +localhost MYSQLtest mysqltest_1 Y Y Y Y Y Y N Y Y Y Y Y +delete from db where db = 'MYSQLtest' and user = 'mysqltest_1' and host = 'localhost'; +flush privileges; +drop user mysqltest_1@localhost; +drop database MYSQLtest; diff --git a/mysql-test/t/lowercase_table_grant-master.opt b/mysql-test/t/lowercase_table_grant-master.opt new file mode 100644 index 00000000000..c718e2feb1b --- /dev/null +++ b/mysql-test/t/lowercase_table_grant-master.opt @@ -0,0 +1 @@ +--lower_case_table_names diff --git a/mysql-test/t/lowercase_table_grant.test b/mysql-test/t/lowercase_table_grant.test new file mode 100644 index 00000000000..5ac35c81c21 --- /dev/null +++ b/mysql-test/t/lowercase_table_grant.test @@ -0,0 +1,25 @@ +# Test of grants when lower_case_table_names is on +use mysql; + +# mixed-case database name for testing +create database MYSQLtest; + +# check that database name gets forced to lowercase +grant all on MySQLtest.* to mysqltest_1@localhost; +show grants for mysqltest_1@localhost; + +# now force it to mixed case, but see that it is lowercased in the acl cache +select * from db where user = 'mysqltest_1'; +update db set db = 'MYSQLtest' where db = 'mysqltest' and user = 'mysqltest_1' and host = 'localhost'; +flush privileges; +show grants for mysqltest_1@localhost; +select * from db where user = 'mysqltest_1'; + +# clear out the user we created +# +# can't use REVOKE because of the mixed-case database name +delete from db where db = 'MYSQLtest' and user = 'mysqltest_1' and host = 'localhost'; +flush privileges; +drop user mysqltest_1@localhost; + +drop database MYSQLtest; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 7c17a4ef275..92d6f471a1e 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -139,6 +139,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) MYSQL_LOCK *lock; my_bool return_val=1; bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE; + char tmp_name[NAME_LEN+1]; DBUG_ENTER("acl_init"); @@ -197,6 +198,24 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) ACL_HOST host; update_hostname(&host.host,get_field(&mem, table->field[0])); host.db= get_field(&mem, table->field[1]); + if (lower_case_table_names) + { + /* + We make a temporary copy of the database, force it to lower case, + and then copy it back over the original name. We can't just update + the host.db pointer, because tmp_name is allocated on the stack. + */ + (void)strmov(tmp_name, host.db); + my_casedn_str(files_charset_info, tmp_name); + if (strcmp(host.db, tmp_name) != 0) + { + sql_print_warning("'host' entry '%s|%s' had database in mixed " + "case that has been forced to lowercase because " + "lower_case_table_names is set.", + host.host.hostname, host.db); + (void)strmov(host.db, tmp_name); + } + } host.access= get_access(table,2); host.access= fix_rights_for_db(host.access); host.sort= get_sort(2,host.host.hostname,host.db); @@ -380,6 +399,24 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) } db.access=get_access(table,3); db.access=fix_rights_for_db(db.access); + if (lower_case_table_names) + { + /* + We make a temporary copy of the database, force it to lower case, + and then copy it back over the original name. We can't just update + the db.db pointer, because tmp_name is allocated on the stack. + */ + (void)strmov(tmp_name, db.db); + my_casedn_str(files_charset_info, tmp_name); + if (strcmp(db.db, tmp_name) != 0) + { + sql_print_warning("'db' entry '%s %s@%s' had database in mixed " + "case that has been forced to lowercase because " + "lower_case_table_names is set.", + db.db, db.user, db.host.hostname, db.host.hostname); + (void)strmov(db.db, tmp_name); + } + } db.sort=get_sort(3,db.host.hostname,db.db,db.user); #ifndef TO_BE_REMOVED if (table->fields <= 9) From 7770f8f9614b9d0950e0f9f1da3fb4500fb3f29a Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 16 Feb 2005 14:03:16 -0800 Subject: [PATCH 09/19] Make post-commit trigger not send emails when the message would not contain any actual changes. (Often the case in merges where the only change involves renumbering ChangeSet entries.) BitKeeper/triggers/post-commit: Suppress emails when there's no changes actually reported --- BitKeeper/triggers/post-commit | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/BitKeeper/triggers/post-commit b/BitKeeper/triggers/post-commit index a38b1f5a068..d2a4f9153b2 100755 --- a/BitKeeper/triggers/post-commit +++ b/BitKeeper/triggers/post-commit @@ -19,6 +19,13 @@ BK_STATUS=$BK_STATUS$BK_COMMIT if [ "$BK_STATUS" = OK ] then +HAS_ACTUAL_CHANGES=`bk cset -r+ -d | grep -v "^#"` +if [ "$HAS_ACTUAL_CHANGES" = "" ] +then + echo ChangeSet had no real changes, not sending emails + exit +fi + CHANGESET=`bk -R prs -r+ -h -d':P:::I:' ChangeSet` BUG=`bk -R prs -r+ -h -d':C:' ChangeSet | sed -ne 's/^.*[Bb][Uu][Gg] *# *\([0-9][0-9]*\).*$/\1/p'` From 6078fcc1f05bb159928a1e09bacbbc57b3ae07cf Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 17 Feb 2005 01:33:59 +0000 Subject: [PATCH 10/19] Bug#8147 Fix ambigious table error for INSERT..SELECT..UPDATE mysql-test/r/insert_update.result: Bug#8147 Alter test for bug mysql-test/t/insert_update.test: Bug#8147 Alter test for bug sql/sql_parse.cc: Bug#8147 Change order of code - skip insert table before calling mysql_prepare_insert() --- mysql-test/r/insert_update.result | 6 +++--- mysql-test/t/insert_update.test | 7 ++++--- sql/sql_parse.cc | 22 ++++++++++++++-------- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/mysql-test/r/insert_update.result b/mysql-test/r/insert_update.result index 753dc2cd749..ff7ec1ba73f 100644 --- a/mysql-test/r/insert_update.result +++ b/mysql-test/r/insert_update.result @@ -140,10 +140,10 @@ a b c 5 6 130 TRUNCATE TABLE t1; INSERT t1 VALUES (1,2,10), (3,4,20); -CREATE TABLE t2 (x INT, y INT, z INT, d INT); +CREATE TABLE t2 (a INT, b INT, c INT, d INT); INSERT t2 VALUES (5,6,30,1), (7,4,40,1), (8,9,60,1); INSERT t2 VALUES (2,1,11,2), (7,4,40,2); -INSERT t1 SELECT x,y,z FROM t2 WHERE d=1 ON DUPLICATE KEY UPDATE c=c+100; +INSERT t1 SELECT a,b,c FROM t2 WHERE d=1 ON DUPLICATE KEY UPDATE c=c+100; SELECT * FROM t1; a b c 1 2 10 @@ -157,7 +157,7 @@ a b c 3 4 120 5 0 30 8 9 60 -INSERT t1 SELECT x,y,z FROM t2 WHERE d=2 ON DUPLICATE KEY UPDATE c=c+VALUES(a); +INSERT t1 SELECT a,b,c FROM t2 WHERE d=2 ON DUPLICATE KEY UPDATE c=c+VALUES(a); SELECT *, VALUES(a) FROM t1; a b c VALUES(a) 1 2 10 NULL diff --git a/mysql-test/t/insert_update.test b/mysql-test/t/insert_update.test index 182baa641da..188de8a5379 100644 --- a/mysql-test/t/insert_update.test +++ b/mysql-test/t/insert_update.test @@ -68,14 +68,15 @@ INSERT t1 SELECT 1,9,70 FROM DUAL ON DUPLICATE KEY UPDATE c=c+100000, b=4; SELECT * FROM t1; TRUNCATE TABLE t1; INSERT t1 VALUES (1,2,10), (3,4,20); -CREATE TABLE t2 (x INT, y INT, z INT, d INT); +CREATE TABLE t2 (a INT, b INT, c INT, d INT); +# column names deliberately clash with columns in t1 (Bug#8147) INSERT t2 VALUES (5,6,30,1), (7,4,40,1), (8,9,60,1); INSERT t2 VALUES (2,1,11,2), (7,4,40,2); -INSERT t1 SELECT x,y,z FROM t2 WHERE d=1 ON DUPLICATE KEY UPDATE c=c+100; +INSERT t1 SELECT a,b,c FROM t2 WHERE d=1 ON DUPLICATE KEY UPDATE c=c+100; SELECT * FROM t1; INSERT t1 SET a=5 ON DUPLICATE KEY UPDATE b=0; SELECT * FROM t1; -INSERT t1 SELECT x,y,z FROM t2 WHERE d=2 ON DUPLICATE KEY UPDATE c=c+VALUES(a); +INSERT t1 SELECT a,b,c FROM t2 WHERE d=2 ON DUPLICATE KEY UPDATE c=c+VALUES(a); SELECT *, VALUES(a) FROM t1; DROP TABLE t1; DROP TABLE t2; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e66eeb279d2..329c29b9b75 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2768,18 +2768,23 @@ unsent_create_error: select_lex->options |= OPTION_BUFFER_RESULT; } - if (!(res= open_and_lock_tables(thd, tables)) && - !(res= mysql_prepare_insert(thd, tables, first_local_table, - tables->table, lex->field_list, 0, + if ((res= open_and_lock_tables(thd, tables))) + break; + + TABLE *table= tables->table; + /* Skip first table, which is the table we are inserting in */ + tables= (TABLE_LIST *) + lex->select_lex.table_list.first= (byte*) first_local_table->next; + first_local_table->next= 0; + + if (!(res= mysql_prepare_insert(thd, tables, first_local_table, + table, lex->field_list, 0, lex->update_list, lex->value_list, lex->duplicates)) && - (result= new select_insert(tables->table, &lex->field_list, + (result= new select_insert(table, &lex->field_list, &lex->update_list, &lex->value_list, lex->duplicates, lex->ignore))) { - TABLE *table= tables->table; - /* Skip first table, which is the table we are inserting in */ - lex->select_lex.table_list.first= (byte*) first_local_table->next; /* insert/replace from SELECT give its SELECT_LEX for SELECT, and item_list belong to SELECT @@ -2787,7 +2792,6 @@ unsent_create_error: lex->select_lex.resolve_mode= SELECT_LEX::SELECT_MODE; res= handle_select(thd, lex, result); /* revert changes for SP */ - lex->select_lex.table_list.first= (byte*) first_local_table; lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE; delete result; table->insert_values= 0; @@ -2796,6 +2800,8 @@ unsent_create_error: } else res= -1; + first_local_table->next= tables; + lex->select_lex.table_list.first= (byte*) first_local_table; break; } case SQLCOM_TRUNCATE: From 23f786b0ad106282387de0e0d82fec4f30037008 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 17 Feb 2005 15:04:04 +0400 Subject: [PATCH 11/19] bug#6958 Fixed that negative arguments to certain integer options wrap around. mysql-test/r/variables.result: Added a test case for bug#6958. mysql-test/t/variables.test: Added a test case for bug#6958. sql/set_var.cc: sys_var_long_ptr::check function was added. sql/set_var.h: Use sys_var_long_ptr::check function for sys_var_long_ptr class. --- mysql-test/r/variables.result | 5 +++++ mysql-test/t/variables.test | 8 ++++++++ sql/set_var.cc | 6 ++++++ sql/set_var.h | 1 + 4 files changed, 20 insertions(+) diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 6b700f7f6a2..633f7c139fd 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -482,3 +482,8 @@ SET GLOBAL MYISAM_DATA_POINTER_SIZE= 8; SHOW VARIABLES LIKE 'MYISAM_DATA_POINTER_SIZE'; Variable_name Value myisam_data_pointer_size 8 +SET GLOBAL table_cache=-1; +SHOW VARIABLES LIKE 'table_cache'; +Variable_name Value +table_cache 1 +SET GLOBAL table_cache=DEFAULT; diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index 3a76ae5136e..f80ca6378a1 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -362,3 +362,11 @@ drop table t1; SET GLOBAL MYISAM_DATA_POINTER_SIZE= 8; SHOW VARIABLES LIKE 'MYISAM_DATA_POINTER_SIZE'; + +# +# Bug #6958: negative arguments to integer options wrap around +# + +SET GLOBAL table_cache=-1; +SHOW VARIABLES LIKE 'table_cache'; +SET GLOBAL table_cache=DEFAULT; diff --git a/sql/set_var.cc b/sql/set_var.cc index ca7987d2636..7f393363ed6 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -1223,6 +1223,12 @@ static void fix_server_id(THD *thd, enum_var_type type) server_id_supplied = 1; } +bool sys_var_long_ptr::check(THD *thd, set_var *var) +{ + longlong v= var->value->val_int(); + var->save_result.ulonglong_value= v < 0 ? 0 : v; + return 0; +} bool sys_var_long_ptr::update(THD *thd, set_var *var) { diff --git a/sql/set_var.h b/sql/set_var.h index df2fd41c7bd..080a2a95ae0 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -93,6 +93,7 @@ public: sys_var_long_ptr(const char *name_arg, ulong *value_ptr, sys_after_update_func func) :sys_var(name_arg,func), value(value_ptr) {} + bool check(THD *thd, set_var *var); bool update(THD *thd, set_var *var); void set_default(THD *thd, enum_var_type type); SHOW_TYPE type() { return SHOW_LONG; } From 6075463f0342c0bf178c40dd7f9ecdeb7d5c8235 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 17 Feb 2005 17:15:29 +0200 Subject: [PATCH 12/19] InnoDB: Make CREATE TABLE return error when the minimum row length exceeds the maximum record size. (Bug #5682) innobase/data/data0type.c: Remove function dtype_str_needs_mysql_cmp(). Document dtype_get_at_most_n_mbchars(). dtype_get_at_most_n_mbchars(): Use mbminlen and mbmaxlen. innobase/dict/dict0crea.c: dict_build_table_def_step(): Reject if minimum row size is too big. innobase/include/data0type.h: Remove dtype_str_needs_mysql_cmp(). Document dtype_get_at_most_n_mbchars(). Add dtype_get_min_size(). innobase/include/data0type.ic: Add dtype_get_min_size(). innobase/include/row0mysql.h: row_mysql_store_col_in_innobase_format(): Add parameter comp, as we will only truncate UTF-8 CHAR(n) columns in row_format=compact. innobase/include/row0mysql.ic: row_mysql_store_col_in_innobase_format(): Add parameter comp, as we will only truncate UTF-8 CHAR(n) columns in row_format=compact. innobase/row/row0mysql.c: Pass parameter comp to row_mysql_store_col_in_innobase_format(). innobase/row/row0sel.c: Pass parameter comp to row_mysql_store_col_in_innobase_format(). row_sel_field_store_in_mysql_format(): Undo the stripping of UTF-8 CHAR(n) columns by padding with spaces. --- innobase/data/data0type.c | 49 ++++++++------------------ innobase/dict/dict0crea.c | 11 ++++++ innobase/include/data0type.h | 38 ++++++++++---------- innobase/include/data0type.ic | 65 +++++++++++++++++++++++++++++++---- innobase/include/row0mysql.h | 1 + innobase/include/row0mysql.ic | 32 +++++++++++++++++ innobase/row/row0mysql.c | 3 +- innobase/row/row0sel.c | 58 ++++++++++++++++++++----------- 8 files changed, 175 insertions(+), 82 deletions(-) diff --git a/innobase/data/data0type.c b/innobase/data/data0type.c index b8e4dd9c7f2..3fcd666b5a5 100644 --- a/innobase/data/data0type.c +++ b/innobase/data/data0type.c @@ -45,54 +45,33 @@ dtype_t dtype_binary_val = {DATA_BINARY, 0, 0, 0, 0, 0}; dtype_t* dtype_binary = &dtype_binary_val; /************************************************************************* -Checks if a string type has to be compared by the MySQL comparison functions. -InnoDB internally only handles binary byte string comparisons, as well as -latin1_swedish_ci strings. For example, UTF-8 strings have to be compared -by MySQL. */ - -ibool -dtype_str_needs_mysql_cmp( -/*======================*/ - /* out: TRUE if a string type that requires - comparison with MySQL functions */ - dtype_t* dtype) /* in: type struct */ -{ - if (dtype->mtype == DATA_MYSQL - || dtype->mtype == DATA_VARMYSQL - || (dtype->mtype == DATA_BLOB - && 0 == (dtype->prtype & DATA_BINARY_TYPE) - && dtype_get_charset_coll(dtype->prtype) != - data_mysql_latin1_swedish_charset_coll)) { - return(TRUE); - } - - return(FALSE); -} - -/************************************************************************* -For the documentation of this function, see innobase_get_at_most_n_mbchars() -in ha_innodb.cc. */ +Determine how many bytes the first n characters of the given string occupy. +If the string is shorter than n characters, returns the number of bytes +the characters in the string occupy. */ ulint dtype_get_at_most_n_mbchars( /*========================*/ - dtype_t* dtype, - ulint prefix_len, - ulint data_len, - const char* str) + /* out: length of the prefix, + in bytes */ + const dtype_t* dtype, /* in: data type */ + ulint prefix_len, /* in: length of the requested + prefix, in characters, multiplied by + dtype_get_mbmaxlen(dtype) */ + ulint data_len, /* in: length of str (in bytes) */ + const char* str) /* in: the string whose prefix + length is being determined */ { #ifndef UNIV_HOTBACKUP ut_a(data_len != UNIV_SQL_NULL); + ut_a(!(prefix_len % dtype->mbmaxlen)); - if (dtype_str_needs_mysql_cmp(dtype)) { + if (dtype->mbminlen != dtype->mbmaxlen) { return(innobase_get_at_most_n_mbchars( dtype_get_charset_coll(dtype->prtype), prefix_len, data_len, str)); } - /* We assume here that the string types that InnoDB itself can compare - are single-byte charsets! */ - if (prefix_len < data_len) { return(prefix_len); diff --git a/innobase/dict/dict0crea.c b/innobase/dict/dict0crea.c index b6f79ad10b4..4926797721c 100644 --- a/innobase/dict/dict0crea.c +++ b/innobase/dict/dict0crea.c @@ -220,6 +220,8 @@ dict_build_table_def_step( const char* path_or_name; ibool is_path; mtr_t mtr; + ulint i; + ulint row_len; #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex))); @@ -231,6 +233,15 @@ dict_build_table_def_step( thr_get_trx(thr)->table_id = table->id; + row_len = 0; + for (i = 0; i < table->n_def; i++) { + row_len += dtype_get_min_size(dict_col_get_type( + &table->cols[i])); + } + if (row_len > BTR_PAGE_MAX_REC_SIZE) { + return(DB_TOO_BIG_RECORD); + } + if (table->type == DICT_TABLE_CLUSTER_MEMBER) { cluster_table = dict_table_get_low(table->cluster_name); diff --git a/innobase/include/data0type.h b/innobase/include/data0type.h index 4c327d0b7ed..174665ca1fa 100644 --- a/innobase/include/data0type.h +++ b/innobase/include/data0type.h @@ -145,28 +145,22 @@ store the charset-collation number; one byte is left unused, though */ #define DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE 6 /************************************************************************* -Checks if a string type has to be compared by the MySQL comparison functions. -InnoDB internally only handles binary byte string comparisons, as well as -latin1_swedish_ci strings. For example, UTF-8 strings have to be compared -by MySQL. */ - -ibool -dtype_str_needs_mysql_cmp( -/*======================*/ - /* out: TRUE if a string type that requires - comparison with MySQL functions */ - dtype_t* dtype); /* in: type struct */ -/************************************************************************* -For the documentation of this function, see innobase_get_at_most_n_mbchars() -in ha_innodb.cc. */ +Determine how many bytes the first n characters of the given string occupy. +If the string is shorter than n characters, returns the number of bytes +the characters in the string occupy. */ ulint dtype_get_at_most_n_mbchars( /*========================*/ - dtype_t* dtype, - ulint prefix_len, - ulint data_len, - const char* str); + /* out: length of the prefix, + in bytes */ + const dtype_t* dtype, /* in: data type */ + ulint prefix_len, /* in: length of the requested + prefix, in characters, multiplied by + dtype_get_mbmaxlen(dtype) */ + ulint data_len, /* in: length of str (in bytes) */ + const char* str); /* in: the string whose prefix + length is being determined */ /************************************************************************* Checks if a data main type is a string type. Also a BLOB is considered a string type. */ @@ -306,6 +300,14 @@ dtype_get_fixed_size( /* out: fixed size, or 0 */ dtype_t* type); /* in: type */ /*************************************************************************** +Returns the minimum size of a data type. */ +UNIV_INLINE +ulint +dtype_get_min_size( +/*===============*/ + /* out: minimum size */ + const dtype_t* type); /* in: type */ +/*************************************************************************** Returns a stored SQL NULL size for a type. For fixed length types it is the fixed length of the type, otherwise 0. */ UNIV_INLINE diff --git a/innobase/include/data0type.ic b/innobase/include/data0type.ic index 761f7b3da7f..47f35bdce67 100644 --- a/innobase/include/data0type.ic +++ b/innobase/include/data0type.ic @@ -314,6 +314,7 @@ dtype_new_read_for_order_and_null_size( dtype_set_mblen(type); } +#ifndef UNIV_HOTBACKUP /*************************************************************************** Returns the size of a fixed size data type, 0 if not a fixed size type. */ UNIV_INLINE @@ -323,7 +324,6 @@ dtype_get_fixed_size( /* out: fixed size, or 0 */ dtype_t* type) /* in: type */ { -#ifndef UNIV_HOTBACKUP ulint mtype; mtype = dtype_get_mtype(type); @@ -401,14 +401,65 @@ dtype_get_fixed_size( } return(0); -#else /* UNIV_HOTBACKUP */ - /* This function depends on MySQL code that is not included in - InnoDB Hot Backup builds. Besides, this function should never - be called in InnoDB Hot Backup. */ - ut_error; -#endif /* UNIV_HOTBACKUP */ } +/*************************************************************************** +Returns the size of a fixed size data type, 0 if not a fixed size type. */ +UNIV_INLINE +ulint +dtype_get_min_size( +/*===============*/ + /* out: minimum size */ + const dtype_t* type) /* in: type */ +{ + switch (type->mtype) { + case DATA_SYS: +#ifdef UNIV_DEBUG + switch (type->prtype & DATA_MYSQL_TYPE_MASK) { + default: + ut_ad(0); + return(0); + case DATA_ROW_ID: + ut_ad(type->len == DATA_ROW_ID_LEN); + break; + case DATA_TRX_ID: + ut_ad(type->len == DATA_TRX_ID_LEN); + break; + case DATA_ROLL_PTR: + ut_ad(type->len == DATA_ROLL_PTR_LEN); + break; + case DATA_MIX_ID: + ut_ad(type->len == DATA_MIX_ID_LEN); + break; + } +#endif /* UNIV_DEBUG */ + case DATA_CHAR: + case DATA_FIXBINARY: + case DATA_INT: + case DATA_FLOAT: + case DATA_DOUBLE: + case DATA_MYSQL: + if ((type->prtype & DATA_BINARY_TYPE) + || type->mbminlen == type->mbmaxlen) { + return(type->len); + } + /* this is a variable-length character set */ + ut_a(type->mbminlen > 0); + ut_a(type->mbmaxlen > type->mbminlen); + return(type->len * type->mbminlen / type->mbmaxlen); + case DATA_VARCHAR: + case DATA_BINARY: + case DATA_DECIMAL: + case DATA_VARMYSQL: + case DATA_BLOB: + return(0); + default: ut_error; + } + + return(0); +} +#endif /* !UNIV_HOTBACKUP */ + /*************************************************************************** Returns a stored SQL NULL size for a type. For fixed length types it is the fixed length of the type, otherwise 0. */ diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h index 7ffa6ebf87d..48a9d9bc941 100644 --- a/innobase/include/row0mysql.h +++ b/innobase/include/row0mysql.h @@ -99,6 +99,7 @@ row_mysql_store_col_in_innobase_format( as dfield is used! */ ulint col_len, /* in: MySQL column length */ ulint type, /* in: data type */ + bool comp, /* in: TRUE=compact format */ ulint is_unsigned); /* in: != 0 if unsigned integer type */ /******************************************************************** Handles user errors and lock waits detected by the database engine. */ diff --git a/innobase/include/row0mysql.ic b/innobase/include/row0mysql.ic index 1f5d0b0c990..910546e298c 100644 --- a/innobase/include/row0mysql.ic +++ b/innobase/include/row0mysql.ic @@ -67,6 +67,7 @@ row_mysql_store_col_in_innobase_format( as dfield is used! */ ulint col_len, /* in: MySQL column length */ ulint type, /* in: data type */ + bool comp, /* in: TRUE=compact format */ ulint is_unsigned) /* in: != 0 if unsigned integer type */ { byte* ptr = mysql_data; @@ -113,6 +114,37 @@ row_mysql_store_col_in_innobase_format( col_len--; } } + } else if (comp && type == DATA_MYSQL + && dtype_get_mbminlen(dfield_get_type(dfield)) == 1 + && dtype_get_mbmaxlen(dfield_get_type(dfield)) > 1) { + /* We assume that this CHAR field is encoded in a + variable-length character set where spaces have + 1:1 correspondence to 0x20 bytes, such as UTF-8. + + Consider a CHAR(n) field, a field of n characters. + It will contain between n*mbminlen and n*mbmaxlen bytes. + We will try to truncate it to n bytes by stripping + space padding. If the field contains single-byte + characters only, it will be truncated to n characters. + Consider a CHAR(5) field containing the string ".a " + where "." denotes a 3-byte character represented by + the bytes "$%&". After our stripping, the string will + be stored as "$%&a " (5 bytes). The string ".abc " + will be stored as "$%&abc" (6 bytes). + + The space padding will be restored in row0sel.c, function + row_sel_field_store_in_mysql_format(). */ + + ulint n_chars; + dtype_t* dtype = dfield_get_type(dfield); + + ut_a(!(dtype_get_len(dtype) % dtype_get_mbmaxlen(dtype))); + n_chars = dtype_get_len(dtype) / dtype_get_mbmaxlen(dtype); + + /* Strip space padding. */ + while (col_len > n_chars && ptr[col_len - 1] == 0x20) { + col_len--; + } } else if (type == DATA_BLOB) { ptr = row_mysql_read_blob_ref(&col_len, mysql_data, col_len); } diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 0ec261e798f..39c4b76f814 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -238,7 +238,8 @@ row_mysql_convert_row_to_innobase( + templ->mysql_col_offset, mysql_rec + templ->mysql_col_offset, templ->mysql_col_len, - templ->type, templ->is_unsigned); + templ->type, prebuilt->table->comp, + templ->is_unsigned); next_column: ; } diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index c0141f896ce..84a160cfc0d 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -2137,6 +2137,7 @@ row_sel_convert_mysql_key_to_innobase( row_mysql_store_col_in_innobase_format( dfield, buf, key_ptr + data_offset, data_len, type, + index->table->comp, dfield_get_type(dfield)->prtype & DATA_UNSIGNED); buf += data_len; @@ -2232,17 +2233,15 @@ row_sel_field_store_in_mysql_format( are not in themselves stored here: the caller must allocate and copy the BLOB into buffer before, and pass the pointer to the BLOB in 'data' */ - ulint col_len,/* in: MySQL column length */ + const mysql_row_templ_t* templ, /* in: MySQL column template */ byte* data, /* in: data to store */ - ulint len, /* in: length of the data */ - ulint type, /* in: data type */ - ulint is_unsigned)/* in: != 0 if an unsigned integer type */ + ulint len) /* in: length of the data */ { byte* ptr; ut_ad(len != UNIV_SQL_NULL); - if (type == DATA_INT) { + if (templ->type == DATA_INT) { /* Convert integer data from Innobase to a little-endian format, sign bit restored to normal */ @@ -2257,31 +2256,47 @@ row_sel_field_store_in_mysql_format( data++; } - if (!is_unsigned) { + if (!templ->is_unsigned) { dest[len - 1] = (byte) (dest[len - 1] ^ 128); } - ut_ad(col_len == len); - } else if (type == DATA_VARCHAR || type == DATA_VARMYSQL - || type == DATA_BINARY) { + ut_ad(templ->mysql_col_len == len); + } else if (templ->type == DATA_VARCHAR || templ->type == DATA_VARMYSQL + || templ->type == DATA_BINARY) { /* Store the length of the data to the first two bytes of dest; does not do anything yet because MySQL has no real vars! */ dest = row_mysql_store_var_len(dest, len); ut_memcpy(dest, data, len); - - /* ut_ad(col_len >= len + 2); No real var implemented in - MySQL yet! */ +#if 0 + /* No real var implemented in MySQL yet! */ + ut_ad(templ->mysql_col_len >= len + 2); +#endif - } else if (type == DATA_BLOB) { + } else if (templ->type == DATA_BLOB) { /* Store a pointer to the BLOB buffer to dest: the BLOB was already copied to the buffer in row_sel_store_mysql_rec */ - row_mysql_store_blob_ref(dest, col_len, data, len); + row_mysql_store_blob_ref(dest, templ->mysql_col_len, + data, len); } else { - ut_memcpy(dest, data, len); - ut_ad(col_len == len); + memcpy(dest, data, len); + + ut_ad(templ->mysql_col_len >= len); + ut_ad(templ->mbmaxlen >= templ->mbminlen); + + ut_ad(templ->mbmaxlen > templ->mbminlen + || templ->mysql_col_len == len); + ut_ad(!templ->mbmaxlen + || !(templ->mysql_col_len % templ->mbmaxlen)); + + if (templ->mbminlen != templ->mbmaxlen) { + /* Pad with spaces. This undoes the stripping + done in row0mysql.ic, function + row_mysql_store_col_in_innobase_format(). */ + memset(dest + len, 0x20, templ->mysql_col_len - len); + } } } @@ -2401,8 +2416,7 @@ row_sel_store_mysql_rec( row_sel_field_store_in_mysql_format( mysql_rec + templ->mysql_col_offset, - templ->mysql_col_len, data, len, - templ->type, templ->is_unsigned); + templ, data, len); if (templ->type == DATA_VARCHAR || templ->type == DATA_VARMYSQL @@ -2487,7 +2501,7 @@ row_sel_store_mysql_rec( len -= 2; } } else { - ut_ad(templ->mbminlen == 1); + ut_ad(!pad_char || templ->mbminlen == 1); memset(mysql_rec + templ->mysql_col_offset, pad_char, templ->mysql_col_len); } @@ -2855,9 +2869,11 @@ row_sel_push_cache_row_for_mysql( ut_ad(prebuilt->fetch_cache_first == 0); - ut_a(row_sel_store_mysql_rec( + if (!row_sel_store_mysql_rec( prebuilt->fetch_cache[prebuilt->n_fetch_cached], - prebuilt, rec, offsets)); + prebuilt, rec, offsets)) { + ut_error; + } prebuilt->n_fetch_cached++; } From d0dbd41a3bf8ba665689f85891267daed1c25787 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 17 Feb 2005 18:40:45 +0200 Subject: [PATCH 13/19] After review fixes (Bug #5682) innobase/include/data0type.ic: dtype_get_fixed_size(), dtype_get_min_size(): Do not check prtype, mbminlen and mbmaxlen for types other than DATA_MYSQL, as that is the only type that can hold fixed-length strings of variable-length objects (UTF-8 encoded characters). innobase/row/row0sel.c: row_sel_field_store_in_mysql_format(): Document which fields of templ will be used. Add 0x20 padding only to DATA_MYSQL fields. Change related debug assertions to real assertions for now, until 5.0 becomes generally available. Check with assertion that all data types handled in the catch-all branch are appropriate. --- innobase/include/data0type.ic | 3 +++ innobase/row/row0sel.c | 25 +++++++++++++++++++------ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/innobase/include/data0type.ic b/innobase/include/data0type.ic index 47f35bdce67..e63dde98974 100644 --- a/innobase/include/data0type.ic +++ b/innobase/include/data0type.ic @@ -354,6 +354,7 @@ dtype_get_fixed_size( case DATA_INT: case DATA_FLOAT: case DATA_DOUBLE: + return(dtype_get_len(type)); case DATA_MYSQL: if (type->prtype & DATA_BINARY_TYPE) { return(dtype_get_len(type)); @@ -438,6 +439,7 @@ dtype_get_min_size( case DATA_INT: case DATA_FLOAT: case DATA_DOUBLE: + return(type->len); case DATA_MYSQL: if ((type->prtype & DATA_BINARY_TYPE) || type->mbminlen == type->mbmaxlen) { @@ -446,6 +448,7 @@ dtype_get_min_size( /* this is a variable-length character set */ ut_a(type->mbminlen > 0); ut_a(type->mbmaxlen > type->mbminlen); + ut_a(type->len % type->mbmaxlen == 0); return(type->len * type->mbminlen / type->mbmaxlen); case DATA_VARCHAR: case DATA_BINARY: diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index 84a160cfc0d..22cece487a0 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -2233,7 +2233,9 @@ row_sel_field_store_in_mysql_format( are not in themselves stored here: the caller must allocate and copy the BLOB into buffer before, and pass the pointer to the BLOB in 'data' */ - const mysql_row_templ_t* templ, /* in: MySQL column template */ + const mysql_row_templ_t* templ, /* in: MySQL column template. + Its following fields are referenced: + type, is_unsigned, mysql_col_len, mbminlen, mbmaxlen */ byte* data, /* in: data to store */ ulint len) /* in: length of the data */ { @@ -2280,16 +2282,17 @@ row_sel_field_store_in_mysql_format( row_mysql_store_blob_ref(dest, templ->mysql_col_len, data, len); - } else { + } else if (templ->type == DATA_MYSQL) { memcpy(dest, data, len); - ut_ad(templ->mysql_col_len >= len); - ut_ad(templ->mbmaxlen >= templ->mbminlen); + ut_a(templ->mysql_col_len >= len); + ut_a(templ->mbmaxlen >= templ->mbminlen); - ut_ad(templ->mbmaxlen > templ->mbminlen + ut_a(templ->mbmaxlen > templ->mbminlen || templ->mysql_col_len == len); - ut_ad(!templ->mbmaxlen + ut_a(!templ->mbmaxlen || !(templ->mysql_col_len % templ->mbmaxlen)); + ut_a(len * templ->mbmaxlen >= templ->mysql_col_len); if (templ->mbminlen != templ->mbmaxlen) { /* Pad with spaces. This undoes the stripping @@ -2297,6 +2300,16 @@ row_sel_field_store_in_mysql_format( row_mysql_store_col_in_innobase_format(). */ memset(dest + len, 0x20, templ->mysql_col_len - len); } + } else { + ut_a(templ->type == DATA_CHAR + || templ->type == DATA_FIXBINARY + /*|| templ->type == DATA_SYS_CHILD + || templ->type == DATA_SYS*/ + || templ->type == DATA_FLOAT + || templ->type == DATA_DOUBLE + || templ->type == DATA_DECIMAL); + ut_ad(templ->mysql_col_len == len); + memcpy(dest, data, len); } } From 342a9f7f6f39dd797a76022ce39af9a790780540 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 17 Feb 2005 19:20:13 +0200 Subject: [PATCH 14/19] innodb.test, innodb.result: Remove the test show status like InnoDB_rows_read; the value on IA64 was 0.01 percent bigger than on x86; maybe some different optimization mysql-test/r/innodb.result: Remove the test show status like InnoDB_rows_read; the value on IA64 was 0.01 percent bigger than on x86; maybe some different optimization mysql-test/t/innodb.test: Remove the test show status like InnoDB_rows_read; the value on IA64 was 0.01 percent bigger than on x86; maybe some different optimization --- mysql-test/r/innodb.result | 3 --- mysql-test/t/innodb.test | 1 - 2 files changed, 4 deletions(-) diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 5928688ca81..83ae86cc709 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -1718,9 +1718,6 @@ Innodb_rows_deleted 2070 show status like "Innodb_rows_inserted"; Variable_name Value Innodb_rows_inserted 31708 -show status like "Innodb_rows_read"; -Variable_name Value -Innodb_rows_read 80162 show status like "Innodb_rows_updated"; Variable_name Value Innodb_rows_updated 29530 diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index da27fcfc734..b16f627f1b8 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -1221,7 +1221,6 @@ show status like "Innodb_buffer_pool_pages_total"; show status like "Innodb_page_size"; show status like "Innodb_rows_deleted"; show status like "Innodb_rows_inserted"; -show status like "Innodb_rows_read"; show status like "Innodb_rows_updated"; # Test for row locks InnoDB status variables. From 307c2140fd8caa1430323752608c1169e07926f4 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 17 Feb 2005 20:20:48 +0200 Subject: [PATCH 15/19] Fixed Bug#7873. --- support-files/mysql.server.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/support-files/mysql.server.sh b/support-files/mysql.server.sh index 849f913bf6c..892de3001d1 100644 --- a/support-files/mysql.server.sh +++ b/support-files/mysql.server.sh @@ -39,17 +39,20 @@ # If you want to affect other MySQL variables, you should make your changes # in the /etc/my.cnf, ~/.my.cnf or other MySQL configuration files. +# If you change base dir, you must also change datadir + basedir= +datadir= # The following variables are only set for letting mysql.server find things. # Set some defaults -datadir=@localstatedir@ pid_file= if test -z "$basedir" then basedir=@prefix@ bindir=@bindir@ + datadir=@localstatedir@ else bindir="$basedir/bin" fi From c36f737d54dfe4fac9870b3a7d50b8ba9f4d5147 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 17 Feb 2005 21:45:13 +0200 Subject: [PATCH 16/19] Fixed Bug#7783, "mysql_free_result removes all resultsets (multi statements)". --- sql-common/client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql-common/client.c b/sql-common/client.c index 9dcf6b3e32c..cca1452d710 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -752,7 +752,7 @@ static void cli_flush_use_result(MYSQL *mysql) { if (protocol_41(mysql)) { - char *pos= (char*) mysql->net.read_pos; + char *pos= (char*) mysql->net.read_pos + 1; mysql->warning_count=uint2korr(pos); pos+=2; mysql->server_status=uint2korr(pos); pos+=2; } From b1e6157d108a25c8c6cd66298d7a66d0949c08c0 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 17 Feb 2005 23:00:48 +0200 Subject: [PATCH 17/19] Fixed Bug#7838, "pipe_sig_handler should be static". --- libmysql/client_settings.h | 4 ++-- libmysql/libmysql.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libmysql/client_settings.h b/libmysql/client_settings.h index 375e75919a4..e0f093aa7c9 100644 --- a/libmysql/client_settings.h +++ b/libmysql/client_settings.h @@ -21,7 +21,7 @@ extern my_string mysql_unix_port; CLIENT_TRANSACTIONS | \ CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION) -sig_handler pipe_sig_handler(int sig); +sig_handler my_pipe_sig_handler(int sig); void read_user_name(char *name); my_bool handle_local_infile(MYSQL *mysql, const char *net_filename); @@ -32,7 +32,7 @@ my_bool handle_local_infile(MYSQL *mysql, const char *net_filename); #if !defined(__WIN__) && defined(SIGPIPE) && !defined(THREAD) #define init_sigpipe_variables sig_return old_signal_handler=(sig_return) 0; -#define set_sigpipe(mysql) if ((mysql)->client_flag & CLIENT_IGNORE_SIGPIPE) old_signal_handler=signal(SIGPIPE,pipe_sig_handler) +#define set_sigpipe(mysql) if ((mysql)->client_flag & CLIENT_IGNORE_SIGPIPE) old_signal_handler=signal(SIGPIPE, my_pipe_sig_handler) #define reset_sigpipe(mysql) if ((mysql)->client_flag & CLIENT_IGNORE_SIGPIPE) signal(SIGPIPE,old_signal_handler); #else #define init_sigpipe_variables diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 6baec95e633..1ef29210c0b 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -92,7 +92,7 @@ my_bool net_flush(NET *net); #define unsigned_field(A) ((A)->flags & UNSIGNED_FLAG) static void append_wild(char *to,char *end,const char *wild); -sig_handler pipe_sig_handler(int sig); +sig_handler my_pipe_sig_handler(int sig); static my_bool mysql_client_init= 0; static my_bool org_my_init_done= 0; @@ -294,11 +294,11 @@ mysql_debug(const char *debug __attribute__((unused))) **************************************************************************/ sig_handler -pipe_sig_handler(int sig __attribute__((unused))) +my_pipe_sig_handler(int sig __attribute__((unused))) { DBUG_PRINT("info",("Hit by signal %d",sig)); #ifdef DONT_REMEMBER_SIGNAL - (void) signal(SIGPIPE,pipe_sig_handler); + (void) signal(SIGPIPE, my_pipe_sig_handler); #endif } From b2dc546ef4abc9534eda1bff3d2e0463068b92ca Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 17 Feb 2005 22:32:21 +0100 Subject: [PATCH 18/19] Fix a compile error (missing return value). sql/item_func.h: Fix a compoile error (missing return value) as proposed by Tomas Ulin. --- sql/item_func.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/item_func.h b/sql/item_func.h index 20f70fce575..70ad1a0375f 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -348,7 +348,7 @@ class Item_func_div :public Item_num_op { public: Item_func_div(Item *a,Item *b) :Item_num_op(a,b) {} - longlong int_op() { DBUG_ASSERT(0); } + longlong int_op() { DBUG_ASSERT(0); return 0; } double real_op(); my_decimal *decimal_op(my_decimal *); const char *func_name() const { return "/"; } From e122a103e29e1525770edcc7a74d75549b9a3dd7 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 17 Feb 2005 18:07:14 -0800 Subject: [PATCH 19/19] Clean up merge from 4.1, including making several enum fields in the grant tables case-insensitive and updating test results. scripts/mysql_create_system_tables.sh: Fix collation of procs_priv.proc_priv scripts/mysql_fix_privilege_tables.sql: Fix enum fields to have case-insensitive collation mysql-test/r/information_schema.result: Update results mysql-test/r/system_mysql_db.result: Update results mysql-test/r/lowercase_table_grant.result: Update results --- mysql-test/r/information_schema.result | 2 +- mysql-test/r/lowercase_table_grant.result | 8 ++++---- mysql-test/r/system_mysql_db.result | 2 +- scripts/mysql_create_system_tables.sh | 2 +- scripts/mysql_fix_privilege_tables.sql | 22 +++++++++++----------- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index 87e6062d411..e8ec4f70139 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -125,7 +125,7 @@ Field Type Collation Null Key Default Extra Privileges Comment a int(11) NULL YES MUL NULL select,insert,update,references show full columns from mysql.db like "Insert%"; Field Type Collation Null Key Default Extra Privileges Comment -Insert_priv enum('N','Y') utf8_bin NO N select,insert,update,references +Insert_priv enum('N','Y') utf8_general_ci NO N select,insert,update,references show full columns from v1; Field Type Collation Null Key Default Extra Privileges Comment c varchar(64) utf8_general_ci NO select,insert,update,references diff --git a/mysql-test/r/lowercase_table_grant.result b/mysql-test/r/lowercase_table_grant.result index 3889bd418db..c3813d57074 100644 --- a/mysql-test/r/lowercase_table_grant.result +++ b/mysql-test/r/lowercase_table_grant.result @@ -6,8 +6,8 @@ Grants for mysqltest_1@localhost GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' GRANT ALL PRIVILEGES ON `mysqltest`.* TO 'mysqltest_1'@'localhost' select * from db where user = 'mysqltest_1'; -Host Db User Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Grant_priv References_priv Index_priv Alter_priv Create_tmp_table_priv Lock_tables_priv -localhost mysqltest mysqltest_1 Y Y Y Y Y Y N Y Y Y Y Y +Host Db User Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Grant_priv References_priv Index_priv Alter_priv Create_tmp_table_priv Lock_tables_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Execute_priv +localhost mysqltest mysqltest_1 Y Y Y Y Y Y N Y Y Y Y Y Y Y Y Y Y update db set db = 'MYSQLtest' where db = 'mysqltest' and user = 'mysqltest_1' and host = 'localhost'; flush privileges; show grants for mysqltest_1@localhost; @@ -15,8 +15,8 @@ Grants for mysqltest_1@localhost GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' GRANT ALL PRIVILEGES ON `mysqltest`.* TO 'mysqltest_1'@'localhost' select * from db where user = 'mysqltest_1'; -Host Db User Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Grant_priv References_priv Index_priv Alter_priv Create_tmp_table_priv Lock_tables_priv -localhost MYSQLtest mysqltest_1 Y Y Y Y Y Y N Y Y Y Y Y +Host Db User Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Grant_priv References_priv Index_priv Alter_priv Create_tmp_table_priv Lock_tables_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Execute_priv +localhost MYSQLtest mysqltest_1 Y Y Y Y Y Y N Y Y Y Y Y Y Y Y Y Y delete from db where db = 'MYSQLtest' and user = 'mysqltest_1' and host = 'localhost'; flush privileges; drop user mysqltest_1@localhost; diff --git a/mysql-test/r/system_mysql_db.result b/mysql-test/r/system_mysql_db.result index 57fac02b732..930acf68706 100644 --- a/mysql-test/r/system_mysql_db.result +++ b/mysql-test/r/system_mysql_db.result @@ -150,7 +150,7 @@ procs_priv CREATE TABLE `procs_priv` ( `Routine_name` char(64) collate utf8_bin NOT NULL default '', `Grantor` char(77) collate utf8_bin NOT NULL default '', `Timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, - `Proc_priv` set('Execute','Alter Routine','Grant') collate utf8_bin NOT NULL default '', + `Proc_priv` set('Execute','Alter Routine','Grant') character set utf8 NOT NULL default '', PRIMARY KEY (`Host`,`Db`,`User`,`Routine_name`), KEY `Grantor` (`Grantor`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Procedure privileges' diff --git a/scripts/mysql_create_system_tables.sh b/scripts/mysql_create_system_tables.sh index b7dab0d931b..ea4c85d7a2c 100644 --- a/scripts/mysql_create_system_tables.sh +++ b/scripts/mysql_create_system_tables.sh @@ -253,7 +253,7 @@ then c_pp="$c_pp Routine_name char(64) binary DEFAULT '' NOT NULL," c_pp="$c_pp Grantor char(77) DEFAULT '' NOT NULL," c_pp="$c_pp Timestamp timestamp(14)," - c_pp="$c_pp Proc_priv set('Execute','Alter Routine','Grant') DEFAULT '' NOT NULL," + c_pp="$c_pp Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL," c_pp="$c_pp PRIMARY KEY (Host,Db,User,Routine_name)," c_pp="$c_pp KEY Grantor (Grantor)" c_pp="$c_pp ) engine=MyISAM" diff --git a/scripts/mysql_fix_privilege_tables.sql b/scripts/mysql_fix_privilege_tables.sql index 918d37264e1..e8012ecc03a 100644 --- a/scripts/mysql_fix_privilege_tables.sql +++ b/scripts/mysql_fix_privilege_tables.sql @@ -243,16 +243,16 @@ SELECT @hadCreateViewPriv:=1 FROM user WHERE Create_view_priv LIKE '%'; # # Create VIEWs privileges (v5.0) # -ALTER TABLE db ADD Create_view_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Lock_tables_priv; -ALTER TABLE host ADD Create_view_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Lock_tables_priv; -ALTER TABLE user ADD Create_view_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Repl_client_priv; +ALTER TABLE db ADD Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Lock_tables_priv; +ALTER TABLE host ADD Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Lock_tables_priv; +ALTER TABLE user ADD Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Repl_client_priv; # # Show VIEWs privileges (v5.0) # -ALTER TABLE db ADD Show_view_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Create_view_priv; -ALTER TABLE host ADD Show_view_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Create_view_priv; -ALTER TABLE user ADD Show_view_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Create_view_priv; +ALTER TABLE db ADD Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Create_view_priv; +ALTER TABLE host ADD Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Create_view_priv; +ALTER TABLE user ADD Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Create_view_priv; # # Assign create/show view privileges to people who have create provileges @@ -268,16 +268,16 @@ SELECT @hadCreateRoutinePriv:=1 FROM user WHERE Create_routine_priv LIKE '%'; # # Create PROCEDUREs privileges (v5.0) # -ALTER TABLE db ADD Create_routine_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Show_view_priv; -ALTER TABLE user ADD Create_routine_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Show_view_priv; +ALTER TABLE db ADD Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Show_view_priv; +ALTER TABLE user ADD Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Show_view_priv; # # Alter PROCEDUREs privileges (v5.0) # -ALTER TABLE db ADD Alter_routine_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Create_routine_priv; -ALTER TABLE user ADD Alter_routine_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Create_routine_priv; +ALTER TABLE db ADD Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Create_routine_priv; +ALTER TABLE user ADD Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Create_routine_priv; -ALTER TABLE db ADD Execute_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Alter_routine_priv; +ALTER TABLE db ADD Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Alter_routine_priv; # # Assign create/alter routine privileges to people who have create privileges