List:Commits« Previous MessageNext Message »
From:Tor Didriksen Date:February 11 2011 8:49am
Subject:bzr commit into mysql-5.5 branch (tor.didriksen:3323) Bug#60085
View as plain text  
#At file:///export/home/didrik/repo/5.5-bug60085nulltime/ based on revid:alexander.barkov@stripped

 3323 Tor Didriksen	2011-02-11
      Bug #60085 crash in Item::save_in_field() with time data type
      
      Item_singlerow_subselect::val_str() incorrectly assumed that
      value->val_str() could set value->null_value= true;
     @ mysql-test/r/subselect_innodb.result
        New test case.
     @ mysql-test/t/subselect_innodb.test
        New test case.
     @ sql/item.cc
        Add some DBUG_TRACE for easier bug-hunting.
     @ sql/item_subselect.cc
        Item_singlerow_subselect::val_xxx() should do
            null_value= value->null_value;
        rather than
            null_value= false;
        Add some DBUG_TRACE for easier bug-hunting.

    modified:
      mysql-test/r/subselect_innodb.result
      mysql-test/t/subselect_innodb.test
      sql/item.cc
      sql/item_subselect.cc
=== modified file 'mysql-test/r/subselect_innodb.result'
--- a/mysql-test/r/subselect_innodb.result	2006-01-26 16:54:34 +0000
+++ b/mysql-test/r/subselect_innodb.result	2011-02-11 08:48:59 +0000
@@ -245,3 +245,11 @@ x
 NULL
 drop procedure p1;
 drop tables t1,t2,t3;
+#
+# Bug#60085 crash in Item::save_in_field() with time data type
+#
+CREATE TABLE t1(a date, b int, unique(b), unique(a), key(b)) engine=innodb;
+INSERT INTO t1 VALUES ('2011-05-13', 0);
+SELECT 1 FROM t1 WHERE b < (SELECT CAST(a as date) FROM t1 GROUP BY a);
+1
+DROP TABLE t1;

=== modified file 'mysql-test/t/subselect_innodb.test'
--- a/mysql-test/t/subselect_innodb.test	2006-01-26 16:54:34 +0000
+++ b/mysql-test/t/subselect_innodb.test	2011-02-11 08:48:59 +0000
@@ -238,3 +238,12 @@ call p1();
 call p1();
 drop procedure p1;
 drop tables t1,t2,t3;
+
+--echo #
+--echo # Bug#60085 crash in Item::save_in_field() with time data type
+--echo #
+
+CREATE TABLE t1(a date, b int, unique(b), unique(a), key(b)) engine=innodb;
+INSERT INTO t1 VALUES ('2011-05-13', 0);
+SELECT 1 FROM t1 WHERE b < (SELECT CAST(a as date) FROM t1 GROUP BY a); 
+DROP TABLE t1;

