List:Commits« Previous MessageNext Message »
From:Evgeny Potemkin Date:November 5 2008 3:40pm
Subject:bzr commit into mysql-5.1 branch (epotemkin:2694) Bug#37870
View as plain text  
#At file:///work/bzr_trees/37870-bug-5.1-bugteam/

 2694 Evgeny Potemkin	2008-11-05
      Bug#37870: Usage of uninitialized value caused failed assertion.
      
      The convert_constant_item function converts a constant to integer using
      field for condition like 'field = a_constant'. In some cases the
      convert_constant_item is called for a subquery when outer select is already
      being executed, so convert_constant_item saves field's value to prevent its
      corruption. For EXPLAIN and at the prepare phase field's value isn't
      initialized yet, thus when convert_constant_item tries to restore saved
      value it fails assertion.
      
      Now the convert_constant_item doesn't save/restore field's value if it's
      haven't been read yet. Outer constant values are always saved.
modified:
  BUILD/SETUP.sh
  mysql-test/r/explain.result
  mysql-test/t/explain.test
  sql/item_cmpfunc.cc

per-file messages:
  mysql-test/r/explain.result
    Added a test case for the bug#37870.
  mysql-test/t/explain.test
    Added a test case for the bug#37870.
  sql/item_cmpfunc.cc
    Bug#37870: Usage of uninitialized value caused failed assertion.
    Now the convert_constant_item doesn't save/restore field's value if it's
    haven't been read yet. Outer constant values are always saved.
=== modified file 'BUILD/SETUP.sh'
--- a/BUILD/SETUP.sh	2007-12-14 13:21:37 +0000
+++ b/BUILD/SETUP.sh	2008-11-05 15:40:23 +0000
@@ -80,7 +80,7 @@ path=`dirname $0`
 . "$path/check-cpu"
 
 export AM_MAKEFLAGS
-AM_MAKEFLAGS="-j 4"
+AM_MAKEFLAGS="-j 6"
 
 # SSL library to use.--with-ssl will select our bundled yaSSL
 # implementation of SSL. To use openSSl you will nee too point out
@@ -105,7 +105,7 @@ if [ "x$warning_mode" != "xpedantic" ]; 
   cxx_warnings="$cxx_warnings -Wreorder"
   cxx_warnings="$cxx_warnings -Wctor-dtor-privacy -Wnon-virtual-dtor"
 # Added unless --with-debug=full
-  debug_extra_cflags="-O1 -Wuninitialized"
+  debug_extra_cflags="-O0 -g3 -gdwarf-2" #1 -Wuninitialized"
 else
   warnings="-W -Wall -ansi -pedantic -Wno-long-long -Wno-unused -D_POSIX_SOURCE"
   c_warnings="$warnings"

=== modified file 'mysql-test/r/explain.result'
--- a/mysql-test/r/explain.result	2008-10-27 12:04:51 +0000
+++ b/mysql-test/r/explain.result	2008-11-05 15:40:23 +0000
@@ -158,15 +158,27 @@ DROP TABLE t1,t2;
 #
 # Bug#37870: Usage of uninitialized value caused failed assertion.
 #
-create table t1 (dt datetime not null);
+create table t1 (dt datetime not null, t time not null);
 create table t2 (dt datetime not null);
-insert into t1 values ('2001-01-01 1:1:1'), ('2001-01-01 1:1:1');
+insert into t1 values ('2001-01-01 1:1:1', '1:1:1'),
+('2001-01-01 1:1:1', '1:1:1');
 insert into t2 values ('2001-01-01 1:1:1'), ('2001-01-01 1:1:1');
 flush tables;
 EXPLAIN SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN (SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.dt IS NULL );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	OUTR	ALL	NULL	NULL	NULL	NULL	2	Using where
 2	DEPENDENT SUBQUERY	INNR	ALL	NULL	NULL	NULL	NULL	2	Using where
+flush tables;
 SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN (SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.dt IS NULL );
 dt
+flush tables;
+EXPLAIN SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN ( SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.t < '2005-11-13 7:41:31' );
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	OUTR	ALL	NULL	NULL	NULL	NULL	2	Using where
+2	DEPENDENT SUBQUERY	INNR	ALL	NULL	NULL	NULL	NULL	2	Using where
+flush tables;
+SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN ( SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.t < '2005-11-13 7:41:31' );
+dt
+2001-01-01 01:01:01
+2001-01-01 01:01:01
 drop tables t1, t2;

=== modified file 'mysql-test/t/explain.test'
--- a/mysql-test/t/explain.test	2008-10-27 12:04:51 +0000
+++ b/mysql-test/t/explain.test	2008-11-05 15:40:23 +0000
@@ -126,13 +126,19 @@ DROP TABLE t1,t2;
 --echo #
 --echo # Bug#37870: Usage of uninitialized value caused failed assertion.
 --echo #
-create table t1 (dt datetime not null);
+create table t1 (dt datetime not null, t time not null);
 create table t2 (dt datetime not null);
-insert into t1 values ('2001-01-01 1:1:1'), ('2001-01-01 1:1:1');
+insert into t1 values ('2001-01-01 1:1:1', '1:1:1'),
+('2001-01-01 1:1:1', '1:1:1');
 insert into t2 values ('2001-01-01 1:1:1'), ('2001-01-01 1:1:1');
 flush tables;
 EXPLAIN SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN (SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.dt IS NULL );
+flush tables;
 SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN (SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.dt IS NULL );
+flush tables;
+EXPLAIN SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN ( SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.t < '2005-11-13 7:41:31' ); 
+flush tables;
+SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN ( SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.t < '2005-11-13 7:41:31' );
 drop tables t1, t2;
 
 # End of 5.0 tests.

=== modified file 'sql/item_cmpfunc.cc'
--- a/sql/item_cmpfunc.cc	2008-10-27 16:19:26 +0000
+++ b/sql/item_cmpfunc.cc	2008-11-05 15:40:23 +0000
@@ -413,11 +413,15 @@ static bool convert_constant_item(THD *t
     thd->count_cuted_fields= CHECK_FIELD_IGNORE;
 
     /*
-      Store the value of the field/constant if it references an outer field because
-      the call to save_in_field below overrides that value.
-      Don't save value of the field for EXPLAIN since it's not initialized.
+      Store the value of the field/constant if it references an outer field
+      because the call to save_in_field below overrides that value.
+      Don't save field value if no data has been read yet.
+      Outer constant values are always saved.
     */
-    if (field_item->depended_from && (!thd->lex->describe || field_item->const_item()))
+    bool save_field_value= (field_item->depended_from &&
+                            (field_item->const_item() ||
+                             !(field->table->status & STATUS_NO_RECORD)));
+    if (save_field_value)
       orig_field_val= field->val_int();
     if (!(*item)->is_null() && !(*item)->save_in_field(field, 1))
     {
@@ -428,7 +432,7 @@ static bool convert_constant_item(THD *t
       result= 1;					// Item was replaced
     }
     /* Restore the original field value. */
-    if (field_item->depended_from && (!thd->lex->describe || field_item->const_item()))
+    if (save_field_value)
     {
       result= field->store(orig_field_val, TRUE);
       /* orig_field_val must be a valid value that can be restored back. */

Thread
bzr commit into mysql-5.1 branch (epotemkin:2694) Bug#37870Evgeny Potemkin5 Nov