From 578fee6990e57877147c5a35ea70714630cbe5cf Mon Sep 17 00:00:00 2001 From: "iggy@mysql.com" <> Date: Tue, 27 Jun 2006 18:07:23 -0400 Subject: [PATCH 01/10] Bug#19298 mysqld_safe still uses obsolete --skip-locking parameter --- configure.in | 8 ++++---- scripts/mysqld_safe-watch.sh | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/configure.in b/configure.in index 7eadc5bd241..773ab7630bd 100644 --- a/configure.in +++ b/configure.in @@ -441,18 +441,18 @@ fi AC_SUBST(LD_VERSION_SCRIPT) # Avoid bug in fcntl on some versions of linux -AC_MSG_CHECKING("if we should use 'skip-locking' as default for $target_os") +AC_MSG_CHECKING([if we should use 'skip-external-locking' as default for $target_os]) # Any wariation of Linux if expr "$target_os" : "[[Ll]]inux.*" > /dev/null then - MYSQLD_DEFAULT_SWITCHES="--skip-locking" + MYSQLD_DEFAULT_SWITCHES="--skip-external-locking" TARGET_LINUX="true" - AC_MSG_RESULT("yes") + AC_MSG_RESULT([yes]) AC_DEFINE([TARGET_OS_LINUX], [1], [Whether we build for Linux]) else MYSQLD_DEFAULT_SWITCHES="" TARGET_LINUX="false" - AC_MSG_RESULT("no") + AC_MSG_RESULT([no]) fi AC_SUBST(MYSQLD_DEFAULT_SWITCHES) AC_SUBST(TARGET_LINUX) diff --git a/scripts/mysqld_safe-watch.sh b/scripts/mysqld_safe-watch.sh index c59b3b2614d..c837ba9a118 100644 --- a/scripts/mysqld_safe-watch.sh +++ b/scripts/mysqld_safe-watch.sh @@ -93,10 +93,10 @@ do if test "$#" -eq 0 then nohup $ledir/mysqld --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR \ - --skip-locking >> $err 2>&1 & + --skip-external-locking >> $err 2>&1 & else nohup $ledir/mysqld --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR \ - --skip-locking "$@" >> $err 2>&1 & + --skip-external-locking "$@" >> $err 2>&1 & fi pid=$! rm -f $lockfile From 8e2099295d09e74ecc8fbdfd98247deb90adfc58 Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Fri, 30 Jun 2006 02:25:35 +0300 Subject: [PATCH 02/10] Fixed include file usage hp_test2 now works again Fixed wrong cast, which caused problems with gcc 4.0 and floats in prepared statements (Bug #19694) --- heap/hp_test1.c | 3 ++- heap/hp_test2.c | 1 + include/my_global.h | 4 ++-- mysys/my_handler.c | 1 + strings/strtod.c | 4 ++-- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/heap/hp_test1.c b/heap/hp_test1.c index dd696528eb8..1efa97842c7 100644 --- a/heap/hp_test1.c +++ b/heap/hp_test1.c @@ -44,6 +44,7 @@ int main(int argc, char **argv) get_options(argc,argv); bzero(&hp_create_info, sizeof(hp_create_info)); + hp_create_info.max_table_size= 1024L*1024L; keyinfo[0].keysegs=1; keyinfo[0].seg=keyseg; @@ -58,7 +59,7 @@ int main(int argc, char **argv) bzero((gptr) flags,sizeof(flags)); printf("- Creating heap-file\n"); - if (heap_create(filename,1,keyinfo,30,(ulong) flag*100000l,10l, + if (heap_create(filename,1,keyinfo,30,(ulong) flag*100000L,101L, &hp_create_info) || !(file= heap_open(filename, 2))) goto err; diff --git a/heap/hp_test2.c b/heap/hp_test2.c index 2de49bcb66b..ff07b402f4d 100644 --- a/heap/hp_test2.c +++ b/heap/hp_test2.c @@ -74,6 +74,7 @@ int main(int argc, char *argv[]) get_options(argc,argv); bzero(&hp_create_info, sizeof(hp_create_info)); + hp_create_info.max_table_size= 1024L*1024L; write_count=update=opt_delete=0; key_check=0; diff --git a/include/my_global.h b/include/my_global.h index 0f99aacd079..6baa4558d50 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -976,8 +976,8 @@ do { doubleget_union _tmp; \ #define doublestore(T,V) do { *((long *) T) = ((doubleget_union *)&V)->m[0]; \ *(((long *) T)+1) = ((doubleget_union *)&V)->m[1]; \ } while (0) -#define float4get(V,M) do { *((long *) &(V)) = *((long*) (M)); } while(0) -#define float8get(V,M) doubleget((V),(M)) +#define float4get(V,M) do { *((float *) &(V)) = *((float*) (M)); } while(0) +#define float8get(V,M) doubleget((V),(M)) #define float4store(V,M) memcpy((byte*) V,(byte*) (&M),sizeof(float)) #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/mysys/my_handler.c b/mysys/my_handler.c index 3eed0ee6c08..156e7892580 100644 --- a/mysys/my_handler.c +++ b/mysys/my_handler.c @@ -15,6 +15,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ +#include #include "my_handler.h" int mi_compare_text(CHARSET_INFO *charset_info, uchar *a, uint a_length, diff --git a/strings/strtod.c b/strings/strtod.c index 61f2c107abe..da1b4f4baa6 100644 --- a/strings/strtod.c +++ b/strings/strtod.c @@ -26,8 +26,8 @@ */ -#include "my_base.h" /* Includes errno.h */ -#include "m_ctype.h" +#include /* Includes errno.h */ +#include #define MAX_DBL_EXP 308 #define MAX_RESULT_FOR_MAX_EXP 1.79769313486232 From 593b359d92963f2a31d843effaeb4e2f017b6f97 Mon Sep 17 00:00:00 2001 From: "kent@mysql.com" <> Date: Fri, 30 Jun 2006 02:49:28 +0200 Subject: [PATCH 03/10] mysql.spec.sh: Disable old RPM strip my_global.h: Fixed wrong cast, which caused problems with gcc 4.0 and floats in prepared statements (Bug #19694) mysqlmanager.vcproj: Place output files in common release/debug directory --- include/my_global.h | 4 ++-- .../instance-manager/mysqlmanager.vcproj | 4 ++-- support-files/mysql.spec.sh | 17 +++++++++++++++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/include/my_global.h b/include/my_global.h index c9f27e0031e..909755aef87 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -1071,8 +1071,8 @@ do { doubleget_union _tmp; \ #define doublestore(T,V) do { *((long *) T) = ((doubleget_union *)&V)->m[0]; \ *(((long *) T)+1) = ((doubleget_union *)&V)->m[1]; \ } while (0) -#define float4get(V,M) do { *((long *) &(V)) = *((long*) (M)); } while(0) -#define float8get(V,M) doubleget((V),(M)) +#define float4get(V,M) do { *((float *) &(V)) = *((float*) (M)); } while(0) +#define float8get(V,M) doubleget((V),(M)) #define float4store(V,M) memcpy((byte*) V,(byte*) (&M),sizeof(float)) #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/server-tools/instance-manager/mysqlmanager.vcproj b/server-tools/instance-manager/mysqlmanager.vcproj index ef8b2dd017e..bbcb94fa221 100644 --- a/server-tools/instance-manager/mysqlmanager.vcproj +++ b/server-tools/instance-manager/mysqlmanager.vcproj @@ -34,7 +34,7 @@ Date: Fri, 30 Jun 2006 04:10:27 +0300 Subject: [PATCH 04/10] Don't read ~/.my.cnf in mysqldump.test --- heap/hp_test1.c | 2 +- mysql-test/mysql-test-run.sh | 20 +++++++------------- mysql-test/t/mysqldump.test | 2 +- sql/ha_ndbcluster.cc | 6 ++++-- 4 files changed, 13 insertions(+), 17 deletions(-) diff --git a/heap/hp_test1.c b/heap/hp_test1.c index 1efa97842c7..703b39b1e2d 100644 --- a/heap/hp_test1.c +++ b/heap/hp_test1.c @@ -59,7 +59,7 @@ int main(int argc, char **argv) bzero((gptr) flags,sizeof(flags)); printf("- Creating heap-file\n"); - if (heap_create(filename,1,keyinfo,30,(ulong) flag*100000L,101L, + if (heap_create(filename,1,keyinfo,30,(ulong) flag*100000L,10L, &hp_create_info) || !(file= heap_open(filename, 2))) goto err; diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 93f741aecff..15c7470a74c 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -1252,16 +1252,16 @@ start_master() if [ x$DO_DDD = x1 ] then - $ECHO "set args $master_args" > $GDB_MASTER_INIT + $ECHO "set args $master_args" > $GDB_MASTER_INIT$1 manager_launch master ddd -display $DISPLAY --debugger \ - "gdb -x $GDB_MASTER_INIT" $MASTER_MYSQLD + "gdb -x $GDB_MASTER_INIT$1" $MASTER_MYSQLD elif [ x$DO_GDB = x1 ] then if [ x$MANUAL_GDB = x1 ] then - $ECHO "set args $master_args" > $GDB_MASTER_INIT + $ECHO "set args $master_args" > $GDB_MASTER_INIT$1 $ECHO "To start gdb for the master , type in another window:" - $ECHO "cd $CWD ; gdb -x $GDB_MASTER_INIT $MASTER_MYSQLD" + $ECHO "cd $CWD ; gdb -x $GDB_MASTER_INIT$1 $MASTER_MYSQLD" wait_for_master=1500 else ( $ECHO set args $master_args; @@ -1273,9 +1273,9 @@ disa 1 end r EOF - fi ) > $GDB_MASTER_INIT + fi ) > $GDB_MASTER_INIT$1 manager_launch master $XTERM -display $DISPLAY \ - -title "Master" -e gdb -x $GDB_MASTER_INIT $MASTER_MYSQLD + -title "Master" -e gdb -x $GDB_MASTER_INIT$1 $MASTER_MYSQLD fi else manager_launch master $MASTER_MYSQLD $master_args @@ -1810,13 +1810,7 @@ then mysql_install_db start_manager - -# Do not automagically start daemons if we are in gdb or running only one test -# case - if [ -z "$DO_GDB" ] && [ -z "$DO_DDD" ] - then - mysql_start - fi + mysql_start $ECHO "Loading Standard Test Databases" mysql_loadstd fi diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index eda89ff2dd3..e86635e24d0 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -652,7 +652,7 @@ drop table t1; # BUG#15328 Segmentation fault occured if my.cnf is invalid for escape sequence # ---exec $MYSQL_MY_PRINT_DEFAULTS --defaults-extra-file=$MYSQL_TEST_DIR/std_data/bug15328.cnf mysqldump +--exec $MYSQL_MY_PRINT_DEFAULTS --defaults-file=$MYSQL_TEST_DIR/std_data/bug15328.cnf mysqldump # BUG #19025 mysqldump doesn't correctly dump "auto_increment = [int]" diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 11fdd33fad9..1837b22cf42 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -2300,12 +2300,14 @@ void ha_ndbcluster::unpack_record(byte* buf) { // Table with hidden primary key int hidden_no= table->fields; + char buff[22]; const NDBTAB *tab= (const NDBTAB *) m_table; const NDBCOL *hidden_col= tab->getColumn(hidden_no); NdbRecAttr* rec= m_value[hidden_no].rec; DBUG_ASSERT(rec); - DBUG_PRINT("hidden", ("%d: %s \"%llu\"", hidden_no, - hidden_col->getName(), rec->u_64_value())); + DBUG_PRINT("hidden", ("%d: %s \"%s\"", hidden_no, + hidden_col->getName(), + llstr(rec->u_64_value(), buff))); } print_results(); #endif From 5cd5e48761187d6cbb4377dba4c0887927ab8f19 Mon Sep 17 00:00:00 2001 From: "elliot@mysql.com" <> Date: Fri, 30 Jun 2006 00:10:41 -0400 Subject: [PATCH 05/10] Fixing windows build. --- strings/strtod.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/strings/strtod.c b/strings/strtod.c index da1b4f4baa6..c2534b509d6 100644 --- a/strings/strtod.c +++ b/strings/strtod.c @@ -26,8 +26,8 @@ */ -#include /* Includes errno.h */ -#include +#include "my_global.h" /* Includes errno.h */ +#include "m_ctype.h" #define MAX_DBL_EXP 308 #define MAX_RESULT_FOR_MAX_EXP 1.79769313486232 From 1d56a9720c7c0eef6f16e9624cce17553cfddd5b Mon Sep 17 00:00:00 2001 From: "knielsen@mysql.com" <> Date: Fri, 30 Jun 2006 09:26:36 +0200 Subject: [PATCH 06/10] BUG#20769: Dangling pointer in ctype_recoding test case. In some functions dealing with strings and character sets, the wrong pointers were saved for restoration in THD::rollback_item_tree_changes(). This could potentially cause random corruption or crashes. Fixed by passing the original Item ** locations, not local stack copies. Also remove unnecessary use of default arguments. --- sql/item.cc | 46 ++++++++++++++++++++++++++--------------- sql/item.h | 7 +++---- sql/item_cmpfunc.cc | 20 +++++++++--------- sql/item_func.cc | 11 +++++----- sql/item_func.h | 10 ++++----- sql/item_strfunc.cc | 50 +++++++++++++++------------------------------ sql/item_sum.cc | 2 +- 7 files changed, 71 insertions(+), 75 deletions(-) diff --git a/sql/item.cc b/sql/item.cc index 24efc1f106f..0448ef8dd65 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1315,35 +1315,37 @@ void my_coll_agg_error(DTCollation &c1, DTCollation &c2, DTCollation &c3, static -void my_coll_agg_error(Item** args, uint count, const char *fname) +void my_coll_agg_error(Item** args, uint count, const char *fname, + int item_sep) { if (count == 2) - my_coll_agg_error(args[0]->collation, args[1]->collation, fname); + my_coll_agg_error(args[0]->collation, args[item_sep]->collation, fname); else if (count == 3) - my_coll_agg_error(args[0]->collation, args[1]->collation, - args[2]->collation, fname); + my_coll_agg_error(args[0]->collation, args[item_sep]->collation, + args[2*item_sep]->collation, fname); else my_error(ER_CANT_AGGREGATE_NCOLLATIONS,MYF(0),fname); } bool agg_item_collations(DTCollation &c, const char *fname, - Item **av, uint count, uint flags) + Item **av, uint count, uint flags, int item_sep) { uint i; + Item **arg; c.set(av[0]->collation); - for (i= 1; i < count; i++) + for (i= 1, arg= &av[item_sep]; i < count; i++, arg++) { - if (c.aggregate(av[i]->collation, flags)) + if (c.aggregate((*arg)->collation, flags)) { - my_coll_agg_error(av, count, fname); + my_coll_agg_error(av, count, fname, item_sep); return TRUE; } } if ((flags & MY_COLL_DISALLOW_NONE) && c.derivation == DERIVATION_NONE) { - my_coll_agg_error(av, count, fname); + my_coll_agg_error(av, count, fname, item_sep); return TRUE; } return FALSE; @@ -1354,7 +1356,7 @@ bool agg_item_collations_for_comparison(DTCollation &c, const char *fname, Item **av, uint count, uint flags) { return (agg_item_collations(c, fname, av, count, - flags | MY_COLL_DISALLOW_NONE)); + flags | MY_COLL_DISALLOW_NONE, 1)); } @@ -1377,13 +1379,22 @@ bool agg_item_collations_for_comparison(DTCollation &c, const char *fname, For functions with more than two arguments: collect(A,B,C) ::= collect(collect(A,B),C) + + Since this function calls THD::change_item_tree() on the passed Item ** + pointers, it is necessary to pass the original Item **'s, not copies. + Otherwise their values will not be properly restored (see BUG#20769). + If the items are not consecutive (eg. args[2] and args[5]), use the + item_sep argument, ie. + + agg_item_charsets(coll, fname, &args[2], 2, flags, 3) + */ bool agg_item_charsets(DTCollation &coll, const char *fname, - Item **args, uint nargs, uint flags) + Item **args, uint nargs, uint flags, int item_sep) { - Item **arg, **last, *safe_args[2]; - if (agg_item_collations(coll, fname, args, nargs, flags)) + Item **arg, *safe_args[2]; + if (agg_item_collations(coll, fname, args, nargs, flags, item_sep)) return TRUE; /* @@ -1396,19 +1407,20 @@ bool agg_item_charsets(DTCollation &coll, const char *fname, if (nargs >=2 && nargs <= 3) { safe_args[0]= args[0]; - safe_args[1]= args[1]; + safe_args[1]= args[item_sep]; } THD *thd= current_thd; Query_arena *arena, backup; bool res= FALSE; + uint i; /* In case we're in statement prepare, create conversion item in its memory: it will be reused on each execute. */ arena= thd->activate_stmt_arena_if_needed(&backup); - for (arg= args, last= args + nargs; arg < last; arg++) + for (i= 0, arg= args; i < nargs; i++, arg+= item_sep) { Item* conv; uint32 dummy_offset; @@ -1423,9 +1435,9 @@ bool agg_item_charsets(DTCollation &coll, const char *fname, { /* restore the original arguments for better error message */ args[0]= safe_args[0]; - args[1]= safe_args[1]; + args[item_sep]= safe_args[1]; } - my_coll_agg_error(args, nargs, fname); + my_coll_agg_error(args, nargs, fname, item_sep); res= TRUE; break; // we cannot return here, we need to restore "arena". } diff --git a/sql/item.h b/sql/item.h index 2cadfda6895..534d20b3aec 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1075,12 +1075,11 @@ public: }; bool agg_item_collations(DTCollation &c, const char *name, - Item **items, uint nitems, uint flags= 0); + Item **items, uint nitems, uint flags, int item_sep); bool agg_item_collations_for_comparison(DTCollation &c, const char *name, - Item **items, uint nitems, - uint flags= 0); + Item **items, uint nitems, uint flags); bool agg_item_charsets(DTCollation &c, const char *name, - Item **items, uint nitems, uint flags= 0); + Item **items, uint nitems, uint flags, int item_sep); class Item_num: public Item diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 80cf756d852..ffacddd534a 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -394,7 +394,7 @@ void Item_bool_func2::fix_length_and_dec() DTCollation coll; if (args[0]->result_type() == STRING_RESULT && args[1]->result_type() == STRING_RESULT && - agg_arg_charsets(coll, args, 2, MY_COLL_CMP_CONV)) + agg_arg_charsets(coll, args, 2, MY_COLL_CMP_CONV, 1)) return; @@ -1211,7 +1211,7 @@ void Item_func_between::fix_length_and_dec() agg_cmp_type(thd, &cmp_type, args, 3); if (cmp_type == STRING_RESULT) - agg_arg_charsets(cmp_collation, args, 3, MY_COLL_CMP_CONV); + agg_arg_charsets(cmp_collation, args, 3, MY_COLL_CMP_CONV, 1); } @@ -1331,7 +1331,7 @@ Item_func_ifnull::fix_length_and_dec() switch (hybrid_type) { case STRING_RESULT: - agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV); + agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1); break; case DECIMAL_RESULT: case REAL_RESULT: @@ -1503,7 +1503,7 @@ Item_func_if::fix_length_and_dec() agg_result_type(&cached_result_type, args+1, 2); if (cached_result_type == STRING_RESULT) { - if (agg_arg_charsets(collation, args+1, 2, MY_COLL_ALLOW_CONV)) + if (agg_arg_charsets(collation, args+1, 2, MY_COLL_ALLOW_CONV, 1)) return; } else @@ -1584,7 +1584,7 @@ Item_func_nullif::fix_length_and_dec() unsigned_flag= args[0]->unsigned_flag; cached_result_type= args[0]->result_type(); if (cached_result_type == STRING_RESULT && - agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV)) + agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1)) return; } } @@ -1876,7 +1876,7 @@ void Item_func_case::fix_length_and_dec() agg_result_type(&cached_result_type, agg, nagg); if ((cached_result_type == STRING_RESULT) && - agg_arg_charsets(collation, agg, nagg, MY_COLL_ALLOW_CONV)) + agg_arg_charsets(collation, agg, nagg, MY_COLL_ALLOW_CONV, 1)) return; @@ -1892,7 +1892,7 @@ void Item_func_case::fix_length_and_dec() nagg++; agg_cmp_type(thd, &cmp_type, agg, nagg); if ((cmp_type == STRING_RESULT) && - agg_arg_charsets(cmp_collation, agg, nagg, MY_COLL_CMP_CONV)) + agg_arg_charsets(cmp_collation, agg, nagg, MY_COLL_CMP_CONV, 1)) return; } @@ -2022,7 +2022,7 @@ void Item_func_coalesce::fix_length_and_dec() case STRING_RESULT: count_only_length(); decimals= NOT_FIXED_DEC; - agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV); + agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1); break; case DECIMAL_RESULT: count_decimal_length(); @@ -2486,7 +2486,7 @@ void Item_func_in::fix_length_and_dec() agg_cmp_type(thd, &cmp_type, args, arg_count); if (cmp_type == STRING_RESULT && - agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV)) + agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1)) return; for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++) @@ -3219,7 +3219,7 @@ Item_func_regex::fix_fields(THD *thd, Item **ref) max_length= 1; decimals= 0; - if (agg_arg_charsets(cmp_collation, args, 2, MY_COLL_CMP_CONV)) + if (agg_arg_charsets(cmp_collation, args, 2, MY_COLL_CMP_CONV, 1)) return TRUE; used_tables_cache=args[0]->used_tables() | args[1]->used_tables(); diff --git a/sql/item_func.cc b/sql/item_func.cc index 194d62b1183..5227e771194 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2038,7 +2038,7 @@ void Item_func_min_max::fix_length_and_dec() cmp_type=item_cmp_type(cmp_type,args[i]->result_type()); } if (cmp_type == STRING_RESULT) - agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV); + agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1); else if ((cmp_type == DECIMAL_RESULT) || (cmp_type == INT_RESULT)) max_length= my_decimal_precision_to_length(max_int_part+decimals, decimals, unsigned_flag); @@ -2227,7 +2227,7 @@ longlong Item_func_coercibility::val_int() void Item_func_locate::fix_length_and_dec() { maybe_null=0; max_length=11; - agg_arg_charsets(cmp_collation, args, 2, MY_COLL_CMP_CONV); + agg_arg_charsets(cmp_collation, args, 2, MY_COLL_CMP_CONV, 1); } @@ -2344,7 +2344,7 @@ void Item_func_field::fix_length_and_dec() for (uint i=1; i < arg_count ; i++) cmp_type= item_cmp_type(cmp_type, args[i]->result_type()); if (cmp_type == STRING_RESULT) - agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV); + agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1); } @@ -2411,7 +2411,7 @@ void Item_func_find_in_set::fix_length_and_dec() } } } - agg_arg_charsets(cmp_collation, args, 2, MY_COLL_CMP_CONV); + agg_arg_charsets(cmp_collation, args, 2, MY_COLL_CMP_CONV, 1); } static const char separator=','; @@ -4401,7 +4401,8 @@ bool Item_func_match::fix_fields(THD *thd, Item **ref) return 1; } table->fulltext_searched=1; - return agg_arg_collations_for_comparison(cmp_collation, args+1, arg_count-1); + return agg_arg_collations_for_comparison(cmp_collation, + args+1, arg_count-1, 0); } bool Item_func_match::fix_index() diff --git a/sql/item_func.h b/sql/item_func.h index 1d8a1bd5e22..2ca4be9f3f2 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -166,21 +166,21 @@ public: my_decimal *val_decimal(my_decimal *); bool agg_arg_collations(DTCollation &c, Item **items, uint nitems, - uint flags= 0) + uint flags) { - return agg_item_collations(c, func_name(), items, nitems, flags); + return agg_item_collations(c, func_name(), items, nitems, flags, 1); } bool agg_arg_collations_for_comparison(DTCollation &c, Item **items, uint nitems, - uint flags= 0) + uint flags) { return agg_item_collations_for_comparison(c, func_name(), items, nitems, flags); } bool agg_arg_charsets(DTCollation &c, Item **items, uint nitems, - uint flags= 0) + uint flags, int item_sep) { - return agg_item_charsets(c, func_name(), items, nitems, flags); + return agg_item_charsets(c, func_name(), items, nitems, flags, item_sep); } bool walk(Item_processor processor, byte *arg); Item *transform(Item_transformer transformer, byte *arg); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 7a35dedc08a..9e3a9b64288 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -405,7 +405,7 @@ void Item_func_concat::fix_length_and_dec() { ulonglong max_result_length= 0; - if (agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV)) + if (agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1)) return; for (uint i=0 ; i < arg_count ; i++) @@ -727,7 +727,7 @@ void Item_func_concat_ws::fix_length_and_dec() { ulonglong max_result_length; - if (agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV)) + if (agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1)) return; /* @@ -937,7 +937,7 @@ void Item_func_replace::fix_length_and_dec() } max_length= (ulong) max_result_length; - if (agg_arg_charsets(collation, args, 3, MY_COLL_CMP_CONV)) + if (agg_arg_charsets(collation, args, 3, MY_COLL_CMP_CONV, 1)) return; } @@ -982,15 +982,11 @@ null: void Item_func_insert::fix_length_and_dec() { - Item *cargs[2]; ulonglong max_result_length; - cargs[0]= args[0]; - cargs[1]= args[3]; - if (agg_arg_charsets(collation, cargs, 2, MY_COLL_ALLOW_CONV)) + // Handle character set for args[0] and args[3]. + if (agg_arg_charsets(collation, &args[0], 2, MY_COLL_ALLOW_CONV, 3)) return; - args[0]= cargs[0]; - args[3]= cargs[1]; max_result_length= ((ulonglong) args[0]->max_length+ (ulonglong) args[3]->max_length); if (max_result_length >= MAX_BLOB_WIDTH) @@ -1161,7 +1157,7 @@ void Item_func_substr_index::fix_length_and_dec() { max_length= args[0]->max_length; - if (agg_arg_charsets(collation, args, 2, MY_COLL_CMP_CONV)) + if (agg_arg_charsets(collation, args, 2, MY_COLL_CMP_CONV, 1)) return; } @@ -1497,13 +1493,10 @@ void Item_func_trim::fix_length_and_dec() } else { - Item *cargs[2]; - cargs[0]= args[1]; - cargs[1]= args[0]; - if (agg_arg_charsets(collation, cargs, 2, MY_COLL_CMP_CONV)) + // Handle character set for args[1] and args[0]. + // Note that we pass args[1] as the first item, and args[0] as the second. + if (agg_arg_charsets(collation, &args[1], 2, MY_COLL_CMP_CONV, -1)) return; - args[0]= cargs[1]; - args[1]= cargs[0]; } } @@ -1887,7 +1880,7 @@ void Item_func_elt::fix_length_and_dec() max_length=0; decimals=0; - if (agg_arg_charsets(collation, args+1, arg_count-1, MY_COLL_ALLOW_CONV)) + if (agg_arg_charsets(collation, args+1, arg_count-1, MY_COLL_ALLOW_CONV, 1)) return; for (uint i= 1 ; i < arg_count ; i++) @@ -1954,7 +1947,7 @@ void Item_func_make_set::fix_length_and_dec() { max_length=arg_count-1; - if (agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV)) + if (agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1)) return; for (uint i=0 ; i < arg_count ; i++) @@ -2162,14 +2155,9 @@ err: void Item_func_rpad::fix_length_and_dec() { - Item *cargs[2]; - - cargs[0]= args[0]; - cargs[1]= args[2]; - if (agg_arg_charsets(collation, cargs, 2, MY_COLL_ALLOW_CONV)) + // Handle character set for args[0] and args[2]. + if (agg_arg_charsets(collation, &args[0], 2, MY_COLL_ALLOW_CONV, 2)) return; - args[0]= cargs[0]; - args[2]= cargs[1]; if (args[1]->const_item()) { ulonglong length= ((ulonglong) args[1]->val_int() * @@ -2249,13 +2237,9 @@ String *Item_func_rpad::val_str(String *str) void Item_func_lpad::fix_length_and_dec() { - Item *cargs[2]; - cargs[0]= args[0]; - cargs[1]= args[2]; - if (agg_arg_charsets(collation, cargs, 2, MY_COLL_ALLOW_CONV)) + // Handle character set for args[0] and args[2]. + if (agg_arg_charsets(collation, &args[0], 2, MY_COLL_ALLOW_CONV, 2)) return; - args[0]= cargs[0]; - args[2]= cargs[1]; if (args[1]->const_item()) { @@ -2712,8 +2696,8 @@ void Item_func_export_set::fix_length_and_dec() uint sep_length=(arg_count > 3 ? args[3]->max_length : 1); max_length=length*64+sep_length*63; - if (agg_arg_charsets(collation, args+1, min(4,arg_count)-1), - MY_COLL_ALLOW_CONV) + if (agg_arg_charsets(collation, args+1, min(4,arg_count)-1, + MY_COLL_ALLOW_CONV, 1)) return; } diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 962454e237e..49faa213186 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -3229,7 +3229,7 @@ Item_func_group_concat::fix_fields(THD *thd, Item **ref) args, /* skip charset aggregation for order columns */ arg_count - arg_count_order, - MY_COLL_ALLOW_CONV)) + MY_COLL_ALLOW_CONV, 1)) return 1; result.set_charset(collation.collation); From 79ca4c1d5579c3f7c23730fc14da90efea1438d0 Mon Sep 17 00:00:00 2001 From: "kroki@mysql.com" <> Date: Fri, 30 Jun 2006 12:52:05 +0400 Subject: [PATCH 07/10] bug #20152: mysql_stmt_execute() overwrites parameter buffers When using a parameter bind MYSQL_TYPE_DATE in a prepared statement, the time part of the MYSQL_TIME buffer was written to zero in mysql_stmt_execute(). The param_store_date() function in libmysql.c worked directly on the provided buffer. Changed to use a copy of the buffer. --- libmysql/libmysql.c | 7 +++--- tests/mysql_client_test.c | 53 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 4b8f1c9da1f..80a7112eab2 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -2409,10 +2409,9 @@ static void net_store_datetime(NET *net, MYSQL_TIME *tm) static void store_param_date(NET *net, MYSQL_BIND *param) { - MYSQL_TIME *tm= (MYSQL_TIME *) param->buffer; - tm->hour= tm->minute= tm->second= 0; - tm->second_part= 0; - net_store_datetime(net, tm); + MYSQL_TIME tm= *((MYSQL_TIME *) param->buffer); + tm.hour= tm.minute= tm.second= tm.second_part= 0; + net_store_datetime(net, &tm); } static void store_param_datetime(NET *net, MYSQL_BIND *param) diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 3c54bf50c15..94034141d81 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -11855,6 +11855,58 @@ static void test_bug15613() mysql_stmt_close(stmt); } + +/* + Bug#20152: mysql_stmt_execute() writes to MYSQL_TYPE_DATE buffer + */ +static void test_bug20152() +{ + MYSQL_BIND bind[1]; + MYSQL_STMT *stmt; + MYSQL_TIME tm; + int rc; + const char *query= "INSERT INTO t1 (f1) VALUES (?)"; + + myheader("test_bug20152"); + + memset(bind, 0, sizeof(bind)); + bind[0].buffer_type= MYSQL_TYPE_DATE; + bind[0].buffer= (void*)&tm; + + tm.year = 2006; + tm.month = 6; + tm.day = 18; + tm.hour = 14; + tm.minute = 9; + tm.second = 42; + + rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1"); + myquery(rc); + rc= mysql_query(mysql, "CREATE TABLE t1 (f1 DATE)"); + myquery(rc); + + stmt= mysql_stmt_init(mysql); + rc= mysql_stmt_prepare(stmt, query, strlen(query)); + check_execute(stmt, rc); + rc= mysql_stmt_bind_param(stmt, bind); + check_execute(stmt, rc); + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + rc= mysql_stmt_close(stmt); + check_execute(stmt, rc); + rc= mysql_query(mysql, "DROP TABLE t1"); + myquery(rc); + + if (tm.hour == 14 && tm.minute == 9 && tm.second == 42) { + if (!opt_silent) + printf("OK!"); + } else { + printf("[14:09:42] != [%02d:%02d:%02d]\n", tm.hour, tm.minute, tm.second); + DIE_UNLESS(0==1); + } +} + + /* Read and parse arguments and MySQL options from my.cnf */ @@ -12078,6 +12130,7 @@ static struct my_tests_st my_tests[]= { { "test_bug11718", test_bug11718 }, { "test_bug12925", test_bug12925 }, { "test_bug15613", test_bug15613 }, + { "test_bug20152", test_bug20152 }, { 0, 0 } }; From a3019ab1965190088db006f0a488ec2352077229 Mon Sep 17 00:00:00 2001 From: "knielsen@mysql.com" <> Date: Fri, 30 Jun 2006 11:10:38 +0200 Subject: [PATCH 08/10] Fix Windows build problem following previous push. --- strings/strtod.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/strings/strtod.c b/strings/strtod.c index c2534b509d6..e0910205d2f 100644 --- a/strings/strtod.c +++ b/strings/strtod.c @@ -26,7 +26,8 @@ */ -#include "my_global.h" /* Includes errno.h */ +#include "my_base.h" /* Defines EOVERFLOW on Windows */ +#include "my_global.h" /* Includes errno.h */ #include "m_ctype.h" #define MAX_DBL_EXP 308 From 2bec1b86bbef1bd40e425badbddc1d7e7bf5d1b8 Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Fri, 30 Jun 2006 18:29:27 +0300 Subject: [PATCH 09/10] Reverted wrong bug fix (Bug#11228) --- mysql-test/r/key.result | 10 +++++++++- mysql-test/t/key.test | 1 + sql/table.cc | 21 +++++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/key.result b/mysql-test/r/key.result index 0bc241c0d19..75fc469460e 100644 --- a/mysql-test/r/key.result +++ b/mysql-test/r/key.result @@ -332,8 +332,16 @@ UNIQUE i1idx (i1), UNIQUE i2idx (i2)); desc t1; Field Type Null Key Default Extra -i1 int(11) UNI 0 +i1 int(11) PRI 0 i2 int(11) UNI 0 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i1` int(11) NOT NULL default '0', + `i2` int(11) NOT NULL default '0', + UNIQUE KEY `i1idx` (`i1`), + UNIQUE KEY `i2idx` (`i2`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; create table t1 ( c1 int, diff --git a/mysql-test/t/key.test b/mysql-test/t/key.test index 796e36cb608..9aab8a13b06 100644 --- a/mysql-test/t/key.test +++ b/mysql-test/t/key.test @@ -330,6 +330,7 @@ create table t1 ( UNIQUE i1idx (i1), UNIQUE i2idx (i2)); desc t1; +show create table t1; drop table t1; # diff --git a/sql/table.cc b/sql/table.cc index 513f42665a6..8ac64ac198d 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -567,6 +567,27 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, if (outparam->key_info[key].flags & HA_FULLTEXT) outparam->key_info[key].algorithm= HA_KEY_ALG_FULLTEXT; + if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME)) + { + /* + If the UNIQUE key doesn't have NULL columns and is not a part key + declare this as a primary key. + */ + primary_key=key; + for (i=0 ; i < keyinfo->key_parts ;i++) + { + uint fieldnr= key_part[i].fieldnr; + if (!fieldnr || + outparam->field[fieldnr-1]->null_ptr || + outparam->field[fieldnr-1]->key_length() != + key_part[i].length) + { + primary_key=MAX_KEY; // Can't be used + break; + } + } + } + for (i=0 ; i < keyinfo->key_parts ; key_part++,i++) { if (new_field_pack_flag <= 1) From f62829636b5bdec183610acfba53ca18e0dd2f98 Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Fri, 30 Jun 2006 20:07:33 +0300 Subject: [PATCH 10/10] After merge fixes --- .bzrignore | 2 ++ include/my_handler.h | 1 - mysql-test/r/key.result | 4 ++-- sql/ha_ndbcluster.cc | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.bzrignore b/.bzrignore index ef02a085144..7ea7f1ab7e2 100644 --- a/.bzrignore +++ b/.bzrignore @@ -1286,3 +1286,5 @@ vio/viotest.cpp zlib/*.ds? zlib/*.vcproj BitKeeper/etc/RESYNC_TREE +mysql-test/r/*.log +scripts/mysql_upgrade_shell diff --git a/include/my_handler.h b/include/my_handler.h index d531e0fb3e1..61665090853 100644 --- a/include/my_handler.h +++ b/include/my_handler.h @@ -18,7 +18,6 @@ #ifndef _my_handler_h #define _my_handler_h -#include "my_global.h" #include "my_base.h" #include "m_ctype.h" #include "myisampack.h" diff --git a/mysql-test/r/key.result b/mysql-test/r/key.result index 6a362d6b86a..0174ea45935 100644 --- a/mysql-test/r/key.result +++ b/mysql-test/r/key.result @@ -341,8 +341,8 @@ i2 int(11) NO UNI show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `i1` int(11) NOT NULL default '0', - `i2` int(11) NOT NULL default '0', + `i1` int(11) NOT NULL, + `i2` int(11) NOT NULL, UNIQUE KEY `i1idx` (`i1`), UNIQUE KEY `i2idx` (`i2`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index c5711d8f0fd..18c220f3f88 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -6476,7 +6476,7 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused))) ("Table: %s commit_count: %s rows: %s", share->table_name, llstr(stat.commit_count, buff), - llstr(stat.row_count, buff2)); + llstr(stat.row_count, buff2))); } else {