From e92dff848f35f29fbf260ece34340a529a0c17bc Mon Sep 17 00:00:00 2001 From: MySQL Build Team Date: Wed, 9 Feb 2011 21:30:48 +0100 Subject: [PATCH] Backport into build-201102032246-5.1.52sp1 > ------------------------------------------------------------ > revno: 3507.1.7 > revision-id: guilhem@mysql.com-20101122085759-53uuoyqyjkh4em2m > parent: davi.arnaut@oracle.com-20101120142951-l0f3bxmcwibcplxq > committer: Guilhem Bichot > branch nick: mysql-5.1-bugteam > timestamp: Mon 2010-11-22 09:57:59 +0100 > message: > Fix for Bug#56138 "valgrind errors about overlapping memory when double-assigning same variable", > and related small fixes. --- mysql-test/r/user_var.result | 3 +++ mysql-test/t/user_var.test | 7 +++++++ sql/field_conv.cc | 7 ++----- sql/item_func.cc | 2 +- sql/sql_select.cc | 8 ++++++-- 5 files changed, 19 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result index 56266a46e20..cf82a18ea83 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -447,4 +447,7 @@ IF( count(*), 1) 1 DROP TABLE t1; +select @v:=@v:=sum(1) from dual; +@v:=@v:=sum(1) +1 End of 5.1 tests diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test index 4f27866de23..56217fe67d5 100644 --- a/mysql-test/t/user_var.test +++ b/mysql-test/t/user_var.test @@ -346,4 +346,11 @@ FROM t1 GROUP BY a LIMIT 1; DROP TABLE t1; +# +# BUG#56138 "valgrind errors about overlapping memory when +# double-assigning same variable" +# + +select @v:=@v:=sum(1) from dual; + --echo End of 5.1 tests diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 0bffde9671a..a4fca6f8ad7 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -786,11 +786,8 @@ int field_conv(Field *to,Field *from) ((Field_varstring*)from)->length_bytes == ((Field_varstring*)to)->length_bytes)) { // Identical fields -#ifdef HAVE_purify - /* This may happen if one does 'UPDATE ... SET x=x' */ - if (to->ptr != from->ptr) -#endif - memcpy(to->ptr,from->ptr,to->pack_length()); + // to->ptr==from->ptr may happen if one does 'UPDATE ... SET x=x' + memmove(to->ptr, from->ptr, to->pack_length()); return 0; } } diff --git a/sql/item_func.cc b/sql/item_func.cc index eaf6a1b6d14..258ba0f01d5 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -3913,7 +3913,7 @@ update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length, length--; // Fix length change above entry->value[length]= 0; // Store end \0 } - memcpy(entry->value,ptr,length); + memmove(entry->value, ptr, length); if (type == DECIMAL_RESULT) ((my_decimal*)entry->value)->fix_buffer_pointer(); entry->length= length; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 08bd0c28738..9bf0a236e1b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4034,8 +4034,12 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, continue; } -#ifdef HAVE_purify - /* Valgrind complains about overlapped memcpy when save_pos==use. */ +#if defined(__GNUC__) && !MY_GNUC_PREREQ(4,4) + /* + Old gcc used a memcpy(), which is undefined if save_pos==use: + http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19410 + http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39480 + */ if (save_pos != use) #endif *save_pos= *use;