diff --git a/BitKeeper/triggers/post-commit b/BitKeeper/triggers/post-commit index 4e0135fa822..d19c724268c 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'` WL=`bk -R prs -r+ -h -d':C:' ChangeSet | sed -ne 's/^.*[Ww][Ll] *# *\([0-9][0-9]*\).*$/ WL#\1/p'` 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; 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..e63dde98974 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); @@ -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)); @@ -401,14 +402,67 @@ 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: + return(type->len); + 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); + ut_a(type->len % type->mbmaxlen == 0); + 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..22cece487a0 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,17 @@ 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. + 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 */ - 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 +2258,58 @@ 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 if (templ->type == DATA_MYSQL) { + memcpy(dest, data, len); + + ut_a(templ->mysql_col_len >= len); + ut_a(templ->mbmaxlen >= templ->mbminlen); + + ut_a(templ->mbmaxlen > templ->mbminlen + || templ->mysql_col_len == len); + 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 + done in row0mysql.ic, function + row_mysql_store_col_in_innobase_format(). */ + memset(dest + len, 0x20, templ->mysql_col_len - len); + } } else { - ut_memcpy(dest, data, len); - ut_ad(col_len == len); + 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); } } @@ -2401,8 +2429,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 +2514,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 +2882,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++; } 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 } 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/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/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/r/insert_update.result b/mysql-test/r/insert_update.result index 7027d7eff79..1817500973e 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/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/r/lowercase_table_grant.result b/mysql-test/r/lowercase_table_grant.result new file mode 100644 index 00000000000..c3813d57074 --- /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 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; +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 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; +drop database MYSQLtest; 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/r/system_mysql_db.result b/mysql-test/r/system_mysql_db.result index a012f300139..930acf68706 100644 --- a/mysql-test/r/system_mysql_db.result +++ b/mysql-test/r/system_mysql_db.result @@ -24,23 +24,23 @@ 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', - `Create_view_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Show_view_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Create_routine_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Alter_routine_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Execute_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', + `Create_view_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Show_view_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Create_routine_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Alter_routine_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Execute_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' @@ -49,20 +49,20 @@ 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', - `Create_view_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Show_view_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', + `Create_view_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Show_view_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; @@ -71,32 +71,32 @@ user CREATE TABLE `user` ( `Host` char(60) collate utf8_bin NOT NULL default '', `User` char(16) collate utf8_bin NOT NULL default '', `Password` char(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', - `Create_view_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Show_view_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Create_routine_priv` enum('N','Y') collate utf8_bin NOT NULL default 'N', - `Alter_routine_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', + `Create_view_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Show_view_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Create_routine_priv` enum('N','Y') character set utf8 NOT NULL default 'N', + `Alter_routine_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, @@ -112,7 +112,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; @@ -124,8 +124,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' @@ -138,7 +138,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 create table procs_priv; @@ -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/mysql-test/r/variables.result b/mysql-test/r/variables.result index 57b73a0515e..908709efba3 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -515,3 +515,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/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/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. 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/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/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/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/mysql-test/t/variables.test b/mysql-test/t/variables.test index 44a324de867..5310d50b7cb 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -380,3 +380,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/mysys/charset.c b/mysys/charset.c index cb2379f8723..5587a6d685f 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -581,6 +581,23 @@ 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 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 + a valid GBK character, but 0xbf5c is. (0x27 = ', 0x5c = \) + */ + if (use_mb_flag && (l= my_mbcharlen(charset_info, *from)) > 1) + { + *to++= '\\'; + *to++= *from; + continue; + } #endif switch (*from) { case 0: /* Must be escaped for 'mysql' */ diff --git a/scripts/mysql_create_system_tables.sh b/scripts/mysql_create_system_tables.sh index 40525cb20ce..ea4c85d7a2c 100644 --- a/scripts/mysql_create_system_tables.sh +++ b/scripts/mysql_create_system_tables.sh @@ -55,23 +55,23 @@ 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 Create_view_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_d="$c_d Show_view_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_d="$c_d Create_routine_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_d="$c_d Alter_routine_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_d="$c_d Execute_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 Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_d="$c_d Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_d="$c_d Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_d="$c_d Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_d="$c_d Execute_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" @@ -91,20 +91,20 @@ 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 Create_view_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_h="$c_h Show_view_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 Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_h="$c_h Show_view_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" @@ -121,32 +121,32 @@ 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 Create_view_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_u="$c_u Show_view_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_u="$c_u Create_routine_priv enum('N','Y') DEFAULT 'N' NOT NULL," - c_u="$c_u Alter_routine_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 Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_u="$c_u Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_u="$c_u Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL," + c_u="$c_u Alter_routine_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," @@ -191,7 +191,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" @@ -211,8 +211,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" @@ -233,7 +233,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" @@ -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" @@ -362,7 +362,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 9373a888bc2..e8012ecc03a 100644 --- a/scripts/mysql_fix_privilege_tables.sql +++ b/scripts/mysql_fix_privilege_tables.sql @@ -9,55 +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 procs_priv type=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; @@ -69,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; @@ -86,10 +54,17 @@ 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; +ALTER TABLE procs_priv type=MyISAM, CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; +ALTER TABLE procs_priv + modify Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL; CREATE TABLE IF NOT EXISTS columns_priv ( Host char(60) DEFAULT '' NOT NULL, @@ -98,22 +73,25 @@ CREATE TABLE IF NOT EXISTS columns_priv ( Table_name char(64) DEFAULT '' NOT NULL, Column_name char(64) 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 @@ -124,13 +102,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 @@ -151,11 +129,11 @@ ADD max_connections int(11) unsigned NOT NULL DEFAULT 0 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 user change max_questions max_questions int(11) unsigned DEFAULT 0 NOT NULL; alter table tables_priv add KEY Grantor (Grantor); @@ -167,6 +145,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; + # # Detect whether we had Create_view_priv # @@ -176,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 @@ -201,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 @@ -233,7 +300,7 @@ User char(16) binary DEFAULT '' NOT NULL, Routine_name char(64) binary DEFAULT '' NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Timestamp timestamp(14), -Proc_priv set('Execute','Alter Routine','Grant') DEFAULT '' NOT NULL, +Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Routine_name), KEY Grantor (Grantor) ) CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges'; @@ -282,9 +349,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, 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; } 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 "/"; } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 63b3d35434c..eea4def42ff 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -867,7 +867,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/set_var.cc b/sql/set_var.cc index 6fb44ae3ea3..cdee9e6d4d1 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -1309,6 +1309,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 3104fd38976..19cf63871ef 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -87,6 +87,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; } diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 71d042eda02..48d436069cb 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -141,6 +141,8 @@ 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"); if (!acl_cache) @@ -199,6 +201,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); @@ -409,6 +429,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->s->fields <= 9) @@ -1447,7 +1485,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; } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 83e3722072d..fcff6643271 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -3586,8 +3586,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); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index fa6f1e05dc6..b7e31dd126d 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -671,6 +671,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table, bool insert_into_view= (table_list->view != 0); /* TODO: use this condition for 'WITH CHECK OPTION' */ bool res; + TABLE_LIST *next_local; DBUG_ENTER("mysql_prepare_insert"); DBUG_PRINT("enter", ("table_list 0x%lx, table 0x%lx, view %d", (ulong)table_list, (ulong)table, @@ -687,6 +688,8 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table, select_insert)) DBUG_RETURN(TRUE); + next_local= table_list->next_local; + table_list->next_local= 0; if ((values && check_insert_fields(thd, table_list, fields, *values, 1, !insert_into_view)) || (values && setup_fields(thd, 0, table_list, *values, 0, 0, 0)) || @@ -697,6 +700,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table, res) || setup_fields(thd, 0, table_list, update_values, 1, 0, 0)))) DBUG_RETURN(TRUE); + table_list->next_local= next_local; if (!table) table= table_list->table; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 08cf4402b74..9d7b2183f52 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -296,7 +296,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) { @@ -324,6 +335,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 @@ -337,7 +352,8 @@ static char *get_text(LEX *lex) continue; } #endif - if (!(lex->thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) && + if (!found_escape && + !(lex->thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) && *str == '\\' && str+1 != end) { switch(*++str) { @@ -364,15 +380,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); 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 diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 0581679a845..1eb0151767d 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -12584,6 +12584,54 @@ static void test_bug7990() } +/* + Test mysql_real_escape_string() with gbk charset + + 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 0x5cbf27 +*/ +#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_bug8378() +{ + MYSQL *lmysql; + char out[9]; /* strlen(TEST_BUG8378)*2+1 */ + int len; + + myheader("test_bug8378"); + + 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_BUG8378_IN, 4); + + /* No escaping should have actually happened. */ + DIE_UNLESS(memcmp(out, TEST_BUG8378_OUT, len) == 0); + + mysql_close(lmysql); +} + /* Read and parse arguments and MySQL options from my.cnf */ @@ -12804,6 +12852,7 @@ static struct my_tests_st my_tests[]= { { "test_truncation_option", test_truncation_option }, { "test_bug8330", test_bug8330 }, { "test_bug7990", test_bug7990 }, + { "test_bug8378", test_bug8378 }, { 0, 0 } };