MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Chad MILLER Date:July 19 2006 11:17pm
Subject:bk commit into 4.0 tree (cmiller:1.2188) BUG#15473
View as plain text  
Below is the list of changes that have just been committed into a local
4.0 repository of cmiller. When cmiller does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2006-07-19 19:17:41-04:00, cmiller@stripped +5 -0
  Bug #15473: RAND(N) no longer produces repeatable sequence
  
  The implicit assumption in this bug (at least by me) was that the random 
  number generator was nondeterministic, and that's a wrong assumption.  It 
  is deterministic, but the mechanism for setting the seed was broken. 
  
  Now, instead of only nonseeding RAND calls getting the state memory location 
  from the thread, both seeding and nonseeding calls get the memory location, 
  and since the seeding is sending data to the correct location, RAND() works 
  as expected in both circumstances.
  
  NOTE: This changeset will be null-merged into version 4.1 and beyond, and
  a new changeset created there.

  mysql-test/r/func_math.result@stripped, 2006-07-19 19:17:40-04:00, cmiller@stripped +11 -1
    Illustrate that one can specify a seed, n, using RAND(n) now.
    
    Also, show that the previous test that seemed to include this test was bogus.

  mysql-test/t/func_math.test@stripped, 2006-07-19 19:17:40-04:00, cmiller@stripped +10 -0
    Illustrate that one can specify a seed, n, using RAND(n) now.
    
    Also, show that the previous test that seemed to include this test was bogus.

  sql/gen_lex_hash.cc@stripped, 2006-07-19 19:17:40-04:00, cmiller@stripped +5 -5
    Whitespace corrections.

  sql/item_func.cc@stripped, 2006-07-19 19:17:40-04:00, cmiller@stripped +7 -6
    Each random item object should now get its "rand" state from the thread, 
    instead of all objects /but/ the seeding cases getting state.  The seeding 
    cases now poke values into the right spot.

  sql/password.c@stripped, 2006-07-19 19:17:40-04:00, cmiller@stripped +8 -7
    Whitespace corrections.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	cmiller
# Host:	zippy.cornsilk.net
# Root:	/home/cmiller/work/mysql/m40-maint_b15473

--- 1.59/sql/gen_lex_hash.cc	2006-07-19 19:17:42 -04:00
+++ 1.60/sql/gen_lex_hash.cc	2006-07-19 19:17:42 -04:00
@@ -81,18 +81,18 @@
   double max_value_dbl;
 };
 
-void randominit(struct rand_struct *rand_st,ulong seed1, ulong seed2)
+void randominit(struct rand_struct *rand_st, ulong seed1, ulong seed2)
 {						/* For mysql 3.21.# */
   rand_st->max_value= 0x3FFFFFFFL;
   rand_st->max_value_dbl=(double) rand_st->max_value;
-  rand_st->seed1=seed1%rand_st->max_value ;
-  rand_st->seed2=seed2%rand_st->max_value;
+  rand_st->seed1= seed1 % rand_st->max_value;
+  rand_st->seed2= seed2 % rand_st->max_value;
 }
 
 double rnd(struct rand_struct *rand_st)
 {
-  rand_st->seed1=(rand_st->seed1*3+rand_st->seed2) % rand_st->max_value;
-  rand_st->seed2=(rand_st->seed1+rand_st->seed2+33) % rand_st->max_value;
+  rand_st->seed1= (rand_st->seed1*3+rand_st->seed2) % rand_st->max_value;
+  rand_st->seed2= (rand_st->seed1+rand_st->seed2+33) % rand_st->max_value;
   return (((double) rand_st->seed1)/rand_st->max_value_dbl);
 }
 

