Hello Tom,

Set random seed for pgbench.

So this patch has ignored the possibility of not having pg_strong_random.

I assumed that pg_strong_random is always available, but may fail with an error if a strong random source is not available, in which case the error message should be enough for the user to figure out that they cannot use the 'rand' value and must rely on 'time' or an integer.

The error message can be improved in this case.

That's moving the portability goalposts in a way that I do not find
acceptable for such a marginal feature.  What behavior do you think we
should have for platforms without that --- accept the seed=rand option
but then error out, or not recognize the option at all?

The first option is currently implemented and documented, and seems fine.

BTW, I also note that the patch is constructing error messages from
sentence fragments, which is verboten per translatability policy.
While that's perhaps not too important as long as we don't have message
translations for pgbench, it still seems like something to fix now not
later.

The elements of the structure could be translatable independently: one part says there is an error, the other provides the context in which this error was triggered. This could be made a little clearer by using parentheses for instance. Otherwise to comply with translability policy the function can be made to return a bool and then the caller show the context.

In the attached, I improved the error message on 'rand' error and printed the error context outside of the function.

Thanks for the review.

--
Fabien.
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 8529e7d..8aa462b 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -4669,8 +4669,8 @@ printResults(TState *threads, StatsData *total, 
instr_time total_time,
 }
 
 /* call srandom based on some seed. NULL triggers the default behavior. */
-static void
-set_random_seed(const char *seed, const char *origin)
+static bool
+set_random_seed(const char *seed)
 {
        /* srandom expects an unsigned int */
        unsigned int iseed;
@@ -4687,8 +4687,10 @@ set_random_seed(const char *seed, const char *origin)
                /* use some "strong" random source */
                if (!pg_strong_random(&iseed, sizeof(iseed)))
                {
-                       fprintf(stderr, "cannot seed random from a strong 
source\n");
-                       exit(1);
+                       fprintf(stderr,
+                                       "cannot seed random from a strong 
source, none available: "
+                                       "use 'time' or an unsigned integer 
value.\n");
+                       return false;
                }
        }
        else
@@ -4698,9 +4700,9 @@ set_random_seed(const char *seed, const char *origin)
                if (sscanf(seed, "%u%c", &iseed, &garbage) != 1)
                {
                        fprintf(stderr,
-                                       "error while scanning '%s' from %s, 
expecting an unsigned integer, 'time' or 'rand'\n",
-                                       seed, origin);
-                       exit(1);
+                                       "error while scanning '%s', expecting 
an unsigned integer, 'time' or 'rand'\n",
+                                       seed);
+                       return false;
                }
        }
 
@@ -4709,6 +4711,7 @@ set_random_seed(const char *seed, const char *origin)
        srandom(iseed);
        /* no precision loss: 32 bit unsigned int cast to 64 bit int */
        random_seed = iseed;
+       return true;
 }
 
 
@@ -4823,7 +4826,11 @@ main(int argc, char **argv)
        memset(state, 0, sizeof(CState));
 
        /* set random seed early, because it may be used while parsing scripts. 
*/
-       set_random_seed(getenv("PGBENCH_RANDOM_SEED"), "PGBENCH_RANDOM_SEED 
environment variable");
+       if (!set_random_seed(getenv("PGBENCH_RANDOM_SEED")))
+       {
+               fprintf(stderr, "error while setting random seed from 
PGBENCH_RANDOM_SEED environment variable");
+               exit(1);
+       }
 
        while ((c = getopt_long(argc, argv, 
"iI:h:nvp:dqb:SNc:j:Crs:t:T:U:lf:D:F:M:P:R:L:", long_options, &optindex)) != -1)
        {
@@ -5099,7 +5106,11 @@ main(int argc, char **argv)
                                break;
                        case 9:                         /* random-seed */
                                benchmarking_option_set = true;
-                               set_random_seed(optarg, "--random-seed option");
+                               if (!set_random_seed(optarg))
+                               {
+                                       fprintf(stderr, "error while setting 
random seed from --random-seed option");
+                                       exit(1);
+                               }
                                break;
                        default:
                                fprintf(stderr, _("Try \"%s --help\" for more 
information.\n"), progname);
diff --git a/src/bin/pgbench/t/002_pgbench_no_server.pl 
b/src/bin/pgbench/t/002_pgbench_no_server.pl
index 682bc22..8a3c4be 100644
--- a/src/bin/pgbench/t/002_pgbench_no_server.pl
+++ b/src/bin/pgbench/t/002_pgbench_no_server.pl
@@ -111,7 +111,8 @@ my @options = (
                [qr{unrecognized initialization step},
                 qr{allowed steps are} ] ],
        [ 'bad random seed', '--random-seed=one',
-               [qr{error while scanning 'one' from --random-seed option, 
expecting an unsigned integer} ] ],
+               [qr{error while scanning 'one', expecting an unsigned integer},
+                qr{error while setting random seed from --random-seed option} 
] ],
 
        # loging sub-options
        [   'sampling => log', '--sampling-rate=0.01',

Reply via email to