diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index 53bf59af67a..8d2e040b21f 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 7eb26d30cf9..ae482a155d5 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -67,7 +67,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; @@ -688,7 +688,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 1324060eb55..2ad35098c33 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 5d3c542dc4d..cce5cf49d43 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -331,7 +331,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 958f987d16b..8694093f06b 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 8369d918d6f..504f0d9844b 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -188,7 +188,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 f6d28101fa0..ba1b92b31a3 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -2763,7 +2763,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}, diff --git a/include/config-win.h b/include/config-win.h index 5c2f8e00e86..edfb4ecc5c7 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -279,10 +279,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 floatstore(T,V) memcpy((byte*)(T), (byte*)(&V), sizeof(float)) #define floatget(V,M) memcpy((byte*)(&V), (byte*)(M), sizeof(float)) diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index a201af78518..c981d3092a7 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -743,3 +743,22 @@ t2 CREATE TABLE `t2` ( `a2` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1, t2; +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/r/ctype_recoding.result b/mysql-test/r/ctype_recoding.result index da0007fdfbe..1b92da2a7a3 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/r/ps.result b/mysql-test/r/ps.result index 742f68be445..994c375da83 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -825,3 +825,10 @@ execute stmt; drop table t1; set names default; 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/create.test b/mysql-test/t/create.test index 470a7bcbb59..6f3bc67cb30 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -631,3 +631,17 @@ show create table t2; drop table t1, t2; # 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/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/mysql-test/t/ps.test b/mysql-test/t/ps.test index 774424a8d55..22d0abf645e 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -871,3 +871,15 @@ set names default; 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/item.cc b/sql/item.cc index 848096e71dc..692f7b58928 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -601,16 +601,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 c33b7403b9c..8c0dea4efb2 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2316,6 +2316,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 522b17bf80e..50ec0b36ce8 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -652,10 +652,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"; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 57d7059dd8f..2e2a6f4d1b1 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4844,11 +4844,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; diff --git a/sql/table.cc b/sql/table.cc index c1704cbd2c9..1b0340a47fe 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1879,10 +1879,10 @@ File create_frm(THD *thd, const char *name, const char *db, #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