From 405bd2af117384e009c3feffe1fd7d9019bf9d2b Mon Sep 17 00:00:00 2001
From: Gleb Shchepa <gshchepa@mysql.com>
Date: Mon, 18 May 2009 09:21:25 +0500
Subject: 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.
---
 sql/item_func.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(limited to 'sql/item_func.h')

diff --git a/sql/item_func.h b/sql/item_func.h
index 147dfcc9d36..e512c94efc1 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -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);  
 };
-- 
cgit v1.2.1