From 56bff85247cfa97aef87193792b8c321c12412fc Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Tue, 12 Apr 2011 13:51:36 +0400 Subject: [PATCH 1/2] 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 | 6 ++++++ mysql-test/t/func_in.test | 6 ++++++ sql/item_cmpfunc.cc | 12 +++++------- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/func_in.result b/mysql-test/r/func_in.result index fdeec2755ca..0b6117581f3 100644 --- a/mysql-test/r/func_in.result +++ b/mysql-test/r/func_in.result @@ -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 diff --git a/mysql-test/t/func_in.test b/mysql-test/t/func_in.test index 6efeb2866e6..08469b37967 100644 --- a/mysql-test/t/func_in.test +++ b/mysql-test/t/func_in.test @@ -554,6 +554,12 @@ SELECT CASE a WHEN a THEN a END FROM t1 GROUP BY a WITH ROLLUP; 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 diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 36ca5537eb5..23f081e1cc0 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -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(); From 60cc2f91d6848ced6be1463a22d21b5b9d2c2dab Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Tue, 12 Apr 2011 14:01:33 +0400 Subject: [PATCH 2/2] 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 | 11 +++++++++++ mysql-test/t/func_group.test | 12 ++++++++++++ sql/field.cc | 2 ++ sql/item_sum.cc | 6 +----- 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index 69bce1c8bd8..b90eb2a4c0f 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -1746,4 +1746,15 @@ MAX(LENGTH(a)) LENGTH(MAX(a)) MIN(a) MAX(a) CONCAT(MIN(a)) CONCAT(MAX(a)) 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 diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test index 600b46fcde6..177a1ca2471 100644 --- a/mysql-test/t/func_group.test +++ b/mysql-test/t/func_group.test @@ -1127,6 +1127,18 @@ INSERT INTO t1 VALUES (18446668621106209655); SELECT MAX(LENGTH(a)), LENGTH(MAX(a)), MIN(a), MAX(a), CONCAT(MIN(a)), CONCAT(MAX(a)) FROM t1; 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 diff --git a/sql/field.cc b/sql/field.cc index 1ad5e408e07..3707c5b056f 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -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(); diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 2a8aea68f7a..c62738abac0 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -612,17 +612,13 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref) 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);