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#15473 | Chad MILLER | 20 Jul |