]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Clean up bogosities in use of random(3) and srandom(3) --- do not assume
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 7 Aug 2000 00:51:42 +0000 (00:51 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 7 Aug 2000 00:51:42 +0000 (00:51 +0000)
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.

doc/src/sgml/func.sgml
doc/src/sgml/ref/set.sgml
src/backend/optimizer/geqo/geqo_main.c
src/backend/postmaster/postmaster.c
src/backend/utils/adt/float.c
src/backend/utils/adt/misc.c
src/include/config.h.in
src/include/optimizer/geqo_random.h

index 2e7144b147baba4d287070bfa771bd2aa11772e0..aa7e2b098989bd46bd4e99a9bf4149c6b321afea 100644 (file)
        <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>
index 7f36aae9d785af6553bdcafbbd8e97f9840a49dc..b76570d5defd2d02b44edb663669ddcb338d7381 100644 (file)
@@ -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>
 
index 4f2f63572c7aa5124ec66e45da74715a1047b78b..eb99c2478f8e6049837b8a1ac097981c7c0908a3 100644 (file)
@@ -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);
index 629ab48e8c04928dbff0fcf80bcc11be063b4289..9626f3bcf8b035d3cd95c58d41df29e93f3eac1e 100644 (file)
@@ -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)
index 54735191a9f2fdffbe09773f658839fd236147cb..7c06e31ed8452b512adf046124b5f65786a93fbe 100644 (file)
@@ -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);
 
index 7e3b8b167b97104efbcf481ed05ffd369189be96..7711cf7cddb6c266f7704b05fe701cae36556137 100644 (file)
@@ -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);
 }
index 7e5413994f8a6fcb656d3157c4a9bf43e66ea4f0..63c7c21b7b80e0e8339e27f9cf2613498cecc2d5 100644 (file)
@@ -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
 
index c005b331b61e400269a8664cd2d59cee4fb9f898..a2203367e78c1e0789a32cb4b6fcd2e86d79c10e 100644 (file)
@@ -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 $
  *
  *-------------------------------------------------------------------------
  */
 
 #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 */