From a247d3a3b7f0ec777a1b03b95f4a0971d1c8118b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 13 Oct 2005 12:28:43 -0700 Subject: [PATCH 1/5] Fix being able to set default TCP port for command-line utilities by using MYSQL_TCP_PORT variable. (Bug #5792) client/mysql.cc: Set default port to 0 so MYSQL_TCP_PORT is handled by mysql_server_init(). client/mysqladmin.cc: Set default port to 0 so MYSQL_TCP_PORT is handled by mysql_server_init(). client/mysqlbinlog.cc: Set default port to 0 so MYSQL_TCP_PORT is handled by mysql_server_init(). client/mysqlcheck.c: Set default port to 0 so MYSQL_TCP_PORT is handled by mysql_server_init(). client/mysqldump.c: Set default port to 0 so MYSQL_TCP_PORT is handled by mysql_server_init(). client/mysqlimport.c: Set default port to 0 so MYSQL_TCP_PORT is handled by mysql_server_init(). client/mysqlshow.c: Set default port to 0 so MYSQL_TCP_PORT is handled by mysql_server_init(). client/mysqltest.c: Set default port to 0 so MYSQL_TCP_PORT is handled by mysql_server_init(). --- client/mysql.cc | 2 +- client/mysqladmin.cc | 2 +- client/mysqlbinlog.cc | 4 ++-- client/mysqlcheck.c | 2 +- client/mysqldump.c | 2 +- client/mysqlimport.c | 2 +- client/mysqlshow.c | 2 +- client/mysqltest.c | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index d82d29a9a54..6b1ea869f39 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -610,7 +610,7 @@ static struct my_option my_long_options[] = NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"port", 'P', "Port number to use for connection.", (gptr*) &opt_mysql_port, - (gptr*) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0, + (gptr*) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"prompt", OPT_PROMPT, "Set the mysql prompt to this value.", (gptr*) ¤t_prompt, (gptr*) ¤t_prompt, 0, GET_STR_ALLOC, diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index da790bce375..dfd279b002f 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -161,7 +161,7 @@ static struct my_option my_long_options[] = NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"port", 'P', "Port number to use for connection.", (gptr*) &tcp_port, - (gptr*) &tcp_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0, 0}, + (gptr*) &tcp_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"relative", 'r', diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 802d5081ad6..09e648015a7 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -49,7 +49,7 @@ static const char* database= 0; static my_bool force_opt= 0, short_form= 0, remote_opt= 0; static ulonglong offset = 0; static const char* host = 0; -static int port = MYSQL_PORT; +static int port= 0; static const char* sock= 0; static const char* user = 0; static char* pass = 0; @@ -462,7 +462,7 @@ static struct my_option my_long_options[] = {"password", 'p', "Password to connect to remote server.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"port", 'P', "Use port to connect to the remote server.", - (gptr*) &port, (gptr*) &port, 0, GET_INT, REQUIRED_ARG, MYSQL_PORT, 0, 0, + (gptr*) &port, (gptr*) &port, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"position", 'j', "Deprecated. Use --start-position instead.", (gptr*) &start_position, (gptr*) &start_position, 0, GET_ULL, diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 2a2ae1311c9..ccca5aec85e 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -122,7 +122,7 @@ static struct my_option my_long_options[] = NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"port", 'P', "Port number to use for connection.", (gptr*) &opt_mysql_port, - (gptr*) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0, + (gptr*) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, diff --git a/client/mysqldump.c b/client/mysqldump.c index 3458f74d8a2..ed1c0a7519b 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -322,7 +322,7 @@ static struct my_option my_long_options[] = NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"port", 'P', "Port number to use for connection.", (gptr*) &opt_mysql_port, - (gptr*) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0, + (gptr*) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, diff --git a/client/mysqlimport.c b/client/mysqlimport.c index ca4acd82db6..a2e408b3982 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -121,7 +121,7 @@ static struct my_option my_long_options[] = NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"port", 'P', "Port number to use for connection.", (gptr*) &opt_mysql_port, - (gptr*) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0, + (gptr*) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, diff --git a/client/mysqlshow.c b/client/mysqlshow.c index 44fc9448782..bc304b2dc11 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -183,7 +183,7 @@ static struct my_option my_long_options[] = "Password to use when connecting to server. If password is not given it's asked from the tty.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"port", 'P', "Port number to use for connection.", (gptr*) &opt_mysql_port, - (gptr*) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0, + (gptr*) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #ifdef __WIN__ {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG, diff --git a/client/mysqltest.c b/client/mysqltest.c index 35408368a73..bd8a0a4fe65 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -2474,7 +2474,7 @@ static struct my_option my_long_options[] = {"password", 'p', "Password to use when connecting to server.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"port", 'P', "Port number to use for connection.", (gptr*) &port, - (gptr*) &port, 0, GET_INT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0, 0}, + (gptr*) &port, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"ps-protocol", OPT_PS_PROTOCOL, "Use prepared statements protocol for communication", (gptr*) &ps_protocol, (gptr*) &ps_protocol, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, From 72d19611d198164e1fcd2e16b270a11824d860bf Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 21 Nov 2005 17:26:31 +0400 Subject: [PATCH 2/5] Bug#10446 Illegal mix of collations: item_strfunc.h, item_strfunc.cc, item.cc: Try to convert a const item into destination character set. If conversion happens without data loss, then cache the converted value and return it during val_str(). Otherwise, if conversion loses data, return Illeral mix of collations error, as it happened previously. ctype_recoding.result, ctype_recoding.test: Fixing tests accordingly. sql/item.cc: Bug#10446 Illegal mix of collations Try to convert a const item into destination character set. If conversion happens without data loss, then cache the converted value and return it during val_str(). Otherwise, if conversion loses data, return Illeral mix of collations error, as it happened previously. sql/item_strfunc.cc: Return cached value when it's possible. mysql-test/t/ctype_recoding.test: Fixing tests accordingly. mysql-test/r/ctype_recoding.result: Fixing tests accordingly. --- mysql-test/r/ctype_recoding.result | 9 +++++++- mysql-test/t/ctype_recoding.test | 11 ++++++++-- sql/item.cc | 12 ++--------- sql/item_strfunc.cc | 2 ++ sql/item_strfunc.h | 34 ++++++++++++++++++++++++++++-- 5 files changed, 53 insertions(+), 15 deletions(-) diff --git a/mysql-test/r/ctype_recoding.result b/mysql-test/r/ctype_recoding.result index 1c75988fd21..0b5c6f8974c 100644 --- a/mysql-test/r/ctype_recoding.result +++ b/mysql-test/r/ctype_recoding.result @@ -181,11 +181,18 @@ select * from t1 where a=_koi8r' a вася select * from t1 where a=concat(_koi8r'вася'); -ERROR HY000: Illegal mix of collations (cp1251_general_ci,IMPLICIT) and (koi8r_general_ci,COERCIBLE) for operation '=' +a +вася select * from t1 where a=_latin1'вася'; ERROR HY000: Illegal mix of collations (cp1251_general_ci,IMPLICIT) and (latin1_swedish_ci,COERCIBLE) for operation '=' drop table t1; set names latin1; +create table t1 (a char(10) character set utf8 collate utf8_bin); +insert into t1 values (' xxx'); +select * from t1 where a=lpad('xxx',10,' '); +a + xxx +drop table t1; set names koi8r; create table t1 (c1 char(10) character set cp1251); insert into t1 values ('ъ'); diff --git a/mysql-test/t/ctype_recoding.test b/mysql-test/t/ctype_recoding.test index 9949ef88da4..5648cea7fd3 100644 --- a/mysql-test/t/ctype_recoding.test +++ b/mysql-test/t/ctype_recoding.test @@ -144,8 +144,7 @@ create table t1 (a char(10) character set cp1251); insert into t1 values (_koi8r'вася'); # this is possible: select * from t1 where a=_koi8r'вася'; -# this is not possible, because we have a function, not just a constant: ---error 1267 +# this is possible, because we have a function with constant arguments: select * from t1 where a=concat(_koi8r'вася'); # this is not posible, cannot convert _latin1'вася' into cp1251: --error 1267 @@ -153,6 +152,14 @@ select * from t1 where a=_latin1' drop table t1; set names latin1; +# +# Bug#10446 Illegal mix of collations +# +create table t1 (a char(10) character set utf8 collate utf8_bin); +insert into t1 values (' xxx'); +select * from t1 where a=lpad('xxx',10,' '); +drop table t1; + # # Check more automatic conversion # diff --git a/sql/item.cc b/sql/item.cc index 642a0ccf1b4..5acde7c082d 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -211,16 +211,8 @@ bool Item::eq(const Item *item, bool binary_cmp) const Item *Item::safe_charset_converter(CHARSET_INFO *tocs) { - /* - Allow conversion from and to "binary". - Don't allow automatic conversion to non-Unicode charsets, - as it potentially loses data. - */ - if (collation.collation != &my_charset_bin && - tocs != &my_charset_bin && - !(tocs->state & MY_CS_UNICODE)) - return NULL; // safe conversion is not possible - return new Item_func_conv_charset(this, tocs); + Item_func_conv_charset *conv= new Item_func_conv_charset(this, tocs, 1); + return conv->safe ? conv : NULL; } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 6ca6ce62c54..60cb3348590 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2252,6 +2252,8 @@ String *Item_func_conv::val_str(String *str) String *Item_func_conv_charset::val_str(String *str) { DBUG_ASSERT(fixed == 1); + if (use_cached_value) + return null_value ? 0 : &str_value; String *arg= args[0]->val_str(str); uint dummy_errors; if (!arg) diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 87aee9ac25c..c4505fce248 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -614,10 +614,40 @@ public: class Item_func_conv_charset :public Item_str_func { + bool use_cached_value; public: + bool safe; CHARSET_INFO *conv_charset; // keep it public - Item_func_conv_charset(Item *a, CHARSET_INFO *cs) :Item_str_func(a) - { conv_charset=cs; } + Item_func_conv_charset(Item *a, CHARSET_INFO *cs) :Item_str_func(a) + { conv_charset= cs; use_cached_value= 0; safe= 0; } + Item_func_conv_charset(Item *a, CHARSET_INFO *cs, bool cache_if_const) + :Item_str_func(a) + { + DBUG_ASSERT(args[0]->fixed); + conv_charset= cs; + if (cache_if_const && args[0]->const_item()) + { + uint errors= 0; + String tmp, *str= args[0]->val_str(&tmp); + if (!str || str_value.copy(str->ptr(), str->length(), + str->charset(), conv_charset, &errors)) + null_value= 1; + use_cached_value= 1; + safe= (errors == 0); + } + else + { + use_cached_value= 0; + /* + Conversion from and to "binary" is safe. + Conversion to Unicode is safe. + Other kind of conversions are potentially lossy. + */ + safe= (args[0]->collation.collation == &my_charset_bin || + cs == &my_charset_bin || + (cs->state & MY_CS_UNICODE)); + } + } String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "convert"; } From 0f64a6222edc0d0ded4e1b48fa428f8a7b44e67e Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 23 Nov 2005 14:57:26 -0800 Subject: [PATCH 3/5] Fix result of ROW_COUNT() after 'EXECUTE prepstmt'. (Bug #14956) mysql-test/r/ps.result: Add new results mysql-test/t/ps.test: Add new test sql/sql_parse.cc: Don't reset row_count after processing EXECUTE statement. --- mysql-test/r/ps.result | 7 +++++++ mysql-test/t/ps.test | 12 ++++++++++++ sql/sql_parse.cc | 12 ++++++++---- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index f1c3672083d..2ce2b5db431 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -806,3 +806,10 @@ execute stmt; @@tx_isolation REPEATABLE-READ deallocate prepare stmt; +create table t1 (id int); +prepare ins_call from "insert into t1 (id) values (1)"; +execute ins_call; +select row_count(); +row_count() +1 +drop table t1; diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 94ee2b1ca39..cfc49bbfd41 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -843,3 +843,15 @@ execute stmt; deallocate prepare stmt; # End of 4.1 tests + +# +# Bug #14956: ROW_COUNT() returns incorrect result after EXECUTE of prepared +# statement +# +create table t1 (id int); +prepare ins_call from "insert into t1 (id) values (1)"; +execute ins_call; +select row_count(); +drop table t1; + +# End of 5.0 tests diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index c19d54feda5..4f45451ddc4 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4822,11 +4822,15 @@ end_with_restore_list: /* - The return value for ROW_COUNT() is "implementation dependent" if - the statement is not DELETE, INSERT or UPDATE (or a CALL executing - such a statement), but -1 is what JDBC and ODBC wants. + The return value for ROW_COUNT() is "implementation dependent" if the + statement is not DELETE, INSERT or UPDATE, but -1 is what JDBC and ODBC + wants. + + We do not change the value for a CALL or EXECUTE statement, so the value + generated by the last called (or executed) statement is preserved. */ - if (lex->sql_command != SQLCOM_CALL && uc_update_queries[lex->sql_command]<2) + if (lex->sql_command != SQLCOM_CALL && lex->sql_command != SQLCOM_EXECUTE && + uc_update_queries[lex->sql_command]<2) thd->row_count_func= -1; goto cleanup; From 687b57be8d5e2ed0d69227f6285d4e0b804982dd Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 23 Nov 2005 17:05:59 -0800 Subject: [PATCH 4/5] Fix handling of maximum value for MAX_ROWS on 64-bit platforms. (Bug #14155) mysql-test/r/create.result: Add new results mysql-test/t/create.test: Add regression test sql/table.cc: To cap a value at 2^32-1 on a 64-bit platform, use UINT_MAX32, not ~(ulong)0, since a ulong may be 64-bit itself. --- mysql-test/r/create.result | 19 +++++++++++++++++++ mysql-test/t/create.test | 14 ++++++++++++++ sql/table.cc | 8 ++++---- 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index 6edd4cbc48f..80a3c2ea82d 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -621,3 +621,22 @@ create table if not exists t1 (a int); Warnings: Note 1050 Table 't1' already exists drop table t1; +create table t1 (i int) engine=myisam max_rows=100000000000; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 MAX_ROWS=4294967295 +alter table t1 max_rows=100; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 MAX_ROWS=100 +alter table t1 max_rows=100000000000; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 MAX_ROWS=4294967295 +drop table t1; diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index 73184853d1a..50a2e1a3cba 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -527,3 +527,17 @@ create table if not exists t1 (a int); drop table t1; # End of 4.1 tests + +# +# Bug #14155: Maximum value of MAX_ROWS handled incorrectly on 64-bit +# platforms +# +create table t1 (i int) engine=myisam max_rows=100000000000; +show create table t1; +alter table t1 max_rows=100; +show create table t1; +alter table t1 max_rows=100000000000; +show create table t1; +drop table t1; + +# End of 5.0 tests diff --git a/sql/table.cc b/sql/table.cc index 04d1a95cd9b..eb8cbf9b5e2 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1253,10 +1253,10 @@ File create_frm(register my_string name, const char *db, const char *table, #if SIZEOF_OFF_T > 4 /* Fix this when we have new .frm files; Current limit is 4G rows (QQ) */ - if (create_info->max_rows > ~(ulong) 0) - create_info->max_rows= ~(ulong) 0; - if (create_info->min_rows > ~(ulong) 0) - create_info->min_rows= ~(ulong) 0; + if (create_info->max_rows > UINT_MAX32) + create_info->max_rows= UINT_MAX32; + if (create_info->min_rows > UINT_MAX32) + create_info->min_rows= UINT_MAX32; #endif /* Ensure that raid_chunks can't be larger than 255, as this would cause From baff781ba45b7aac77a3efdcfc3bb8d5ef9e9135 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 28 Nov 2005 15:07:20 +0100 Subject: [PATCH 5/5] Minor Win32 compile fixes for 4.1.16 release. sql/log_event.cc: Add missing cast needed for Win32 compilation. include/config-win.h: Win32 compile fix: quote multi-line macros with do { ... } while(0) to follow earlier changes in my_global.h. --- include/config-win.h | 8 ++++---- sql/log_event.cc | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/config-win.h b/include/config-win.h index 9663947683e..e1972051e67 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -278,10 +278,10 @@ inline double ulonglong2double(ulonglong value) *((T)+4)=(uchar) (((A) >> 32)); } #define int8store(T,A) *((ulonglong *) (T))= (ulonglong) (A) -#define doubleget(V,M) { *((long *) &V) = *((long*) M); \ - *(((long *) &V)+1) = *(((long*) M)+1); } -#define doublestore(T,V) { *((long *) T) = *((long*) &V); \ - *(((long *) T)+1) = *(((long*) &V)+1); } +#define doubleget(V,M) do { *((long *) &V) = *((long*) M); \ + *(((long *) &V)+1) = *(((long*) M)+1); } while(0) +#define doublestore(T,V) do { *((long *) T) = *((long*) &V); \ + *(((long *) T)+1) = *(((long*) &V)+1); } while(0) #define float4get(V,M) { *((long *) &(V)) = *((long*) (M)); } #define floatget(V,M) memcpy((byte*) &V,(byte*) (M),sizeof(float)) #define floatstore(T,V) memcpy((byte*)(T), (byte*)(&V), sizeof(float)) diff --git a/sql/log_event.cc b/sql/log_event.cc index be4654bccd3..3f545df5776 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2035,7 +2035,7 @@ Rotate_log_event::Rotate_log_event(THD* thd_arg, llstr(pos_arg, buff), flags)); #endif if (flags & DUP_NAME) - new_log_ident= my_strdup_with_length(new_log_ident_arg, + new_log_ident= my_strdup_with_length((byte*) new_log_ident_arg, ident_len, MYF(MY_WME)); DBUG_VOID_RETURN;