#At file:///home/uchum/work/bzr/44768-5.1/ based on revid:anurag.shekhar@stripped
2880 Gleb Shchepa 2009-05-14
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-14 13:13:15 +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-14 13:13:15 +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-10 16:20:35 +0000
+++ b/sql/item_func.cc 2009-05-14 13:13:15 +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,16 @@ 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)
+ {
+ first_eval= FALSE;
+ seed_random(args[0]);
+ }
+ }
return my_rnd(rand);
}
=== modified file 'sql/item_func.h'
--- a/sql/item_func.h 2009-05-10 16:20:35 +0000
+++ b/sql/item_func.h 2009-05-14 13:13:15 +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-20090514131315-wu8poit2o0gml2a5.bundle
| Thread |
|---|
| • bzr commit into mysql-5.1-bugteam branch (gshchepa:2880) Bug#44768 | Gleb Shchepa | 14 May |