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