From: Sergey Glukhov Date: April 12 2011 10:32am Subject: bzr push into mysql-5.1 branch (sergey.glukhov:3653 to 3655) Bug#11766270 List-Archive: http://lists.mysql.com/commits/135248 X-Bug: 11766270 Message-Id: <201104121031.p3CAVtea029099@acsmt357.oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 3655 Sergey Glukhov 2011-04-12 Bug#11766270 59343: YEAR(4): INCORRECT RESULT AND VALGRIND WARNINGS WITH MIN/MAX, UNION When we create temporary result table for UNION incorrect max_length for YEAR field is used and it leads to incorrect field value and incorrect result string length as YEAR field value calculation depends on field length. The fix is to use underlying item max_length for Item_sum_hybrid::max_length intialization. @ mysql-test/r/func_group.result test case @ mysql-test/t/func_group.test test case @ sql/field.cc added assert @ sql/item_sum.cc init Item_sum_hybrid::max_length with use underlying item max_length for INT result type. modified: mysql-test/r/func_group.result mysql-test/t/func_group.test sql/field.cc sql/item_sum.cc 3654 Sergey Glukhov 2011-04-12 Bug#11766212 59270: NOT IN (YEAR( ... ), ... ) PRODUCES MANY VALGRIND WARNINGS Valgrind warning happens due to early null values check in Item_func_in::fix_length_and_dec(before item evaluation). As result null value items with uninitialized values are placed into array and it leads to valgrind warnings during value array sorting. The fix is to check null value after item evaluation, item is evaluated in in_array::set() method. @ mysql-test/r/func_in.result test case @ mysql-test/t/func_in.test test case @ sql/item_cmpfunc.cc The fix is to check null value after item evaluation. modified: mysql-test/r/func_in.result mysql-test/t/func_in.test sql/item_cmpfunc.cc 3653 Sven Sandberg 2011-04-11 corrected bug reference for experimental test modified: mysql-test/collections/default.experimental === modified file 'mysql-test/r/func_group.result' --- a/mysql-test/r/func_group.result 2011-03-31 18:59:11 +0000 +++ b/mysql-test/r/func_group.result 2011-04-12 10:01:33 +0000 @@ -1746,4 +1746,15 @@ MAX(LENGTH(a)) LENGTH(MAX(a)) MIN(a) MAX 20 20 18446668621106209655 18446668621106209655 18446668621106209655 18446668621106209655 DROP TABLE t1; # +# Bug #11766270 59343: YEAR(4): INCORRECT RESULT AND VALGRIND WARNINGS WITH MIN/MAX, UNION +# +CREATE TABLE t1(f1 YEAR(4)); +INSERT INTO t1 VALUES (0000),(2001); +(SELECT MAX(f1) FROM t1) UNION (SELECT MAX(f1) FROM t1); +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def MAX(f1) MAX(f1) 13 4 4 Y 32864 0 63 +MAX(f1) +2001 +DROP TABLE t1; +# End of 5.1 tests === modified file 'mysql-test/r/func_in.result' --- a/mysql-test/r/func_in.result 2010-06-22 18:53:08 +0000 +++ b/mysql-test/r/func_in.result 2011-04-12 09:51:36 +0000 @@ -770,4 +770,10 @@ CASE a WHEN a THEN a END NULL DROP TABLE t1; # +# Bug #11766212 59270: NOT IN (YEAR( ... ), ... ) PRODUCES MANY VALGRIND WARNINGS +# +SELECT 1 IN (YEAR(FROM_UNIXTIME(NULL)) ,1); +1 IN (YEAR(FROM_UNIXTIME(NULL)) ,1) +1 +# End of 5.1 tests === modified file 'mysql-test/t/func_group.test' --- a/mysql-test/t/func_group.test 2011-03-31 18:59:11 +0000 +++ b/mysql-test/t/func_group.test 2011-04-12 10:01:33 +0000 @@ -1128,5 +1128,17 @@ SELECT MAX(LENGTH(a)), LENGTH(MAX(a)), M DROP TABLE t1; --echo # +--echo # Bug #11766270 59343: YEAR(4): INCORRECT RESULT AND VALGRIND WARNINGS WITH MIN/MAX, UNION +--echo # + +CREATE TABLE t1(f1 YEAR(4)); +INSERT INTO t1 VALUES (0000),(2001); +--enable_metadata +(SELECT MAX(f1) FROM t1) UNION (SELECT MAX(f1) FROM t1); +--disable_metadata +DROP TABLE t1; + + +--echo # --echo End of 5.1 tests === modified file 'mysql-test/t/func_in.test' --- a/mysql-test/t/func_in.test 2010-06-22 18:53:08 +0000 +++ b/mysql-test/t/func_in.test 2011-04-12 09:51:36 +0000 @@ -555,5 +555,11 @@ SELECT CASE a WHEN a THEN a END FROM t1 DROP TABLE t1; --echo # +--echo # Bug #11766212 59270: NOT IN (YEAR( ... ), ... ) PRODUCES MANY VALGRIND WARNINGS +--echo # + +SELECT 1 IN (YEAR(FROM_UNIXTIME(NULL)) ,1); + +--echo # --echo End of 5.1 tests === modified file 'sql/field.cc' --- a/sql/field.cc 2011-02-08 11:52:33 +0000 +++ b/sql/field.cc 2011-04-12 10:01:33 +0000 @@ -5467,6 +5467,7 @@ double Field_year::val_real(void) longlong Field_year::val_int(void) { ASSERT_COLUMN_MARKED_FOR_READ; + DBUG_ASSERT(field_length == 2 || field_length == 4); int tmp= (int) ptr[0]; if (field_length != 4) tmp%=100; // Return last 2 char @@ -5479,6 +5480,7 @@ longlong Field_year::val_int(void) String *Field_year::val_str(String *val_buffer, String *val_ptr __attribute__((unused))) { + DBUG_ASSERT(field_length < 5); val_buffer->alloc(5); val_buffer->length(field_length); char *to=(char*) val_buffer->ptr(); === modified file 'sql/item_cmpfunc.cc' --- a/sql/item_cmpfunc.cc 2011-03-03 20:11:47 +0000 +++ b/sql/item_cmpfunc.cc 2011-04-12 09:51:36 +0000 @@ -4000,13 +4000,11 @@ void Item_func_in::fix_length_and_dec() uint j=0; for (uint i=1 ; i < arg_count ; i++) { - if (!args[i]->null_value) // Skip NULL values - { - array->set(j,args[i]); - j++; - } - else - have_null= 1; + array->set(j,args[i]); + if (!args[i]->null_value) // Skip NULL values + j++; + else + have_null= 1; } if ((array->used_count= j)) array->sort(); === modified file 'sql/item_sum.cc' --- a/sql/item_sum.cc 2011-02-22 21:03:32 +0000 +++ b/sql/item_sum.cc 2011-04-12 10:01:33 +0000 @@ -612,17 +612,13 @@ Item_sum_hybrid::fix_fields(THD *thd, It switch (hybrid_type= item->result_type()) { case INT_RESULT: - max_length= 20; - break; case DECIMAL_RESULT: + case STRING_RESULT: max_length= item->max_length; break; case REAL_RESULT: max_length= float_length(decimals); break; - case STRING_RESULT: - max_length= item->max_length; - break; case ROW_RESULT: default: DBUG_ASSERT(0); No bundle (reason: useless for push emails).