mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-30 19:00:29 +08:00
Clean up bogosities in use of random(3) and srandom(3) --- do not assume
that RAND_MAX applies to them, since it doesn't. Instead add a config.h parameter MAX_RANDOM_VALUE. This is currently set at 2^31-1 but could be auto-configured if that ever proves necessary. Also fix some outright bugs like calling srand() where srandom() is appropriate.
This commit is contained in:
parent
259489bab7
commit
9426047021
@ -171,6 +171,18 @@
|
||||
<entry>convert floating point to integer</entry>
|
||||
<entry>integer(2.0)</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>random()</entry>
|
||||
<entry>float8</entry>
|
||||
<entry>random value in the range 0.0 to 1.0</entry>
|
||||
<entry>random()</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>setseed(float8)</entry>
|
||||
<entry>int</entry>
|
||||
<entry>set seed for subsequent random() calls</entry>
|
||||
<entry>setseed(0.54823)</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/ref/set.sgml,v 1.46 2000/07/14 15:27:14 thomas Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/ref/set.sgml,v 1.47 2000/08/07 00:51:18 tgl Exp $
|
||||
Postgres documentation
|
||||
-->
|
||||
|
||||
@ -194,9 +194,9 @@ SET TIME ZONE { '<replaceable class="PARAMETER">timezone</replaceable>' | LOCAL
|
||||
<listitem>
|
||||
<para>
|
||||
The value for the seed to be used by the
|
||||
<function>random</function> catalog function. Significant
|
||||
<function>random</function> function. Allowed
|
||||
values are floating point numbers between 0 and 1, which
|
||||
are then multiplied by RAND_MAX. This product will
|
||||
are then multiplied by 2^31-1. This product will
|
||||
silently overflow if a number outside the range is used.
|
||||
</para>
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: geqo_main.c,v 1.22 2000/06/28 03:31:45 tgl Exp $
|
||||
* $Id: geqo_main.c,v 1.23 2000/08/07 00:51:23 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -106,9 +106,9 @@ geqo(Query *root)
|
||||
/* seed random number generator */
|
||||
/* XXX why is this done every time around? */
|
||||
if (Geqo_random_seed >= 0)
|
||||
srandom(Geqo_random_seed);
|
||||
srandom((unsigned int) Geqo_random_seed);
|
||||
else
|
||||
srandom(time(NULL));
|
||||
srandom((unsigned int) time(NULL));
|
||||
|
||||
/* allocate genetic pool memory */
|
||||
pool = alloc_pool(pool_size, number_of_rels);
|
||||
|
@ -11,7 +11,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.158 2000/07/28 02:13:26 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.159 2000/08/07 00:51:30 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
*
|
||||
@ -1850,7 +1850,7 @@ DoBackend(Port *port)
|
||||
*/
|
||||
random_seed = 0;
|
||||
gettimeofday(&now, &tz);
|
||||
srandom(now.tv_usec);
|
||||
srandom((unsigned int) now.tv_usec);
|
||||
|
||||
/* ----------------
|
||||
* Now, build the argv vector that will be given to PostgresMain.
|
||||
@ -2029,7 +2029,6 @@ RandomSalt(char *salt)
|
||||
static long
|
||||
PostmasterRandom(void)
|
||||
{
|
||||
|
||||
static bool initialized = false;
|
||||
|
||||
if (!initialized)
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/float.c,v 1.67 2000/08/01 18:29:35 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/float.c,v 1.68 2000/08/07 00:51:14 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -1315,7 +1315,7 @@ drandom(PG_FUNCTION_ARGS)
|
||||
float8 result;
|
||||
|
||||
/* result 0.0-1.0 */
|
||||
result = ((double) random()) / RAND_MAX;
|
||||
result = ((double) random()) / ((double) MAX_RANDOM_VALUE);
|
||||
|
||||
PG_RETURN_FLOAT8(result);
|
||||
}
|
||||
@ -1328,7 +1328,7 @@ Datum
|
||||
setseed(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float8 seed = PG_GETARG_FLOAT8(0);
|
||||
int iseed = (seed * RAND_MAX);
|
||||
int iseed = (int) (seed * MAX_RANDOM_VALUE);
|
||||
|
||||
srandom((unsigned int) iseed);
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/misc.c,v 1.19 2000/06/05 07:28:52 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/misc.c,v 1.20 2000/08/07 00:51:14 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -45,15 +45,18 @@ nonnullvalue(PG_FUNCTION_ARGS)
|
||||
|
||||
/*
|
||||
* oidrand (oid o, int4 X)-
|
||||
* takes in an oid and a int4 X, and will return 'true'
|
||||
* about 1/X of the time.
|
||||
* Takes in an oid and a int4 X, and will return 'true' about 1/X of
|
||||
* the time. If X == 0, this will always return true.
|
||||
* Useful for doing random sampling or subsetting.
|
||||
* if X == 0, this will always return true;
|
||||
*
|
||||
* Example use:
|
||||
* select * from TEMP where oidrand(TEMP.oid, 10)
|
||||
* will return about 1/10 of the tuples in TEMP
|
||||
*
|
||||
* NOTE: the OID input is not used at all. It is there just because of
|
||||
* an old optimizer bug: a qual expression containing no variables was
|
||||
* mistakenly assumed to be a constant. Pretending to access the row's OID
|
||||
* prevented the optimizer from treating the oidrand() result as constant.
|
||||
*/
|
||||
|
||||
static bool random_initialized = false;
|
||||
@ -61,7 +64,6 @@ static bool random_initialized = false;
|
||||
Datum
|
||||
oidrand(PG_FUNCTION_ARGS)
|
||||
{
|
||||
/* XXX seems like we ought to be using the oid for something? */
|
||||
#ifdef NOT_USED
|
||||
Oid o = PG_GETARG_OID(0);
|
||||
#endif
|
||||
@ -96,7 +98,7 @@ oidsrand(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int32 X = PG_GETARG_INT32(0);
|
||||
|
||||
srand(X);
|
||||
srandom((unsigned int) X);
|
||||
random_initialized = true;
|
||||
PG_RETURN_BOOL(true);
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
* or in config.h afterwards. Of course, if you edit config.h, then your
|
||||
* changes will be overwritten the next time you run configure.
|
||||
*
|
||||
* $Id: config.h.in,v 1.128 2000/07/28 02:13:40 tgl Exp $
|
||||
* $Id: config.h.in,v 1.129 2000/08/07 00:51:38 tgl Exp $
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_H
|
||||
@ -484,6 +484,15 @@ extern long random(void);
|
||||
extern void srandom(unsigned int seed);
|
||||
#endif
|
||||
|
||||
/* The random() function is expected to yield values 0 .. MAX_RANDOM_VALUE */
|
||||
/* Currently, all known implementations yield 0..2^31-1, so we just hardwire
|
||||
* this constant. We could do a configure test if it proves to be necessary.
|
||||
* CAUTION: Think not to replace this with RAND_MAX. RAND_MAX defines the
|
||||
* maximum value of the older rand() function, which is often different from
|
||||
* --- and considerably inferior to --- random().
|
||||
*/
|
||||
#define MAX_RANDOM_VALUE (0x7FFFFFFF)
|
||||
|
||||
/* Set to 1 if you have libz.a */
|
||||
#undef HAVE_LIBZ
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: geqo_random.h,v 1.6 2000/01/26 05:58:20 momjian Exp $
|
||||
* $Id: geqo_random.h,v 1.7 2000/08/07 00:51:42 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -26,13 +26,13 @@
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#define GEQOMASK 2147483647
|
||||
/* geqo_rand returns a random float value between 0 and 1 inclusive */
|
||||
|
||||
#define geqo_rand() ((double)random()/GEQOMASK)
|
||||
#define geqo_rand() (((double) random()) / ((double) MAX_RANDOM_VALUE))
|
||||
|
||||
/* geqo_randint returns integer value
|
||||
between lower and upper inclusive */
|
||||
/* geqo_randint returns integer value between lower and upper inclusive */
|
||||
|
||||
#define geqo_randint(upper,lower) ( (int) floor( geqo_rand()*((upper-lower)+0.999999) ) + lower )
|
||||
#define geqo_randint(upper,lower) \
|
||||
( (int) floor( geqo_rand()*(((upper)-(lower))+0.999999) ) + (lower) )
|
||||
|
||||
#endif /* GEQO_RANDOM_H */
|
||||
|
Loading…
Reference in New Issue
Block a user