--- 1.113/sql/item_func.cc	2006-07-19 19:17:42 -04:00
+++ 1.114/sql/item_func.cc	2006-07-19 19:17:42 -04:00
@@ -720,18 +720,20 @@
 
 void Item_func_rand::fix_length_and_dec()
 {
+  THD *thd= current_thd;
+
   decimals=NOT_FIXED_DEC; 
   max_length=float_length(decimals);
-  if (arg_count)
+  rand= &thd->rand;
+  if (arg_count != 0)
   {					// Only use argument once in query
     uint32 tmp= (uint32) (args[0]->val_int());
-    if ((rand= (struct rand_struct*) sql_alloc(sizeof(*rand))))
-      randominit(rand,(uint32) (tmp*0x10001L+55555555L),
-		 (uint32) (tmp*0x10000001L));
+    /* Saves the seeds in thd */
+    randominit(rand, /*seed1*/(uint32) (tmp*0x10001L+55555555L),
+               /*seed2*/(uint32) (tmp*0x10000001L));
   }
   else
   {
-    THD *thd= current_thd;
     /*
       No need to send a Rand log event if seed was given eg: RAND(seed),
       as it will be replicated in the query as such.
@@ -743,7 +745,6 @@
     thd->rand_used=1;
     thd->rand_saved_seed1=thd->rand.seed1;
     thd->rand_saved_seed2=thd->rand.seed2;
-    rand= &thd->rand;
   }
 }
 

--- 1.8/sql/password.c	2006-07-19 19:17:42 -04:00
+++ 1.9/sql/password.c	2006-07-19 19:17:42 -04:00
@@ -40,23 +40,24 @@
 #include "mysql.h"
 
 
-void randominit(struct rand_struct *rand_st,ulong seed1, ulong seed2)
+void randominit(struct rand_struct *rand_st, ulong seed1, ulong seed2)
 {						/* For mysql 3.21.# */
 #ifdef HAVE_purify
-  bzero((char*) rand_st,sizeof(*rand_st));	/* Avoid UMC varnings */
+  bzero((char*) rand_st, sizeof(*rand_st));	/* Avoid UMC varnings */
 #endif
   rand_st->max_value= 0x3FFFFFFFL;
-  rand_st->max_value_dbl=(double) rand_st->max_value;
-  rand_st->seed1=seed1%rand_st->max_value ;
-  rand_st->seed2=seed2%rand_st->max_value;
+  rand_st->max_value_dbl= (double) rand_st->max_value;
+  rand_st->seed1= seed1 % rand_st->max_value;
+  rand_st->seed2= seed2 % rand_st->max_value;
 }
 
-static void old_randominit(struct rand_struct *rand_st,ulong seed1)
+static void old_randominit(struct rand_struct *rand_st, ulong seed1)
 {						/* For mysql 3.20.# */
   rand_st->max_value= 0x01FFFFFFL;
   rand_st->max_value_dbl=(double) rand_st->max_value;
   seed1%=rand_st->max_value;
-  rand_st->seed1=seed1 ; rand_st->seed2=seed1/2;
+  rand_st->seed1=seed1; 
+  rand_st->seed2=seed1/2;
 }
 
 double my_rnd(struct rand_struct *rand_st)

--- 1.18/mysql-test/r/func_math.result	2006-07-19 19:17:42 -04:00
+++ 1.19/mysql-test/r/func_math.result	2006-07-19 19:17:42 -04:00
@@ -34,7 +34,11 @@
 set @@rand_seed1=10000000,@@rand_seed2=1000000;
 select rand(999999),rand();
 rand(999999)	rand()
-0.014231365187309	0.028870999839968
+0.014231365187309	0.8078568166195
+set @@rand_seed1=10000000,@@rand_seed2=1000000;
+select rand();
+rand()
+0.028870999839968
 select pi(),format(sin(pi()/2),6),format(cos(pi()/2),6),format(abs(tan(pi())),6),format(cot(1),6),format(asin(1),6),format(acos(0),6),format(atan(1),6);
 pi()	format(sin(pi()/2),6)	format(cos(pi()/2),6)	format(abs(tan(pi())),6)	format(cot(1),6)	format(asin(1),6)	format(acos(0),6)	format(atan(1),6)
 3.141593	1.000000	0.000000	0.000000	0.642093	1.570796	1.570796	0.785398
@@ -59,3 +63,9 @@
 SELECT ASIN(1.2-0.2);
 ASIN(1.2-0.2)
 1.5707963267949
+SELECT RAND(1), RAND(), RAND(), RAND();
+RAND(1)	RAND()	RAND()	RAND()
+0.40540353712198	0.87161418038571	0.14186032129625	0.094459096057768
+SELECT RAND(1), RAND(), RAND(), RAND();
+RAND(1)	RAND()	RAND()	RAND()
+0.40540353712198	0.87161418038571	0.14186032129625	0.094459096057768

--- 1.11/mysql-test/t/func_math.test	2006-07-19 19:17:42 -04:00
+++ 1.12/mysql-test/t/func_math.test	2006-07-19 19:17:42 -04:00
@@ -15,6 +15,8 @@
 select pow(10,log10(10)),power(2,4);
 set @@rand_seed1=10000000,@@rand_seed2=1000000;
 select rand(999999),rand();
+set @@rand_seed1=10000000,@@rand_seed2=1000000;
+select rand();
 select pi(),format(sin(pi()/2),6),format(cos(pi()/2),6),format(abs(tan(pi())),6),format(cot(1),6),format(asin(1),6),format(acos(0),6),format(atan(1),6);
 select degrees(pi()),radians(360);
 
@@ -37,3 +39,11 @@
 #select floor(log(4)/log(2));
 #select floor(log(8)/log(2));
 #select floor(log(16)/log(2));
+
+
+#
+# Bug#15473: RAND(N) no longer produces repeatable sequence
+#
+SELECT RAND(1), RAND(), RAND(), RAND();
+SELECT RAND(1), RAND(), RAND(), RAND();
+
Thread
bk commit into 4.0 tree (cmiller:1.2188) BUG#15473Chad MILLER20 Jul