diff options
author | Dean Rasheed <dean.a.rasheed@gmail.com> | 2024-03-27 10:12:39 +0000 |
---|---|---|
committer | Dean Rasheed <dean.a.rasheed@gmail.com> | 2024-03-27 10:12:39 +0000 |
commit | e6341323a8da64b18e9af3e75a4578230702d61c (patch) | |
tree | f04f8e7fa84af4b569e58c85d2a7d98f65f45303 /src/backend/utils/adt/float.c | |
parent | 818861eb578663a0d4d8d7dc4e18c96a148b3c75 (diff) | |
download | postgresql-e6341323a8da64b18e9af3e75a4578230702d61c.tar.gz postgresql-e6341323a8da64b18e9af3e75a4578230702d61c.zip |
Add functions to generate random numbers in a specified range.
This adds 3 new variants of the random() function:
random(min integer, max integer) returns integer
random(min bigint, max bigint) returns bigint
random(min numeric, max numeric) returns numeric
Each returns a random number x in the range min <= x <= max.
For the numeric function, the number of digits after the decimal point
is equal to the number of digits that "min" or "max" has after the
decimal point, whichever has more.
The main entry points for these functions are in a new C source file.
The existing random(), random_normal(), and setseed() functions are
moved there too, so that they can all share the same PRNG state, which
is kept private to that file.
Dean Rasheed, reviewed by Jian He, David Zhang, Aleksander Alekseev,
and Tomas Vondra.
Discussion: https://postgr.es/m/CAEZATCV89Vxuq93xQdmc0t-0Y2zeeNQTdsjbmV7dyFBPykbV4Q@mail.gmail.com
Diffstat (limited to 'src/backend/utils/adt/float.c')
-rw-r--r-- | src/backend/utils/adt/float.c | 95 |
1 files changed, 0 insertions, 95 deletions
diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c index 901edcc8961..cbbb8aecafc 100644 --- a/src/backend/utils/adt/float.c +++ b/src/backend/utils/adt/float.c @@ -21,10 +21,8 @@ #include "catalog/pg_type.h" #include "common/int.h" -#include "common/pg_prng.h" #include "common/shortest_dec.h" #include "libpq/pqformat.h" -#include "miscadmin.h" #include "utils/array.h" #include "utils/float.h" #include "utils/fmgrprotos.h" @@ -64,10 +62,6 @@ float8 degree_c_sixty = 60.0; float8 degree_c_one_half = 0.5; float8 degree_c_one = 1.0; -/* State for drandom() and setseed() */ -static bool drandom_seed_set = false; -static pg_prng_state drandom_seed; - /* Local function prototypes */ static double sind_q1(double x); static double cosd_q1(double x); @@ -2785,95 +2779,6 @@ derfc(PG_FUNCTION_ARGS) } -/* ========== RANDOM FUNCTIONS ========== */ - - -/* - * initialize_drandom_seed - initialize drandom_seed if not yet done - */ -static void -initialize_drandom_seed(void) -{ - /* Initialize random seed, if not done yet in this process */ - if (unlikely(!drandom_seed_set)) - { - /* - * If possible, initialize the seed using high-quality random bits. - * Should that fail for some reason, we fall back on a lower-quality - * seed based on current time and PID. - */ - if (unlikely(!pg_prng_strong_seed(&drandom_seed))) - { - TimestampTz now = GetCurrentTimestamp(); - uint64 iseed; - - /* Mix the PID with the most predictable bits of the timestamp */ - iseed = (uint64) now ^ ((uint64) MyProcPid << 32); - pg_prng_seed(&drandom_seed, iseed); - } - drandom_seed_set = true; - } -} - -/* - * drandom - returns a random number - */ -Datum -drandom(PG_FUNCTION_ARGS) -{ - float8 result; - - initialize_drandom_seed(); - - /* pg_prng_double produces desired result range [0.0 - 1.0) */ - result = pg_prng_double(&drandom_seed); - - PG_RETURN_FLOAT8(result); -} - -/* - * drandom_normal - returns a random number from a normal distribution - */ -Datum -drandom_normal(PG_FUNCTION_ARGS) -{ - float8 mean = PG_GETARG_FLOAT8(0); - float8 stddev = PG_GETARG_FLOAT8(1); - float8 result, - z; - - initialize_drandom_seed(); - - /* Get random value from standard normal(mean = 0.0, stddev = 1.0) */ - z = pg_prng_double_normal(&drandom_seed); - /* Transform the normal standard variable (z) */ - /* using the target normal distribution parameters */ - result = (stddev * z) + mean; - - PG_RETURN_FLOAT8(result); -} - -/* - * setseed - set seed for the random number generator - */ -Datum -setseed(PG_FUNCTION_ARGS) -{ - float8 seed = PG_GETARG_FLOAT8(0); - - if (seed < -1 || seed > 1 || isnan(seed)) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("setseed parameter %g is out of allowed range [-1,1]", - seed))); - - pg_prng_fseed(&drandom_seed, seed); - drandom_seed_set = true; - - PG_RETURN_VOID(); -} - - /* * ========================= |