Bug #48052 Valgrind warning - uninitialized value in init_read_record() - (records.cc:274)
Submitted: 14 Oct 2009 18:58 Modified: 12 Mar 2010 17:14
Reporter: Patrick Crews Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Optimizer Severity:S3 (Non-critical)
Version:5.1,6.0 OS:Any
Assigned to: Jørgen Løland CPU Architecture:Any
Tags: uninitialised value, valgrind, warning

[14 Oct 2009 18:58] Patrick Crews
Description:
Valgrind warning detected during an RQG run of subquery_materialization.yy
Used the 6.0-codebase-bugfixing tree

Query preceding the valgrind warning:
SELECT  STD( OUTR . `datetime_key` ) AS X FROM B AS OUTR2 LEFT JOIN C AS OUTR ON ( OUTR2 . `time_nokey` <= OUTR . `datetime_nokey` ) WHERE OUTR . `pk` IN ( SELECT  INNR . `int_key` AS Y FROM CC AS INNR2 LEFT JOIN BB AS INNR ON ( INNR2 . `varchar_key` <> INNR . `varchar_nokey` ) WHERE INNR . `pk` IS NOT NULL  ) AND OUTR . `datetime_nokey` >= '2003-09-24' AND OUTR . `int_key` IS NULL HAVING X < '14:47:17' ORDER BY OUTR . `date_key` , OUTR . `pk`
Wed Oct 14 13:55:21 2009 [9416] Query: SELECT DISTINCT OUTR . `datetime_key` AS X FROM B AS OUTR WHERE ( OUTR . `varchar_nokey` , OUTR . `varchar_nokey` ) IN ( SELECT  INNR . `varchar_key` AS X , INNR . `varchar_key` AS Y FROM CC AS INNR WHERE INNR . `varchar_nokey` <> 'p' XOR OUTR . `date_nokey` > '2004-06-22' ORDER BY INNR . `varchar_key` ) OR OUTR . `time_key` IS NULL XOR OUTR . `datetime_nokey` BETWEEN '2009-10-25' AND '2000-09-26' HAVING X >= '10:38:14' ORDER BY OUTR . `int_key` , OUTR . `pk

Warning body:

5733:==9372== Thread 26:
5734:==9372== Conditional jump or move depends on uninitialised value(s)
5735:==9372==    at 0x84501AF: init_read_record(READ_RECORD*, THD*, TABLE*, SQL_SELECT*, int, bool, bool) (records.cc:274)
5736:==9372==    by 0x8385BE8: join_init_read_record(st_join_table*) (sql_select.cc:17075)
5737:==9372==    by 0x8389ED6: sub_select(JOIN*, st_join_table*, bool) (sql_select.cc:16265)
5738:==9372==    by 0x839760B: do_select(JOIN*, List<Item>*, TABLE*, Procedure*) (sql_select.cc:15828)
5739:==9372==    by 0x83AFE76: JOIN::exec() (sql_select.cc:2896)
5740:==9372==    by 0x83AA4BC: mysql_select(THD*, Item***, TABLE_LIST*, unsigned int, List<Item>&, Item*, unsigned int, st_order*, st_order*, Item*, st_order*, unsigned long long, select_result*, st_select_lex_unit*, st_select_lex*) (sql_select.cc:3087)
5741:==9372==    by 0x83B01A7: handle_select(THD*, LEX*, select_result*, unsigned long) (sql_select.cc:307)
5742:==9372==    by 0x830A792: execute_sqlcom_select(THD*, TABLE_LIST*) (sql_parse.cc:4976)
5743:==9372==    by 0x830C8F6: mysql_execute_command(THD*) (sql_parse.cc:2121)
5744:==9372==    by 0x8315CD6: mysql_parse(THD*, char const*, unsigned int, char const**) (sql_parse.cc:5991)
5745:==9372==    by 0x8316854: dispatch_command(enum_server_command, THD*, char*, unsigned int) (sql_parse.cc:1074)
5746:==9372==    by 0x8317D6D: do_command(THD*) (sql_parse.cc:756)
5747:==9372==    by 0x8303C39: handle_one_connection (sql_connect.cc:1164)
5748:==9372==    by 0x40494FE: start_thread (in /lib/tls/i686/cmov/libpthread-2.9.so)
5749:==9372==    by 0x42B449D: clone (in /lib/tls/i686/cmov/libc-2.9.so)

How to repeat:
perl ./runall.pl --threads=1 --basedir=<path>/mysql-6.0-codebase-bugfixing --validator=MarkErrorLog --valgrind --views  --queries=100000 --mysqld=--init-file=/home/pcrews/bzr/work/optimizer_retest/6.sql --grammar=conf/subquery_materialization.yy --reporter=Shutdown

init-file contents:
SET GLOBAL OPTIMIZER_SWITCH = 'materialization=off,semijoin=off,loosescan=off,firstmatch=off';

SET GLOBAL optimizer_use_mrr = 'disable';

SET GLOBAL debug = '+d,optimizer_no_icp';

SET GLOBAL engine_condition_pushdown = 1;

SET GLOBAL join_cache_level = 1;
[27 Oct 2009 17:39] Patrick Crews
MTR test case.  Run with the --valgrind switch to repeat the error.

Attachment: bug48052_test.txt (text/plain), 8.05 KiB.

[6 Nov 2009 9:45] Jørgen Løland
Very simplified testcase that fails in the same way:

/*!50400 SET SESSION optimizer_switch =
'firstmatch=off,index_merge=off,index_merge_union=off,index_merge_sort_union=off,index_merge_intersection=off,loosescan=off,materialization=off,semijoin=off'
*/;
/*!50400 SET SESSION engine_condition_pushdown = 'OFF' */;

CREATE TABLE t1 (
  pk int(11) NOT NULL,
  i int(11) DEFAULT NULL,
  v varchar(1) DEFAULT NULL,
  PRIMARY KEY (pk)
) ENGINE=MyISAM;

INSERT INTO t1 VALUES (2,7,'m');
INSERT INTO t1 VALUES (3,9,'m');

SELECT  v
FROM t1
WHERE NOT pk > 0  
HAVING v <= 't' 
ORDER BY pk;

DROP TABLE t1;
[6 Nov 2009 13:44] Jørgen Løland
The uninitialized variable is 

select->cond->used_tables_cache 
accessed through (item_cmpfunc.cc):

table_map
Item_cond::used_tables() const
{						// This caches used_tables
  return used_tables_cache;
}

This Item_cond is an Item_cond_and item created in JOIN::exec() (sql_select.cc around line 2810):

if (!curr_table->select->cond)
  curr_table->select->cond= sort_table_cond;
else					// This should never happen
{
  if (!(curr_table->select->cond=
	new Item_cond_and(curr_table->select->cond,     // ** HERE **
			  sort_table_cond)))
    DBUG_VOID_RETURN;
  /*
    Item_cond_and do not need fix_fields for execution, its parameters
    are fixed or do not need fix_fields, too
  */
  curr_table->select->cond->quick_fix_field();
}

The correct value for used_tables_cache table_map is "OR" of the two arguments to the Item_cond_and constructor.

I see two possible solutions: 
 1) call fix_fields instead of quick_fix_field.
 2) set used_tables_cache directly:
    curr_table->select->cond->used_tables_cache= "item1"->u_t_c | "item2"->u_t_c
[9 Nov 2009 7:14] Jørgen Løland
Another alternative:
 3) Call curr_table->select->cond->update_used_tables() after quick_fix_field()

Alternative 3 will update only the used_tables_cache variable in the item. However, although alternative 3 seems to be cheaper than 1, update_used_tables() recursively calls update_used_tables() on it's "sub-items". fix_fields() is only recursive if the "sub-items" have not already been fixed (and they have been fixed at this point).
[9 Nov 2009 9:35] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/89746

3202 Jorgen Loland	2009-11-09
      Bug#48052: Valgrind warning - uninitialized value in 
                 init_read_record() - (records.cc:274)
      
      Item_cond::used_tables_cache was accessed in 
      records.cc#init_read_record() without being initialized.
      It had not been initialized because it was wrongly assumed 
      that the Item's variables would not be accessed, and hence
      quick_fix_field() was used instead of fix_fields() to save
      a few CPU cycles at creation time. 
      
      The fix is to properly initilize the Item by replacing 
      quick_fix_field() with fix_fields().
     @ mysql-test/r/select.result
        Add test for BUG#48052
     @ mysql-test/t/select.test
        Add test for BUG#48052
     @ sql/sql_select.cc
        Properly initialize Item_cond_and by calling fix_fields (instead of quick_fix_field) when the Item that "ANDs" WHERE clause conditions with HAVING clause conditions is created.
[13 Nov 2009 10:17] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/90322

3200 Jorgen Loland	2009-11-13
      Bug#48052: Valgrind warning - uninitialized value in 
                 init_read_record() - (records.cc:274)
            
      Item_cond::used_tables_cache was accessed in
      records.cc#init_read_record() without being initialized. It had
      not been initialized because it was wrongly assumed that the
      Item's variables would not be accessed, and hence
      quick_fix_field() was used instead of fix_fields() to save a few
      CPU cycles at creation time.
      
      The fix is to properly initilize the Item by replacing
      quick_fix_field() with fix_fields().
     @ mysql-test/r/select.result
        Add test for BUG#48052
     @ mysql-test/t/select.test
        Add test for BUG#48052
     @ sql/sql_select.cc
        Properly initialize Item_cond_and by calling fix_fields (instead of quick_fix_field) when the Item that "ANDs" WHERE clause conditions with HAVING clause conditions is created.
[13 Nov 2009 11:22] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/90332

3200 Jorgen Loland	2009-11-13
      Bug#48052: Valgrind warning - uninitialized value in 
                 init_read_record() - (records.cc:274)
            
      Item_cond::used_tables_cache was accessed in
      records.cc#init_read_record() without being initialized. It had
      not been initialized because it was wrongly assumed that the
      Item's variables would not be accessed, and hence
      quick_fix_field() was used instead of fix_fields() to save a few
      CPU cycles at creation time.
      
      The fix is to properly initilize the Item by replacing
      quick_fix_field() with fix_fields().
     @ mysql-test/r/select.result
        Add test for BUG#48052
     @ mysql-test/t/select.test
        Add test for BUG#48052
     @ sql/sql_select.cc
        Properly initialize Item_cond_and by calling fix_fields (instead of quick_fix_field) when the Item that "ANDs" WHERE clause conditions with HAVING clause conditions is created.
[13 Nov 2009 11:26] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/90334

3681 Jorgen Loland	2009-11-13 [merge]
      Merge BUG#48052 from mysql-5.1-bugteam to mysql-pe
[13 Nov 2009 11:32] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/90335

3682 Jorgen Loland	2009-11-13
      Turning engine_condition_pushdown off for test of BUG#48052 in the 6.0 codebase
[13 Nov 2009 11:34] Jørgen Løland
Pushed to mysql-5.1-bugteam and mysql-pe
[2 Dec 2009 8:03] Bugs System
Pushed into 5.1.42 (revid:joro@sun.com-20091202080033-mndu4sxwx19lz2zs) (version source revid:davi.arnaut@sun.com-20091125130912-d7hrln14ef7y5d7i) (merge vers: 5.1.42) (pib:13)
[16 Dec 2009 8:35] Bugs System
Pushed into 6.0.14-alpha (revid:alik@sun.com-20091216083311-xorsasf5kopjxshf) (version source revid:alik@sun.com-20091214191830-wznm8245ku8xo702) (merge vers: 6.0.14-alpha) (pib:14)
[16 Dec 2009 8:42] Bugs System
Pushed into 5.5.0-beta (revid:alik@sun.com-20091216082430-s0gtzibcgkv4pqul) (version source revid:alexey.kopytov@sun.com-20091124083136-iqm136jm31sfdwg3) (merge vers: 5.5.0-beta) (pib:14)
[16 Dec 2009 8:48] Bugs System
Pushed into mysql-next-mr (revid:alik@sun.com-20091216083231-rp8ecpnvkkbhtb27) (version source revid:alik@sun.com-20091212203859-fx4rx5uab47wwuzd) (merge vers: 5.6.0-beta) (pib:14)
[18 Dec 2009 1:53] Paul DuBois
No changelog entry needed. Little user impact.
[16 Feb 2010 15:05] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/100517

3344 Sergey Glukhov	2010-02-16
      Bug#50995 Having clause on subquery result produces incorrect results.
      This is the result of bug#48052 fix.
      The problem is that we can not use cond->fix_fields(thd, 0) here as
      it will break condition if it's AND condition. In our case fix_fields()
      cuts off 'having' condition.
      The fix:
      reverted fix_fields() to quick_fix_field() and
      updated cond->used_tables_cache with appropriate value.
     @ mysql-test/r/having.result
        test result
     @ mysql-test/t/having.test
        test case
     @ sql/sql_select.cc
        reverted fix_fields() to quick_fix_field() and
        updated cond->used_tables_cache with appropriate value.
[12 Mar 2010 14:06] Bugs System
Pushed into 5.1.44-ndb-7.0.14 (revid:jonas@mysql.com-20100312135944-t0z8s1da2orvl66x) (version source revid:jonas@mysql.com-20100312115609-woou0te4a6s4ae9y) (merge vers: 5.1.44-ndb-7.0.14) (pib:16)
[12 Mar 2010 14:22] Bugs System
Pushed into 5.1.44-ndb-6.2.19 (revid:jonas@mysql.com-20100312134846-tuqhd9w3tv4xgl3d) (version source revid:jonas@mysql.com-20100312060623-mx6407w2vx76h3by) (merge vers: 5.1.44-ndb-6.2.19) (pib:16)
[12 Mar 2010 14:36] Bugs System
Pushed into 5.1.44-ndb-6.3.33 (revid:jonas@mysql.com-20100312135724-xcw8vw2lu3mijrhn) (version source revid:jonas@mysql.com-20100312103652-snkltsd197l7q2yg) (merge vers: 5.1.44-ndb-6.3.33) (pib:16)
[12 Mar 2010 17:14] Paul DuBois
No changelog entry needed.