=== modified file 'sql/item.cc'
--- a/sql/item.cc	2011-01-12 12:58:47 +0000
+++ b/sql/item.cc	2011-02-11 08:48:59 +0000
@@ -1051,6 +1051,7 @@ CHARSET_INFO *Item::default_charset()
 
 int Item::save_in_field_no_warnings(Field *field, bool no_conversions)
 {
+  DBUG_ENTER("Item::save_in_field_no_warnings");
   int res;
   TABLE *table= field->table;
   THD *thd= table->in_use;
@@ -1059,11 +1060,13 @@ int Item::save_in_field_no_warnings(Fiel
   ulonglong sql_mode= thd->variables.sql_mode;
   thd->variables.sql_mode&= ~(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE);
   thd->count_cuted_fields= CHECK_FIELD_IGNORE;
+
   res= save_in_field(field, no_conversions);
+
   thd->count_cuted_fields= tmp;
   dbug_tmp_restore_column_map(table->write_set, old_map);
   thd->variables.sql_mode= sql_mode;
-  return res;
+  DBUG_RETURN(res);
 }
 
 
@@ -5373,6 +5376,7 @@ int Item_null::save_safe_in_field(Field 
 int Item::save_in_field(Field *field, bool no_conversions)
 {
   int error;
+  DBUG_ENTER("Item::save_in_field");
   if (result_type() == STRING_RESULT)
   {
     String *result;
@@ -5383,7 +5387,8 @@ int Item::save_in_field(Field *field, bo
     if (null_value)
     {
       str_value.set_quick(0, 0, cs);
-      return set_field_to_null_with_conversions(field, no_conversions);
+      int retval= set_field_to_null_with_conversions(field, no_conversions);
+      DBUG_RETURN(retval);
     }
 
     /* NOTE: If null_value == FALSE, "result" must be not NULL.  */
@@ -5396,8 +5401,10 @@ int Item::save_in_field(Field *field, bo
            field->result_type() == STRING_RESULT)
   {
     double nr= val_real();
-    if (null_value)
-      return set_field_to_null_with_conversions(field, no_conversions);
+    if (null_value) {
+      int retval= set_field_to_null_with_conversions(field, no_conversions);
+      DBUG_RETURN(retval);
+    }
     field->set_notnull();
     error= field->store(nr);
   }
@@ -5405,7 +5412,10 @@ int Item::save_in_field(Field *field, bo
   {
     double nr= val_real();
     if (null_value)
-      return set_field_to_null_with_conversions(field, no_conversions);
+    {
+      int retval= set_field_to_null_with_conversions(field, no_conversions);
+      DBUG_RETURN(retval);
+    }
     field->set_notnull();
     error=field->store(nr);
   }
@@ -5414,7 +5424,10 @@ int Item::save_in_field(Field *field, bo
     my_decimal decimal_value;
     my_decimal *value= val_decimal(&decimal_value);
     if (null_value)
-      return set_field_to_null_with_conversions(field, no_conversions);
+    {
+      int retval= set_field_to_null_with_conversions(field, no_conversions);
+      DBUG_RETURN(retval);
+    }
     field->set_notnull();
     error=field->store_decimal(value);
   }
@@ -5422,11 +5435,14 @@ int Item::save_in_field(Field *field, bo
   {
     longlong nr=val_int();
     if (null_value)
-      return set_field_to_null_with_conversions(field, no_conversions);
+    {
+      int retval= set_field_to_null_with_conversions(field, no_conversions);
+      DBUG_RETURN(retval);
+    }
     field->set_notnull();
     error=field->store(nr, unsigned_flag);
   }
-  return error ? error : (field->table->in_use->is_error() ? 1 : 0);
+  DBUG_RETURN(error ? error : (field->table->in_use->is_error() ? 1 : 0));
 }
 
 
@@ -7516,8 +7532,10 @@ String *Item_cache_datetime::val_str(Str
 {
   DBUG_ASSERT(fixed == 1);
 
+  DBUG_ENTER("Item_cache_datetime::val_str");
+
   if ((value_cached || str_value_cached) && null_value)
-    return NULL;
+    DBUG_RETURN(NULL);
 
   if (!str_value_cached)
   {
@@ -7535,7 +7553,7 @@ String *Item_cache_datetime::val_str(Str
       /* Return NULL in case of OOM/conversion error. */
       null_value= TRUE;
       if (str_value.alloc(MAX_DATE_STRING_REP_LENGTH))
-        return NULL;
+        DBUG_RETURN(NULL);
       if (cached_field_type == MYSQL_TYPE_TIME)
       {
         longlong time= int_value;
@@ -7558,7 +7576,7 @@ String *Item_cache_datetime::val_str(Str
         longlong res;
         res= number_to_datetime(int_value, &ltime, TIME_FUZZY_DATE, &was_cut);
         if (res == -1)
-          return NULL;
+          DBUG_RETURN(NULL);
       }
       str_value.length(my_TIME_to_str(&ltime,
                                       const_cast<char*>(str_value.ptr())));
@@ -7566,9 +7584,9 @@ String *Item_cache_datetime::val_str(Str
       null_value= FALSE;
     }
     else if (!cache_value())
-      return NULL;
+      DBUG_RETURN(NULL);
   }
-  return &str_value;
+  DBUG_RETURN(&str_value);
 }
 
 

=== modified file 'sql/item_subselect.cc'
--- a/sql/item_subselect.cc	2011-01-12 12:15:22 +0000
+++ b/sql/item_subselect.cc	2011-02-11 08:48:59 +0000
@@ -258,28 +258,31 @@ bool Item_subselect::exec()
 {
   int res;
 
+  DBUG_ENTER("Item_subselect::exec");
+
   /*
     Do not execute subselect in case of a fatal error
     or if the query has been killed.
   */
   if (thd->is_error() || thd->killed)
-    return 1;
+    DBUG_RETURN(1);
 
   DBUG_ASSERT(!thd->lex->context_analysis_only);
   /*
     Simulate a failure in sub-query execution. Used to test e.g.
     out of memory or query being killed conditions.
   */
-  DBUG_EXECUTE_IF("subselect_exec_fail", return 1;);
+  DBUG_EXECUTE_IF("subselect_exec_fail", DBUG_RETURN(1););
 
   res= engine->exec();
 
   if (engine_changed)
   {
     engine_changed= 0;
-    return exec();
+    bool retval= exec();
+    DBUG_RETURN(retval);
   }
-  return (res);
+  DBUG_RETURN(res);
 }
 
 Item::Type Item_subselect::type() const
@@ -572,8 +575,9 @@ double Item_singlerow_subselect::val_rea
   DBUG_ASSERT(fixed == 1);
   if (!exec() && !value->null_value)
   {
-    null_value= FALSE;
-    return value->val_real();
+    double retval= value->val_real();
+    null_value= value->null_value;
+    return retval;
   }
   else
   {
@@ -587,8 +591,9 @@ longlong Item_singlerow_subselect::val_i
   DBUG_ASSERT(fixed == 1);
   if (!exec() && !value->null_value)
   {
-    null_value= FALSE;
-    return value->val_int();
+    longlong retval= value->val_int();
+    null_value= value->null_value;
+    return retval;
   }
   else
   {
@@ -599,15 +604,17 @@ longlong Item_singlerow_subselect::val_i
 
 String *Item_singlerow_subselect::val_str(String *str)
 {
+  DBUG_ENTER("Item_singlerow_subselect::val_str");
   if (!exec() && !value->null_value)
   {
-    null_value= FALSE;
-    return value->val_str(str);
+    String *retval= value->val_str(str);
+    null_value= value->null_value;
+    DBUG_RETURN(retval);
   }
   else
   {
     reset();
-    return 0;
+    DBUG_RETURN(0);
   }
 }
 
@@ -616,8 +623,9 @@ my_decimal *Item_singlerow_subselect::va
 {
   if (!exec() && !value->null_value)
   {
-    null_value= FALSE;
-    return value->val_decimal(decimal_value);
+    my_decimal *retval= value->val_decimal(decimal_value);
+    null_value= value->null_value;
+    return retval;
   }
   else
   {
@@ -631,8 +639,9 @@ bool Item_singlerow_subselect::val_bool(
 {
   if (!exec() && !value->null_value)
   {
-    null_value= FALSE;
-    return value->val_bool();
+    bool retval= value->val_bool();
+    null_value= value->null_value;
+    return retval;
   }
   else
   {


Attachment: [text/bzr-bundle] bzr/tor.didriksen@oracle.com-20110211084859-pyhqsyyvj595fn42.bundle
Thread
bzr commit into mysql-5.5 branch (tor.didriksen:3323) Bug#60085Tor Didriksen11 Feb
  • Re: bzr commit into mysql-5.5 branch (tor.didriksen:3323) Bug#60085Øystein Grøvlen11 Feb
  • Re: bzr commit into mysql-5.5 branch (tor.didriksen:3323) Bug#60085Jorgen Loland11 Feb
    • Re: bzr commit into mysql-5.5 branch (tor.didriksen:3323) Bug#60085Øystein Grøvlen11 Feb
      • Re: bzr commit into mysql-5.5 branch (tor.didriksen:3323) Bug#60085Tor Didriksen11 Feb