On 2015-06-30 20:52, Tom Lane wrote:
> Petr Jelinek <petr@2ndquadrant.com> writes:
>> Right, very good point.
>
>> So, we used to protect against this problem by using long value and doing:
>> ((double) random() + 1) / ((double) MAX_RANDOM_VALUE + 2)
>
>> Maybe best solution is to have pg_lrand48() variant which accepts seed
>> as parameter same way pg_erand48() does and use the same logic we used
>> to have before sampling was added.
>
> I'm unimpressed with this coding because it presumes that MAX_RANDOM_VALUE
> (which is defined as the maximum value returned by random()) has something
> to do with the output range of pg_lrand48(). While that might
> accidentally fail to fail on all known platforms, it's not good, because
> those functions don't have the same provenance and so there's no good
> reason to assume that they produce the same output range.
Well, by this logic all the other places which are using
MAX_RANDOM_VALUE would be broken as well as our port version of random()
just calls pg_lrand48(). Not to mention that we hardwire
MAX_RANDOM_VALUE to be same as PG_INT32_MAX (which we could use in the
code I proposed instead of MAX_RANDOM_VALUE to be safe).
>
> Rather than expanding the API of port.h still further, I continue to think
> that the best answer is just to repeat if we get a zero from pg_erand48.
>
Looping over function call until you get value you like seems quite ugly
to me tbh.
--
Petr Jelinek http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services