List:Commits« Previous MessageNext Message »
From:Gleb Shchepa Date:May 18 2009 4:21am
Subject:bzr commit into mysql-5.1-bugteam branch (gshchepa:2883) Bug#44768
View as plain text  
#At file:///home/uchum/work/bzr/mysql-5.1-bugteam/ based on revid:kristofer.pettersson@stripped

 2883 Gleb Shchepa	2009-05-18
      Bug #44768: SIGFPE crash when selecting rand from a view containing null
      
      The RAND(N) function where the N is a field of "constant" table
      (table of single row) failed with a SIGFPE.
      
      Evaluation of RAND(N) rely on constant status of its argument.
      Current server "seeded" random value for each constant argument
      only once, in the Item_func_rand::fix_fields method.
      Then the server skipped a call to seed_random() in the
      Item_func_rand::val_real method for such constant arguments.
      
      However, non-constant state of an argument may be changed
      after the call to fix_fields, if an argument is a field of
      "constant" table. Thus, pre-initialization of random value
      in the fix_fields method is too early.
      
      
      Initialization of random value by seed_random() has been
      removed from Item_func_rand::fix_fields method.
      The Item_func_rand::val_real method has been modified to
      call seed_random() on the first evaluation of this method
      if an argument is a function.
     @ mysql-test/r/func_math.result
        Added test case for bug #44768.
     @ mysql-test/t/func_math.test
        Added test case for bug #44768.
     @ sql/item_func.cc
        Bug #44768: SIGFPE crash when selecting rand from a view containing null
        
        1. Initialization of random value by seed_random() has been
           removed from Item_func_rand::fix_fields method.
        2. The Item_func_rand::val_real method has been modified to
           call seed_random() on the first evaluation of this method
           if an argument is a function.
     @ sql/item_func.h
        Bug #44768: SIGFPE crash when selecting rand from a view containing null
        
        1. The Item_func_rand::first_eval has been added to trace
           the first evaluation of the val_real method.
        2. The Item_func_rand::cleanup method has been added to
           cleanup the first_eval flag.

    modified:
      mysql-test/r/func_math.result
      mysql-test/t/func_math.test
      sql/item_func.cc
      sql/item_func.h
=== modified file 'mysql-test/r/func_math.result'
--- a/mysql-test/r/func_math.result	2009-02-23 12:42:31 +0000
+++ b/mysql-test/r/func_math.result	2009-05-18 04:21:25 +0000
@@ -456,4 +456,23 @@ NULL
 SELECT POW(10, 309);
 POW(10, 309)
 NULL
+#
+# Bug #44768: SIGFPE crash when selecting rand from a view
+#             containing null
+#
+CREATE OR REPLACE VIEW v1 AS SELECT NULL AS a;
+SELECT RAND(a) FROM v1;
+RAND(a)
+0.155220427694936
+DROP VIEW v1;
+SELECT RAND(a) FROM (SELECT NULL AS a) b;
+RAND(a)
+0.155220427694936
+CREATE TABLE t1 (i INT);
+INSERT INTO t1 VALUES (NULL);
+SELECT RAND(i) FROM t1;
+RAND(i)
+0.155220427694936
+DROP TABLE t1;
+#
 End of 5.1 tests

=== modified file 'mysql-test/t/func_math.test'
--- a/mysql-test/t/func_math.test	2009-02-23 12:42:31 +0000
+++ b/mysql-test/t/func_math.test	2009-05-18 04:21:25 +0000
@@ -282,4 +282,22 @@ SELECT 1e300 / 1e-300;
 SELECT EXP(750);
 SELECT POW(10, 309);
 
+--echo #
+--echo # Bug #44768: SIGFPE crash when selecting rand from a view
+--echo #             containing null
+--echo #
+
+CREATE OR REPLACE VIEW v1 AS SELECT NULL AS a;
+SELECT RAND(a) FROM v1;
+DROP VIEW v1;
+
+SELECT RAND(a) FROM (SELECT NULL AS a) b;
+
+CREATE TABLE t1 (i INT);
+INSERT INTO t1 VALUES (NULL);
+SELECT RAND(i) FROM t1;
+DROP TABLE t1;
+
+--echo #
+
 --echo End of 5.1 tests

=== modified file 'sql/item_func.cc'
--- a/sql/item_func.cc	2009-05-15 13:25:29 +0000
+++ b/sql/item_func.cc	2009-05-18 04:21:25 +0000
@@ -2143,9 +2143,6 @@ bool Item_func_rand::fix_fields(THD *thd
     if (!rand && !(rand= (struct rand_struct*)
                    thd->stmt_arena->alloc(sizeof(*rand))))
       return TRUE;
-
-    if (args[0]->const_item())
-      seed_random (args[0]);
   }
   else
   {
@@ -2175,8 +2172,21 @@ void Item_func_rand::update_used_tables(
 double Item_func_rand::val_real()
 {
   DBUG_ASSERT(fixed == 1);
-  if (arg_count && !args[0]->const_item())
-    seed_random (args[0]);
+  if (arg_count)
+  {
+    if (!args[0]->const_item())
+      seed_random(args[0]);
+    else if (first_eval)
+    {
+      /*
+        Constantness of args[0] may be set during JOIN::optimize(), if arg[0]
+        is a field item of "constant" table. Thus, we have to evaluate
+        seed_random() for constant arg there but not at the fix_fields method.
+      */
+      first_eval= FALSE;
+      seed_random(args[0]);
+    }
+  }
   return my_rnd(rand);
 }
 

=== modified file 'sql/item_func.h'
--- a/sql/item_func.h	2009-05-15 13:03:22 +0000
+++ b/sql/item_func.h	2009-05-18 04:21:25 +0000
@@ -696,14 +696,16 @@ public:
 class Item_func_rand :public Item_real_func
 {
   struct rand_struct *rand;
+  bool first_eval; // TRUE if val_real() is called 1st time
 public:
-  Item_func_rand(Item *a) :Item_real_func(a), rand(0) {}
+  Item_func_rand(Item *a) :Item_real_func(a), rand(0), first_eval(TRUE) {}
   Item_func_rand()	  :Item_real_func() {}
   double val_real();
   const char *func_name() const { return "rand"; }
   bool const_item() const { return 0; }
   void update_used_tables();
   bool fix_fields(THD *thd, Item **ref);
+  void cleanup() { first_eval= TRUE; Item_real_func::cleanup(); }
 private:
   void seed_random (Item * val);  
 };


Attachment: [text/bzr-bundle] bzr/gshchepa@mysql.com-20090518042125-wr0asj8n8p94b1vi.bundle
Thread
bzr commit into mysql-5.1-bugteam branch (gshchepa:2883) Bug#44768Gleb Shchepa18 May