PostgreSQL Source Code  git master
pgbench.c
Go to the documentation of this file.
1 /*
2  * pgbench.c
3  *
4  * A simple benchmark program for PostgreSQL
5  * Originally written by Tatsuo Ishii and enhanced by many contributors.
6  *
7  * src/bin/pgbench/pgbench.c
8  * Copyright (c) 2000-2020, PostgreSQL Global Development Group
9  * ALL RIGHTS RESERVED;
10  *
11  * Permission to use, copy, modify, and distribute this software and its
12  * documentation for any purpose, without fee, and without a written agreement
13  * is hereby granted, provided that the above copyright notice and this
14  * paragraph and the following two paragraphs appear in all copies.
15  *
16  * IN NO EVENT SHALL THE AUTHOR OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
17  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
18  * LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
19  * DOCUMENTATION, EVEN IF THE AUTHOR OR DISTRIBUTORS HAVE BEEN ADVISED OF THE
20  * POSSIBILITY OF SUCH DAMAGE.
21  *
22  * THE AUTHOR AND DISTRIBUTORS SPECIFICALLY DISCLAIMS ANY WARRANTIES,
23  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
24  * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
25  * ON AN "AS IS" BASIS, AND THE AUTHOR AND DISTRIBUTORS HAS NO OBLIGATIONS TO
26  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
27  *
28  */
29 
30 #ifdef WIN32
31 #define FD_SETSIZE 1024 /* must set before winsock2.h is included */
32 #endif
33 
34 #include "postgres_fe.h"
35 
36 #include <ctype.h>
37 #include <float.h>
38 #include <limits.h>
39 #include <math.h>
40 #include <signal.h>
41 #include <time.h>
42 #include <sys/time.h>
43 #ifdef HAVE_SYS_RESOURCE_H
44 #include <sys/resource.h> /* for getrlimit */
45 #endif
46 
47 /* For testing, PGBENCH_USE_SELECT can be defined to force use of that code */
48 #if defined(HAVE_PPOLL) && !defined(PGBENCH_USE_SELECT)
49 #define POLL_USING_PPOLL
50 #ifdef HAVE_POLL_H
51 #include <poll.h>
52 #endif
53 #else /* no ppoll(), so use select() */
54 #define POLL_USING_SELECT
55 #ifdef HAVE_SYS_SELECT_H
56 #include <sys/select.h>
57 #endif
58 #endif
59 
60 #include "common/int.h"
61 #include "common/logging.h"
62 #include "fe_utils/cancel.h"
63 #include "fe_utils/conditional.h"
64 #include "getopt_long.h"
65 #include "libpq-fe.h"
66 #include "pgbench.h"
67 #include "portability/instr_time.h"
68 
69 #ifndef M_PI
70 #define M_PI 3.14159265358979323846
71 #endif
72 
73 #define ERRCODE_UNDEFINED_TABLE "42P01"
74 
75 /*
76  * Hashing constants
77  */
78 #define FNV_PRIME UINT64CONST(0x100000001b3)
79 #define FNV_OFFSET_BASIS UINT64CONST(0xcbf29ce484222325)
80 #define MM2_MUL UINT64CONST(0xc6a4a7935bd1e995)
81 #define MM2_MUL_TIMES_8 UINT64CONST(0x35253c9ade8f4ca8)
82 #define MM2_ROT 47
83 
84 /*
85  * Multi-platform socket set implementations
86  */
87 
88 #ifdef POLL_USING_PPOLL
89 #define SOCKET_WAIT_METHOD "ppoll"
90 
91 typedef struct socket_set
92 {
93  int maxfds; /* allocated length of pollfds[] array */
94  int curfds; /* number currently in use */
95  struct pollfd pollfds[FLEXIBLE_ARRAY_MEMBER];
96 } socket_set;
97 
98 #endif /* POLL_USING_PPOLL */
99 
100 #ifdef POLL_USING_SELECT
101 #define SOCKET_WAIT_METHOD "select"
102 
103 typedef struct socket_set
104 {
105  int maxfd; /* largest FD currently set in fds */
106  fd_set fds;
107 } socket_set;
108 
109 #endif /* POLL_USING_SELECT */
110 
111 /*
112  * Multi-platform pthread implementations
113  */
114 
115 #ifdef WIN32
116 /* Use native win32 threads on Windows */
117 typedef struct win32_pthread *pthread_t;
118 typedef int pthread_attr_t;
119 
120 static int pthread_create(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
121 static int pthread_join(pthread_t th, void **thread_return);
122 #elif defined(ENABLE_THREAD_SAFETY)
123 /* Use platform-dependent pthread capability */
124 #include <pthread.h>
125 #else
126 /* No threads implementation, use none (-j 1) */
127 #define pthread_t void *
128 #endif
129 
130 
131 /********************************************************************
132  * some configurable parameters */
133 
134 #define DEFAULT_INIT_STEPS "dtgvp" /* default -I setting */
135 #define ALL_INIT_STEPS "dtgGvpf" /* all possible steps */
136 
137 #define LOG_STEP_SECONDS 5 /* seconds between log messages */
138 #define DEFAULT_NXACTS 10 /* default nxacts */
139 
140 #define MIN_GAUSSIAN_PARAM 2.0 /* minimum parameter for gauss */
141 
142 #define MIN_ZIPFIAN_PARAM 1.001 /* minimum parameter for zipfian */
143 #define MAX_ZIPFIAN_PARAM 1000.0 /* maximum parameter for zipfian */
144 
145 int nxacts = 0; /* number of transactions per client */
146 int duration = 0; /* duration in seconds */
147 int64 end_time = 0; /* when to stop in micro seconds, under -T */
148 
149 /*
150  * scaling factor. for example, scale = 10 will make 1000000 tuples in
151  * pgbench_accounts table.
152  */
153 int scale = 1;
154 
155 /*
156  * fillfactor. for example, fillfactor = 90 will use only 90 percent
157  * space during inserts and leave 10 percent free.
158  */
159 int fillfactor = 100;
160 
161 /*
162  * use unlogged tables?
163  */
164 bool unlogged_tables = false;
165 
166 /*
167  * log sampling rate (1.0 = log everything, 0.0 = option not given)
168  */
169 double sample_rate = 0.0;
170 
171 /*
172  * When threads are throttled to a given rate limit, this is the target delay
173  * to reach that rate in usec. 0 is the default and means no throttling.
174  */
175 double throttle_delay = 0;
176 
177 /*
178  * Transactions which take longer than this limit (in usec) are counted as
179  * late, and reported as such, although they are completed anyway. When
180  * throttling is enabled, execution time slots that are more than this late
181  * are skipped altogether, and counted separately.
182  */
183 int64 latency_limit = 0;
184 
185 /*
186  * tablespace selection
187  */
188 char *tablespace = NULL;
189 char *index_tablespace = NULL;
190 
191 /*
192  * Number of "pgbench_accounts" partitions. 0 is the default and means no
193  * partitioning.
194  */
195 static int partitions = 0;
196 
197 /* partitioning strategy for "pgbench_accounts" */
198 typedef enum
199 {
200  PART_NONE, /* no partitioning */
201  PART_RANGE, /* range partitioning */
202  PART_HASH /* hash partitioning */
204 
205 static partition_method_t partition_method = PART_NONE;
206 static const char *PARTITION_METHOD[] = {"none", "range", "hash"};
207 
208 /* random seed used to initialize base_random_sequence */
209 int64 random_seed = -1;
210 
211 /*
212  * end of configurable parameters
213  *********************************************************************/
214 
215 #define nbranches 1 /* Makes little sense to change this. Change
216  * -s instead */
217 #define ntellers 10
218 #define naccounts 100000
219 
220 /*
221  * The scale factor at/beyond which 32bit integers are incapable of storing
222  * 64bit values.
223  *
224  * Although the actual threshold is 21474, we use 20000 because it is easier to
225  * document and remember, and isn't that far away from the real threshold.
226  */
227 #define SCALE_32BIT_THRESHOLD 20000
228 
229 bool use_log; /* log transaction latencies to a file */
230 bool use_quiet; /* quiet logging onto stderr */
231 int agg_interval; /* log aggregates instead of individual
232  * transactions */
233 bool per_script_stats = false; /* whether to collect stats per script */
234 int progress = 0; /* thread progress report every this seconds */
235 bool progress_timestamp = false; /* progress report with Unix time */
236 int nclients = 1; /* number of clients */
237 int nthreads = 1; /* number of threads */
238 bool is_connect; /* establish connection for each transaction */
239 bool report_per_command; /* report per-command latencies */
240 int main_pid; /* main process id used in log filename */
241 
242 char *pghost = "";
243 char *pgport = "";
244 char *login = NULL;
245 char *dbName;
246 char *logfile_prefix = NULL;
247 const char *progname;
248 
249 #define WSEP '@' /* weight separator */
250 
251 volatile bool timer_exceeded = false; /* flag from signal handler */
252 
253 /*
254  * Variable definitions.
255  *
256  * If a variable only has a string value, "svalue" is that value, and value is
257  * "not set". If the value is known, "value" contains the value (in any
258  * variant).
259  *
260  * In this case "svalue" contains the string equivalent of the value, if we've
261  * had occasion to compute that, or NULL if we haven't.
262  */
263 typedef struct
264 {
265  char *name; /* variable's name */
266  char *svalue; /* its value in string form, if known */
267  PgBenchValue value; /* actual variable's value */
268 } Variable;
269 
270 #define MAX_SCRIPTS 128 /* max number of SQL scripts allowed */
271 #define SHELL_COMMAND_SIZE 256 /* maximum size allowed for shell command */
272 
273 /*
274  * Simple data structure to keep stats about something.
275  *
276  * XXX probably the first value should be kept and used as an offset for
277  * better numerical stability...
278  */
279 typedef struct SimpleStats
280 {
281  int64 count; /* how many values were encountered */
282  double min; /* the minimum seen */
283  double max; /* the maximum seen */
284  double sum; /* sum of values */
285  double sum2; /* sum of squared values */
286 } SimpleStats;
287 
288 /*
289  * Data structure to hold various statistics: per-thread and per-script stats
290  * are maintained and merged together.
291  */
292 typedef struct StatsData
293 {
294  time_t start_time; /* interval start time, for aggregates */
295  int64 cnt; /* number of transactions, including skipped */
296  int64 skipped; /* number of transactions skipped under --rate
297  * and --latency-limit */
300 } StatsData;
301 
302 /*
303  * Struct to keep random state.
304  */
305 typedef struct RandomState
306 {
307  unsigned short xseed[3];
308 } RandomState;
309 
310 /* Various random sequences are initialized from this one. */
312 
313 /*
314  * Connection state machine states.
315  */
316 typedef enum
317 {
318  /*
319  * The client must first choose a script to execute. Once chosen, it can
320  * either be throttled (state CSTATE_PREPARE_THROTTLE under --rate), start
321  * right away (state CSTATE_START_TX) or not start at all if the timer was
322  * exceeded (state CSTATE_FINISHED).
323  */
325 
326  /*
327  * CSTATE_START_TX performs start-of-transaction processing. Establishes
328  * a new connection for the transaction in --connect mode, records the
329  * transaction start time, and proceed to the first command.
330  *
331  * Note: once a script is started, it will either error or run till its
332  * end, where it may be interrupted. It is not interrupted while running,
333  * so pgbench --time is to be understood as tx are allowed to start in
334  * that time, and will finish when their work is completed.
335  */
337 
338  /*
339  * In CSTATE_PREPARE_THROTTLE state, we calculate when to begin the next
340  * transaction, and advance to CSTATE_THROTTLE. CSTATE_THROTTLE state
341  * sleeps until that moment, then advances to CSTATE_START_TX, or
342  * CSTATE_FINISHED if the next transaction would start beyond the end of
343  * the run.
344  */
347 
348  /*
349  * We loop through these states, to process each command in the script:
350  *
351  * CSTATE_START_COMMAND starts the execution of a command. On a SQL
352  * command, the command is sent to the server, and we move to
353  * CSTATE_WAIT_RESULT state. On a \sleep meta-command, the timer is set,
354  * and we enter the CSTATE_SLEEP state to wait for it to expire. Other
355  * meta-commands are executed immediately. If the command about to start
356  * is actually beyond the end of the script, advance to CSTATE_END_TX.
357  *
358  * CSTATE_WAIT_RESULT waits until we get a result set back from the server
359  * for the current command.
360  *
361  * CSTATE_SLEEP waits until the end of \sleep.
362  *
363  * CSTATE_END_COMMAND records the end-of-command timestamp, increments the
364  * command counter, and loops back to CSTATE_START_COMMAND state.
365  *
366  * CSTATE_SKIP_COMMAND is used by conditional branches which are not
367  * executed. It quickly skip commands that do not need any evaluation.
368  * This state can move forward several commands, till there is something
369  * to do or the end of the script.
370  */
376 
377  /*
378  * CSTATE_END_TX performs end-of-transaction processing. It calculates
379  * latency, and logs the transaction. In --connect mode, it closes the
380  * current connection.
381  *
382  * Then either starts over in CSTATE_CHOOSE_SCRIPT, or enters
383  * CSTATE_FINISHED if we have no more work to do.
384  */
386 
387  /*
388  * Final states. CSTATE_ABORTED means that the script execution was
389  * aborted because a command failed, CSTATE_FINISHED means success.
390  */
394 
395 /*
396  * Connection state.
397  */
398 typedef struct
399 {
400  PGconn *con; /* connection handle to DB */
401  int id; /* client No. */
402  ConnectionStateEnum state; /* state machine's current state. */
403  ConditionalStack cstack; /* enclosing conditionals state */
404 
405  /*
406  * Separate randomness for each client. This is used for random functions
407  * PGBENCH_RANDOM_* during the execution of the script.
408  */
410 
411  int use_file; /* index in sql_script for this client */
412  int command; /* command number in script */
413 
414  /* client variables */
415  Variable *variables; /* array of variable definitions */
416  int nvariables; /* number of variables */
417  bool vars_sorted; /* are variables sorted by name? */
418 
419  /* various times about current transaction */
420  int64 txn_scheduled; /* scheduled start time of transaction (usec) */
421  int64 sleep_until; /* scheduled start time of next cmd (usec) */
422  instr_time txn_begin; /* used for measuring schedule lag times */
423  instr_time stmt_begin; /* used for measuring statement latencies */
424 
425  bool prepared[MAX_SCRIPTS]; /* whether client prepared the script */
426 
427  /* per client collected stats */
428  int64 cnt; /* client transaction count, for -t */
429  int ecnt; /* error count */
430 } CState;
431 
432 /*
433  * Thread state
434  */
435 typedef struct
436 {
437  int tid; /* thread id */
438  pthread_t thread; /* thread handle */
439  CState *state; /* array of CState */
440  int nstate; /* length of state[] */
441 
442  /*
443  * Separate randomness for each thread. Each thread option uses its own
444  * random state to make all of them independent of each other and
445  * therefore deterministic at the thread level.
446  */
447  RandomState ts_choose_rs; /* random state for selecting a script */
448  RandomState ts_throttle_rs; /* random state for transaction throttling */
449  RandomState ts_sample_rs; /* random state for log sampling */
450 
451  int64 throttle_trigger; /* previous/next throttling (us) */
452  FILE *logfile; /* where to log, or NULL */
453 
454  /* per thread collected stats */
455  instr_time start_time; /* thread start time */
458  int64 latency_late; /* executed but late transactions */
459 } TState;
460 
461 #define INVALID_THREAD ((pthread_t) 0)
462 
463 /*
464  * queries read from files
465  */
466 #define SQL_COMMAND 1
467 #define META_COMMAND 2
468 
469 /*
470  * max number of backslash command arguments or SQL variables,
471  * including the command or SQL statement itself
472  */
473 #define MAX_ARGS 256
474 
475 typedef enum MetaCommand
476 {
477  META_NONE, /* not a known meta-command */
478  META_SET, /* \set */
479  META_SETSHELL, /* \setshell */
480  META_SHELL, /* \shell */
481  META_SLEEP, /* \sleep */
482  META_GSET, /* \gset */
483  META_IF, /* \if */
484  META_ELIF, /* \elif */
485  META_ELSE, /* \else */
486  META_ENDIF /* \endif */
487 } MetaCommand;
488 
489 typedef enum QueryMode
490 {
491  QUERY_SIMPLE, /* simple query */
492  QUERY_EXTENDED, /* extended query */
493  QUERY_PREPARED, /* extended query with prepared statements */
495 } QueryMode;
496 
497 static QueryMode querymode = QUERY_SIMPLE;
498 static const char *QUERYMODE[] = {"simple", "extended", "prepared"};
499 
500 /*
501  * struct Command represents one command in a script.
502  *
503  * lines The raw, possibly multi-line command text. Variable substitution
504  * not applied.
505  * first_line A short, single-line extract of 'lines', for error reporting.
506  * type SQL_COMMAND or META_COMMAND
507  * meta The type of meta-command, or META_NONE if command is SQL
508  * argc Number of arguments of the command, 0 if not yet processed.
509  * argv Command arguments, the first of which is the command or SQL
510  * string itself. For SQL commands, after post-processing
511  * argv[0] is the same as 'lines' with variables substituted.
512  * varprefix SQL commands terminated with \gset have this set
513  * to a non NULL value. If nonempty, it's used to prefix the
514  * variable name that receives the value.
515  * expr Parsed expression, if needed.
516  * stats Time spent in this command.
517  */
518 typedef struct Command
519 {
521  char *first_line;
522  int type;
523  MetaCommand meta;
524  int argc;
525  char *argv[MAX_ARGS];
526  char *varprefix;
529 } Command;
530 
531 typedef struct ParsedScript
532 {
533  const char *desc; /* script descriptor (eg, file name) */
534  int weight; /* selection weight */
535  Command **commands; /* NULL-terminated array of Commands */
536  StatsData stats; /* total time spent in script */
537 } ParsedScript;
538 
539 static ParsedScript sql_script[MAX_SCRIPTS]; /* SQL script files */
540 static int num_scripts; /* number of scripts in sql_script[] */
541 static int64 total_weight = 0;
542 
543 /* Builtin test scripts */
544 typedef struct BuiltinScript
545 {
546  const char *name; /* very short name for -b ... */
547  const char *desc; /* short description */
548  const char *script; /* actual pgbench script */
549 } BuiltinScript;
550 
552 {
553  {
554  "tpcb-like",
555  "<builtin: TPC-B (sort of)>",
556  "\\set aid random(1, " CppAsString2(naccounts) " * :scale)\n"
557  "\\set bid random(1, " CppAsString2(nbranches) " * :scale)\n"
558  "\\set tid random(1, " CppAsString2(ntellers) " * :scale)\n"
559  "\\set delta random(-5000, 5000)\n"
560  "BEGIN;\n"
561  "UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;\n"
562  "SELECT abalance FROM pgbench_accounts WHERE aid = :aid;\n"
563  "UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;\n"
564  "UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;\n"
565  "INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);\n"
566  "END;\n"
567  },
568  {
569  "simple-update",
570  "<builtin: simple update>",
571  "\\set aid random(1, " CppAsString2(naccounts) " * :scale)\n"
572  "\\set bid random(1, " CppAsString2(nbranches) " * :scale)\n"
573  "\\set tid random(1, " CppAsString2(ntellers) " * :scale)\n"
574  "\\set delta random(-5000, 5000)\n"
575  "BEGIN;\n"
576  "UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;\n"
577  "SELECT abalance FROM pgbench_accounts WHERE aid = :aid;\n"
578  "INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);\n"
579  "END;\n"
580  },
581  {
582  "select-only",
583  "<builtin: select only>",
584  "\\set aid random(1, " CppAsString2(naccounts) " * :scale)\n"
585  "SELECT abalance FROM pgbench_accounts WHERE aid = :aid;\n"
586  }
587 };
588 
589 
590 /* Function prototypes */
591 static void setNullValue(PgBenchValue *pv);
592 static void setBoolValue(PgBenchValue *pv, bool bval);
593 static void setIntValue(PgBenchValue *pv, int64 ival);
594 static void setDoubleValue(PgBenchValue *pv, double dval);
595 static bool evaluateExpr(CState *st, PgBenchExpr *expr,
596  PgBenchValue *retval);
597 static ConnectionStateEnum executeMetaCommand(CState *st, instr_time *now);
598 static void doLog(TState *thread, CState *st,
599  StatsData *agg, bool skipped, double latency, double lag);
600 static void processXactStats(TState *thread, CState *st, instr_time *now,
601  bool skipped, StatsData *agg);
602 static void append_fillfactor(char *opts, int len);
603 static void addScript(ParsedScript script);
604 static void *threadRun(void *arg);
605 static void finishCon(CState *st);
606 static void setalarm(int seconds);
607 static socket_set *alloc_socket_set(int count);
608 static void free_socket_set(socket_set *sa);
609 static void clear_socket_set(socket_set *sa);
610 static void add_socket_to_set(socket_set *sa, int fd, int idx);
611 static int wait_on_socket_set(socket_set *sa, int64 usecs);
612 static bool socket_has_input(socket_set *sa, int fd, int idx);
613 
614 
615 /* callback functions for our flex lexer */
617  NULL, /* don't need get_variable functionality */
618 };
619 
620 
621 static void
622 usage(void)
623 {
624  printf("%s is a benchmarking tool for PostgreSQL.\n\n"
625  "Usage:\n"
626  " %s [OPTION]... [DBNAME]\n"
627  "\nInitialization options:\n"
628  " -i, --initialize invokes initialization mode\n"
629  " -I, --init-steps=[" ALL_INIT_STEPS "]+ (default \"" DEFAULT_INIT_STEPS "\")\n"
630  " run selected initialization steps\n"
631  " -F, --fillfactor=NUM set fill factor\n"
632  " -n, --no-vacuum do not run VACUUM during initialization\n"
633  " -q, --quiet quiet logging (one message each 5 seconds)\n"
634  " -s, --scale=NUM scaling factor\n"
635  " --foreign-keys create foreign key constraints between tables\n"
636  " --index-tablespace=TABLESPACE\n"
637  " create indexes in the specified tablespace\n"
638  " --partitions=NUM partition pgbench_accounts in NUM parts (default: 0)\n"
639  " --partition-method=(range|hash)\n"
640  " partition pgbench_accounts with this method (default: range)\n"
641  " --tablespace=TABLESPACE create tables in the specified tablespace\n"
642  " --unlogged-tables create tables as unlogged tables\n"
643  "\nOptions to select what to run:\n"
644  " -b, --builtin=NAME[@W] add builtin script NAME weighted at W (default: 1)\n"
645  " (use \"-b list\" to list available scripts)\n"
646  " -f, --file=FILENAME[@W] add script FILENAME weighted at W (default: 1)\n"
647  " -N, --skip-some-updates skip updates of pgbench_tellers and pgbench_branches\n"
648  " (same as \"-b simple-update\")\n"
649  " -S, --select-only perform SELECT-only transactions\n"
650  " (same as \"-b select-only\")\n"
651  "\nBenchmarking options:\n"
652  " -c, --client=NUM number of concurrent database clients (default: 1)\n"
653  " -C, --connect establish new connection for each transaction\n"
654  " -D, --define=VARNAME=VALUE\n"
655  " define variable for use by custom script\n"
656  " -j, --jobs=NUM number of threads (default: 1)\n"
657  " -l, --log write transaction times to log file\n"
658  " -L, --latency-limit=NUM count transactions lasting more than NUM ms as late\n"
659  " -M, --protocol=simple|extended|prepared\n"
660  " protocol for submitting queries (default: simple)\n"
661  " -n, --no-vacuum do not run VACUUM before tests\n"
662  " -P, --progress=NUM show thread progress report every NUM seconds\n"
663  " -r, --report-latencies report average latency per command\n"
664  " -R, --rate=NUM target rate in transactions per second\n"
665  " -s, --scale=NUM report this scale factor in output\n"
666  " -t, --transactions=NUM number of transactions each client runs (default: 10)\n"
667  " -T, --time=NUM duration of benchmark test in seconds\n"
668  " -v, --vacuum-all vacuum all four standard tables before tests\n"
669  " --aggregate-interval=NUM aggregate data over NUM seconds\n"
670  " --log-prefix=PREFIX prefix for transaction time log file\n"
671  " (default: \"pgbench_log\")\n"
672  " --progress-timestamp use Unix epoch timestamps for progress\n"
673  " --random-seed=SEED set random seed (\"time\", \"rand\", integer)\n"
674  " --sampling-rate=NUM fraction of transactions to log (e.g., 0.01 for 1%%)\n"
675  " --show-script=NAME show builtin script code, then exit\n"
676  "\nCommon options:\n"
677  " -d, --debug print debugging output\n"
678  " -h, --host=HOSTNAME database server host or socket directory\n"
679  " -p, --port=PORT database server port number\n"
680  " -U, --username=USERNAME connect as specified database user\n"
681  " -V, --version output version information, then exit\n"
682  " -?, --help show this help, then exit\n"
683  "\n"
684  "Report bugs to <%s>.\n"
685  "%s home page: <%s>\n",
686  progname, progname, PACKAGE_BUGREPORT, PACKAGE_NAME, PACKAGE_URL);
687 }
688 
689 /* return whether str matches "^\s*[-+]?[0-9]+$" */
690 static bool
691 is_an_int(const char *str)
692 {
693  const char *ptr = str;
694 
695  /* skip leading spaces; cast is consistent with strtoint64 */
696  while (*ptr && isspace((unsigned char) *ptr))
697  ptr++;
698 
699  /* skip sign */
700  if (*ptr == '+' || *ptr == '-')
701  ptr++;
702 
703  /* at least one digit */
704  if (*ptr && !isdigit((unsigned char) *ptr))
705  return false;
706 
707  /* eat all digits */
708  while (*ptr && isdigit((unsigned char) *ptr))
709  ptr++;
710 
711  /* must have reached end of string */
712  return *ptr == '\0';
713 }
714 
715 
716 /*
717  * strtoint64 -- convert a string to 64-bit integer
718  *
719  * This function is a slightly modified version of scanint8() from
720  * src/backend/utils/adt/int8.c.
721  *
722  * The function returns whether the conversion worked, and if so
723  * "*result" is set to the result.
724  *
725  * If not errorOK, an error message is also printed out on errors.
726  */
727 bool
728 strtoint64(const char *str, bool errorOK, int64 *result)
729 {
730  const char *ptr = str;
731  int64 tmp = 0;
732  bool neg = false;
733 
734  /*
735  * Do our own scan, rather than relying on sscanf which might be broken
736  * for long long.
737  *
738  * As INT64_MIN can't be stored as a positive 64 bit integer, accumulate
739  * value as a negative number.
740  */
741 
742  /* skip leading spaces */
743  while (*ptr && isspace((unsigned char) *ptr))
744  ptr++;
745 
746  /* handle sign */
747  if (*ptr == '-')
748  {
749  ptr++;
750  neg = true;
751  }
752  else if (*ptr == '+')
753  ptr++;
754 
755  /* require at least one digit */
756  if (unlikely(!isdigit((unsigned char) *ptr)))
757  goto invalid_syntax;
758 
759  /* process digits */
760  while (*ptr && isdigit((unsigned char) *ptr))
761  {
762  int8 digit = (*ptr++ - '0');
763 
764  if (unlikely(pg_mul_s64_overflow(tmp, 10, &tmp)) ||
765  unlikely(pg_sub_s64_overflow(tmp, digit, &tmp)))
766  goto out_of_range;
767  }
768 
769  /* allow trailing whitespace, but not other trailing chars */
770  while (*ptr != '\0' && isspace((unsigned char) *ptr))
771  ptr++;
772 
773  if (unlikely(*ptr != '\0'))
774  goto invalid_syntax;
775 
776  if (!neg)
777  {
778  if (unlikely(tmp == PG_INT64_MIN))
779  goto out_of_range;
780  tmp = -tmp;
781  }
782 
783  *result = tmp;
784  return true;
785 
786 out_of_range:
787  if (!errorOK)
788  pg_log_error("value \"%s\" is out of range for type bigint", str);
789  return false;
790 
791 invalid_syntax:
792  if (!errorOK)
793  pg_log_error("invalid input syntax for type bigint: \"%s\"", str);
794  return false;
795 }
796 
797 /* convert string to double, detecting overflows/underflows */
798 bool
799 strtodouble(const char *str, bool errorOK, double *dv)
800 {
801  char *end;
802 
803  errno = 0;
804  *dv = strtod(str, &end);
805 
806  if (unlikely(errno != 0))
807  {
808  if (!errorOK)
809  pg_log_error("value \"%s\" is out of range for type double", str);
810  return false;
811  }
812 
813  if (unlikely(end == str || *end != '\0'))
814  {
815  if (!errorOK)
816  pg_log_error("invalid input syntax for type double: \"%s\"", str);
817  return false;
818  }
819  return true;
820 }
821 
822 /*
823  * Initialize a random state struct.
824  *
825  * We derive the seed from base_random_sequence, which must be set up already.
826  */
827 static void
829 {
830  random_state->xseed[0] = (unsigned short)
831  (pg_jrand48(base_random_sequence.xseed) & 0xFFFF);
832  random_state->xseed[1] = (unsigned short)
833  (pg_jrand48(base_random_sequence.xseed) & 0xFFFF);
834  random_state->xseed[2] = (unsigned short)
835  (pg_jrand48(base_random_sequence.xseed) & 0xFFFF);
836 }
837 
838 /*
839  * Random number generator: uniform distribution from min to max inclusive.
840  *
841  * Although the limits are expressed as int64, you can't generate the full
842  * int64 range in one call, because the difference of the limits mustn't
843  * overflow int64. In practice it's unwise to ask for more than an int32
844  * range, because of the limited precision of pg_erand48().
845  */
846 static int64
847 getrand(RandomState *random_state, int64 min, int64 max)
848 {
849  /*
850  * Odd coding is so that min and max have approximately the same chance of
851  * being selected as do numbers between them.
852  *
853  * pg_erand48() is thread-safe and concurrent, which is why we use it
854  * rather than random(), which in glibc is non-reentrant, and therefore
855  * protected by a mutex, and therefore a bottleneck on machines with many
856  * CPUs.
857  */
858  return min + (int64) ((max - min + 1) * pg_erand48(random_state->xseed));
859 }
860 
861 /*
862  * random number generator: exponential distribution from min to max inclusive.
863  * the parameter is so that the density of probability for the last cut-off max
864  * value is exp(-parameter).
865  */
866 static int64
867 getExponentialRand(RandomState *random_state, int64 min, int64 max,
868  double parameter)
869 {
870  double cut,
871  uniform,
872  rand;
873 
874  /* abort if wrong parameter, but must really be checked beforehand */
875  Assert(parameter > 0.0);
876  cut = exp(-parameter);
877  /* erand in [0, 1), uniform in (0, 1] */
878  uniform = 1.0 - pg_erand48(random_state->xseed);
879 
880  /*
881  * inner expression in (cut, 1] (if parameter > 0), rand in [0, 1)
882  */
883  Assert((1.0 - cut) != 0.0);
884  rand = -log(cut + (1.0 - cut) * uniform) / parameter;
885  /* return int64 random number within between min and max */
886  return min + (int64) ((max - min + 1) * rand);
887 }
888 
889 /* random number generator: gaussian distribution from min to max inclusive */
890 static int64
891 getGaussianRand(RandomState *random_state, int64 min, int64 max,
892  double parameter)
893 {
894  double stdev;
895  double rand;
896 
897  /* abort if parameter is too low, but must really be checked beforehand */
898  Assert(parameter >= MIN_GAUSSIAN_PARAM);
899 
900  /*
901  * Get user specified random number from this loop, with -parameter <
902  * stdev <= parameter
903  *
904  * This loop is executed until the number is in the expected range.
905  *
906  * As the minimum parameter is 2.0, the probability of looping is low:
907  * sqrt(-2 ln(r)) <= 2 => r >= e^{-2} ~ 0.135, then when taking the
908  * average sinus multiplier as 2/pi, we have a 8.6% looping probability in
909  * the worst case. For a parameter value of 5.0, the looping probability
910  * is about e^{-5} * 2 / pi ~ 0.43%.
911  */
912  do
913  {
914  /*
915  * pg_erand48 generates [0,1), but for the basic version of the
916  * Box-Muller transform the two uniformly distributed random numbers
917  * are expected in (0, 1] (see
918  * https://en.wikipedia.org/wiki/Box-Muller_transform)
919  */
920  double rand1 = 1.0 - pg_erand48(random_state->xseed);
921  double rand2 = 1.0 - pg_erand48(random_state->xseed);
922 
923  /* Box-Muller basic form transform */
924  double var_sqrt = sqrt(-2.0 * log(rand1));
925 
926  stdev = var_sqrt * sin(2.0 * M_PI * rand2);
927 
928  /*
929  * we may try with cos, but there may be a bias induced if the
930  * previous value fails the test. To be on the safe side, let us try
931  * over.
932  */
933  }
934  while (stdev < -parameter || stdev >= parameter);
935 
936  /* stdev is in [-parameter, parameter), normalization to [0,1) */
937  rand = (stdev + parameter) / (parameter * 2.0);
938 
939  /* return int64 random number within between min and max */
940  return min + (int64) ((max - min + 1) * rand);
941 }
942 
943 /*
944  * random number generator: generate a value, such that the series of values
945  * will approximate a Poisson distribution centered on the given value.
946  *
947  * Individual results are rounded to integers, though the center value need
948  * not be one.
949  */
950 static int64
951 getPoissonRand(RandomState *random_state, double center)
952 {
953  /*
954  * Use inverse transform sampling to generate a value > 0, such that the
955  * expected (i.e. average) value is the given argument.
956  */
957  double uniform;
958 
959  /* erand in [0, 1), uniform in (0, 1] */
960  uniform = 1.0 - pg_erand48(random_state->xseed);
961 
962  return (int64) (-log(uniform) * center + 0.5);
963 }
964 
965 /*
966  * Computing zipfian using rejection method, based on
967  * "Non-Uniform Random Variate Generation",
968  * Luc Devroye, p. 550-551, Springer 1986.
969  *
970  * This works for s > 1.0, but may perform badly for s very close to 1.0.
971  */
972 static int64
973 computeIterativeZipfian(RandomState *random_state, int64 n, double s)
974 {
975  double b = pow(2.0, s - 1.0);
976  double x,
977  t,
978  u,
979  v;
980 
981  /* Ensure n is sane */
982  if (n <= 1)
983  return 1;
984 
985  while (true)
986  {
987  /* random variates */
988  u = pg_erand48(random_state->xseed);
989  v = pg_erand48(random_state->xseed);
990 
991  x = floor(pow(u, -1.0 / (s - 1.0)));
992 
993  t = pow(1.0 + 1.0 / x, s - 1.0);
994  /* reject if too large or out of bound */
995  if (v * x * (t - 1.0) / (b - 1.0) <= t / b && x <= n)
996  break;
997  }
998  return (int64) x;
999 }
1000 
1001 /* random number generator: zipfian distribution from min to max inclusive */
1002 static int64
1003 getZipfianRand(RandomState *random_state, int64 min, int64 max, double s)
1004 {
1005  int64 n = max - min + 1;
1006 
1007  /* abort if parameter is invalid */
1009 
1010  return min - 1 + computeIterativeZipfian(random_state, n, s);
1011 }
1012 
1013 /*
1014  * FNV-1a hash function
1015  */
1016 static int64
1017 getHashFnv1a(int64 val, uint64 seed)
1018 {
1019  int64 result;
1020  int i;
1021 
1022  result = FNV_OFFSET_BASIS ^ seed;
1023  for (i = 0; i < 8; ++i)
1024  {
1025  int32 octet = val & 0xff;
1026 
1027  val = val >> 8;
1028  result = result ^ octet;
1029  result = result * FNV_PRIME;
1030  }
1031 
1032  return result;
1033 }
1034 
1035 /*
1036  * Murmur2 hash function
1037  *
1038  * Based on original work of Austin Appleby
1039  * https://github.com/aappleby/smhasher/blob/master/src/MurmurHash2.cpp
1040  */
1041 static int64
1042 getHashMurmur2(int64 val, uint64 seed)
1043 {
1044  uint64 result = seed ^ MM2_MUL_TIMES_8; /* sizeof(int64) */
1045  uint64 k = (uint64) val;
1046 
1047  k *= MM2_MUL;
1048  k ^= k >> MM2_ROT;
1049  k *= MM2_MUL;
1050 
1051  result ^= k;
1052  result *= MM2_MUL;
1053 
1054  result ^= result >> MM2_ROT;
1055  result *= MM2_MUL;
1056  result ^= result >> MM2_ROT;
1057 
1058  return (int64) result;
1059 }
1060 
1061 /*
1062  * Initialize the given SimpleStats struct to all zeroes
1063  */
1064 static void
1066 {
1067  memset(ss, 0, sizeof(SimpleStats));
1068 }
1069 
1070 /*
1071  * Accumulate one value into a SimpleStats struct.
1072  */
1073 static void
1075 {
1076  if (ss->count == 0 || val < ss->min)
1077  ss->min = val;
1078  if (ss->count == 0 || val > ss->max)
1079  ss->max = val;
1080  ss->count++;
1081  ss->sum += val;
1082  ss->sum2 += val * val;
1083 }
1084 
1085 /*
1086  * Merge two SimpleStats objects
1087  */
1088 static void
1090 {
1091  if (acc->count == 0 || ss->min < acc->min)
1092  acc->min = ss->min;
1093  if (acc->count == 0 || ss->max > acc->max)
1094  acc->max = ss->max;
1095  acc->count += ss->count;
1096  acc->sum += ss->sum;
1097  acc->sum2 += ss->sum2;
1098 }
1099 
1100 /*
1101  * Initialize a StatsData struct to mostly zeroes, with its start time set to
1102  * the given value.
1103  */
1104 static void
1106 {
1107  sd->start_time = start_time;
1108  sd->cnt = 0;
1109  sd->skipped = 0;
1110  initSimpleStats(&sd->latency);
1111  initSimpleStats(&sd->lag);
1112 }
1113 
1114 /*
1115  * Accumulate one additional item into the given stats object.
1116  */
1117 static void
1118 accumStats(StatsData *stats, bool skipped, double lat, double lag)
1119 {
1120  stats->cnt++;
1121 
1122  if (skipped)
1123  {
1124  /* no latency to record on skipped transactions */
1125  stats->skipped++;
1126  }
1127  else
1128  {
1129  addToSimpleStats(&stats->latency, lat);
1130 
1131  /* and possibly the same for schedule lag */
1132  if (throttle_delay)
1133  addToSimpleStats(&stats->lag, lag);
1134  }
1135 }
1136 
1137 /* call PQexec() and exit() on failure */
1138 static void
1139 executeStatement(PGconn *con, const char *sql)
1140 {
1141  PGresult *res;
1142 
1143  res = PQexec(con, sql);
1144  if (PQresultStatus(res) != PGRES_COMMAND_OK)
1145  {
1146  pg_log_fatal("query failed: %s", PQerrorMessage(con));
1147  pg_log_info("query was: %s", sql);
1148  exit(1);
1149  }
1150  PQclear(res);
1151 }
1152 
1153 /* call PQexec() and complain, but without exiting, on failure */
1154 static void
1155 tryExecuteStatement(PGconn *con, const char *sql)
1156 {
1157  PGresult *res;
1158 
1159  res = PQexec(con, sql);
1160  if (PQresultStatus(res) != PGRES_COMMAND_OK)
1161  {
1162  pg_log_error("%s", PQerrorMessage(con));
1163  pg_log_info("(ignoring this error and continuing anyway)");
1164  }
1165  PQclear(res);
1166 }
1167 
1168 /* set up a connection to the backend */
1169 static PGconn *
1171 {
1172  PGconn *conn;
1173  bool new_pass;
1174  static bool have_password = false;
1175  static char password[100];
1176 
1177  /*
1178  * Start the connection. Loop until we have a password if requested by
1179  * backend.
1180  */
1181  do
1182  {
1183 #define PARAMS_ARRAY_SIZE 7
1184 
1185  const char *keywords[PARAMS_ARRAY_SIZE];
1186  const char *values[PARAMS_ARRAY_SIZE];
1187 
1188  keywords[0] = "host";
1189  values[0] = pghost;
1190  keywords[1] = "port";
1191  values[1] = pgport;
1192  keywords[2] = "user";
1193  values[2] = login;
1194  keywords[3] = "password";
1195  values[3] = have_password ? password : NULL;
1196  keywords[4] = "dbname";
1197  values[4] = dbName;
1198  keywords[5] = "fallback_application_name";
1199  values[5] = progname;
1200  keywords[6] = NULL;
1201  values[6] = NULL;
1202 
1203  new_pass = false;
1204 
1205  conn = PQconnectdbParams(keywords, values, true);
1206 
1207  if (!conn)
1208  {
1209  pg_log_error("connection to database \"%s\" failed", dbName);
1210  return NULL;
1211  }
1212 
1213  if (PQstatus(conn) == CONNECTION_BAD &&
1214  PQconnectionNeedsPassword(conn) &&
1215  !have_password)
1216  {
1217  PQfinish(conn);
1218  simple_prompt("Password: ", password, sizeof(password), false);
1219  have_password = true;
1220  new_pass = true;
1221  }
1222  } while (new_pass);
1223 
1224  /* check to see that the backend connection was successfully made */
1225  if (PQstatus(conn) == CONNECTION_BAD)
1226  {
1227  pg_log_error("connection to database \"%s\" failed: %s",
1228  dbName, PQerrorMessage(conn));
1229  PQfinish(conn);
1230  return NULL;
1231  }
1232 
1233  return conn;
1234 }
1235 
1236 /* qsort comparator for Variable array */
1237 static int
1238 compareVariableNames(const void *v1, const void *v2)
1239 {
1240  return strcmp(((const Variable *) v1)->name,
1241  ((const Variable *) v2)->name);
1242 }
1243 
1244 /* Locate a variable by name; returns NULL if unknown */
1245 static Variable *
1247 {
1248  Variable key;
1249 
1250  /* On some versions of Solaris, bsearch of zero items dumps core */
1251  if (st->nvariables <= 0)
1252  return NULL;
1253 
1254  /* Sort if we have to */
1255  if (!st->vars_sorted)
1256  {
1257  qsort((void *) st->variables, st->nvariables, sizeof(Variable),
1259  st->vars_sorted = true;
1260  }
1261 
1262  /* Now we can search */
1263  key.name = name;
1264  return (Variable *) bsearch((void *) &key,
1265  (void *) st->variables,
1266  st->nvariables,
1267  sizeof(Variable),
1269 }
1270 
1271 /* Get the value of a variable, in string form; returns NULL if unknown */
1272 static char *
1274 {
1275  Variable *var;
1276  char stringform[64];
1277 
1278  var = lookupVariable(st, name);
1279  if (var == NULL)
1280  return NULL; /* not found */
1281 
1282  if (var->svalue)
1283  return var->svalue; /* we have it in string form */
1284 
1285  /* We need to produce a string equivalent of the value */
1286  Assert(var->value.type != PGBT_NO_VALUE);
1287  if (var->value.type == PGBT_NULL)
1288  snprintf(stringform, sizeof(stringform), "NULL");
1289  else if (var->value.type == PGBT_BOOLEAN)
1290  snprintf(stringform, sizeof(stringform),
1291  "%s", var->value.u.bval ? "true" : "false");
1292  else if (var->value.type == PGBT_INT)
1293  snprintf(stringform, sizeof(stringform),
1294  INT64_FORMAT, var->value.u.ival);
1295  else if (var->value.type == PGBT_DOUBLE)
1296  snprintf(stringform, sizeof(stringform),
1297  "%.*g", DBL_DIG, var->value.u.dval);
1298  else /* internal error, unexpected type */
1299  Assert(0);
1300  var->svalue = pg_strdup(stringform);
1301  return var->svalue;
1302 }
1303 
1304 /* Try to convert variable to a value; return false on failure */
1305 static bool
1307 {
1308  size_t slen;
1309 
1310  if (var->value.type != PGBT_NO_VALUE)
1311  return true; /* no work */
1312 
1313  slen = strlen(var->svalue);
1314 
1315  if (slen == 0)
1316  /* what should it do on ""? */
1317  return false;
1318 
1319  if (pg_strcasecmp(var->svalue, "null") == 0)
1320  {
1321  setNullValue(&var->value);
1322  }
1323 
1324  /*
1325  * accept prefixes such as y, ye, n, no... but not for "o". 0/1 are
1326  * recognized later as an int, which is converted to bool if needed.
1327  */
1328  else if (pg_strncasecmp(var->svalue, "true", slen) == 0 ||
1329  pg_strncasecmp(var->svalue, "yes", slen) == 0 ||
1330  pg_strcasecmp(var->svalue, "on") == 0)
1331  {
1332  setBoolValue(&var->value, true);
1333  }
1334  else if (pg_strncasecmp(var->svalue, "false", slen) == 0 ||
1335  pg_strncasecmp(var->svalue, "no", slen) == 0 ||
1336  pg_strcasecmp(var->svalue, "off") == 0 ||
1337  pg_strcasecmp(var->svalue, "of") == 0)
1338  {
1339  setBoolValue(&var->value, false);
1340  }
1341  else if (is_an_int(var->svalue))
1342  {
1343  /* if it looks like an int, it must be an int without overflow */
1344  int64 iv;
1345 
1346  if (!strtoint64(var->svalue, false, &iv))
1347  return false;
1348 
1349  setIntValue(&var->value, iv);
1350  }
1351  else /* type should be double */
1352  {
1353  double dv;
1354 
1355  if (!strtodouble(var->svalue, true, &dv))
1356  {
1357  pg_log_error("malformed variable \"%s\" value: \"%s\"",
1358  var->name, var->svalue);
1359  return false;
1360  }
1361  setDoubleValue(&var->value, dv);
1362  }
1363  return true;
1364 }
1365 
1366 /*
1367  * Check whether a variable's name is allowed.
1368  *
1369  * We allow any non-ASCII character, as well as ASCII letters, digits, and
1370  * underscore.
1371  *
1372  * Keep this in sync with the definitions of variable name characters in
1373  * "src/fe_utils/psqlscan.l", "src/bin/psql/psqlscanslash.l" and
1374  * "src/bin/pgbench/exprscan.l". Also see parseVariable(), below.
1375  *
1376  * Note: this static function is copied from "src/bin/psql/variables.c"
1377  */
1378 static bool
1380 {
1381  const unsigned char *ptr = (const unsigned char *) name;
1382 
1383  /* Mustn't be zero-length */
1384  if (*ptr == '\0')
1385  return false;
1386 
1387  while (*ptr)
1388  {
1389  if (IS_HIGHBIT_SET(*ptr) ||
1390  strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
1391  "_0123456789", *ptr) != NULL)
1392  ptr++;
1393  else
1394  return false;
1395  }
1396 
1397  return true;
1398 }
1399 
1400 /*
1401  * Lookup a variable by name, creating it if need be.
1402  * Caller is expected to assign a value to the variable.
1403  * Returns NULL on failure (bad name).
1404  */
1405 static Variable *
1406 lookupCreateVariable(CState *st, const char *context, char *name)
1407 {
1408  Variable *var;
1409 
1410  var = lookupVariable(st, name);
1411  if (var == NULL)
1412  {
1413  Variable *newvars;
1414 
1415  /*
1416  * Check for the name only when declaring a new variable to avoid
1417  * overhead.
1418  */
1419  if (!valid_variable_name(name))
1420  {
1421  pg_log_error("%s: invalid variable name: \"%s\"", context, name);
1422  return NULL;
1423  }
1424 
1425  /* Create variable at the end of the array */
1426  if (st->variables)
1427  newvars = (Variable *) pg_realloc(st->variables,
1428  (st->nvariables + 1) * sizeof(Variable));
1429  else
1430  newvars = (Variable *) pg_malloc(sizeof(Variable));
1431 
1432  st->variables = newvars;
1433 
1434  var = &newvars[st->nvariables];
1435 
1436  var->name = pg_strdup(name);
1437  var->svalue = NULL;
1438  /* caller is expected to initialize remaining fields */
1439 
1440  st->nvariables++;
1441  /* we don't re-sort the array till we have to */
1442  st->vars_sorted = false;
1443  }
1444 
1445  return var;
1446 }
1447 
1448 /* Assign a string value to a variable, creating it if need be */
1449 /* Returns false on failure (bad name) */
1450 static bool
1451 putVariable(CState *st, const char *context, char *name, const char *value)
1452 {
1453  Variable *var;
1454  char *val;
1455 
1456  var = lookupCreateVariable(st, context, name);
1457  if (!var)
1458  return false;
1459 
1460  /* dup then free, in case value is pointing at this variable */
1461  val = pg_strdup(value);
1462 
1463  if (var->svalue)
1464  free(var->svalue);
1465  var->svalue = val;
1466  var->value.type = PGBT_NO_VALUE;
1467 
1468  return true;
1469 }
1470 
1471 /* Assign a value to a variable, creating it if need be */
1472 /* Returns false on failure (bad name) */
1473 static bool
1474 putVariableValue(CState *st, const char *context, char *name,
1475  const PgBenchValue *value)
1476 {
1477  Variable *var;
1478 
1479  var = lookupCreateVariable(st, context, name);
1480  if (!var)
1481  return false;
1482 
1483  if (var->svalue)
1484  free(var->svalue);
1485  var->svalue = NULL;
1486  var->value = *value;
1487 
1488  return true;
1489 }
1490 
1491 /* Assign an integer value to a variable, creating it if need be */
1492 /* Returns false on failure (bad name) */
1493 static bool
1494 putVariableInt(CState *st, const char *context, char *name, int64 value)
1495 {
1496  PgBenchValue val;
1497 
1498  setIntValue(&val, value);
1499  return putVariableValue(st, context, name, &val);
1500 }
1501 
1502 /*
1503  * Parse a possible variable reference (:varname).
1504  *
1505  * "sql" points at a colon. If what follows it looks like a valid
1506  * variable name, return a malloc'd string containing the variable name,
1507  * and set *eaten to the number of characters consumed.
1508  * Otherwise, return NULL.
1509  */
1510 static char *
1511 parseVariable(const char *sql, int *eaten)
1512 {
1513  int i = 0;
1514  char *name;
1515 
1516  do
1517  {
1518  i++;
1519  } while (IS_HIGHBIT_SET(sql[i]) ||
1520  strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
1521  "_0123456789", sql[i]) != NULL);
1522  if (i == 1)
1523  return NULL; /* no valid variable name chars */
1524 
1525  name = pg_malloc(i);
1526  memcpy(name, &sql[1], i - 1);
1527  name[i - 1] = '\0';
1528 
1529  *eaten = i;
1530  return name;
1531 }
1532 
1533 static char *
1534 replaceVariable(char **sql, char *param, int len, char *value)
1535 {
1536  int valueln = strlen(value);
1537 
1538  if (valueln > len)
1539  {
1540  size_t offset = param - *sql;
1541 
1542  *sql = pg_realloc(*sql, strlen(*sql) - len + valueln + 1);
1543  param = *sql + offset;
1544  }
1545 
1546  if (valueln != len)
1547  memmove(param + valueln, param + len, strlen(param + len) + 1);
1548  memcpy(param, value, valueln);
1549 
1550  return param + valueln;
1551 }
1552 
1553 static char *
1554 assignVariables(CState *st, char *sql)
1555 {
1556  char *p,
1557  *name,
1558  *val;
1559 
1560  p = sql;
1561  while ((p = strchr(p, ':')) != NULL)
1562  {
1563  int eaten;
1564 
1565  name = parseVariable(p, &eaten);
1566  if (name == NULL)
1567  {
1568  while (*p == ':')
1569  {
1570  p++;
1571  }
1572  continue;
1573  }
1574 
1575  val = getVariable(st, name);
1576  free(name);
1577  if (val == NULL)
1578  {
1579  p++;
1580  continue;
1581  }
1582 
1583  p = replaceVariable(&sql, p, eaten, val);
1584  }
1585 
1586  return sql;
1587 }
1588 
1589 static void
1590 getQueryParams(CState *st, const Command *command, const char **params)
1591 {
1592  int i;
1593 
1594  for (i = 0; i < command->argc - 1; i++)
1595  params[i] = getVariable(st, command->argv[i + 1]);
1596 }
1597 
1598 static char *
1600 {
1601  if (pval->type == PGBT_NO_VALUE)
1602  return "none";
1603  else if (pval->type == PGBT_NULL)
1604  return "null";
1605  else if (pval->type == PGBT_INT)
1606  return "int";
1607  else if (pval->type == PGBT_DOUBLE)
1608  return "double";
1609  else if (pval->type == PGBT_BOOLEAN)
1610  return "boolean";
1611  else
1612  {
1613  /* internal error, should never get there */
1614  Assert(false);
1615  return NULL;
1616  }
1617 }
1618 
1619 /* get a value as a boolean, or tell if there is a problem */
1620 static bool
1621 coerceToBool(PgBenchValue *pval, bool *bval)
1622 {
1623  if (pval->type == PGBT_BOOLEAN)
1624  {
1625  *bval = pval->u.bval;
1626  return true;
1627  }
1628  else /* NULL, INT or DOUBLE */
1629  {
1630  pg_log_error("cannot coerce %s to boolean", valueTypeName(pval));
1631  *bval = false; /* suppress uninitialized-variable warnings */
1632  return false;
1633  }
1634 }
1635 
1636 /*
1637  * Return true or false from an expression for conditional purposes.
1638  * Non zero numerical values are true, zero and NULL are false.
1639  */
1640 static bool
1642 {
1643  switch (pval->type)
1644  {
1645  case PGBT_NULL:
1646  return false;
1647  case PGBT_BOOLEAN:
1648  return pval->u.bval;
1649  case PGBT_INT:
1650  return pval->u.ival != 0;
1651  case PGBT_DOUBLE:
1652  return pval->u.dval != 0.0;
1653  default:
1654  /* internal error, unexpected type */
1655  Assert(0);
1656  return false;
1657  }
1658 }
1659 
1660 /* get a value as an int, tell if there is a problem */
1661 static bool
1662 coerceToInt(PgBenchValue *pval, int64 *ival)
1663 {
1664  if (pval->type == PGBT_INT)
1665  {
1666  *ival = pval->u.ival;
1667  return true;
1668  }
1669  else if (pval->type == PGBT_DOUBLE)
1670  {
1671  double dval = rint(pval->u.dval);
1672 
1673  if (isnan(dval) || !FLOAT8_FITS_IN_INT64(dval))
1674  {
1675  pg_log_error("double to int overflow for %f", dval);
1676  return false;
1677  }
1678  *ival = (int64) dval;
1679  return true;
1680  }
1681  else /* BOOLEAN or NULL */
1682  {
1683  pg_log_error("cannot coerce %s to int", valueTypeName(pval));
1684  return false;
1685  }
1686 }
1687 
1688 /* get a value as a double, or tell if there is a problem */
1689 static bool
1690 coerceToDouble(PgBenchValue *pval, double *dval)
1691 {
1692  if (pval->type == PGBT_DOUBLE)
1693  {
1694  *dval = pval->u.dval;
1695  return true;
1696  }
1697  else if (pval->type == PGBT_INT)
1698  {
1699  *dval = (double) pval->u.ival;
1700  return true;
1701  }
1702  else /* BOOLEAN or NULL */
1703  {
1704  pg_log_error("cannot coerce %s to double", valueTypeName(pval));
1705  return false;
1706  }
1707 }
1708 
1709 /* assign a null value */
1710 static void
1712 {
1713  pv->type = PGBT_NULL;
1714  pv->u.ival = 0;
1715 }
1716 
1717 /* assign a boolean value */
1718 static void
1720 {
1721  pv->type = PGBT_BOOLEAN;
1722  pv->u.bval = bval;
1723 }
1724 
1725 /* assign an integer value */
1726 static void
1727 setIntValue(PgBenchValue *pv, int64 ival)
1728 {
1729  pv->type = PGBT_INT;
1730  pv->u.ival = ival;
1731 }
1732 
1733 /* assign a double value */
1734 static void
1735 setDoubleValue(PgBenchValue *pv, double dval)
1736 {
1737  pv->type = PGBT_DOUBLE;
1738  pv->u.dval = dval;
1739 }
1740 
1741 static bool
1743 {
1744  return func == PGBENCH_AND || func == PGBENCH_OR || func == PGBENCH_CASE;
1745 }
1746 
1747 /* lazy evaluation of some functions */
1748 static bool
1751 {
1752  PgBenchValue a1,
1753  a2;
1754  bool ba1,
1755  ba2;
1756 
1757  Assert(isLazyFunc(func) && args != NULL && args->next != NULL);
1758 
1759  /* args points to first condition */
1760  if (!evaluateExpr(st, args->expr, &a1))
1761  return false;
1762 
1763  /* second condition for AND/OR and corresponding branch for CASE */
1764  args = args->next;
1765 
1766  switch (func)
1767  {
1768  case PGBENCH_AND:
1769  if (a1.type == PGBT_NULL)
1770  {
1771  setNullValue(retval);
1772  return true;
1773  }
1774 
1775  if (!coerceToBool(&a1, &ba1))
1776  return false;
1777 
1778  if (!ba1)
1779  {
1780  setBoolValue(retval, false);
1781  return true;
1782  }
1783 
1784  if (!evaluateExpr(st, args->expr, &a2))
1785  return false;
1786 
1787  if (a2.type == PGBT_NULL)
1788  {
1789  setNullValue(retval);
1790  return true;
1791  }
1792  else if (!coerceToBool(&a2, &ba2))
1793  return false;
1794  else
1795  {
1796  setBoolValue(retval, ba2);
1797  return true;
1798  }
1799 
1800  return true;
1801 
1802  case PGBENCH_OR:
1803 
1804  if (a1.type == PGBT_NULL)
1805  {
1806  setNullValue(retval);
1807  return true;
1808  }
1809 
1810  if (!coerceToBool(&a1, &ba1))
1811  return false;
1812 
1813  if (ba1)
1814  {
1815  setBoolValue(retval, true);
1816  return true;
1817  }
1818 
1819  if (!evaluateExpr(st, args->expr, &a2))
1820  return false;
1821 
1822  if (a2.type == PGBT_NULL)
1823  {
1824  setNullValue(retval);
1825  return true;
1826  }
1827  else if (!coerceToBool(&a2, &ba2))
1828  return false;
1829  else
1830  {
1831  setBoolValue(retval, ba2);
1832  return true;
1833  }
1834 
1835  case PGBENCH_CASE:
1836  /* when true, execute branch */
1837  if (valueTruth(&a1))
1838  return evaluateExpr(st, args->expr, retval);
1839 
1840  /* now args contains next condition or final else expression */
1841  args = args->next;
1842 
1843  /* final else case? */
1844  if (args->next == NULL)
1845  return evaluateExpr(st, args->expr, retval);
1846 
1847  /* no, another when, proceed */
1848  return evalLazyFunc(st, PGBENCH_CASE, args, retval);
1849 
1850  default:
1851  /* internal error, cannot get here */
1852  Assert(0);
1853  break;
1854  }
1855  return false;
1856 }
1857 
1858 /* maximum number of function arguments */
1859 #define MAX_FARGS 16
1860 
1861 /*
1862  * Recursive evaluation of standard functions,
1863  * which do not require lazy evaluation.
1864  */
1865 static bool
1868  PgBenchValue *retval)
1869 {
1870  /* evaluate all function arguments */
1871  int nargs = 0;
1872  PgBenchValue vargs[MAX_FARGS];
1873  PgBenchExprLink *l = args;
1874  bool has_null = false;
1875 
1876  for (nargs = 0; nargs < MAX_FARGS && l != NULL; nargs++, l = l->next)
1877  {
1878  if (!evaluateExpr(st, l->expr, &vargs[nargs]))
1879  return false;
1880  has_null |= vargs[nargs].type == PGBT_NULL;
1881  }
1882 
1883  if (l != NULL)
1884  {
1885  pg_log_error("too many function arguments, maximum is %d", MAX_FARGS);
1886  return false;
1887  }
1888 
1889  /* NULL arguments */
1890  if (has_null && func != PGBENCH_IS && func != PGBENCH_DEBUG)
1891  {
1892  setNullValue(retval);
1893  return true;
1894  }
1895 
1896  /* then evaluate function */
1897  switch (func)
1898  {
1899  /* overloaded operators */
1900  case PGBENCH_ADD:
1901  case PGBENCH_SUB:
1902  case PGBENCH_MUL:
1903  case PGBENCH_DIV:
1904  case PGBENCH_MOD:
1905  case PGBENCH_EQ:
1906  case PGBENCH_NE:
1907  case PGBENCH_LE:
1908  case PGBENCH_LT:
1909  {
1910  PgBenchValue *lval = &vargs[0],
1911  *rval = &vargs[1];
1912 
1913  Assert(nargs == 2);
1914 
1915  /* overloaded type management, double if some double */
1916  if ((lval->type == PGBT_DOUBLE ||
1917  rval->type == PGBT_DOUBLE) && func != PGBENCH_MOD)
1918  {
1919  double ld,
1920  rd;
1921 
1922  if (!coerceToDouble(lval, &ld) ||
1923  !coerceToDouble(rval, &rd))
1924  return false;
1925 
1926  switch (func)
1927  {
1928  case PGBENCH_ADD:
1929  setDoubleValue(retval, ld + rd);
1930  return true;
1931 
1932  case PGBENCH_SUB:
1933  setDoubleValue(retval, ld - rd);
1934  return true;
1935 
1936  case PGBENCH_MUL:
1937  setDoubleValue(retval, ld * rd);
1938  return true;
1939 
1940  case PGBENCH_DIV:
1941  setDoubleValue(retval, ld / rd);
1942  return true;
1943 
1944  case PGBENCH_EQ:
1945  setBoolValue(retval, ld == rd);
1946  return true;
1947 
1948  case PGBENCH_NE:
1949  setBoolValue(retval, ld != rd);
1950  return true;
1951 
1952  case PGBENCH_LE:
1953  setBoolValue(retval, ld <= rd);
1954  return true;
1955 
1956  case PGBENCH_LT:
1957  setBoolValue(retval, ld < rd);
1958  return true;
1959 
1960  default:
1961  /* cannot get here */
1962  Assert(0);
1963  }
1964  }
1965  else /* we have integer operands, or % */
1966  {
1967  int64 li,
1968  ri,
1969  res;
1970 
1971  if (!coerceToInt(lval, &li) ||
1972  !coerceToInt(rval, &ri))
1973  return false;
1974 
1975  switch (func)
1976  {
1977  case PGBENCH_ADD:
1978  if (pg_add_s64_overflow(li, ri, &res))
1979  {
1980  pg_log_error("bigint add out of range");
1981  return false;
1982  }
1983  setIntValue(retval, res);
1984  return true;
1985 
1986  case PGBENCH_SUB:
1987  if (pg_sub_s64_overflow(li, ri, &res))
1988  {
1989  pg_log_error("bigint sub out of range");
1990  return false;
1991  }
1992  setIntValue(retval, res);
1993  return true;
1994 
1995  case PGBENCH_MUL:
1996  if (pg_mul_s64_overflow(li, ri, &res))
1997  {
1998  pg_log_error("bigint mul out of range");
1999  return false;
2000  }
2001  setIntValue(retval, res);
2002  return true;
2003 
2004  case PGBENCH_EQ:
2005  setBoolValue(retval, li == ri);
2006  return true;
2007 
2008  case PGBENCH_NE:
2009  setBoolValue(retval, li != ri);
2010  return true;
2011 
2012  case PGBENCH_LE:
2013  setBoolValue(retval, li <= ri);
2014  return true;
2015 
2016  case PGBENCH_LT:
2017  setBoolValue(retval, li < ri);
2018  return true;
2019 
2020  case PGBENCH_DIV:
2021  case PGBENCH_MOD:
2022  if (ri == 0)
2023  {
2024  pg_log_error("division by zero");
2025  return false;
2026  }
2027  /* special handling of -1 divisor */
2028  if (ri == -1)
2029  {
2030  if (func == PGBENCH_DIV)
2031  {
2032  /* overflow check (needed for INT64_MIN) */
2033  if (li == PG_INT64_MIN)
2034  {
2035  pg_log_error("bigint div out of range");
2036  return false;
2037  }
2038  else
2039  setIntValue(retval, -li);
2040  }
2041  else
2042  setIntValue(retval, 0);
2043  return true;
2044  }
2045  /* else divisor is not -1 */
2046  if (func == PGBENCH_DIV)
2047  setIntValue(retval, li / ri);
2048  else /* func == PGBENCH_MOD */
2049  setIntValue(retval, li % ri);
2050 
2051  return true;
2052 
2053  default:
2054  /* cannot get here */
2055  Assert(0);
2056  }
2057  }
2058 
2059  Assert(0);
2060  return false; /* NOTREACHED */
2061  }
2062 
2063  /* integer bitwise operators */
2064  case PGBENCH_BITAND:
2065  case PGBENCH_BITOR:
2066  case PGBENCH_BITXOR:
2067  case PGBENCH_LSHIFT:
2068  case PGBENCH_RSHIFT:
2069  {
2070  int64 li,
2071  ri;
2072 
2073  if (!coerceToInt(&vargs[0], &li) || !coerceToInt(&vargs[1], &ri))
2074  return false;
2075 
2076  if (func == PGBENCH_BITAND)
2077  setIntValue(retval, li & ri);
2078  else if (func == PGBENCH_BITOR)
2079  setIntValue(retval, li | ri);
2080  else if (func == PGBENCH_BITXOR)
2081  setIntValue(retval, li ^ ri);
2082  else if (func == PGBENCH_LSHIFT)
2083  setIntValue(retval, li << ri);
2084  else if (func == PGBENCH_RSHIFT)
2085  setIntValue(retval, li >> ri);
2086  else /* cannot get here */
2087  Assert(0);
2088 
2089  return true;
2090  }
2091 
2092  /* logical operators */
2093  case PGBENCH_NOT:
2094  {
2095  bool b;
2096 
2097  if (!coerceToBool(&vargs[0], &b))
2098  return false;
2099 
2100  setBoolValue(retval, !b);
2101  return true;
2102  }
2103 
2104  /* no arguments */
2105  case PGBENCH_PI:
2106  setDoubleValue(retval, M_PI);
2107  return true;
2108 
2109  /* 1 overloaded argument */
2110  case PGBENCH_ABS:
2111  {
2112  PgBenchValue *varg = &vargs[0];
2113 
2114  Assert(nargs == 1);
2115 
2116  if (varg->type == PGBT_INT)
2117  {
2118  int64 i = varg->u.ival;
2119 
2120  setIntValue(retval, i < 0 ? -i : i);
2121  }
2122  else
2123  {
2124  double d = varg->u.dval;
2125 
2126  Assert(varg->type == PGBT_DOUBLE);
2127  setDoubleValue(retval, d < 0.0 ? -d : d);
2128  }
2129 
2130  return true;
2131  }
2132 
2133  case PGBENCH_DEBUG:
2134  {
2135  PgBenchValue *varg = &vargs[0];
2136 
2137  Assert(nargs == 1);
2138 
2139  fprintf(stderr, "debug(script=%d,command=%d): ",
2140  st->use_file, st->command + 1);
2141 
2142  if (varg->type == PGBT_NULL)
2143  fprintf(stderr, "null\n");
2144  else if (varg->type == PGBT_BOOLEAN)
2145  fprintf(stderr, "boolean %s\n", varg->u.bval ? "true" : "false");
2146  else if (varg->type == PGBT_INT)
2147  fprintf(stderr, "int " INT64_FORMAT "\n", varg->u.ival);
2148  else if (varg->type == PGBT_DOUBLE)
2149  fprintf(stderr, "double %.*g\n", DBL_DIG, varg->u.dval);
2150  else /* internal error, unexpected type */
2151  Assert(0);
2152 
2153  *retval = *varg;
2154 
2155  return true;
2156  }
2157 
2158  /* 1 double argument */
2159  case PGBENCH_DOUBLE:
2160  case PGBENCH_SQRT:
2161  case PGBENCH_LN:
2162  case PGBENCH_EXP:
2163  {
2164  double dval;
2165 
2166  Assert(nargs == 1);
2167 
2168  if (!coerceToDouble(&vargs[0], &dval))
2169  return false;
2170 
2171  if (func == PGBENCH_SQRT)
2172  dval = sqrt(dval);
2173  else if (func == PGBENCH_LN)
2174  dval = log(dval);
2175  else if (func == PGBENCH_EXP)
2176  dval = exp(dval);
2177  /* else is cast: do nothing */
2178 
2179  setDoubleValue(retval, dval);
2180  return true;
2181  }
2182 
2183  /* 1 int argument */
2184  case PGBENCH_INT:
2185  {
2186  int64 ival;
2187 
2188  Assert(nargs == 1);
2189 
2190  if (!coerceToInt(&vargs[0], &ival))
2191  return false;
2192 
2193  setIntValue(retval, ival);
2194  return true;
2195  }
2196 
2197  /* variable number of arguments */
2198  case PGBENCH_LEAST:
2199  case PGBENCH_GREATEST:
2200  {
2201  bool havedouble;
2202  int i;
2203 
2204  Assert(nargs >= 1);
2205 
2206  /* need double result if any input is double */
2207  havedouble = false;
2208  for (i = 0; i < nargs; i++)
2209  {
2210  if (vargs[i].type == PGBT_DOUBLE)
2211  {
2212  havedouble = true;
2213  break;
2214  }
2215  }
2216  if (havedouble)
2217  {
2218  double extremum;
2219 
2220  if (!coerceToDouble(&vargs[0], &extremum))
2221  return false;
2222  for (i = 1; i < nargs; i++)
2223  {
2224  double dval;
2225 
2226  if (!coerceToDouble(&vargs[i], &dval))
2227  return false;
2228  if (func == PGBENCH_LEAST)
2229  extremum = Min(extremum, dval);
2230  else
2231  extremum = Max(extremum, dval);
2232  }
2233  setDoubleValue(retval, extremum);
2234  }
2235  else
2236  {
2237  int64 extremum;
2238 
2239  if (!coerceToInt(&vargs[0], &extremum))
2240  return false;
2241  for (i = 1; i < nargs; i++)
2242  {
2243  int64 ival;
2244 
2245  if (!coerceToInt(&vargs[i], &ival))
2246  return false;
2247  if (func == PGBENCH_LEAST)
2248  extremum = Min(extremum, ival);
2249  else
2250  extremum = Max(extremum, ival);
2251  }
2252  setIntValue(retval, extremum);
2253  }
2254  return true;
2255  }
2256 
2257  /* random functions */
2258  case PGBENCH_RANDOM:
2262  {
2263  int64 imin,
2264  imax;
2265 
2266  Assert(nargs >= 2);
2267 
2268  if (!coerceToInt(&vargs[0], &imin) ||
2269  !coerceToInt(&vargs[1], &imax))
2270  return false;
2271 
2272  /* check random range */
2273  if (imin > imax)
2274  {
2275  pg_log_error("empty range given to random");
2276  return false;
2277  }
2278  else if (imax - imin < 0 || (imax - imin) + 1 < 0)
2279  {
2280  /* prevent int overflows in random functions */
2281  pg_log_error("random range is too large");
2282  return false;
2283  }
2284 
2285  if (func == PGBENCH_RANDOM)
2286  {
2287  Assert(nargs == 2);
2288  setIntValue(retval, getrand(&st->cs_func_rs, imin, imax));
2289  }
2290  else /* gaussian & exponential */
2291  {
2292  double param;
2293 
2294  Assert(nargs == 3);
2295 
2296  if (!coerceToDouble(&vargs[2], &param))
2297  return false;
2298 
2299  if (func == PGBENCH_RANDOM_GAUSSIAN)
2300  {
2301  if (param < MIN_GAUSSIAN_PARAM)
2302  {
2303  pg_log_error("gaussian parameter must be at least %f (not %f)",
2304  MIN_GAUSSIAN_PARAM, param);
2305  return false;
2306  }
2307 
2308  setIntValue(retval,
2310  imin, imax, param));
2311  }
2312  else if (func == PGBENCH_RANDOM_ZIPFIAN)
2313  {
2314  if (param < MIN_ZIPFIAN_PARAM || param > MAX_ZIPFIAN_PARAM)
2315  {
2316  pg_log_error("zipfian parameter must be in range [%.3f, %.0f] (not %f)",
2317  MIN_ZIPFIAN_PARAM, MAX_ZIPFIAN_PARAM, param);
2318  return false;
2319  }
2320 
2321  setIntValue(retval,
2322  getZipfianRand(&st->cs_func_rs, imin, imax, param));
2323  }
2324  else /* exponential */
2325  {
2326  if (param <= 0.0)
2327  {
2328  pg_log_error("exponential parameter must be greater than zero (not %f)",
2329  param);
2330  return false;
2331  }
2332 
2333  setIntValue(retval,
2335  imin, imax, param));
2336  }
2337  }
2338 
2339  return true;
2340  }
2341 
2342  case PGBENCH_POW:
2343  {
2344  PgBenchValue *lval = &vargs[0];
2345  PgBenchValue *rval = &vargs[1];
2346  double ld,
2347  rd;
2348 
2349  Assert(nargs == 2);
2350 
2351  if (!coerceToDouble(lval, &ld) ||
2352  !coerceToDouble(rval, &rd))
2353  return false;
2354 
2355  setDoubleValue(retval, pow(ld, rd));
2356 
2357  return true;
2358  }
2359 
2360  case PGBENCH_IS:
2361  {
2362  Assert(nargs == 2);
2363 
2364  /*
2365  * note: this simple implementation is more permissive than
2366  * SQL
2367  */
2368  setBoolValue(retval,
2369  vargs[0].type == vargs[1].type &&
2370  vargs[0].u.bval == vargs[1].u.bval);
2371  return true;
2372  }
2373 
2374  /* hashing */
2375  case PGBENCH_HASH_FNV1A:
2376  case PGBENCH_HASH_MURMUR2:
2377  {
2378  int64 val,
2379  seed;
2380 
2381  Assert(nargs == 2);
2382 
2383  if (!coerceToInt(&vargs[0], &val) ||
2384  !coerceToInt(&vargs[1], &seed))
2385  return false;
2386 
2387  if (func == PGBENCH_HASH_MURMUR2)
2388  setIntValue(retval, getHashMurmur2(val, seed));
2389  else if (func == PGBENCH_HASH_FNV1A)
2390  setIntValue(retval, getHashFnv1a(val, seed));
2391  else
2392  /* cannot get here */
2393  Assert(0);
2394 
2395  return true;
2396  }
2397 
2398  default:
2399  /* cannot get here */
2400  Assert(0);
2401  /* dead code to avoid a compiler warning */
2402  return false;
2403  }
2404 }
2405 
2406 /* evaluate some function */
2407 static bool
2410 {
2411  if (isLazyFunc(func))
2412  return evalLazyFunc(st, func, args, retval);
2413  else
2414  return evalStandardFunc(st, func, args, retval);
2415 }
2416 
2417 /*
2418  * Recursive evaluation of an expression in a pgbench script
2419  * using the current state of variables.
2420  * Returns whether the evaluation was ok,
2421  * the value itself is returned through the retval pointer.
2422  */
2423 static bool
2425 {
2426  switch (expr->etype)
2427  {
2428  case ENODE_CONSTANT:
2429  {
2430  *retval = expr->u.constant;
2431  return true;
2432  }
2433 
2434  case ENODE_VARIABLE:
2435  {
2436  Variable *var;
2437 
2438  if ((var = lookupVariable(st, expr->u.variable.varname)) == NULL)
2439  {
2440  pg_log_error("undefined variable \"%s\"", expr->u.variable.varname);
2441  return false;
2442  }
2443 
2444  if (!makeVariableValue(var))
2445  return false;
2446 
2447  *retval = var->value;
2448  return true;
2449  }
2450 
2451  case ENODE_FUNCTION:
2452  return evalFunc(st,
2453  expr->u.function.function,
2454  expr->u.function.args,
2455  retval);
2456 
2457  default:
2458  /* internal error which should never occur */
2459  pg_log_fatal("unexpected enode type in evaluation: %d", expr->etype);
2460  exit(1);
2461  }
2462 }
2463 
2464 /*
2465  * Convert command name to meta-command enum identifier
2466  */
2467 static MetaCommand
2468 getMetaCommand(const char *cmd)
2469 {
2470  MetaCommand mc;
2471 
2472  if (cmd == NULL)
2473  mc = META_NONE;
2474  else if (pg_strcasecmp(cmd, "set") == 0)
2475  mc = META_SET;
2476  else if (pg_strcasecmp(cmd, "setshell") == 0)
2477  mc = META_SETSHELL;
2478  else if (pg_strcasecmp(cmd, "shell") == 0)
2479  mc = META_SHELL;
2480  else if (pg_strcasecmp(cmd, "sleep") == 0)
2481  mc = META_SLEEP;
2482  else if (pg_strcasecmp(cmd, "if") == 0)
2483  mc = META_IF;
2484  else if (pg_strcasecmp(cmd, "elif") == 0)
2485  mc = META_ELIF;
2486  else if (pg_strcasecmp(cmd, "else") == 0)
2487  mc = META_ELSE;
2488  else if (pg_strcasecmp(cmd, "endif") == 0)
2489  mc = META_ENDIF;
2490  else if (pg_strcasecmp(cmd, "gset") == 0)
2491  mc = META_GSET;
2492  else
2493  mc = META_NONE;
2494  return mc;
2495 }
2496 
2497 /*
2498  * Run a shell command. The result is assigned to the variable if not NULL.
2499  * Return true if succeeded, or false on error.
2500  */
2501 static bool
2502 runShellCommand(CState *st, char *variable, char **argv, int argc)
2503 {
2504  char command[SHELL_COMMAND_SIZE];
2505  int i,
2506  len = 0;
2507  FILE *fp;
2508  char res[64];
2509  char *endptr;
2510  int retval;
2511 
2512  /*----------
2513  * Join arguments with whitespace separators. Arguments starting with
2514  * exactly one colon are treated as variables:
2515  * name - append a string "name"
2516  * :var - append a variable named 'var'
2517  * ::name - append a string ":name"
2518  *----------
2519  */
2520  for (i = 0; i < argc; i++)
2521  {
2522  char *arg;
2523  int arglen;
2524 
2525  if (argv[i][0] != ':')
2526  {
2527  arg = argv[i]; /* a string literal */
2528  }
2529  else if (argv[i][1] == ':')
2530  {
2531  arg = argv[i] + 1; /* a string literal starting with colons */
2532  }
2533  else if ((arg = getVariable(st, argv[i] + 1)) == NULL)
2534  {
2535  pg_log_error("%s: undefined variable \"%s\"", argv[0], argv[i]);
2536  return false;
2537  }
2538 
2539  arglen = strlen(arg);
2540  if (len + arglen + (i > 0 ? 1 : 0) >= SHELL_COMMAND_SIZE - 1)
2541  {
2542  pg_log_error("%s: shell command is too long", argv[0]);
2543  return false;
2544  }
2545 
2546  if (i > 0)
2547  command[len++] = ' ';
2548  memcpy(command + len, arg, arglen);
2549  len += arglen;
2550  }
2551 
2552  command[len] = '\0';
2553 
2554  /* Fast path for non-assignment case */
2555  if (variable == NULL)
2556  {
2557  if (system(command))
2558  {
2559  if (!timer_exceeded)
2560  pg_log_error("%s: could not launch shell command", argv[0]);
2561  return false;
2562  }
2563  return true;
2564  }
2565 
2566  /* Execute the command with pipe and read the standard output. */
2567  if ((fp = popen(command, "r")) == NULL)
2568  {
2569  pg_log_error("%s: could not launch shell command", argv[0]);
2570  return false;
2571  }
2572  if (fgets(res, sizeof(res), fp) == NULL)
2573  {
2574  if (!timer_exceeded)
2575  pg_log_error("%s: could not read result of shell command", argv[0]);
2576  (void) pclose(fp);
2577  return false;
2578  }
2579  if (pclose(fp) < 0)
2580  {
2581  pg_log_error("%s: could not close shell command", argv[0]);
2582  return false;
2583  }
2584 
2585  /* Check whether the result is an integer and assign it to the variable */
2586  retval = (int) strtol(res, &endptr, 10);
2587  while (*endptr != '\0' && isspace((unsigned char) *endptr))
2588  endptr++;
2589  if (*res == '\0' || *endptr != '\0')
2590  {
2591  pg_log_error("%s: shell command must return an integer (not \"%s\")", argv[0], res);
2592  return false;
2593  }
2594  if (!putVariableInt(st, "setshell", variable, retval))
2595  return false;
2596 
2597  pg_log_debug("%s: shell parameter name: \"%s\", value: \"%s\"", argv[0], argv[1], res);
2598 
2599  return true;
2600 }
2601 
2602 #define MAX_PREPARE_NAME 32
2603 static void
2604 preparedStatementName(char *buffer, int file, int state)
2605 {
2606  sprintf(buffer, "P%d_%d", file, state);
2607 }
2608 
2609 static void
2610 commandFailed(CState *st, const char *cmd, const char *message)
2611 {
2612  pg_log_error("client %d aborted in command %d (%s) of script %d; %s",
2613  st->id, st->command, cmd, st->use_file, message);
2614 }
2615 
2616 /* return a script number with a weighted choice. */
2617 static int
2619 {
2620  int i = 0;
2621  int64 w;
2622 
2623  if (num_scripts == 1)
2624  return 0;
2625 
2626  w = getrand(&thread->ts_choose_rs, 0, total_weight - 1);
2627  do
2628  {
2629  w -= sql_script[i++].weight;
2630  } while (w >= 0);
2631 
2632  return i - 1;
2633 }
2634 
2635 /* Send a SQL command, using the chosen querymode */
2636 static bool
2638 {
2639  int r;
2640 
2641  if (querymode == QUERY_SIMPLE)
2642  {
2643  char *sql;
2644 
2645  sql = pg_strdup(command->argv[0]);
2646  sql = assignVariables(st, sql);
2647 
2648  pg_log_debug("client %d sending %s", st->id, sql);
2649  r = PQsendQuery(st->con, sql);
2650  free(sql);
2651  }
2652  else if (querymode == QUERY_EXTENDED)
2653  {
2654  const char *sql = command->argv[0];
2655  const char *params[MAX_ARGS];
2656 
2657  getQueryParams(st, command, params);
2658 
2659  pg_log_debug("client %d sending %s", st->id, sql);
2660  r = PQsendQueryParams(st->con, sql, command->argc - 1,
2661  NULL, params, NULL, NULL, 0);
2662  }
2663  else if (querymode == QUERY_PREPARED)
2664  {
2665  char name[MAX_PREPARE_NAME];
2666  const char *params[MAX_ARGS];
2667 
2668  if (!st->prepared[st->use_file])
2669  {
2670  int j;
2671  Command **commands = sql_script[st->use_file].commands;
2672 
2673  for (j = 0; commands[j] != NULL; j++)
2674  {
2675  PGresult *res;
2676  char name[MAX_PREPARE_NAME];
2677 
2678  if (commands[j]->type != SQL_COMMAND)
2679  continue;
2680  preparedStatementName(name, st->use_file, j);
2681  res = PQprepare(st->con, name,
2682  commands[j]->argv[0], commands[j]->argc - 1, NULL);
2683  if (PQresultStatus(res) != PGRES_COMMAND_OK)
2684  pg_log_error("%s", PQerrorMessage(st->con));
2685  PQclear(res);
2686  }
2687  st->prepared[st->use_file] = true;
2688  }
2689 
2690  getQueryParams(st, command, params);
2691  preparedStatementName(name, st->use_file, st->command);
2692 
2693  pg_log_debug("client %d sending %s", st->id, name);
2694  r = PQsendQueryPrepared(st->con, name, command->argc - 1,
2695  params, NULL, NULL, 0);
2696  }
2697  else /* unknown sql mode */
2698  r = 0;
2699 
2700  if (r == 0)
2701  {
2702  pg_log_debug("client %d could not send %s", st->id, command->argv[0]);
2703  st->ecnt++;
2704  return false;
2705  }
2706  else
2707  return true;
2708 }
2709 
2710 /*
2711  * Process query response from the backend.
2712  *
2713  * If varprefix is not NULL, it's the variable name prefix where to store
2714  * the results of the *last* command.
2715  *
2716  * Returns true if everything is A-OK, false if any error occurs.
2717  */
2718 static bool
2719 readCommandResponse(CState *st, char *varprefix)
2720 {
2721  PGresult *res;
2722  PGresult *next_res;
2723  int qrynum = 0;
2724 
2725  res = PQgetResult(st->con);
2726 
2727  while (res != NULL)
2728  {
2729  bool is_last;
2730 
2731  /* peek at the next result to know whether the current is last */
2732  next_res = PQgetResult(st->con);
2733  is_last = (next_res == NULL);
2734 
2735  switch (PQresultStatus(res))
2736  {
2737  case PGRES_COMMAND_OK: /* non-SELECT commands */
2738  case PGRES_EMPTY_QUERY: /* may be used for testing no-op overhead */
2739  if (is_last && varprefix != NULL)
2740  {
2741  pg_log_error("client %d script %d command %d query %d: expected one row, got %d",
2742  st->id, st->use_file, st->command, qrynum, 0);
2743  goto error;
2744  }
2745  break;
2746 
2747  case PGRES_TUPLES_OK:
2748  if (is_last && varprefix != NULL)
2749  {
2750  if (PQntuples(res) != 1)
2751  {
2752  pg_log_error("client %d script %d command %d query %d: expected one row, got %d",
2753  st->id, st->use_file, st->command, qrynum, PQntuples(res));
2754  goto error;
2755  }
2756 
2757  /* store results into variables */
2758  for (int fld = 0; fld < PQnfields(res); fld++)
2759  {
2760  char *varname = PQfname(res, fld);
2761 
2762  /* allocate varname only if necessary, freed below */
2763  if (*varprefix != '\0')
2764  varname = psprintf("%s%s", varprefix, varname);
2765 
2766  /* store result as a string */
2767  if (!putVariable(st, "gset", varname,
2768  PQgetvalue(res, 0, fld)))
2769  {
2770  /* internal error */
2771  pg_log_error("client %d script %d command %d query %d: error storing into variable %s",
2772  st->id, st->use_file, st->command, qrynum, varname);
2773  goto error;
2774  }
2775 
2776  if (*varprefix != '\0')
2777  pg_free(varname);
2778  }
2779  }
2780  /* otherwise the result is simply thrown away by PQclear below */
2781  break;
2782 
2783  default:
2784  /* anything else is unexpected */
2785  pg_log_error("client %d script %d aborted in command %d query %d: %s",
2786  st->id, st->use_file, st->command, qrynum,
2787  PQerrorMessage(st->con));
2788  goto error;
2789  }
2790 
2791  PQclear(res);
2792  qrynum++;
2793  res = next_res;
2794  }
2795 
2796  if (qrynum == 0)
2797  {
2798  pg_log_error("client %d command %d: no results", st->id, st->command);
2799  st->ecnt++;
2800  return false;
2801  }
2802 
2803  return true;
2804 
2805 error:
2806  st->ecnt++;
2807  PQclear(res);
2808  PQclear(next_res);
2809  do
2810  {
2811  res = PQgetResult(st->con);
2812  PQclear(res);
2813  } while (res);
2814 
2815  return false;
2816 }
2817 
2818 /*
2819  * Parse the argument to a \sleep command, and return the requested amount
2820  * of delay, in microseconds. Returns true on success, false on error.
2821  */
2822 static bool
2823 evaluateSleep(CState *st, int argc, char **argv, int *usecs)
2824 {
2825  char *var;
2826  int usec;
2827 
2828  if (*argv[1] == ':')
2829  {
2830  if ((var = getVariable(st, argv[1] + 1)) == NULL)
2831  {
2832  pg_log_error("%s: undefined variable \"%s\"", argv[0], argv[1] + 1);
2833  return false;
2834  }
2835  usec = atoi(var);
2836  }
2837  else
2838  usec = atoi(argv[1]);
2839 
2840  if (argc > 2)
2841  {
2842  if (pg_strcasecmp(argv[2], "ms") == 0)
2843  usec *= 1000;
2844  else if (pg_strcasecmp(argv[2], "s") == 0)
2845  usec *= 1000000;
2846  }
2847  else
2848  usec *= 1000000;
2849 
2850  *usecs = usec;
2851  return true;
2852 }
2853 
2854 /*
2855  * Advance the state machine of a connection.
2856  */
2857 static void
2859 {
2860  instr_time now;
2861 
2862  /*
2863  * gettimeofday() isn't free, so we get the current timestamp lazily the
2864  * first time it's needed, and reuse the same value throughout this
2865  * function after that. This also ensures that e.g. the calculated
2866  * latency reported in the log file and in the totals are the same. Zero
2867  * means "not set yet". Reset "now" when we execute shell commands or
2868  * expressions, which might take a non-negligible amount of time, though.
2869  */
2870  INSTR_TIME_SET_ZERO(now);
2871 
2872  /*
2873  * Loop in the state machine, until we have to wait for a result from the
2874  * server or have to sleep for throttling or \sleep.
2875  *
2876  * Note: In the switch-statement below, 'break' will loop back here,
2877  * meaning "continue in the state machine". Return is used to return to
2878  * the caller, giving the thread the opportunity to advance another
2879  * client.
2880  */
2881  for (;;)
2882  {
2883  Command *command;
2884 
2885  switch (st->state)
2886  {
2887  /* Select transaction (script) to run. */
2888  case CSTATE_CHOOSE_SCRIPT:
2889  st->use_file = chooseScript(thread);
2891 
2892  pg_log_debug("client %d executing script \"%s\"",
2893  st->id, sql_script[st->use_file].desc);
2894 
2895  /*
2896  * If time is over, we're done; otherwise, get ready to start
2897  * a new transaction, or to get throttled if that's requested.
2898  */
2899  st->state = timer_exceeded ? CSTATE_FINISHED :
2900  throttle_delay > 0 ? CSTATE_PREPARE_THROTTLE : CSTATE_START_TX;
2901  break;
2902 
2903  /* Start new transaction (script) */
2904  case CSTATE_START_TX:
2905 
2906  /* establish connection if needed, i.e. under --connect */
2907  if (st->con == NULL)
2908  {
2909  instr_time start;
2910 
2912  start = now;
2913  if ((st->con = doConnect()) == NULL)
2914  {
2915  pg_log_error("client %d aborted while establishing connection", st->id);
2916  st->state = CSTATE_ABORTED;
2917  break;
2918  }
2920  INSTR_TIME_ACCUM_DIFF(thread->conn_time, now, start);
2921 
2922  /* Reset session-local state */
2923  memset(st->prepared, 0, sizeof(st->prepared));
2924  }
2925 
2926  /* record transaction start time */
2928  st->txn_begin = now;
2929 
2930  /*
2931  * When not throttling, this is also the transaction's
2932  * scheduled start time.
2933  */
2934  if (!throttle_delay)
2936 
2937  /* Begin with the first command */
2939  st->command = 0;
2940  break;
2941 
2942  /*
2943  * Handle throttling once per transaction by sleeping.
2944  */
2946 
2947  /*
2948  * Generate a delay such that the series of delays will
2949  * approximate a Poisson distribution centered on the
2950  * throttle_delay time.
2951  *
2952  * If transactions are too slow or a given wait is shorter
2953  * than a transaction, the next transaction will start right
2954  * away.
2955  */
2956  Assert(throttle_delay > 0);
2957 
2958  thread->throttle_trigger +=
2959  getPoissonRand(&thread->ts_throttle_rs, throttle_delay);
2960  st->txn_scheduled = thread->throttle_trigger;
2961 
2962  /*
2963  * If --latency-limit is used, and this slot is already late
2964  * so that the transaction will miss the latency limit even if
2965  * it completed immediately, skip this time slot and schedule
2966  * to continue running on the next slot that isn't late yet.
2967  * But don't iterate beyond the -t limit, if one is given.
2968  */
2969  if (latency_limit)
2970  {
2971  int64 now_us;
2972 
2974  now_us = INSTR_TIME_GET_MICROSEC(now);
2975 
2976  while (thread->throttle_trigger < now_us - latency_limit &&
2977  (nxacts <= 0 || st->cnt < nxacts))
2978  {
2979  processXactStats(thread, st, &now, true, agg);
2980  /* next rendez-vous */
2981  thread->throttle_trigger +=
2982  getPoissonRand(&thread->ts_throttle_rs, throttle_delay);
2983  st->txn_scheduled = thread->throttle_trigger;
2984  }
2985 
2986  /*
2987  * stop client if -t was exceeded in the previous skip
2988  * loop
2989  */
2990  if (nxacts > 0 && st->cnt >= nxacts)
2991  {
2992  st->state = CSTATE_FINISHED;
2993  break;
2994  }
2995  }
2996 
2997  /*
2998  * stop client if next transaction is beyond pgbench end of
2999  * execution; otherwise, throttle it.
3000  */
3001  st->state = end_time > 0 && st->txn_scheduled > end_time ?
3003  break;
3004 
3005  /*
3006  * Wait until it's time to start next transaction.
3007  */
3008  case CSTATE_THROTTLE:
3010 
3011  if (INSTR_TIME_GET_MICROSEC(now) < st->txn_scheduled)
3012  return; /* still sleeping, nothing to do here */
3013 
3014  /* done sleeping, but don't start transaction if we're done */
3015  st->state = timer_exceeded ? CSTATE_FINISHED : CSTATE_START_TX;
3016  break;
3017 
3018  /*
3019  * Send a command to server (or execute a meta-command)
3020  */
3021  case CSTATE_START_COMMAND:
3022  command = sql_script[st->use_file].commands[st->command];
3023 
3024  /* Transition to script end processing if done */
3025  if (command == NULL)
3026  {
3027  st->state = CSTATE_END_TX;
3028  break;
3029  }
3030 
3031  /* record begin time of next command, and initiate it */
3032  if (report_per_command)
3033  {
3035  st->stmt_begin = now;
3036  }
3037 
3038  /* Execute the command */
3039  if (command->type == SQL_COMMAND)
3040  {
3041  if (!sendCommand(st, command))
3042  {
3043  commandFailed(st, "SQL", "SQL command send failed");
3044  st->state = CSTATE_ABORTED;
3045  }
3046  else
3047  st->state = CSTATE_WAIT_RESULT;
3048  }
3049  else if (command->type == META_COMMAND)
3050  {
3051  /*-----
3052  * Possible state changes when executing meta commands:
3053  * - on errors CSTATE_ABORTED
3054  * - on sleep CSTATE_SLEEP
3055  * - else CSTATE_END_COMMAND
3056  */
3057  st->state = executeMetaCommand(st, &now);
3058  }
3059 
3060  /*
3061  * We're now waiting for an SQL command to complete, or
3062  * finished processing a metacommand, or need to sleep, or
3063  * something bad happened.
3064  */
3065  Assert(st->state == CSTATE_WAIT_RESULT ||
3066  st->state == CSTATE_END_COMMAND ||
3067  st->state == CSTATE_SLEEP ||
3068  st->state == CSTATE_ABORTED);
3069  break;
3070 
3071  /*
3072  * non executed conditional branch
3073  */
3074  case CSTATE_SKIP_COMMAND:
3076  /* quickly skip commands until something to do... */
3077  while (true)
3078  {
3079  Command *command;
3080 
3081  command = sql_script[st->use_file].commands[st->command];
3082 
3083  /* cannot reach end of script in that state */
3084  Assert(command != NULL);
3085 
3086  /*
3087  * if this is conditional related, update conditional
3088  * state
3089  */
3090  if (command->type == META_COMMAND &&
3091  (command->meta == META_IF ||
3092  command->meta == META_ELIF ||
3093  command->meta == META_ELSE ||
3094  command->meta == META_ENDIF))
3095  {
3096  switch (conditional_stack_peek(st->cstack))
3097  {
3098  case IFSTATE_FALSE:
3099  if (command->meta == META_IF ||
3100  command->meta == META_ELIF)
3101  {
3102  /* we must evaluate the condition */
3104  }
3105  else if (command->meta == META_ELSE)
3106  {
3107  /* we must execute next command */
3111  st->command++;
3112  }
3113  else if (command->meta == META_ENDIF)
3114  {
3117  if (conditional_active(st->cstack))
3119 
3120  /*
3121  * else state remains in
3122  * CSTATE_SKIP_COMMAND
3123  */
3124  st->command++;
3125  }
3126  break;
3127 
3128  case IFSTATE_IGNORED:
3129  case IFSTATE_ELSE_FALSE:
3130  if (command->meta == META_IF)
3132  IFSTATE_IGNORED);
3133  else if (command->meta == META_ENDIF)
3134  {
3137  if (conditional_active(st->cstack))
3139  }
3140  /* could detect "else" & "elif" after "else" */
3141  st->command++;
3142  break;
3143 
3144  case IFSTATE_NONE:
3145  case IFSTATE_TRUE:
3146  case IFSTATE_ELSE_TRUE:
3147  default:
3148 
3149  /*
3150  * inconsistent if inactive, unreachable dead
3151  * code
3152  */
3153  Assert(false);
3154  }
3155  }
3156  else
3157  {
3158  /* skip and consider next */
3159  st->command++;
3160  }
3161 
3162  if (st->state != CSTATE_SKIP_COMMAND)
3163  /* out of quick skip command loop */
3164  break;
3165  }
3166  break;
3167 
3168  /*
3169  * Wait for the current SQL command to complete
3170  */
3171  case CSTATE_WAIT_RESULT:
3172  pg_log_debug("client %d receiving", st->id);
3173  if (!PQconsumeInput(st->con))
3174  {
3175  /* there's something wrong */
3176  commandFailed(st, "SQL", "perhaps the backend died while processing");
3177  st->state = CSTATE_ABORTED;
3178  break;
3179  }
3180  if (PQisBusy(st->con))
3181  return; /* don't have the whole result yet */
3182 
3183  /* store or discard the query results */
3184  if (readCommandResponse(st, sql_script[st->use_file].commands[st->command]->varprefix))
3185  st->state = CSTATE_END_COMMAND;
3186  else
3187  st->state = CSTATE_ABORTED;
3188  break;
3189 
3190  /*
3191  * Wait until sleep is done. This state is entered after a
3192  * \sleep metacommand. The behavior is similar to
3193  * CSTATE_THROTTLE, but proceeds to CSTATE_START_COMMAND
3194  * instead of CSTATE_START_TX.
3195  */
3196  case CSTATE_SLEEP:
3198  if (INSTR_TIME_GET_MICROSEC(now) < st->sleep_until)
3199  return; /* still sleeping, nothing to do here */
3200  /* Else done sleeping. */
3201  st->state = CSTATE_END_COMMAND;
3202  break;
3203 
3204  /*
3205  * End of command: record stats and proceed to next command.
3206  */
3207  case CSTATE_END_COMMAND:
3208 
3209  /*
3210  * command completed: accumulate per-command execution times
3211  * in thread-local data structure, if per-command latencies
3212  * are requested.
3213  */
3214  if (report_per_command)
3215  {
3216  Command *command;
3217 
3219 
3220  command = sql_script[st->use_file].commands[st->command];
3221  /* XXX could use a mutex here, but we choose not to */
3222  addToSimpleStats(&command->stats,
3223  INSTR_TIME_GET_DOUBLE(now) -
3225  }
3226 
3227  /* Go ahead with next command, to be executed or skipped */
3228  st->command++;
3229  st->state = conditional_active(st->cstack) ?
3231  break;
3232 
3233  /*
3234  * End of transaction (end of script, really).
3235  */
3236  case CSTATE_END_TX:
3237 
3238  /* transaction finished: calculate latency and do log */
3239  processXactStats(thread, st, &now, false, agg);
3240 
3241  /*
3242  * missing \endif... cannot happen if CheckConditional was
3243  * okay
3244  */
3246 
3247  if (is_connect)
3248  {
3249  finishCon(st);
3250  INSTR_TIME_SET_ZERO(now);
3251  }
3252 
3253  if ((st->cnt >= nxacts && duration <= 0) || timer_exceeded)
3254  {
3255  /* script completed */
3256  st->state = CSTATE_FINISHED;
3257  break;
3258  }
3259 
3260  /* next transaction (script) */
3262 
3263  /*
3264  * Ensure that we always return on this point, so as to avoid
3265  * an infinite loop if the script only contains meta commands.
3266  */
3267  return;
3268 
3269  /*
3270  * Final states. Close the connection if it's still open.
3271  */
3272  case CSTATE_ABORTED:
3273  case CSTATE_FINISHED:
3274  finishCon(st);
3275  return;
3276  }
3277  }
3278 }
3279 
3280 /*
3281  * Subroutine for advanceConnectionState -- initiate or execute the current
3282  * meta command, and return the next state to set.
3283  *
3284  * *now is updated to the current time, unless the command is expected to
3285  * take no time to execute.
3286  */
3287 static ConnectionStateEnum
3289 {
3290  Command *command = sql_script[st->use_file].commands[st->command];
3291  int argc;
3292  char **argv;
3293 
3294  Assert(command != NULL && command->type == META_COMMAND);
3295 
3296  argc = command->argc;
3297  argv = command->argv;
3298 
3300  {
3302 
3303  initPQExpBuffer(&buf);
3304 
3305  printfPQExpBuffer(&buf, "client %d executing \\%s", st->id, argv[0]);
3306  for (int i = 1; i < argc; i++)
3307  appendPQExpBuffer(&buf, " %s", argv[i]);
3308 
3309  pg_log_debug("%s", buf.data);
3310 
3311  termPQExpBuffer(&buf);
3312  }
3313 
3314  if (command->meta == META_SLEEP)
3315  {
3316  int usec;
3317 
3318  /*
3319  * A \sleep doesn't execute anything, we just get the delay from the
3320  * argument, and enter the CSTATE_SLEEP state. (The per-command
3321  * latency will be recorded in CSTATE_SLEEP state, not here, after the
3322  * delay has elapsed.)
3323  */
3324  if (!evaluateSleep(st, argc, argv, &usec))
3325  {
3326  commandFailed(st, "sleep", "execution of meta-command failed");
3327  return CSTATE_ABORTED;
3328  }
3329 
3331  st->sleep_until = INSTR_TIME_GET_MICROSEC(*now) + usec;
3332  return CSTATE_SLEEP;
3333  }
3334  else if (command->meta == META_SET)
3335  {
3336  PgBenchExpr *expr = command->expr;
3337  PgBenchValue result;
3338 
3339  if (!evaluateExpr(st, expr, &result))
3340  {
3341  commandFailed(st, argv[0], "evaluation of meta-command failed");
3342  return CSTATE_ABORTED;
3343  }
3344 
3345  if (!putVariableValue(st, argv[0], argv[1], &result))
3346  {
3347  commandFailed(st, "set", "assignment of meta-command failed");
3348  return CSTATE_ABORTED;
3349  }
3350  }
3351  else if (command->meta == META_IF)
3352  {
3353  /* backslash commands with an expression to evaluate */
3354  PgBenchExpr *expr = command->expr;
3355  PgBenchValue result;
3356  bool cond;
3357 
3358  if (!evaluateExpr(st, expr, &result))
3359  {
3360  commandFailed(st, argv[0], "evaluation of meta-command failed");
3361  return CSTATE_ABORTED;
3362  }
3363 
3364  cond = valueTruth(&result);
3366  }
3367  else if (command->meta == META_ELIF)
3368  {
3369  /* backslash commands with an expression to evaluate */
3370  PgBenchExpr *expr = command->expr;
3371  PgBenchValue result;
3372  bool cond;
3373 
3375  {
3376  /* elif after executed block, skip eval and wait for endif. */
3378  return CSTATE_END_COMMAND;
3379  }
3380 
3381  if (!evaluateExpr(st, expr, &result))
3382  {
3383  commandFailed(st, argv[0], "evaluation of meta-command failed");
3384  return CSTATE_ABORTED;
3385  }
3386 
3387  cond = valueTruth(&result);
3390  }
3391  else if (command->meta == META_ELSE)
3392  {
3393  switch (conditional_stack_peek(st->cstack))
3394  {
3395  case IFSTATE_TRUE:
3397  break;
3398  case IFSTATE_FALSE: /* inconsistent if active */
3399  case IFSTATE_IGNORED: /* inconsistent if active */
3400  case IFSTATE_NONE: /* else without if */
3401  case IFSTATE_ELSE_TRUE: /* else after else */
3402  case IFSTATE_ELSE_FALSE: /* else after else */
3403  default:
3404  /* dead code if conditional check is ok */
3405  Assert(false);
3406  }
3407  }
3408  else if (command->meta == META_ENDIF)
3409  {
3412  }
3413  else if (command->meta == META_SETSHELL)
3414  {
3415  if (!runShellCommand(st, argv[1], argv + 2, argc - 2))
3416  {
3417  commandFailed(st, "setshell", "execution of meta-command failed");
3418  return CSTATE_ABORTED;
3419  }
3420  }
3421  else if (command->meta == META_SHELL)
3422  {
3423  if (!runShellCommand(st, NULL, argv + 1, argc - 1))
3424  {
3425  commandFailed(st, "shell", "execution of meta-command failed");
3426  return CSTATE_ABORTED;
3427  }
3428  }
3429 
3430  /*
3431  * executing the expression or shell command might have taken a
3432  * non-negligible amount of time, so reset 'now'
3433  */
3434  INSTR_TIME_SET_ZERO(*now);
3435 
3436  return CSTATE_END_COMMAND;
3437 }
3438 
3439 /*
3440  * Print log entry after completing one transaction.
3441  *
3442  * We print Unix-epoch timestamps in the log, so that entries can be
3443  * correlated against other logs. On some platforms this could be obtained
3444  * from the instr_time reading the caller has, but rather than get entangled
3445  * with that, we just eat the cost of an extra syscall in all cases.
3446  */
3447 static void
3448 doLog(TState *thread, CState *st,
3449  StatsData *agg, bool skipped, double latency, double lag)
3450 {
3451  FILE *logfile = thread->logfile;
3452 
3453  Assert(use_log);
3454 
3455  /*
3456  * Skip the log entry if sampling is enabled and this row doesn't belong
3457  * to the random sample.
3458  */
3459  if (sample_rate != 0.0 &&
3460  pg_erand48(thread->ts_sample_rs.xseed) > sample_rate)
3461  return;
3462 
3463  /* should we aggregate the results or not? */
3464  if (agg_interval > 0)
3465  {
3466  /*
3467  * Loop until we reach the interval of the current moment, and print
3468  * any empty intervals in between (this may happen with very low tps,
3469  * e.g. --rate=0.1).
3470  */
3471  time_t now = time(NULL);
3472 
3473  while (agg->start_time + agg_interval <= now)
3474  {
3475  /* print aggregated report to logfile */
3476  fprintf(logfile, "%ld " INT64_FORMAT " %.0f %.0f %.0f %.0f",
3477  (long) agg->start_time,
3478  agg->cnt,
3479  agg->latency.sum,
3480  agg->latency.sum2,
3481  agg->latency.min,
3482  agg->latency.max);
3483  if (throttle_delay)
3484  {
3485  fprintf(logfile, " %.0f %.0f %.0f %.0f",
3486  agg->lag.sum,
3487  agg->lag.sum2,
3488  agg->lag.min,
3489  agg->lag.max);
3490  if (latency_limit)
3491  fprintf(logfile, " " INT64_FORMAT, agg->skipped);
3492  }
3493  fputc('\n', logfile);
3494 
3495  /* reset data and move to next interval */
3496  initStats(agg, agg->start_time + agg_interval);
3497  }
3498 
3499  /* accumulate the current transaction */
3500  accumStats(agg, skipped, latency, lag);
3501  }
3502  else
3503  {
3504  /* no, print raw transactions */
3505  struct timeval tv;
3506 
3507  gettimeofday(&tv, NULL);
3508  if (skipped)
3509  fprintf(logfile, "%d " INT64_FORMAT " skipped %d %ld %ld",
3510  st->id, st->cnt, st->use_file,
3511  (long) tv.tv_sec, (long) tv.tv_usec);
3512  else
3513  fprintf(logfile, "%d " INT64_FORMAT " %.0f %d %ld %ld",
3514  st->id, st->cnt, latency, st->use_file,
3515  (long) tv.tv_sec, (long) tv.tv_usec);
3516  if (throttle_delay)
3517  fprintf(logfile, " %.0f", lag);
3518  fputc('\n', logfile);
3519  }
3520 }
3521 
3522 /*
3523  * Accumulate and report statistics at end of a transaction.
3524  *
3525  * (This is also called when a transaction is late and thus skipped.
3526  * Note that even skipped transactions are counted in the "cnt" fields.)
3527  */
3528 static void
3530  bool skipped, StatsData *agg)
3531 {
3532  double latency = 0.0,
3533  lag = 0.0;
3534  bool thread_details = progress || throttle_delay || latency_limit,
3535  detailed = thread_details || use_log || per_script_stats;
3536 
3537  if (detailed && !skipped)
3538  {
3540 
3541  /* compute latency & lag */
3542  latency = INSTR_TIME_GET_MICROSEC(*now) - st->txn_scheduled;
3544  }
3545 
3546  if (thread_details)
3547  {
3548  /* keep detailed thread stats */
3549  accumStats(&thread->stats, skipped, latency, lag);
3550 
3551  /* count transactions over the latency limit, if needed */
3552  if (latency_limit && latency > latency_limit)
3553  thread->latency_late++;
3554  }
3555  else
3556  {
3557  /* no detailed stats, just count */
3558  thread->stats.cnt++;
3559  }
3560 
3561  /* client stat is just counting */
3562  st->cnt++;
3563 
3564  if (use_log)
3565  doLog(thread, st, agg, skipped, latency, lag);
3566 
3567  /* XXX could use a mutex here, but we choose not to */
3568  if (per_script_stats)
3569  accumStats(&sql_script[st->use_file].stats, skipped, latency, lag);
3570 }
3571 
3572 
3573 /* discard connections */
3574 static void
3576 {
3577  int i;
3578 
3579  for (i = 0; i < length; i++)
3580  finishCon(&state[i]);
3581 }
3582 
3583 /*
3584  * Remove old pgbench tables, if any exist
3585  */
3586 static void
3588 {
3589  fprintf(stderr, "dropping old tables...\n");
3590 
3591  /*
3592  * We drop all the tables in one command, so that whether there are
3593  * foreign key dependencies or not doesn't matter.
3594  */
3595  executeStatement(con, "drop table if exists "
3596  "pgbench_accounts, "
3597  "pgbench_branches, "
3598  "pgbench_history, "
3599  "pgbench_tellers");
3600 }
3601 
3602 /*
3603  * Create "pgbench_accounts" partitions if needed.
3604  *
3605  * This is the larger table of pgbench default tpc-b like schema
3606  * with a known size, so we choose to partition it.
3607  */
3608 static void
3610 {
3611  char ff[64];
3612 
3613  ff[0] = '\0';
3614 
3615  /*
3616  * Per ddlinfo in initCreateTables, fillfactor is needed on table
3617  * pgbench_accounts.
3618  */
3619  append_fillfactor(ff, sizeof(ff));
3620 
3621  /* we must have to create some partitions */
3622  Assert(partitions > 0);
3623 
3624  fprintf(stderr, "creating %d partitions...\n", partitions);
3625 
3626  for (int p = 1; p <= partitions; p++)
3627  {
3628  char query[256];
3629 
3630  if (partition_method == PART_RANGE)
3631  {
3632  int64 part_size = (naccounts * (int64) scale + partitions - 1) / partitions;
3633  char minvalue[32],
3634  maxvalue[32];
3635 
3636  /*
3637  * For RANGE, we use open-ended partitions at the beginning and
3638  * end to allow any valid value for the primary key. Although the
3639  * actual minimum and maximum values can be derived from the
3640  * scale, it is more generic and the performance is better.
3641  */
3642  if (p == 1)
3643  sprintf(minvalue, "minvalue");
3644  else
3645  sprintf(minvalue, INT64_FORMAT, (p - 1) * part_size + 1);
3646 
3647  if (p < partitions)
3648  sprintf(maxvalue, INT64_FORMAT, p * part_size + 1);
3649  else
3650  sprintf(maxvalue, "maxvalue");
3651 
3652  snprintf(query, sizeof(query),
3653  "create%s table pgbench_accounts_%d\n"
3654  " partition of pgbench_accounts\n"
3655  " for values from (%s) to (%s)%s\n",
3656  unlogged_tables ? " unlogged" : "", p,
3657  minvalue, maxvalue, ff);
3658  }
3659  else if (partition_method == PART_HASH)
3660  snprintf(query, sizeof(query),
3661  "create%s table pgbench_accounts_%d\n"
3662  " partition of pgbench_accounts\n"
3663  " for values with (modulus %d, remainder %d)%s\n",
3664  unlogged_tables ? " unlogged" : "", p,
3665  partitions, p - 1, ff);
3666  else /* cannot get there */
3667  Assert(0);
3668 
3669  executeStatement(con, query);
3670  }
3671 }
3672 
3673 /*
3674  * Create pgbench's standard tables
3675  */
3676 static void
3678 {
3679  /*
3680  * Note: TPC-B requires at least 100 bytes per row, and the "filler"
3681  * fields in these table declarations were intended to comply with that.
3682  * The pgbench_accounts table complies with that because the "filler"
3683  * column is set to blank-padded empty string. But for all other tables
3684  * the columns default to NULL and so don't actually take any space. We
3685  * could fix that by giving them non-null default values. However, that
3686  * would completely break comparability of pgbench results with prior
3687  * versions. Since pgbench has never pretended to be fully TPC-B compliant
3688  * anyway, we stick with the historical behavior.
3689  */
3690  struct ddlinfo
3691  {
3692  const char *table; /* table name */
3693  const char *smcols; /* column decls if accountIDs are 32 bits */
3694  const char *bigcols; /* column decls if accountIDs are 64 bits */
3695  int declare_fillfactor;
3696  };
3697  static const struct ddlinfo DDLs[] = {
3698  {
3699  "pgbench_history",
3700  "tid int,bid int,aid int,delta int,mtime timestamp,filler char(22)",
3701  "tid int,bid int,aid bigint,delta int,mtime timestamp,filler char(22)",
3702  0
3703  },
3704  {
3705  "pgbench_tellers",
3706  "tid int not null,bid int,tbalance int,filler char(84)",
3707  "tid int not null,bid int,tbalance int,filler char(84)",
3708  1
3709  },
3710  {
3711  "pgbench_accounts",
3712  "aid int not null,bid int,abalance int,filler char(84)",
3713  "aid bigint not null,bid int,abalance int,filler char(84)",
3714  1
3715  },
3716  {
3717  "pgbench_branches",
3718  "bid int not null,bbalance int,filler char(88)",
3719  "bid int not null,bbalance int,filler char(88)",
3720  1
3721  }
3722  };
3723  int i;
3724 
3725  fprintf(stderr, "creating tables...\n");
3726 
3727  for (i = 0; i < lengthof(DDLs); i++)
3728  {
3729  char opts[256];
3730  char buffer[256];
3731  const struct ddlinfo *ddl = &DDLs[i];
3732  const char *cols;
3733 
3734  /* Construct new create table statement. */
3735  opts[0] = '\0';
3736 
3737  /* Partition pgbench_accounts table */
3738  if (partition_method != PART_NONE && strcmp(ddl->table, "pgbench_accounts") == 0)
3739  snprintf(opts + strlen(opts), sizeof(opts) - strlen(opts),
3740  " partition by %s (aid)", PARTITION_METHOD[partition_method]);
3741  else if (ddl->declare_fillfactor)
3742  /* fillfactor is only expected on actual tables */
3743  append_fillfactor(opts, sizeof(opts));
3744 
3745  if (tablespace != NULL)
3746  {
3747  char *escape_tablespace;
3748 
3749  escape_tablespace = PQescapeIdentifier(con, tablespace,
3750  strlen(tablespace));
3751  snprintf(opts + strlen(opts), sizeof(opts) - strlen(opts),
3752  " tablespace %s", escape_tablespace);
3753  PQfreemem(escape_tablespace);
3754  }
3755 
3756  cols = (scale >= SCALE_32BIT_THRESHOLD) ? ddl->bigcols : ddl->smcols;
3757 
3758  snprintf(buffer, sizeof(buffer), "create%s table %s(%s)%s",
3759  unlogged_tables ? " unlogged" : "",
3760  ddl->table, cols, opts);
3761 
3762  executeStatement(con, buffer);
3763  }
3764 
3765  if (partition_method != PART_NONE)
3766  createPartitions(con);
3767 }
3768 
3769 /*
3770  * add fillfactor percent option.
3771  *
3772  * XXX - As default is 100, it could be removed in this case.
3773  */
3774 static void
3775 append_fillfactor(char *opts, int len)
3776 {
3777  snprintf(opts + strlen(opts), len - strlen(opts),
3778  " with (fillfactor=%d)", fillfactor);
3779 }
3780 
3781 /*
3782  * Truncate away any old data, in one command in case there are foreign keys
3783  */
3784 static void
3786 {
3787  executeStatement(con, "truncate table "
3788  "pgbench_accounts, "
3789  "pgbench_branches, "
3790  "pgbench_history, "
3791  "pgbench_tellers");
3792 }
3793 
3794 /*
3795  * Fill the standard tables with some data generated and sent from the client
3796  */
3797 static void
3799 {
3800  char sql[256];
3801  PGresult *res;
3802  int i;
3803  int64 k;
3804 
3805  /* used to track elapsed time and estimate of the remaining time */
3806  instr_time start,
3807  diff;
3808  double elapsed_sec,
3809  remaining_sec;
3810  int log_interval = 1;
3811 
3812  /* Stay on the same line if reporting to a terminal */
3813  char eol = isatty(fileno(stderr)) ? '\r' : '\n';
3814 
3815  fprintf(stderr, "generating data (client-side)...\n");
3816 
3817  /*
3818  * we do all of this in one transaction to enable the backend's
3819  * data-loading optimizations
3820  */
3821  executeStatement(con, "begin");
3822 
3823  /* truncate away any old data */
3824  initTruncateTables(con);
3825 
3826  /*
3827  * fill branches, tellers, accounts in that order in case foreign keys
3828  * already exist
3829  */
3830  for (i = 0; i < nbranches * scale; i++)
3831  {
3832  /* "filler" column defaults to NULL */
3833  snprintf(sql, sizeof(sql),
3834  "insert into pgbench_branches(bid,bbalance) values(%d,0)",
3835  i + 1);
3836  executeStatement(con, sql);
3837  }
3838 
3839  for (i = 0; i < ntellers * scale; i++)
3840  {
3841  /* "filler" column defaults to NULL */
3842  snprintf(sql, sizeof(sql),
3843  "insert into pgbench_tellers(tid,bid,tbalance) values (%d,%d,0)",
3844  i + 1, i / ntellers + 1);
3845  executeStatement(con, sql);
3846  }
3847 
3848  /*
3849  * accounts is big enough to be worth using COPY and tracking runtime
3850  */
3851  res = PQexec(con, "copy pgbench_accounts from stdin");
3852  if (PQresultStatus(res) != PGRES_COPY_IN)
3853  {
3854  pg_log_fatal("unexpected copy in result: %s", PQerrorMessage(con));
3855  exit(1);
3856  }
3857  PQclear(res);
3858 
3859  INSTR_TIME_SET_CURRENT(start);
3860 
3861  for (k = 0; k < (int64) naccounts * scale; k++)
3862  {
3863  int64 j = k + 1;
3864 
3865  /* "filler" column defaults to blank padded empty string */
3866  snprintf(sql, sizeof(sql),
3867  INT64_FORMAT "\t" INT64_FORMAT "\t%d\t\n",
3868  j, k / naccounts + 1, 0);
3869  if (PQputline(con, sql))
3870  {
3871  pg_log_fatal("PQputline failed");
3872  exit(1);
3873  }
3874 
3875  if (CancelRequested)
3876  break;
3877 
3878  /*
3879  * If we want to stick with the original logging, print a message each
3880  * 100k inserted rows.
3881  */
3882  if ((!use_quiet) && (j % 100000 == 0))
3883  {
3884  INSTR_TIME_SET_CURRENT(diff);
3885  INSTR_TIME_SUBTRACT(diff, start);
3886 
3887  elapsed_sec = INSTR_TIME_GET_DOUBLE(diff);
3888  remaining_sec = ((double) scale * naccounts - j) * elapsed_sec / j;
3889 
3890  fprintf(stderr, INT64_FORMAT " of " INT64_FORMAT " tuples (%d%%) done (elapsed %.2f s, remaining %.2f s)%c",
3891  j, (int64) naccounts * scale,
3892  (int) (((int64) j * 100) / (naccounts * (int64) scale)),
3893  elapsed_sec, remaining_sec, eol);
3894  }
3895  /* let's not call the timing for each row, but only each 100 rows */
3896  else if (use_quiet && (j % 100 == 0))
3897  {
3898  INSTR_TIME_SET_CURRENT(diff);
3899  INSTR_TIME_SUBTRACT(diff, start);
3900 
3901  elapsed_sec = INSTR_TIME_GET_DOUBLE(diff);
3902  remaining_sec = ((double) scale * naccounts - j) * elapsed_sec / j;
3903 
3904  /* have we reached the next interval (or end)? */
3905  if ((j == scale * naccounts) || (elapsed_sec >= log_interval * LOG_STEP_SECONDS))
3906  {
3907  fprintf(stderr, INT64_FORMAT " of " INT64_FORMAT " tuples (%d%%) done (elapsed %.2f s, remaining %.2f s)%c",
3908  j, (int64) naccounts * scale,
3909  (int) (((int64) j * 100) / (naccounts * (int64) scale)), elapsed_sec, remaining_sec, eol);
3910 
3911  /* skip to the next interval */
3912  log_interval = (int) ceil(elapsed_sec / LOG_STEP_SECONDS);
3913  }
3914  }
3915  }
3916 
3917  if (eol != '\n')
3918  fputc('\n', stderr); /* Need to move to next line */
3919 
3920  if (PQputline(con, "\\.\n"))
3921  {
3922  pg_log_fatal("very last PQputline failed");
3923  exit(1);
3924  }
3925  if (PQendcopy(con))
3926  {
3927  pg_log_fatal("PQendcopy failed");
3928  exit(1);
3929  }
3930 
3931  executeStatement(con, "commit");
3932 }
3933 
3934 /*
3935  * Fill the standard tables with some data generated on the server
3936  *
3937  * As already the case with the client-side data generation, the filler
3938  * column defaults to NULL in pgbench_branches and pgbench_tellers,
3939  * and is a blank-padded string in pgbench_accounts.
3940  */
3941 static void
3943 {
3944  char sql[256];
3945 
3946  fprintf(stderr, "generating data (server-side)...\n");
3947 
3948  /*
3949  * we do all of this in one transaction to enable the backend's
3950  * data-loading optimizations
3951  */
3952  executeStatement(con, "begin");
3953 
3954  /* truncate away any old data */
3955  initTruncateTables(con);
3956 
3957  snprintf(sql, sizeof(sql),
3958  "insert into pgbench_branches(bid,bbalance) "
3959  "select bid, 0 "
3960  "from generate_series(1, %d) as bid", nbranches * scale);
3961  executeStatement(con, sql);
3962 
3963  snprintf(sql, sizeof(sql),
3964  "insert into pgbench_tellers(tid,bid,tbalance) "
3965  "select tid, (tid - 1) / %d + 1, 0 "
3966  "from generate_series(1, %d) as tid", ntellers, ntellers * scale);
3967  executeStatement(con, sql);
3968 
3969  snprintf(sql, sizeof(sql),
3970  "insert into pgbench_accounts(aid,bid,abalance,filler) "
3971  "select aid, (aid - 1) / %d + 1, 0, '' "
3972  "from generate_series(1, "INT64_FORMAT") as aid",
3973  naccounts, (int64) naccounts * scale);
3974  executeStatement(con, sql);
3975 
3976  executeStatement(con, "commit");
3977 }
3978 
3979 /*
3980  * Invoke vacuum on the standard tables
3981  */
3982 static void
3984 {
3985  fprintf(stderr, "vacuuming...\n");
3986  executeStatement(con, "vacuum analyze pgbench_branches");
3987  executeStatement(con, "vacuum analyze pgbench_tellers");
3988  executeStatement(con, "vacuum analyze pgbench_accounts");
3989  executeStatement(con, "vacuum analyze pgbench_history");
3990 }
3991 
3992 /*
3993  * Create primary keys on the standard tables
3994  */
3995 static void
3997 {
3998  static const char *const DDLINDEXes[] = {
3999  "alter table pgbench_branches add primary key (bid)",
4000  "alter table pgbench_tellers add primary key (tid)",
4001  "alter table pgbench_accounts add primary key (aid)"
4002  };
4003  int i;
4004 
4005  fprintf(stderr, "creating primary keys...\n");
4006  for (i = 0; i < lengthof(DDLINDEXes); i++)
4007  {
4008  char buffer[256];
4009 
4010  strlcpy(buffer, DDLINDEXes[i], sizeof(buffer));
4011 
4012  if (index_tablespace != NULL)
4013  {
4014  char *escape_tablespace;
4015 
4016  escape_tablespace = PQescapeIdentifier(con, index_tablespace,
4017  strlen(index_tablespace));
4018  snprintf(buffer + strlen(buffer), sizeof(buffer) - strlen(buffer),
4019  " using index tablespace %s", escape_tablespace);
4020  PQfreemem(escape_tablespace);
4021  }
4022 
4023  executeStatement(con, buffer);
4024  }
4025 }
4026 
4027 /*
4028  * Create foreign key constraints between the standard tables
4029  */
4030 static void
4032 {
4033  static const char *const DDLKEYs[] = {
4034  "alter table pgbench_tellers add constraint pgbench_tellers_bid_fkey foreign key (bid) references pgbench_branches",
4035  "alter table pgbench_accounts add constraint pgbench_accounts_bid_fkey foreign key (bid) references pgbench_branches",
4036  "alter table pgbench_history add constraint pgbench_history_bid_fkey foreign key (bid) references pgbench_branches",
4037  "alter table pgbench_history add constraint pgbench_history_tid_fkey foreign key (tid) references pgbench_tellers",
4038  "alter table pgbench_history add constraint pgbench_history_aid_fkey foreign key (aid) references pgbench_accounts"
4039  };
4040  int i;
4041 
4042  fprintf(stderr, "creating foreign keys...\n");
4043  for (i = 0; i < lengthof(DDLKEYs); i++)
4044  {
4045  executeStatement(con, DDLKEYs[i]);
4046  }
4047 }
4048 
4049 /*
4050  * Validate an initialization-steps string
4051  *
4052  * (We could just leave it to runInitSteps() to fail if there are wrong
4053  * characters, but since initialization can take awhile, it seems friendlier
4054  * to check during option parsing.)
4055  */
4056 static void
4057 checkInitSteps(const char *initialize_steps)
4058 {
4059  if (initialize_steps[0] == '\0')
4060  {
4061  pg_log_fatal("no initialization steps specified");
4062  exit(1);
4063  }
4064 
4065  for (const char *step = initialize_steps; *step != '\0'; step++)
4066  {
4067  if (strchr(ALL_INIT_STEPS " ", *step) == NULL)
4068  {
4069  pg_log_fatal("unrecognized initialization step \"%c\"", *step);
4070  pg_log_info("Allowed step characters are: \"" ALL_INIT_STEPS "\".");
4071  exit(1);
4072  }
4073  }
4074 }
4075 
4076 /*
4077  * Invoke each initialization step in the given string
4078  */
4079 static void
4080 runInitSteps(const char *initialize_steps)
4081 {
4082  PQExpBufferData stats;
4083  PGconn *con;
4084  const char *step;
4085  double run_time = 0.0;
4086  bool first = true;
4087 
4088  initPQExpBuffer(&stats);
4089 
4090  if ((con = doConnect()) == NULL)
4091  exit(1);
4092 
4093  setup_cancel_handler(NULL);
4094  SetCancelConn(con);
4095 
4096  for (step = initialize_steps; *step != '\0'; step++)
4097  {
4098  instr_time start;
4099  char *op = NULL;
4100 
4101  INSTR_TIME_SET_CURRENT(start);
4102 
4103  switch (*step)
4104  {
4105  case 'd':
4106  op = "drop tables";
4107  initDropTables(con);
4108  break;
4109  case 't':
4110  op = "create tables";
4111  initCreateTables(con);
4112  break;
4113  case 'g':
4114  op = "client-side generate";
4116  break;
4117  case 'G':
4118  op = "server-side generate";
4120  break;
4121  case 'v':
4122  op = "vacuum";
4123  initVacuum(con);
4124  break;
4125  case 'p':
4126  op = "primary keys";
4127  initCreatePKeys(con);
4128  break;
4129  case 'f':
4130  op = "foreign keys";
4131  initCreateFKeys(con);
4132  break;
4133  case ' ':
4134  break; /* ignore */
4135  default:
4136  pg_log_fatal("unrecognized initialization step \"%c\"", *step);
4137  PQfinish(con);
4138  exit(1);
4139  }
4140 
4141  if (op != NULL)
4142  {
4143  instr_time diff;
4144  double elapsed_sec;
4145 
4146  INSTR_TIME_SET_CURRENT(diff);
4147  INSTR_TIME_SUBTRACT(diff, start);
4148  elapsed_sec = INSTR_TIME_GET_DOUBLE(diff);
4149 
4150  if (!first)
4151  appendPQExpBufferStr(&stats, ", ");
4152  else
4153  first = false;
4154 
4155  appendPQExpBuffer(&stats, "%s %.2f s", op, elapsed_sec);
4156 
4157  run_time += elapsed_sec;
4158  }
4159  }
4160 
4161  fprintf(stderr, "done in %.2f s (%s).\n", run_time, stats.data);
4162  ResetCancelConn();
4163  PQfinish(con);
4164  termPQExpBuffer(&stats);
4165 }
4166 
4167 /*
4168  * Extract pgbench table informations into global variables scale,
4169  * partition_method and partitions.
4170  */
4171 static void
4172 GetTableInfo(PGconn *con, bool scale_given)
4173 {
4174  PGresult *res;
4175 
4176  /*
4177  * get the scaling factor that should be same as count(*) from
4178  * pgbench_branches if this is not a custom query
4179  */
4180  res = PQexec(con, "select count(*) from pgbench_branches");
4181  if (PQresultStatus(res) != PGRES_TUPLES_OK)
4182  {
4183  char *sqlState = PQresultErrorField(res, PG_DIAG_SQLSTATE);
4184 
4185  pg_log_fatal("could not count number of branches: %s", PQerrorMessage(con));
4186 
4187  if (sqlState && strcmp(sqlState, ERRCODE_UNDEFINED_TABLE) == 0)
4188  pg_log_info("Perhaps you need to do initialization (\"pgbench -i\") in database \"%s\"",
4189  PQdb(con));
4190 
4191  exit(1);
4192  }
4193  scale = atoi(PQgetvalue(res, 0, 0));
4194  if (scale < 0)
4195  {
4196  pg_log_fatal("invalid count(*) from pgbench_branches: \"%s\"",
4197  PQgetvalue(res, 0, 0));
4198  exit(1);
4199  }
4200  PQclear(res);
4201 
4202  /* warn if we override user-given -s switch */
4203  if (scale_given)
4204  pg_log_warning("scale option ignored, using count from pgbench_branches table (%d)",
4205  scale);
4206 
4207  /*
4208  * Get the partition information for the first "pgbench_accounts" table
4209  * found in search_path.
4210  *
4211  * The result is empty if no "pgbench_accounts" is found.
4212  *
4213  * Otherwise, it always returns one row even if the table is not
4214  * partitioned (in which case the partition strategy is NULL).
4215  *
4216  * The number of partitions can be 0 even for partitioned tables, if no
4217  * partition is attached.
4218  *
4219  * We assume no partitioning on any failure, so as to avoid failing on an
4220  * old version without "pg_partitioned_table".
4221  */
4222  res = PQexec(con,
4223  "select o.n, p.partstrat, pg_catalog.count(i.inhparent) "
4224  "from pg_catalog.pg_class as c "
4225  "join pg_catalog.pg_namespace as n on (n.oid = c.relnamespace) "
4226  "cross join lateral (select pg_catalog.array_position(pg_catalog.current_schemas(true), n.nspname)) as o(n) "
4227  "left join pg_catalog.pg_partitioned_table as p on (p.partrelid = c.oid) "
4228  "left join pg_catalog.pg_inherits as i on (c.oid = i.inhparent) "
4229  "where c.relname = 'pgbench_accounts' and o.n is not null "
4230  "group by 1, 2 "
4231  "order by 1 asc "
4232  "limit 1");
4233 
4234  if (PQresultStatus(res) != PGRES_TUPLES_OK)
4235  {
4236  /* probably an older version, coldly assume no partitioning */
4237  partition_method = PART_NONE;
4238  partitions = 0;
4239  }
4240  else if (PQntuples(res) == 0)
4241  {
4242  /*
4243  * This case is unlikely as pgbench already found "pgbench_branches"
4244  * above to compute the scale.
4245  */
4246  pg_log_fatal("no pgbench_accounts table found in search_path");
4247  pg_log_info("Perhaps you need to do initialization (\"pgbench -i\") in database \"%s\".", PQdb(con));
4248  exit(1);
4249  }
4250  else /* PQntupes(res) == 1 */
4251  {
4252  /* normal case, extract partition information */
4253  if (PQgetisnull(res, 0, 1))
4254  partition_method = PART_NONE;
4255  else
4256  {
4257  char *ps = PQgetvalue(res, 0, 1);
4258 
4259  /* column must be there */
4260  Assert(ps != NULL);
4261 
4262  if (strcmp(ps, "r") == 0)
4263  partition_method = PART_RANGE;
4264  else if (strcmp(ps, "h") == 0)
4265  partition_method = PART_HASH;
4266  else
4267  {
4268  /* possibly a newer version with new partition method */
4269  pg_log_fatal("unexpected partition method: \"%s\"", ps);
4270  exit(1);
4271  }
4272  }
4273 
4274  partitions = atoi(PQgetvalue(res, 0, 2));
4275  }
4276 
4277  PQclear(res);
4278 }
4279 
4280 /*
4281  * Replace :param with $n throughout the command's SQL text, which
4282  * is a modifiable string in cmd->lines.
4283  */
4284 static bool
4286 {
4287  char *sql,
4288  *p;
4289 
4290  cmd->argc = 1;
4291 
4292  p = sql = pg_strdup(cmd->lines.data);
4293  while ((p = strchr(p, ':')) != NULL)
4294  {
4295  char var[13];
4296  char *name;
4297  int eaten;
4298 
4299  name = parseVariable(p, &eaten);
4300  if (name == NULL)
4301  {
4302  while (*p == ':')
4303  {
4304  p++;
4305  }
4306  continue;
4307  }
4308 
4309  /*
4310  * cmd->argv[0] is the SQL statement itself, so the max number of
4311  * arguments is one less than MAX_ARGS
4312  */
4313  if (cmd->argc >= MAX_ARGS)
4314  {
4315  pg_log_error("statement has too many arguments (maximum is %d): %s",
4316  MAX_ARGS - 1, cmd->lines.data);
4317  pg_free(name);
4318  return false;
4319  }
4320 
4321  sprintf(var, "$%d", cmd->argc);
4322  p = replaceVariable(&sql, p, eaten, var);
4323 
4324  cmd->argv[cmd->argc] = name;
4325  cmd->argc++;
4326  }
4327 
4328  Assert(cmd->argv[0] == NULL);
4329  cmd->argv[0] = sql;
4330  return true;
4331 }
4332 
4333 /*
4334  * syntax error while parsing a script (in practice, while parsing a
4335  * backslash command, because we don't detect syntax errors in SQL)
4336  *
4337  * source: source of script (filename or builtin-script ID)
4338  * lineno: line number within script (count from 1)
4339  * line: whole line of backslash command, if available
4340  * command: backslash command name, if available
4341  * msg: the actual error message
4342  * more: optional extra message
4343  * column: zero-based column number, or -1 if unknown
4344  */
4345 void
4346 syntax_error(const char *source, int lineno,
4347  const char *line, const char *command,
4348  const char *msg, const char *more, int column)
4349 {
4351 
4352  initPQExpBuffer(&buf);
4353 
4354  printfPQExpBuffer(&buf, "%s:%d: %s", source, lineno, msg);
4355  if (more != NULL)
4356  appendPQExpBuffer(&buf, " (%s)", more);
4357  if (column >= 0 && line == NULL)
4358  appendPQExpBuffer(&buf, " at column %d", column + 1);
4359  if (command != NULL)
4360  appendPQExpBuffer(&buf, " in command \"%s\"", command);
4361 
4362  pg_log_fatal("%s", buf.data);
4363 
4364  termPQExpBuffer(&buf);
4365 
4366  if (line != NULL)
4367  {
4368  fprintf(stderr, "%s\n", line);
4369  if (column >= 0)
4370  fprintf(stderr, "%*c error found here\n", column+1, '^');
4371  }
4372 
4373  exit(1);
4374 }
4375 
4376 /*
4377  * Return a pointer to the start of the SQL command, after skipping over
4378  * whitespace and "--" comments.
4379  * If the end of the string is reached, return NULL.
4380  */
4381 static char *
4382 skip_sql_comments(char *sql_command)
4383 {
4384  char *p = sql_command;
4385 
4386  /* Skip any leading whitespace, as well as "--" style comments */
4387  for (;;)
4388  {
4389  if (isspace((unsigned char) *p))
4390  p++;
4391  else if (strncmp(p, "--", 2) == 0)
4392  {
4393  p = strchr(p, '\n');
4394  if (p == NULL)
4395  return NULL;
4396  p++;
4397  }
4398  else
4399  break;
4400  }
4401 
4402  /* NULL if there's nothing but whitespace and comments */
4403  if (*p == '\0')
4404  return NULL;
4405 
4406  return p;
4407 }
4408 
4409 /*
4410  * Parse a SQL command; return a Command struct, or NULL if it's a comment
4411  *
4412  * On entry, psqlscan.l has collected the command into "buf", so we don't
4413  * really need to do much here except check for comments and set up a Command
4414  * struct.
4415  */
4416 static Command *
4417 create_sql_command(PQExpBuffer buf, const char *source)
4418 {
4419  Command *my_command;
4420  char *p = skip_sql_comments(buf->data);
4421 
4422  if (p == NULL)
4423  return NULL;
4424 
4425  /* Allocate and initialize Command structure */
4426  my_command = (Command *) pg_malloc(sizeof(Command));
4427  initPQExpBuffer(&my_command->lines);
4428  appendPQExpBufferStr(&my_command->lines, p);
4429  my_command->first_line = NULL; /* this is set later */
4430  my_command->type = SQL_COMMAND;
4431  my_command->meta = META_NONE;
4432  my_command->argc = 0;
4433  memset(my_command->argv, 0, sizeof(my_command->argv));
4434  my_command->varprefix = NULL; /* allocated later, if needed */
4435  my_command->expr = NULL;
4436  initSimpleStats(&my_command->stats);
4437 
4438  return my_command;
4439 }
4440 
4441 /* Free a Command structure and associated data */
4442 static void
4444 {
4445  termPQExpBuffer(&command->lines);
4446  if (command->first_line)
4447  pg_free(command->first_line);
4448  for (int i = 0; i < command->argc; i++)
4449  pg_free(command->argv[i]);
4450  if (command->varprefix)
4451  pg_free(command->varprefix);
4452 
4453  /*
4454  * It should also free expr recursively, but this is currently not needed
4455  * as only gset commands (which do not have an expression) are freed.
4456  */
4457  pg_free(command);
4458 }
4459 
4460 /*
4461  * Once an SQL command is fully parsed, possibly by accumulating several
4462  * parts, complete other fields of the Command structure.
4463  */
4464 static void
4466 {
4467  char buffer[128];
4468 
4469  Assert(my_command->type == SQL_COMMAND);
4470 
4471  /* Save the first line for error display. */
4472  strlcpy(buffer, my_command->lines.data, sizeof(buffer));
4473  buffer[strcspn(buffer, "\n\r")] = '\0';
4474  my_command->first_line = pg_strdup(buffer);
4475 
4476  /* parse query if necessary */
4477  switch (querymode)
4478  {
4479  case QUERY_SIMPLE:
4480  my_command->argv[0] = my_command->lines.data;
4481  my_command->argc++;
4482  break;
4483  case QUERY_EXTENDED:
4484  case QUERY_PREPARED:
4485  if (!parseQuery(my_command))
4486  exit(1);
4487  break;
4488  default:
4489  exit(1);
4490  }
4491 }
4492 
4493 /*
4494  * Parse a backslash command; return a Command struct, or NULL if comment
4495  *
4496  * At call, we have scanned only the initial backslash.
4497  */
4498 static Command *
4499 process_backslash_command(PsqlScanState sstate, const char *source)
4500 {
4501  Command *my_command;
4502  PQExpBufferData word_buf;
4503  int word_offset;
4504  int offsets[MAX_ARGS]; /* offsets of argument words */
4505  int start_offset;
4506  int lineno;
4507  int j;
4508 
4509  initPQExpBuffer(&word_buf);
4510 
4511  /* Remember location of the backslash */
4512  start_offset = expr_scanner_offset(sstate) - 1;
4513  lineno = expr_scanner_get_lineno(sstate, start_offset);
4514 
4515  /* Collect first word of command */
4516  if (!expr_lex_one_word(sstate, &word_buf, &word_offset))
4517  {
4518  termPQExpBuffer(&word_buf);
4519  return NULL;
4520  }
4521 
4522  /* Allocate and initialize Command structure */
4523  my_command = (Command *) pg_malloc0(sizeof(Command));
4524  my_command->type = META_COMMAND;
4525  my_command->argc = 0;
4526  initSimpleStats(&my_command->stats);
4527 
4528  /* Save first word (command name) */
4529  j = 0;
4530  offsets[j] = word_offset;
4531  my_command->argv[j++] = pg_strdup(word_buf.data);
4532  my_command->argc++;
4533 
4534  /* ... and convert it to enum form */
4535  my_command->meta = getMetaCommand(my_command->argv[0]);
4536 
4537  if (my_command->meta == META_SET ||
4538  my_command->meta == META_IF ||
4539  my_command->meta == META_ELIF)
4540  {
4542 
4543  /* For \set, collect var name */
4544  if (my_command->meta == META_SET)
4545  {
4546  if (!expr_lex_one_word(sstate, &word_buf, &word_offset))
4547  syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
4548  "missing argument", NULL, -1);
4549 
4550  offsets[j] = word_offset;
4551  my_command->argv[j++] = pg_strdup(word_buf.data);
4552  my_command->argc++;
4553  }
4554 
4555  /* then for all parse the expression */
4556  yyscanner = expr_scanner_init(sstate, source, lineno, start_offset,
4557  my_command->argv[0]);
4558 
4559  if (expr_yyparse(yyscanner) != 0)
4560  {
4561  /* dead code: exit done from syntax_error called by yyerror */
4562  exit(1);
4563  }
4564 
4565  my_command->expr = expr_parse_result;
4566 
4567  /* Save line, trimming any trailing newline */
4568  my_command->first_line =
4570  start_offset,
4571  expr_scanner_offset(sstate),
4572  true);
4573 
4574  expr_scanner_finish(yyscanner);
4575 
4576  termPQExpBuffer(&word_buf);
4577 
4578  return my_command;
4579  }
4580 
4581  /* For all other commands, collect remaining words. */
4582  while (expr_lex_one_word(sstate, &word_buf, &word_offset))
4583  {
4584  /*
4585  * my_command->argv[0] is the command itself, so the max number of
4586  * arguments is one less than MAX_ARGS
4587  */
4588  if (j >= MAX_ARGS)
4589  syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
4590  "too many arguments", NULL, -1);
4591 
4592  offsets[j] = word_offset;
4593  my_command->argv[j++] = pg_strdup(word_buf.data);
4594  my_command->argc++;
4595  }
4596 
4597  /* Save line, trimming any trailing newline */
4598  my_command->first_line =
4600  start_offset,
4601  expr_scanner_offset(sstate),
4602  true);
4603 
4604  if (my_command->meta == META_SLEEP)
4605  {
4606  if (my_command->argc < 2)
4607  syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
4608  "missing argument", NULL, -1);
4609 
4610  if (my_command->argc > 3)
4611  syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
4612  "too many arguments", NULL,
4613  offsets[3] - start_offset);
4614 
4615  /*
4616  * Split argument into number and unit to allow "sleep 1ms" etc. We
4617  * don't have to terminate the number argument with null because it
4618  * will be parsed with atoi, which ignores trailing non-digit
4619  * characters.
4620  */
4621  if (my_command->argc == 2 && my_command->argv[1][0] != ':')
4622  {
4623  char *c = my_command->argv[1];
4624 
4625  while (isdigit((unsigned char) *c))
4626  c++;
4627  if (*c)
4628  {
4629  my_command->argv[2] = c;
4630  offsets[2] = offsets[1] + (c - my_command->argv[1]);
4631  my_command->argc = 3;
4632  }
4633  }
4634 
4635  if (my_command->argc == 3)
4636  {
4637  if (pg_strcasecmp(my_command->argv[2], "us") != 0 &&
4638  pg_strcasecmp(my_command->argv[2], "ms") != 0 &&
4639  pg_strcasecmp(my_command->argv[2], "s") != 0)
4640  syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
4641  "unrecognized time unit, must be us, ms or s",
4642  my_command->argv[2], offsets[2] - start_offset);
4643  }
4644  }
4645  else if (my_command->meta == META_SETSHELL)
4646  {
4647  if (my_command->argc < 3)
4648  syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
4649  "missing argument", NULL, -1);
4650  }
4651  else if (my_command->meta == META_SHELL)
4652  {
4653  if (my_command->argc < 2)
4654  syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
4655  "missing command", NULL, -1);
4656  }
4657  else if (my_command->meta == META_ELSE || my_command->meta == META_ENDIF)
4658  {
4659  if (my_command->argc != 1)
4660  syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
4661  "unexpected argument", NULL, -1);
4662  }
4663  else if (my_command->meta == META_GSET)
4664  {
4665  if (my_command->argc > 2)
4666  syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
4667  "too many arguments", NULL, -1);
4668  }
4669  else
4670  {
4671  /* my_command->meta == META_NONE */
4672  syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
4673  "invalid command", NULL, -1);
4674  }
4675 
4676  termPQExpBuffer(&word_buf);
4677 
4678  return my_command;
4679 }
4680 
4681 static void
4682 ConditionError(const char *desc, int cmdn, const char *msg)
4683 {
4684  pg_log_fatal("condition error in script \"%s\" command %d: %s",
4685  desc, cmdn, msg);
4686  exit(1);
4687 }
4688 
4689 /*
4690  * Partial evaluation of conditionals before recording and running the script.
4691  */
4692 static void
4694 {
4695  /* statically check conditional structure */
4697  int i;
4698 
4699  for (i = 0; ps.commands[i] != NULL; i++)
4700  {
4701  Command *cmd = ps.commands[i];
4702 
4703  if (cmd->type == META_COMMAND)
4704  {
4705  switch (cmd->meta)
4706  {
4707  case META_IF:
4709  break;
4710  case META_ELIF:
4711  if (conditional_stack_empty(cs))
4712  ConditionError(ps.desc, i + 1, "\\elif without matching \\if");
4714  ConditionError(ps.desc, i + 1, "\\elif after \\else");
4715  break;
4716  case META_ELSE:
4717  if (conditional_stack_empty(cs))
4718  ConditionError(ps.desc, i + 1, "\\else without matching \\if");
4720  ConditionError(ps.desc, i + 1, "\\else after \\else");
4722  break;
4723  case META_ENDIF:
4724  if (!conditional_stack_pop(cs))
4725  ConditionError(ps.desc, i + 1, "\\endif without matching \\if");
4726  break;
4727  default:
4728  /* ignore anything else... */
4729  break;
4730  }
4731  }
4732  }
4733  if (!conditional_stack_empty(cs))
4734  ConditionError(ps.desc, i + 1, "\\if without matching \\endif");
4736 }
4737 
4738 /*
4739  * Parse a script (either the contents of a file, or a built-in script)
4740  * and add it to the list of scripts.
4741  */
4742 static void
4743 ParseScript(const char *script, const char *desc, int weight)
4744 {
4745  ParsedScript ps;
4746  PsqlScanState sstate;
4747  PQExpBufferData line_buf;
4748  int alloc_num;
4749  int index;
4750  int lineno;
4751  int start_offset;
4752 
4753 #define COMMANDS_ALLOC_NUM 128
4754  alloc_num = COMMANDS_ALLOC_NUM;
4755 
4756  /* Initialize all fields of ps */
4757  ps.desc = desc;
4758  ps.weight = weight;
4759  ps.commands = (Command **) pg_malloc(sizeof(Command *) * alloc_num);
4760  initStats(&ps.stats, 0);
4761 
4762  /* Prepare to parse script */
4763  sstate = psql_scan_create(&pgbench_callbacks);
4764 
4765  /*
4766  * Ideally, we'd scan scripts using the encoding and stdstrings settings
4767  * we get from a DB connection. However, without major rearrangement of
4768  * pgbench's argument parsing, we can't have a DB connection at the time
4769  * we parse scripts. Using SQL_ASCII (encoding 0) should work well enough
4770  * with any backend-safe encoding, though conceivably we could be fooled
4771  * if a script file uses a client-only encoding. We also assume that
4772  * stdstrings should be true, which is a bit riskier.
4773  */
4774  psql_scan_setup(sstate, script, strlen(script), 0, true);
4775  start_offset = expr_scanner_offset(sstate) - 1;
4776 
4777  initPQExpBuffer(&line_buf);
4778 
4779  index = 0;
4780 
4781  for (;;)
4782  {
4783  PsqlScanResult sr;
4784  promptStatus_t prompt;
4785  Command *command = NULL;
4786 
4787  resetPQExpBuffer(&line_buf);
4788  lineno = expr_scanner_get_lineno(sstate, start_offset);
4789 
4790  sr = psql_scan(sstate, &line_buf, &prompt);
4791 
4792  /* If we collected a new SQL command, process that */
4793  command = create_sql_command(&line_buf, desc);
4794 
4795  /* store new command */
4796  if (command)
4797  ps.commands[index++] = command;
4798 
4799  /* If we reached a backslash, process that */
4800  if (sr == PSCAN_BACKSLASH)
4801  {
4802  command = process_backslash_command(sstate, desc);
4803 
4804  if (command)
4805  {
4806  /*
4807  * If this is gset, merge into the preceding command. (We
4808  * don't use a command slot in this case).
4809  */
4810  if (command->meta == META_GSET)
4811  {
4812  Command *cmd;
4813 
4814  if (index == 0)
4815  syntax_error(desc, lineno, NULL, NULL,
4816  "\\gset must follow a SQL command",
4817  NULL, -1);
4818 
4819  cmd = ps.commands[index - 1];
4820 
4821  if (cmd->type != SQL_COMMAND ||
4822  cmd->varprefix != NULL)
4823  syntax_error(desc, lineno, NULL, NULL,
4824  "\\gset must follow a SQL command",
4825  cmd->first_line, -1);
4826 
4827  /* get variable prefix */
4828  if (command->argc <= 1 || command->argv[1][0] == '\0')
4829  cmd->varprefix = pg_strdup("");
4830  else
4831  cmd->varprefix = pg_strdup(command->argv[1]);
4832 
4833  /* cleanup unused command */
4834  free_command(command);
4835 
4836  continue;
4837  }
4838 
4839  /* Attach any other backslash command as a new command */
4840  ps.commands[index++] = command;
4841  }
4842  }
4843 
4844  /*
4845  * Since we used a command slot, allocate more if needed. Note we
4846  * always allocate one more in order to accommodate the NULL
4847  * terminator below.
4848  */
4849  if (index >= alloc_num)
4850  {
4851  alloc_num += COMMANDS_ALLOC_NUM;
4852  ps.commands = (Command **)
4853  pg_realloc(ps.commands, sizeof(Command *) * alloc_num);
4854  }
4855 
4856  /* Done if we reached EOF */
4857  if (sr == PSCAN_INCOMPLETE || sr == PSCAN_EOL)
4858  break;
4859  }
4860 
4861  ps.commands[index] = NULL;
4862 
4863  addScript(ps);
4864 
4865  termPQExpBuffer(&line_buf);
4866  psql_scan_finish(sstate);
4867  psql_scan_destroy(sstate);
4868 }
4869 
4870 /*
4871  * Read the entire contents of file fd, and return it in a malloc'd buffer.
4872  *
4873  * The buffer will typically be larger than necessary, but we don't care
4874  * in this program, because we'll free it as soon as we've parsed the script.
4875  */
4876 static char *
4878 {
4879  char *buf;
4880  size_t buflen = BUFSIZ;
4881  size_t used = 0;
4882 
4883  buf = (char *) pg_malloc(buflen);
4884 
4885  for (;;)
4886  {
4887  size_t nread;
4888 
4889  nread = fread(buf + used, 1, BUFSIZ, fd);
4890  used += nread;
4891  /* If fread() read less than requested, must be EOF or error */
4892  if (nread < BUFSIZ)
4893  break;
4894  /* Enlarge buf so we can read some more */
4895  buflen += BUFSIZ;
4896  buf = (char *) pg_realloc(buf, buflen);
4897  }
4898  /* There is surely room for a terminator */
4899  buf[used] = '\0';
4900 
4901  return buf;
4902 }
4903 
4904 /*
4905  * Given a file name, read it and add its script to the list.
4906  * "-" means to read stdin.
4907  * NB: filename must be storage that won't disappear.
4908  */
4909 static void
4910 process_file(const char *filename, int weight)
4911 {
4912  FILE *fd;
4913  char *buf;
4914 
4915  /* Slurp the file contents into "buf" */
4916  if (strcmp(filename, "-") == 0)
4917  fd = stdin;
4918  else if ((fd = fopen(filename, "r")) == NULL)
4919  {
4920  pg_log_fatal("could not open file \"%s\": %m", filename);
4921  exit(1);
4922  }
4923 
4924  buf = read_file_contents(fd);
4925 
4926  if (ferror(fd))
4927  {
4928  pg_log_fatal("could not read file \"%s\": %m", filename);
4929  exit(1);
4930  }
4931 
4932  if (fd != stdin)
4933  fclose(fd);
4934 
4935  ParseScript(buf, filename, weight);
4936 
4937  free(buf);
4938 }
4939 
4940 /* Parse the given builtin script and add it to the list. */
4941 static void
4942 process_builtin(const BuiltinScript *bi, int weight)
4943 {
4944  ParseScript(bi->script, bi->desc, weight);
4945 }
4946 
4947 /* show available builtin scripts */
4948 static void
4950 {
4951  int i;
4952 
4953  fprintf(stderr, "Available builtin scripts:\n");
4954  for (i = 0; i < lengthof(builtin_script); i++)
4955  fprintf(stderr, " %13s: %s\n", builtin_script[i].name, builtin_script[i].desc);
4956  fprintf(stderr, "\n");
4957 }
4958 
4959 /* return builtin script "name" if unambiguous, fails if not found */
4960 static const BuiltinScript *
4961 findBuiltin(const char *name)
4962 {
4963  int i,
4964  found = 0,
4965  len = strlen(name);
4966  const BuiltinScript *result = NULL;
4967 
4968  for (i = 0; i < lengthof(builtin_script); i++)
4969  {
4970  if (strncmp(builtin_script[i].name, name, len) == 0)
4971  {
4972  result = &builtin_script[i];
4973  found++;
4974  }
4975  }
4976 
4977  /* ok, unambiguous result */
4978  if (found == 1)
4979  return result;
4980 
4981  /* error cases */
4982  if (found == 0)
4983  pg_log_fatal("no builtin script found for name \"%s\"", name);
4984  else /* found > 1 */
4985  pg_log_fatal("ambiguous builtin name: %d builtin scripts found for prefix \"%s\"", found, name);
4986 
4988  exit(1);
4989 }
4990 
4991 /*
4992  * Determine the weight specification from a script option (-b, -f), if any,
4993  * and return it as an integer (1 is returned if there's no weight). The
4994  * script name is returned in *script as a malloc'd string.
4995  */
4996 static int
4997 parseScriptWeight(const char *option, char **script)
4998 {
4999  char *sep;
5000  int weight;
5001 
5002  if ((sep = strrchr(option, WSEP)))
5003  {
5004  int namelen = sep - option;
5005  long wtmp;
5006  char *badp;
5007 
5008  /* generate the script name */
5009  *script = pg_malloc(namelen + 1);
5010  strncpy(*script, option, namelen);
5011  (*script)[namelen] = '\0';
5012 
5013  /* process digits of the weight spec */
5014  errno = 0;
5015  wtmp = strtol(sep + 1, &badp, 10);
5016  if (errno != 0 || badp == sep + 1 || *badp != '\0')
5017  {
5018  pg_log_fatal("invalid weight specification: %s", sep);
5019  exit(1);
5020  }
5021  if (wtmp > INT_MAX || wtmp < 0)
5022  {
5023  pg_log_fatal("weight specification out of range (0 .. %u): " INT64_FORMAT,
5024  INT_MAX, (int64) wtmp);
5025  exit(1);
5026  }
5027  weight = wtmp;
5028  }
5029  else
5030  {
5031  *script = pg_strdup(option);
5032  weight = 1;
5033  }
5034 
5035  return weight;
5036 }
5037 
5038 /* append a script to the list of scripts to process */
5039 static void
5041 {
5042  if (script.commands == NULL || script.commands[0] == NULL)
5043  {
5044  pg_log_fatal("empty command list for script \"%s\"", script.desc);
5045  exit(1);
5046  }
5047 
5048  if (num_scripts >= MAX_SCRIPTS)
5049  {
5050  pg_log_fatal("at most %d SQL scripts are allowed", MAX_SCRIPTS);
5051  exit(1);
5052  }
5053 
5054  CheckConditional(script);
5055 
5056  sql_script[num_scripts] = script;
5057  num_scripts++;
5058 }
5059 
5060 /*
5061  * Print progress report.
5062  *
5063  * On entry, *last and *last_report contain the statistics and time of last
5064  * progress report. On exit, they are updated with the new stats.
5065  */
5066 static void
5067 printProgressReport(TState *threads, int64 test_start, int64 now,
5068  StatsData *last, int64 *last_report)
5069 {
5070  /* generate and show report */
5071  int64 run = now - *last_report,
5072  ntx;
5073  double tps,
5074  total_run,
5075  latency,
5076  sqlat,
5077  lag,
5078  stdev;
5079  char tbuf[315];
5080  StatsData cur;
5081 
5082  /*
5083  * Add up the statistics of all threads.
5084  *
5085  * XXX: No locking. There is no guarantee that we get an atomic snapshot
5086  * of the transaction count and latencies, so these figures can well be
5087  * off by a small amount. The progress report's purpose is to give a
5088  * quick overview of how the test is going, so that shouldn't matter too
5089  * much. (If a read from a 64-bit integer is not atomic, you might get a
5090  * "torn" read and completely bogus latencies though!)
5091  */
5092  initStats(&cur, 0);
5093  for (int i = 0; i < nthreads; i++)
5094  {
5095  mergeSimpleStats(&cur.latency, &threads[i].stats.latency);
5096  mergeSimpleStats(&cur.lag, &threads[i].stats.lag);
5097  cur.cnt += threads[i].stats.cnt;
5098  cur.skipped += threads[i].stats.skipped;
5099  }
5100 
5101  /* we count only actually executed transactions */
5102  ntx = (cur.cnt - cur.skipped) - (last->cnt - last->skipped);
5103  total_run = (now - test_start) / 1000000.0;
5104  tps = 1000000.0 * ntx / run;
5105  if (ntx > 0)
5106  {
5107  latency = 0.001 * (cur.latency.sum - last->latency.sum) / ntx;
5108  sqlat = 1.0 * (cur.latency.sum2 - last->latency.sum2) / ntx;
5109  stdev = 0.001 * sqrt(sqlat - 1000000.0 * latency * latency);
5110  lag = 0.001 * (cur.lag.sum - last->lag.sum) / ntx;
5111  }
5112  else
5113  {
5114  latency = sqlat = stdev = lag = 0;
5115  }
5116 
5117  if (progress_timestamp)
5118  {
5119  /*
5120  * On some platforms the current system timestamp is available in
5121  * now_time, but rather than get entangled with that, we just eat the
5122  * cost of an extra syscall in all cases.
5123  */
5124  struct timeval tv;
5125 
5126  gettimeofday(&tv, NULL);
5127  snprintf(tbuf, sizeof(tbuf), "%ld.%03ld s",
5128  (long) tv.tv_sec, (long) (tv.tv_usec / 1000));
5129  }
5130  else
5131  {
5132  /* round seconds are expected, but the thread may be late */
5133  snprintf(tbuf, sizeof(tbuf), "%.1f s", total_run);
5134  }
5135 
5136  fprintf(stderr,
5137  "progress: %s, %.1f tps, lat %.3f ms stddev %.3f",
5138  tbuf, tps, latency, stdev);
5139 
5140  if (throttle_delay)
5141  {
5142  fprintf(stderr, ", lag %.3f ms", lag);
5143  if (latency_limit)
5144  fprintf(stderr, ", " INT64_FORMAT " skipped",
5145  cur.skipped - last->skipped);
5146  }
5147  fprintf(stderr, "\n");
5148 
5149  *last = cur;
5150  *last_report = now;
5151 }
5152 
5153 static void
5154 printSimpleStats(const char *prefix, SimpleStats *ss)
5155 {
5156  if (ss->count > 0)
5157  {
5158  double latency = ss->sum / ss->count;
5159  double stddev = sqrt(ss->sum2 / ss->count - latency * latency);
5160 
5161  printf("%s average = %.3f ms\n", prefix, 0.001 * latency);
5162  printf("%s stddev = %.3f ms\n", prefix, 0.001 * stddev);
5163  }
5164 }
5165 
5166 /* print out results */
5167 static void
5168 printResults(StatsData *total, instr_time total_time,
5169  instr_time conn_total_time, int64 latency_late)
5170 {
5171  double time_include,
5172  tps_include,
5173  tps_exclude;
5174  int64 ntx = total->cnt - total->skipped;
5175 
5176  time_include = INSTR_TIME_GET_DOUBLE(total_time);
5177 
5178  /* tps is about actually executed transactions */
5179  tps_include = ntx / time_include;
5180  tps_exclude = ntx /
5181  (time_include - (INSTR_TIME_GET_DOUBLE(conn_total_time) / nclients));
5182 
5183  /* Report test parameters. */
5184  printf("transaction type: %s\n",
5185  num_scripts == 1 ? sql_script[0].desc : "multiple scripts");
5186  printf("scaling factor: %d\n", scale);
5187  /* only print partitioning information if some partitioning was detected */
5188  if (partition_method != PART_NONE)
5189  printf("partition method: %s\npartitions: %d\n",
5190  PARTITION_METHOD[partition_method], partitions);
5191  printf("query mode: %s\n", QUERYMODE[querymode]);
5192  printf("number of clients: %d\n", nclients);
5193  printf("number of threads: %d\n", nthreads);
5194  if (duration <= 0)
5195  {
5196  printf("number of transactions per client: %d\n", nxacts);
5197  printf("number of transactions actually processed: " INT64_FORMAT "/%d\n",
5198  ntx, nxacts * nclients);
5199  }
5200  else
5201  {
5202  printf("duration: %d s\n", duration);
5203  printf("number of transactions actually processed: " INT64_FORMAT "\n",
5204  ntx);
5205  }
5206 
5207  /* Remaining stats are nonsensical if we failed to execute any xacts */
5208  if (total->cnt <= 0)
5209  return;
5210 
5211  if (throttle_delay && latency_limit)
5212  printf("number of transactions skipped: " INT64_FORMAT " (%.3f %%)\n",
5213  total->skipped,
5214  100.0 * total->skipped / total->cnt);
5215 
5216  if (latency_limit)
5217  printf("number of transactions above the %.1f ms latency limit: " INT64_FORMAT "/" INT64_FORMAT " (%.3f %%)\n",
5218  latency_limit / 1000.0, latency_late, ntx,
5219  (ntx > 0) ? 100.0 * latency_late / ntx : 0.0);
5220 
5221  if (throttle_delay || progress || latency_limit)
5222  printSimpleStats("latency", &total->latency);
5223  else
5224  {
5225  /* no measurement, show average latency computed from run time */
5226  printf("latency average = %.3f ms\n",
5227  1000.0 * time_include * nclients / total->cnt);
5228  }
5229 
5230  if (throttle_delay)
5231  {
5232  /*
5233  * Report average transaction lag under rate limit throttling. This
5234  * is the delay between scheduled and actual start times for the
5235  * transaction. The measured lag may be caused by thread/client load,
5236  * the database load, or the Poisson throttling process.
5237  */
5238  printf("rate limit schedule lag: avg %.3f (max %.3f) ms\n",
5239  0.001 * total->lag.sum / total->cnt, 0.001 * total->lag.max);
5240  }
5241 
5242  printf("tps = %f (including connections establishing)\n", tps_include);
5243  printf("tps = %f (excluding connections establishing)\n", tps_exclude);
5244 
5245  /* Report per-script/command statistics */
5246  if (per_script_stats || report_per_command)
5247  {
5248  int i;
5249 
5250  for (i = 0; i < num_scripts; i++)
5251  {
5252  if (per_script_stats)
5253  {
5254  StatsData *sstats = &sql_script[i].stats;
5255 
5256  printf("SQL script %d: %s\n"
5257  " - weight: %d (targets %.1f%% of total)\n"
5258  " - " INT64_FORMAT " transactions (%.1f%% of total, tps = %f)\n",
5259  i + 1, sql_script[i].desc,
5260  sql_script[i].weight,
5261  100.0 * sql_script[i].weight / total_weight,
5262  sstats->cnt,
5263  100.0 * sstats->cnt / total->cnt,
5264  (sstats->cnt - sstats->skipped) / time_include);
5265 
5266  if (throttle_delay && latency_limit && sstats->cnt > 0)
5267  printf(" - number of transactions skipped: " INT64_FORMAT " (%.3f%%)\n",
5268  sstats->skipped,
5269  100.0 * sstats->skipped / sstats->cnt);
5270 
5271  printSimpleStats(" - latency", &sstats->latency);
5272  }
5273 
5274  /* Report per-command latencies */
5275  if (report_per_command)
5276  {
5277  Command **commands;
5278 
5279  if (per_script_stats)
5280  printf(" - statement latencies in milliseconds:\n");
5281  else
5282  printf("statement latencies in milliseconds:\n");
5283 
5284  for (commands = sql_script[i].commands;
5285  *commands != NULL;
5286  commands++)
5287  {
5288  SimpleStats *cstats = &(*commands)->stats;
5289 
5290  printf(" %11.3f %s\n",
5291  (cstats->count > 0) ?
5292  1000.0 * cstats->sum / cstats->count : 0.0,
5293  (*commands)->first_line);
5294  }
5295  }
5296  }
5297  }
5298 }
5299 
5300 /*
5301  * Set up a random seed according to seed parameter (NULL means default),
5302  * and initialize base_random_sequence for use in initializing other sequences.
5303  */
5304 static bool
5305 set_random_seed(const char *seed)
5306 {
5307  uint64 iseed;
5308 
5309  if (seed == NULL || strcmp(seed, "time") == 0)
5310  {
5311  /* rely on current time */
5312  instr_time now;
5313 
5315  iseed = (uint64) INSTR_TIME_GET_MICROSEC(now);
5316  }
5317  else if (strcmp(seed, "rand") == 0)
5318  {
5319  /* use some "strong" random source */
5320  if (!pg_strong_random(&iseed, sizeof(iseed)))
5321  {
5322  pg_log_error("could not generate random seed");
5323  return false;
5324  }
5325  }
5326  else
5327  {
5328  /* parse unsigned-int seed value */
5329  unsigned long ulseed;
5330  char garbage;
5331 
5332  /* Don't try to use UINT64_FORMAT here; it might not work for sscanf */
5333  if (sscanf(seed, "%lu%c", &ulseed, &garbage) != 1)
5334  {
5335  pg_log_error("unrecognized random seed option \"%s\"", seed);
5336  pg_log_info("Expecting an unsigned integer, \"time\" or \"rand\"");
5337  return false;
5338  }
5339  iseed = (uint64) ulseed;
5340  }
5341 
5342  if (seed != NULL)
5343  pg_log_info("setting random seed to " UINT64_FORMAT, iseed);
5344  random_seed = iseed;
5345 
5346  /* Fill base_random_sequence with low-order bits of seed */
5347  base_random_sequence.xseed[0] = iseed & 0xFFFF;
5348  base_random_sequence.xseed[1] = (iseed >> 16) & 0xFFFF;
5349  base_random_sequence.xseed[2] = (iseed >> 32) & 0xFFFF;
5350 
5351  return true;
5352 }
5353 
5354 int
5355 main(int argc, char **argv)
5356 {
5357  static struct option long_options[] = {
5358  /* systematic long/short named options */
5359  {"builtin", required_argument, NULL, 'b'},
5360  {"client", required_argument, NULL, 'c'},
5361  {"connect", no_argument, NULL, 'C'},
5362  {"debug", no_argument, NULL, 'd'},
5363  {"define", required_argument, NULL, 'D'},
5364  {"file", required_argument, NULL, 'f'},
5365  {"fillfactor", required_argument, NULL, 'F'},
5366  {"host", required_argument, NULL, 'h'},
5367  {"initialize", no_argument, NULL, 'i'},
5368  {"init-steps", required_argument, NULL, 'I'},
5369  {"jobs", required_argument, NULL, 'j'},
5370  {"log", no_argument, NULL, 'l'},
5371  {"latency-limit", required_argument, NULL, 'L'},
5372  {"no-vacuum", no_argument, NULL, 'n'},
5373  {"port", required_argument, NULL, 'p'},
5374  {"progress", required_argument, NULL, 'P'},
5375  {"protocol", required_argument, NULL, 'M'},
5376  {"quiet", no_argument, NULL, 'q'},
5377  {"report-latencies", no_argument, NULL, 'r'},
5378  {"rate", required_argument, NULL, 'R'},
5379  {"scale", required_argument, NULL, 's'},
5380  {"select-only", no_argument, NULL, 'S'},
5381  {"skip-some-updates", no_argument, NULL, 'N'},
5382  {"time", required_argument, NULL, 'T'},
5383  {"transactions", required_argument, NULL, 't'},
5384  {"username", required_argument, NULL, 'U'},
5385  {"vacuum-all", no_argument, NULL, 'v'},
5386  /* long-named only options */
5387  {"unlogged-tables", no_argument, NULL, 1},
5388  {"tablespace", required_argument, NULL, 2},
5389  {"index-tablespace", required_argument, NULL, 3},
5390  {"sampling-rate", required_argument, NULL, 4},
5391  {"aggregate-interval", required_argument, NULL, 5},
5392  {"progress-timestamp", no_argument, NULL, 6},
5393  {"log-prefix", required_argument, NULL, 7},
5394  {"foreign-keys", no_argument, NULL, 8},
5395  {"random-seed", required_argument, NULL, 9},
5396  {"show-script", required_argument, NULL, 10},
5397  {"partitions", required_argument, NULL, 11},
5398  {"partition-method", required_argument, NULL, 12},
5399  {NULL, 0, NULL, 0}
5400  };
5401 
5402  int c;
5403  bool is_init_mode = false; /* initialize mode? */
5404  char *initialize_steps = NULL;
5405  bool foreign_keys = false;
5406  bool is_no_vacuum = false;
5407  bool do_vacuum_accounts = false; /* vacuum accounts table? */
5408  int optindex;
5409  bool scale_given = false;
5410 
5411  bool benchmarking_option_set = false;
5412  bool initialization_option_set = false;
5413  bool internal_script_used = false;
5414 
5415  CState *state; /* status of clients */
5416  TState *threads; /* array of thread */
5417 
5418  instr_time start_time; /* start up time */
5419  instr_time total_time;
5420  instr_time conn_total_time;
5421  int64 latency_late = 0;
5422  StatsData stats;
5423  int weight;
5424 
5425  int i;
5426  int nclients_dealt;
5427 
5428 #ifdef HAVE_GETRLIMIT
5429  struct rlimit rlim;
5430 #endif
5431 
5432  PGconn *con;
5433  char *env;
5434 
5435  int exit_code = 0;
5436 
5437  pg_logging_init(argv[0]);
5438  progname = get_progname(argv[0]);
5439 
5440  if (argc > 1)
5441  {
5442  if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
5443  {
5444  usage();
5445  exit(0);
5446  }
5447  if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
5448  {
5449  puts("pgbench (PostgreSQL) " PG_VERSION);
5450  exit(0);
5451  }
5452  }
5453 
5454  if ((env = getenv("PGHOST")) != NULL && *env != '\0')
5455  pghost = env;
5456  if ((env = getenv("PGPORT")) != NULL && *env != '\0')
5457  pgport = env;
5458  else if ((env = getenv("PGUSER")) != NULL && *env != '\0')
5459  login = env;
5460 
5461  state = (CState *) pg_malloc0(sizeof(CState));
5462 
5463  /* set random seed early, because it may be used while parsing scripts. */
5464  if (!set_random_seed(getenv("PGBENCH_RANDOM_SEED")))
5465  {
5466  pg_log_fatal("error while setting random seed from PGBENCH_RANDOM_SEED environment variable");
5467  exit(1);
5468  }
5469 
5470  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)
5471  {
5472  char *script;
5473 
5474  switch (c)
5475  {
5476  case 'i':
5477  is_init_mode = true;
5478  break;
5479  case 'I':
5480  if (initialize_steps)
5481  pg_free(initialize_steps);
5482  initialize_steps = pg_strdup(optarg);
5483  checkInitSteps(initialize_steps);
5484  initialization_option_set = true;
5485  break;
5486  case 'h':
5487  pghost = pg_strdup(optarg);
5488  break;
5489  case 'n':
5490  is_no_vacuum = true;
5491  break;
5492  case 'v':
5493  benchmarking_option_set = true;
5494  do_vacuum_accounts = true;
5495  break;
5496  case 'p':
5497  pgport = pg_strdup(optarg);
5498  break;
5499  case 'd':
5501  break;
5502  case 'c':
5503  benchmarking_option_set = true;
5504  nclients = atoi(optarg);
5505  if (nclients <= 0)
5506  {
5507  pg_log_fatal("invalid number of clients: \"%s\"", optarg);
5508  exit(1);
5509  }
5510 #ifdef HAVE_GETRLIMIT
5511 #ifdef RLIMIT_NOFILE /* most platforms use RLIMIT_NOFILE */
5512  if (getrlimit(RLIMIT_NOFILE, &rlim) == -1)
5513 #else /* but BSD doesn't ... */
5514  if (getrlimit(RLIMIT_OFILE, &rlim) == -1)
5515 #endif /* RLIMIT_NOFILE */
5516  {
5517  pg_log_fatal("getrlimit failed: %m");
5518  exit(1);
5519  }
5520  if (rlim.rlim_cur < nclients + 3)
5521  {
5522  pg_log_fatal("need at least %d open files, but system limit is %ld",
5523  nclients + 3, (long) rlim.rlim_cur);
5524  pg_log_info("Reduce number of clients, or use limit/ulimit to increase the system limit.");
5525  exit(1);
5526  }
5527 #endif /* HAVE_GETRLIMIT */
5528  break;
5529  case 'j': /* jobs */
5530  benchmarking_option_set = true;
5531  nthreads = atoi(optarg);
5532  if (nthreads <= 0)
5533  {
5534  pg_log_fatal("invalid number of threads: \"%s\"", optarg);
5535  exit(1);
5536  }
5537 #ifndef ENABLE_THREAD_SAFETY
5538  if (nthreads != 1)
5539  {
5540  pg_log_fatal("threads are not supported on this platform; use -j1");
5541  exit(1);
5542  }
5543 #endif /* !ENABLE_THREAD_SAFETY */
5544  break;
5545  case 'C':
5546  benchmarking_option_set = true;
5547  is_connect = true;
5548  break;
5549  case 'r':
5550  benchmarking_option_set = true;
5551  report_per_command = true;
5552  break;
5553  case 's':
5554  scale_given = true;
5555  scale = atoi(optarg);
5556  if (scale <= 0)
5557  {
5558  pg_log_fatal("invalid scaling factor: \"%s\"", optarg);
5559  exit(1);
5560  }
5561  break;
5562  case 't':
5563  benchmarking_option_set = true;
5564  nxacts = atoi(optarg);
5565  if (nxacts <= 0)
5566  {
5567  pg_log_fatal("invalid number of transactions: \"%s\"", optarg);
5568  exit(1);
5569  }
5570  break;
5571  case 'T':
5572  benchmarking_option_set = true;
5573  duration = atoi(optarg);
5574  if (duration <= 0)
5575  {
5576  pg_log_fatal("invalid duration: \"%s\"", optarg);
5577  exit(1);
5578  }
5579  break;
5580  case 'U':
5581  login = pg_strdup(optarg);
5582  break;
5583  case 'l':
5584  benchmarking_option_set = true;
5585  use_log = true;
5586  break;
5587  case 'q':
5588  initialization_option_set = true;
5589  use_quiet = true;
5590  break;
5591  case 'b':
5592  if (strcmp(optarg, "list") == 0)
5593  {
5595  exit(0);
5596  }
5597  weight = parseScriptWeight(optarg, &script);
5598  process_builtin(findBuiltin(script), weight);
5599  benchmarking_option_set = true;
5600  internal_script_used = true;
5601  break;
5602  case 'S':
5603  process_builtin(findBuiltin("select-only"), 1);
5604  benchmarking_option_set = true;
5605  internal_script_used = true;
5606  break;
5607  case 'N':
5608  process_builtin(findBuiltin("simple-update"), 1);
5609  benchmarking_option_set = true;
5610  internal_script_used = true;
5611  break;
5612  case 'f':
5613  weight = parseScriptWeight(optarg, &script);
5614  process_file(script, weight);
5615  benchmarking_option_set = true;
5616  break;
5617  case 'D':
5618  {
5619  char *p;
5620 
5621  benchmarking_option_set = true;
5622 
5623  if ((p = strchr(optarg, '=')) == NULL || p == optarg || *(p + 1) == '\0')
5624  {
5625  pg_log_fatal("invalid variable definition: \"%s\"", optarg);
5626  exit(1);
5627  }
5628 
5629  *p++ = '\0';
5630  if (!putVariable(&state[0], "option", optarg, p))
5631  exit(1);
5632  }
5633  break;
5634  case 'F':
5635  initialization_option_set = true;
5636  fillfactor = atoi(optarg);
5637  if (fillfactor < 10 || fillfactor > 100)
5638  {
5639  pg_log_fatal("invalid fillfactor: \"%s\"", optarg);
5640  exit(1);
5641  }
5642  break;
5643  case 'M':
5644  benchmarking_option_set = true;
5645  for (querymode = 0; querymode < NUM_QUERYMODE; querymode++)
5646  if (strcmp(optarg, QUERYMODE[querymode]) == 0)
5647  break;
5648  if (querymode >= NUM_QUERYMODE)
5649  {
5650  pg_log_fatal("invalid query mode (-M): \"%s\"", optarg);
5651  exit(1);
5652  }
5653  break;
5654  case 'P':
5655  benchmarking_option_set = true;
5656  progress = atoi(optarg);
5657  if (progress <= 0)
5658  {
5659  pg_log_fatal("invalid thread progress delay: \"%s\"", optarg);
5660  exit(1);
5661  }
5662  break;
5663  case 'R':
5664  {
5665  /* get a double from the beginning of option value */
5666  double throttle_value = atof(optarg);
5667 
5668  benchmarking_option_set = true;
5669 
5670  if (throttle_value <= 0.0)
5671  {
5672  pg_log_fatal("invalid rate limit: \"%s\"", optarg);
5673  exit(1);
5674  }
5675  /* Invert rate limit into per-transaction delay in usec */
5676  throttle_delay = 1000000.0 / throttle_value;
5677  }
5678  break;
5679  case 'L':
5680  {
5681  double limit_ms = atof(optarg);
5682 
5683  if (limit_ms <= 0.0)
5684  {
5685  pg_log_fatal("invalid latency limit: \"%s\"", optarg);
5686  exit(1);
5687  }
5688  benchmarking_option_set = true;
5689  latency_limit = (int64) (limit_ms * 1000);
5690  }
5691  break;
5692  case 1: /* unlogged-tables */
5693  initialization_option_set = true;
5694  unlogged_tables = true;
5695  break;
5696  case 2: /* tablespace */
5697  initialization_option_set = true;
5698  tablespace = pg_strdup(optarg);
5699  break;
5700  case 3: /* index-tablespace */
5701  initialization_option_set = true;
5702  index_tablespace = pg_strdup(optarg);
5703  break;
5704  case 4: /* sampling-rate */
5705  benchmarking_option_set = true;
5706  sample_rate = atof(optarg);
5707  if (sample_rate <= 0.0 || sample_rate > 1.0)
5708  {
5709  pg_log_fatal("invalid sampling rate: \"%s\"", optarg);
5710  exit(1);
5711  }
5712  break;
5713  case 5: /* aggregate-interval */
5714  benchmarking_option_set = true;
5715  agg_interval = atoi(optarg);
5716  if (agg_interval <= 0)
5717  {
5718  pg_log_fatal("invalid number of seconds for aggregation: \"%s\"", optarg);
5719  exit(1);
5720  }
5721  break;
5722  case 6: /* progress-timestamp */
5723  progress_timestamp = true;
5724  benchmarking_option_set = true;
5725  break;
5726  case 7: /* log-prefix */
5727  benchmarking_option_set = true;
5728  logfile_prefix = pg_strdup(optarg);
5729  break;
5730  case 8: /* foreign-keys */
5731  initialization_option_set = true;
5732  foreign_keys = true;
5733  break;
5734  case 9: /* random-seed */
5735  benchmarking_option_set = true;
5736  if (!set_random_seed(optarg))
5737  {
5738  pg_log_fatal("error while setting random seed from --random-seed option");
5739  exit(1);
5740  }
5741  break;
5742  case 10: /* list */
5743  {
5744  const BuiltinScript *s = findBuiltin(optarg);
5745 
5746  fprintf(stderr, "-- %s: %s\n%s\n", s->name, s->desc, s->script);
5747  exit(0);
5748  }
5749  break;
5750  case 11: /* partitions */
5751  initialization_option_set = true;
5752  partitions = atoi(optarg);
5753  if (partitions < 0)
5754  {
5755  pg_log_fatal("invalid number of partitions: \"%s\"", optarg);
5756  exit(1);
5757  }
5758  break;
5759  case 12: /* partition-method */
5760  initialization_option_set = true;
5761  if (pg_strcasecmp(optarg, "range") == 0)
5762  partition_method = PART_RANGE;
5763  else if (pg_strcasecmp(optarg, "hash") == 0)
5764  partition_method = PART_HASH;
5765  else
5766  {
5767  pg_log_fatal("invalid partition method, expecting \"range\" or \"hash\", got: \"%s\"",
5768  optarg);
5769  exit(1);
5770  }
5771  break;
5772  default:
5773  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
5774  exit(1);
5775  break;
5776  }
5777  }
5778 
5779  /* set default script if none */
5780  if (num_scripts == 0 && !is_init_mode)
5781  {
5782  process_builtin(findBuiltin("tpcb-like"), 1);
5783  benchmarking_option_set = true;
5784  internal_script_used = true;
5785  }
5786 
5787  /* complete SQL command initialization and compute total weight */
5788  for (i = 0; i < num_scripts; i++)
5789  {
5790  Command **commands = sql_script[i].commands;
5791 
5792  for (int j = 0; commands[j] != NULL; j++)
5793  if (commands[j]->type == SQL_COMMAND)
5794  postprocess_sql_command(commands[j]);
5795 
5796  /* cannot overflow: weight is 32b, total_weight 64b */
5797  total_weight += sql_script[i].weight;
5798  }
5799 
5800  if (total_weight == 0 && !is_init_mode)
5801  {
5802  pg_log_fatal("total script weight must not be zero");
5803  exit(1);
5804  }
5805 
5806  /* show per script stats if several scripts are used */
5807  if (num_scripts > 1)
5808  per_script_stats = true;
5809 
5810  /*
5811  * Don't need more threads than there are clients. (This is not merely an
5812  * optimization; throttle_delay is calculated incorrectly below if some
5813  * threads have no clients assigned to them.)
5814  */
5815  if (nthreads > nclients)
5816  nthreads = nclients;
5817 
5818  /*
5819  * Convert throttle_delay to a per-thread delay time. Note that this
5820  * might be a fractional number of usec, but that's OK, since it's just
5821  * the center of a Poisson distribution of delays.
5822  */
5823  throttle_delay *= nthreads;
5824 
5825  if (argc > optind)
5826  dbName = argv[optind++];
5827  else
5828  {
5829  if ((env = getenv("PGDATABASE")) != NULL && *env != '\0')
5830  dbName = env;
5831  else if (login != NULL && *login != '\0')
5832  dbName = login;
5833  else
5834  dbName = "";
5835  }
5836 
5837  if (optind < argc)
5838  {
5839  pg_log_fatal("too many command-line arguments (first is \"%s\")",
5840  argv[optind]);
5841  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
5842  exit(1);
5843  }
5844 
5845  if (is_init_mode)
5846  {
5847  if (benchmarking_option_set)
5848  {
5849  pg_log_fatal("some of the specified options cannot be used in initialization (-i) mode");
5850  exit(1);
5851  }
5852 
5853  if (partitions == 0 && partition_method != PART_NONE)
5854  {
5855  pg_log_fatal("--partition-method requires greater than zero --partitions");
5856  exit(1);
5857  }
5858 
5859  /* set default method */
5860  if (partitions > 0 && partition_method == PART_NONE)
5861  partition_method = PART_RANGE;
5862 
5863  if (initialize_steps == NULL)
5864  initialize_steps = pg_strdup(DEFAULT_INIT_STEPS);
5865 
5866  if (is_no_vacuum)
5867  {
5868  /* Remove any vacuum step in initialize_steps */
5869  char *p;
5870 
5871  while ((p = strchr(initialize_steps, 'v')) !