Bug #44768 SIGFPE crash when selecting rand from a view containing null

Submitted: 10 May 2009 20:45 Modified: 26 Jun 2009 2:27
Reporter: Shane Bester (Platinum Quality Contributor) Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: DML Severity:S1 (Critical)
Version:5.1.30, 5.1.34, 5.1.35 OS:Linux (32-bit fc8)
Assigned to: Gleb Shchepa CPU Architecture:Any
Tags: crash, rand, regression, SIGFPE

[10 May 2009 20:45] Shane Bester
Description:
SIGFPE crash when selecting rand from a view containing null. 5.1.35 output (cut):

Program received signal SIGFPE, Arithmetic exception.
[Switching to Thread -1271317616 (LWP 9207)]
0x081fd6c3 in my_rnd (rand_st=0x9cc93c8) at password.c:101
101       rand_st->seed1=(rand_st->seed1*3+rand_st->seed2) % rand_st->max_value;
Current language:  auto; currently c

(gdb) bt
 my_rnd (rand_st=0x9cc93c8) at password.c:101
 Item_func_rand::val_real (this=0x9cc84c8) at item_func.cc:2180
 Item::send at item.cc:5350
 select_send::send_data  at sql_class.cc:1587
 end_send  at sql_select.cc:11976
 in do_select at sql_select.cc:10854
 JOIN::exec at sql_select.cc:2199
 mysql_select at sql_select.cc:2378
 handle_select  at sql_select.cc:268
 execute_sqlcom_select at sql_parse.cc:5009
 mysql_execute_command at sql_parse.cc:2211
 mysql_parse at sql_parse.cc:5929
 dispatch_command at sql_parse.cc:1216
 do_command (thd=0x9ca86d8) at sql_parse.cc:857
 handle_one_connection (arg=0x9ca86d8) at sql_connect.cc:1115
 start_thread () from /lib/i686/nosegneg/libpthread.so.0

How to repeat:
create or replace view `vt` as select null as `a`;
select rand(`a`) from `vt` limit 1;
[10 May 2009 21:11] Shane Bester
5.0 gives correct response: ERROR 1210 (HY000): Incorrect arguments to RAND.
so, this is a regression.
[14 May 2009 5:36] Gleb Shchepa
Analysis:

This issue is a regression of the bugfix for bug #6172.

The problem is wider: not only views returning NULL are affected, but any "constant" table (i.e. a table returning only 1 row):

1. select rand(a) from (select null as a) b;

or even

2. CREATE TABLE t1 (i INT);
   INSERT INTO t1 VALUES (1);
   SELECT RAND(i) FROM t1;

This problem is caused in Item_func_rand::val_real() 
by uninitialized memory:

2175	double Item_func_rand::val_real()
2176	{
2177	  DBUG_ASSERT(fixed == 1);
2178	  if (arg_count && !args[0]->const_item())
2179	    seed_random (args[0]);
2180	  return my_rnd(rand);
2181	}

(gdb) p/x *rand
$1 = {
  seed1 = 0x8f8f8f8f, 
  seed2 = 0x8f8f8f8f, 
  max_value = 0x8f8f8f8f, 
  max_value_dbl = 0x0
}

The root cause is constantness of a field item arg[0]:
at Item_func_rand:val_real() it is constant, so it supposes
that seed_random() was called at Item_func_rand::fix_fields():

2147	    if (args[0]->const_item())
2148	      seed_random (args[0]);

but there args[0]->const_item() is false! So it never call
seed_random() for this item, and *Item_func_rand::rand is
uninitialized.

The constant state of a field item arg[0] is changed because
of an execution order:

1. Item_func_rand::fix_fields() is called from JOIN::prepare,
at that moment tables in the FROM list are not constant;

2. JOIN::optimize() --> make_join_statistics() --> join_read_const_table()
marks some tables as constant.

3. JOIN:execute() calls Item_func_rand::var_real(), where arg[0]->const_item() is changed.
[14 May 2009 13:36] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/74052

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.
[15 May 2009 9:08] Georgi Kodinov
Gleb,

Check what our docs say : 
http://dev.mysql.com/doc/refman/5.1/en/mathematical-functions.html#function_rand.

Basically if a constant argument is specified we need to initialize only once (as this is documented). 
And if non-constant initializer is specified (a column name etc) it will initialize on each evaluation.
[18 May 2009 5:19] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/74331

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.
[28 May 2009 8:17] Bugs System
Pushed into 5.1.36 (revid:joro@sun.com-20090528073639-yohsb4q1jzg7ycws) (version source revid:kristofer.pettersson@sun.com-20090518083544-lm5vcjzm0id10y12) (merge vers: 5.1.36) (pib:6)
[2 Jun 2009 16:52] Paul DuBois
Noted in 5.1.36 changelog.

Selecting RAND(N) function where N is a column of a constant table
(table with a single row) failed with a SIGFPE signal. 

Setting report to NDI pending push into 6.0.x.
[17 Jun 2009 19:24] Bugs System
Pushed into 5.4.4-alpha (revid:alik@sun.com-20090616183122-chjzbaa30qopdra9) (version source revid:gshchepa@mysql.com-20090518050211-88uzx48nvazgyhh6) (merge vers: 6.0.12-alpha) (pib:11)
[26 Jun 2009 2:27] Paul DuBois
Noted in 5.4.4 changelog.
[12 Aug 2009 22:28] Paul DuBois
Noted in 5.4.2 changelog because next 5.4 version will be 5.4.2 and not 5.4.4.
[15 Aug 2009 1:47] Paul DuBois
Ignore previous comment about 5.4.2.
[26 Aug 2009 13:46] Bugs System
Pushed into 5.1.37-ndb-7.0.8 (revid:jonas@mysql.com-20090826132541-yablppc59e3yb54l) (version source revid:jonas@mysql.com-20090826132541-yablppc59e3yb54l) (merge vers: 5.1.37-ndb-7.0.8) (pib:11)
[26 Aug 2009 13:46] Bugs System
Pushed into 5.1.37-ndb-6.3.27 (revid:jonas@mysql.com-20090826105955-bkj027t47gfbamnc) (version source revid:jonas@mysql.com-20090826105955-bkj027t47gfbamnc) (merge vers: 5.1.37-ndb-6.3.27) (pib:11)
[26 Aug 2009 13:48] Bugs System
Pushed into 5.1.37-ndb-6.2.19 (revid:jonas@mysql.com-20090825194404-37rtosk049t9koc4) (version source revid:jonas@mysql.com-20090825194404-37rtosk049t9koc4) (merge vers: 5.1.37-ndb-6.2.19) (pib:11)
[27 Aug 2009 16:32] Bugs System
Pushed into 5.1.35-ndb-7.1.0 (revid:magnus.blaudd@sun.com-20090827163030-6o3kk6r2oua159hr) (version source revid:jonas@mysql.com-20090826132541-yablppc59e3yb54l) (merge vers: 5.1.37-ndb-7.0.8) (pib:11)
[7 Oct 2009 19:34] Paul DuBois
The 5.4 fix has been pushed to 5.4.2.

Portions of this website are copyright © 2001, 2002 The PHP Group

Page generated in 0.085 sec. using MySQL 8.4.7-u6-cloud

Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the respective copyright holders.
It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.