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-2024, 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 #if defined(WIN32) && FD_SETSIZE < 1024
31 #error FD_SETSIZE needs to have been increased
32 #endif
33 
34 #include "postgres_fe.h"
35 
36 #include <ctype.h>
37 #include <float.h>
38 #include <limits.h>
39 #include <math.h>
40 #include <signal.h>
41 #include <time.h>
42 #include <sys/time.h>
43 #include <sys/resource.h> /* for getrlimit */
44 
45 /* For testing, PGBENCH_USE_SELECT can be defined to force use of that code */
46 #if defined(HAVE_PPOLL) && !defined(PGBENCH_USE_SELECT)
47 #define POLL_USING_PPOLL
48 #ifdef HAVE_POLL_H
49 #include <poll.h>
50 #endif
51 #else /* no ppoll(), so use select() */
52 #define POLL_USING_SELECT
53 #include <sys/select.h>
54 #endif
55 
56 #include "common/int.h"
57 #include "common/logging.h"
58 #include "common/pg_prng.h"
59 #include "common/string.h"
60 #include "common/username.h"
61 #include "fe_utils/cancel.h"
62 #include "fe_utils/conditional.h"
63 #include "fe_utils/option_utils.h"
64 #include "fe_utils/string_utils.h"
65 #include "getopt_long.h"
66 #include "libpq-fe.h"
67 #include "pgbench.h"
68 #include "port/pg_bitutils.h"
69 #include "portability/instr_time.h"
70 
71 /* X/Open (XSI) requires <math.h> to provide M_PI, but core POSIX does not */
72 #ifndef M_PI
73 #define M_PI 3.14159265358979323846
74 #endif
75 
76 #define ERRCODE_T_R_SERIALIZATION_FAILURE "40001"
77 #define ERRCODE_T_R_DEADLOCK_DETECTED "40P01"
78 #define ERRCODE_UNDEFINED_TABLE "42P01"
79 
80 /*
81  * Hashing constants
82  */
83 #define FNV_PRIME UINT64CONST(0x100000001b3)
84 #define FNV_OFFSET_BASIS UINT64CONST(0xcbf29ce484222325)
85 #define MM2_MUL UINT64CONST(0xc6a4a7935bd1e995)
86 #define MM2_MUL_TIMES_8 UINT64CONST(0x35253c9ade8f4ca8)
87 #define MM2_ROT 47
88 
89 /*
90  * Multi-platform socket set implementations
91  */
92 
93 #ifdef POLL_USING_PPOLL
94 #define SOCKET_WAIT_METHOD "ppoll"
95 
96 typedef struct socket_set
97 {
98  int maxfds; /* allocated length of pollfds[] array */
99  int curfds; /* number currently in use */
100  struct pollfd pollfds[FLEXIBLE_ARRAY_MEMBER];
101 } socket_set;
102 
103 #endif /* POLL_USING_PPOLL */
104 
105 #ifdef POLL_USING_SELECT
106 #define SOCKET_WAIT_METHOD "select"
107 
108 typedef struct socket_set
109 {
110  int maxfd; /* largest FD currently set in fds */
111  fd_set fds;
113 
114 #endif /* POLL_USING_SELECT */
115 
116 /*
117  * Multi-platform thread implementations
118  */
119 
120 #ifdef WIN32
121 /* Use Windows threads */
122 #include <windows.h>
123 #define GETERRNO() (_dosmaperr(GetLastError()), errno)
124 #define THREAD_T HANDLE
125 #define THREAD_FUNC_RETURN_TYPE unsigned
126 #define THREAD_FUNC_RETURN return 0
127 #define THREAD_FUNC_CC __stdcall
128 #define THREAD_CREATE(handle, function, arg) \
129  ((*(handle) = (HANDLE) _beginthreadex(NULL, 0, (function), (arg), 0, NULL)) == 0 ? errno : 0)
130 #define THREAD_JOIN(handle) \
131  (WaitForSingleObject(handle, INFINITE) != WAIT_OBJECT_0 ? \
132  GETERRNO() : CloseHandle(handle) ? 0 : GETERRNO())
133 #define THREAD_BARRIER_T SYNCHRONIZATION_BARRIER
134 #define THREAD_BARRIER_INIT(barrier, n) \
135  (InitializeSynchronizationBarrier((barrier), (n), 0) ? 0 : GETERRNO())
136 #define THREAD_BARRIER_WAIT(barrier) \
137  EnterSynchronizationBarrier((barrier), \
138  SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY)
139 #define THREAD_BARRIER_DESTROY(barrier)
140 #else
141 /* Use POSIX threads */
142 #include "port/pg_pthread.h"
143 #define THREAD_T pthread_t
144 #define THREAD_FUNC_RETURN_TYPE void *
145 #define THREAD_FUNC_RETURN return NULL
146 #define THREAD_FUNC_CC
147 #define THREAD_CREATE(handle, function, arg) \
148  pthread_create((handle), NULL, (function), (arg))
149 #define THREAD_JOIN(handle) \
150  pthread_join((handle), NULL)
151 #define THREAD_BARRIER_T pthread_barrier_t
152 #define THREAD_BARRIER_INIT(barrier, n) \
153  pthread_barrier_init((barrier), NULL, (n))
154 #define THREAD_BARRIER_WAIT(barrier) pthread_barrier_wait((barrier))
155 #define THREAD_BARRIER_DESTROY(barrier) pthread_barrier_destroy((barrier))
156 #endif
157 
158 
159 /********************************************************************
160  * some configurable parameters */
161 
162 #define DEFAULT_INIT_STEPS "dtgvp" /* default -I setting */
163 #define ALL_INIT_STEPS "dtgGvpf" /* all possible steps */
164 
165 #define LOG_STEP_SECONDS 5 /* seconds between log messages */
166 #define DEFAULT_NXACTS 10 /* default nxacts */
167 
168 #define MIN_GAUSSIAN_PARAM 2.0 /* minimum parameter for gauss */
169 
170 #define MIN_ZIPFIAN_PARAM 1.001 /* minimum parameter for zipfian */
171 #define MAX_ZIPFIAN_PARAM 1000.0 /* maximum parameter for zipfian */
172 
173 static int nxacts = 0; /* number of transactions per client */
174 static int duration = 0; /* duration in seconds */
175 static int64 end_time = 0; /* when to stop in micro seconds, under -T */
176 
177 /*
178  * scaling factor. for example, scale = 10 will make 1000000 tuples in
179  * pgbench_accounts table.
180  */
181 static int scale = 1;
182 
183 /*
184  * fillfactor. for example, fillfactor = 90 will use only 90 percent
185  * space during inserts and leave 10 percent free.
186  */
187 static int fillfactor = 100;
188 
189 /*
190  * use unlogged tables?
191  */
192 static bool unlogged_tables = false;
193 
194 /*
195  * log sampling rate (1.0 = log everything, 0.0 = option not given)
196  */
197 static double sample_rate = 0.0;
198 
199 /*
200  * When threads are throttled to a given rate limit, this is the target delay
201  * to reach that rate in usec. 0 is the default and means no throttling.
202  */
203 static double throttle_delay = 0;
204 
205 /*
206  * Transactions which take longer than this limit (in usec) are counted as
207  * late, and reported as such, although they are completed anyway. When
208  * throttling is enabled, execution time slots that are more than this late
209  * are skipped altogether, and counted separately.
210  */
211 static int64 latency_limit = 0;
212 
213 /*
214  * tablespace selection
215  */
216 static char *tablespace = NULL;
217 static char *index_tablespace = NULL;
218 
219 /*
220  * Number of "pgbench_accounts" partitions. 0 is the default and means no
221  * partitioning.
222  */
223 static int partitions = 0;
224 
225 /* partitioning strategy for "pgbench_accounts" */
226 typedef enum
227 {
228  PART_NONE, /* no partitioning */
229  PART_RANGE, /* range partitioning */
230  PART_HASH, /* hash partitioning */
232 
234 static const char *const PARTITION_METHOD[] = {"none", "range", "hash"};
235 
236 /* random seed used to initialize base_random_sequence */
237 static int64 random_seed = -1;
238 
239 /*
240  * end of configurable parameters
241  *********************************************************************/
242 
243 #define nbranches 1 /* Makes little sense to change this. Change
244  * -s instead */
245 #define ntellers 10
246 #define naccounts 100000
247 
248 /*
249  * The scale factor at/beyond which 32bit integers are incapable of storing
250  * 64bit values.
251  *
252  * Although the actual threshold is 21474, we use 20000 because it is easier to
253  * document and remember, and isn't that far away from the real threshold.
254  */
255 #define SCALE_32BIT_THRESHOLD 20000
256 
257 static bool use_log; /* log transaction latencies to a file */
258 static bool use_quiet; /* quiet logging onto stderr */
259 static int agg_interval; /* log aggregates instead of individual
260  * transactions */
261 static bool per_script_stats = false; /* whether to collect stats per script */
262 static int progress = 0; /* thread progress report every this seconds */
263 static bool progress_timestamp = false; /* progress report with Unix time */
264 static int nclients = 1; /* number of clients */
265 static int nthreads = 1; /* number of threads */
266 static bool is_connect; /* establish connection for each transaction */
267 static bool report_per_command = false; /* report per-command latencies,
268  * retries after errors and failures
269  * (errors without retrying) */
270 static int main_pid; /* main process id used in log filename */
271 
272 /*
273  * There are different types of restrictions for deciding that the current
274  * transaction with a serialization/deadlock error can no longer be retried and
275  * should be reported as failed:
276  * - max_tries (--max-tries) can be used to limit the number of tries;
277  * - latency_limit (-L) can be used to limit the total time of tries;
278  * - duration (-T) can be used to limit the total benchmark time.
279  *
280  * They can be combined together, and you need to use at least one of them to
281  * retry the transactions with serialization/deadlock errors. If none of them is
282  * used, the default value of max_tries is 1 and such transactions will not be
283  * retried.
284  */
285 
286 /*
287  * We cannot retry a transaction after the serialization/deadlock error if its
288  * number of tries reaches this maximum; if its value is zero, it is not used.
289  */
290 static uint32 max_tries = 1;
291 
292 static bool failures_detailed = false; /* whether to group failures in
293  * reports or logs by basic types */
294 
295 static const char *pghost = NULL;
296 static const char *pgport = NULL;
297 static const char *username = NULL;
298 static const char *dbName = NULL;
299 static char *logfile_prefix = NULL;
300 static const char *progname;
301 
302 #define WSEP '@' /* weight separator */
303 
304 static volatile sig_atomic_t timer_exceeded = false; /* flag from signal
305  * handler */
306 
307 /*
308  * We don't want to allocate variables one by one; for efficiency, add a
309  * constant margin each time it overflows.
310  */
311 #define VARIABLES_ALLOC_MARGIN 8
312 
313 /*
314  * Variable definitions.
315  *
316  * If a variable only has a string value, "svalue" is that value, and value is
317  * "not set". If the value is known, "value" contains the value (in any
318  * variant).
319  *
320  * In this case "svalue" contains the string equivalent of the value, if we've
321  * had occasion to compute that, or NULL if we haven't.
322  */
323 typedef struct
324 {
325  char *name; /* variable's name */
326  char *svalue; /* its value in string form, if known */
327  PgBenchValue value; /* actual variable's value */
328 } Variable;
329 
330 /*
331  * Data structure for client variables.
332  */
333 typedef struct
334 {
335  Variable *vars; /* array of variable definitions */
336  int nvars; /* number of variables */
337 
338  /*
339  * The maximum number of variables that we can currently store in 'vars'
340  * without having to reallocate more space. We must always have max_vars
341  * >= nvars.
342  */
343  int max_vars;
344 
345  bool vars_sorted; /* are variables sorted by name? */
346 } Variables;
347 
348 #define MAX_SCRIPTS 128 /* max number of SQL scripts allowed */
349 #define SHELL_COMMAND_SIZE 256 /* maximum size allowed for shell command */
350 
351 /*
352  * Simple data structure to keep stats about something.
353  *
354  * XXX probably the first value should be kept and used as an offset for
355  * better numerical stability...
356  */
357 typedef struct SimpleStats
358 {
359  int64 count; /* how many values were encountered */
360  double min; /* the minimum seen */
361  double max; /* the maximum seen */
362  double sum; /* sum of values */
363  double sum2; /* sum of squared values */
364 } SimpleStats;
365 
366 /*
367  * The instr_time type is expensive when dealing with time arithmetic. Define
368  * a type to hold microseconds instead. Type int64 is good enough for about
369  * 584500 years.
370  */
371 typedef int64 pg_time_usec_t;
372 
373 /*
374  * Data structure to hold various statistics: per-thread and per-script stats
375  * are maintained and merged together.
376  */
377 typedef struct StatsData
378 {
379  pg_time_usec_t start_time; /* interval start time, for aggregates */
380 
381  /*----------
382  * Transactions are counted depending on their execution and outcome.
383  * First a transaction may have started or not: skipped transactions occur
384  * under --rate and --latency-limit when the client is too late to execute
385  * them. Secondly, a started transaction may ultimately succeed or fail,
386  * possibly after some retries when --max-tries is not one. Thus
387  *
388  * the number of all transactions =
389  * 'skipped' (it was too late to execute them) +
390  * 'cnt' (the number of successful transactions) +
391  * 'failed' (the number of failed transactions).
392  *
393  * A successful transaction can have several unsuccessful tries before a
394  * successful run. Thus
395  *
396  * 'cnt' (the number of successful transactions) =
397  * successfully retried transactions (they got a serialization or a
398  * deadlock error(s), but were
399  * successfully retried from the very
400  * beginning) +
401  * directly successful transactions (they were successfully completed on
402  * the first try).
403  *
404  * A failed transaction is defined as unsuccessfully retried transactions.
405  * It can be one of two types:
406  *
407  * failed (the number of failed transactions) =
408  * 'serialization_failures' (they got a serialization error and were not
409  * successfully retried) +
410  * 'deadlock_failures' (they got a deadlock error and were not
411  * successfully retried).
412  *
413  * If the transaction was retried after a serialization or a deadlock
414  * error this does not guarantee that this retry was successful. Thus
415  *
416  * 'retries' (number of retries) =
417  * number of retries in all retried transactions =
418  * number of retries in (successfully retried transactions +
419  * failed transactions);
420  *
421  * 'retried' (number of all retried transactions) =
422  * successfully retried transactions +
423  * failed transactions.
424  *----------
425  */
426  int64 cnt; /* number of successful transactions, not
427  * including 'skipped' */
428  int64 skipped; /* number of transactions skipped under --rate
429  * and --latency-limit */
430  int64 retries; /* number of retries after a serialization or
431  * a deadlock error in all the transactions */
432  int64 retried; /* number of all transactions that were
433  * retried after a serialization or a deadlock
434  * error (perhaps the last try was
435  * unsuccessful) */
436  int64 serialization_failures; /* number of transactions that were
437  * not successfully retried after a
438  * serialization error */
439  int64 deadlock_failures; /* number of transactions that were not
440  * successfully retried after a deadlock
441  * error */
444 } StatsData;
445 
446 /*
447  * For displaying Unix epoch timestamps, as some time functions may have
448  * another reference.
449  */
451 
452 /*
453  * Error status for errors during script execution.
454  */
455 typedef enum EStatus
456 {
459 
460  /* SQL errors */
464 } EStatus;
465 
466 /*
467  * Transaction status at the end of a command.
468  */
469 typedef enum TStatus
470 {
475 } TStatus;
476 
477 /* Various random sequences are initialized from this one. */
479 
480 /* Synchronization barrier for start and connection */
482 
483 /*
484  * Connection state machine states.
485  */
486 typedef enum
487 {
488  /*
489  * The client must first choose a script to execute. Once chosen, it can
490  * either be throttled (state CSTATE_PREPARE_THROTTLE under --rate), start
491  * right away (state CSTATE_START_TX) or not start at all if the timer was
492  * exceeded (state CSTATE_FINISHED).
493  */
495 
496  /*
497  * CSTATE_START_TX performs start-of-transaction processing. Establishes
498  * a new connection for the transaction in --connect mode, records the
499  * transaction start time, and proceed to the first command.
500  *
501  * Note: once a script is started, it will either error or run till its
502  * end, where it may be interrupted. It is not interrupted while running,
503  * so pgbench --time is to be understood as tx are allowed to start in
504  * that time, and will finish when their work is completed.
505  */
507 
508  /*
509  * In CSTATE_PREPARE_THROTTLE state, we calculate when to begin the next
510  * transaction, and advance to CSTATE_THROTTLE. CSTATE_THROTTLE state
511  * sleeps until that moment, then advances to CSTATE_START_TX, or
512  * CSTATE_FINISHED if the next transaction would start beyond the end of
513  * the run.
514  */
517 
518  /*
519  * We loop through these states, to process each command in the script:
520  *
521  * CSTATE_START_COMMAND starts the execution of a command. On a SQL
522  * command, the command is sent to the server, and we move to
523  * CSTATE_WAIT_RESULT state unless in pipeline mode. On a \sleep
524  * meta-command, the timer is set, and we enter the CSTATE_SLEEP state to
525  * wait for it to expire. Other meta-commands are executed immediately. If
526  * the command about to start is actually beyond the end of the script,
527  * advance to CSTATE_END_TX.
528  *
529  * CSTATE_WAIT_RESULT waits until we get a result set back from the server
530  * for the current command.
531  *
532  * CSTATE_SLEEP waits until the end of \sleep.
533  *
534  * CSTATE_END_COMMAND records the end-of-command timestamp, increments the
535  * command counter, and loops back to CSTATE_START_COMMAND state.
536  *
537  * CSTATE_SKIP_COMMAND is used by conditional branches which are not
538  * executed. It quickly skip commands that do not need any evaluation.
539  * This state can move forward several commands, till there is something
540  * to do or the end of the script.
541  */
547 
548  /*
549  * States for failed commands.
550  *
551  * If the SQL/meta command fails, in CSTATE_ERROR clean up after an error:
552  * (1) clear the conditional stack; (2) if we have an unterminated
553  * (possibly failed) transaction block, send the rollback command to the
554  * server and wait for the result in CSTATE_WAIT_ROLLBACK_RESULT. If
555  * something goes wrong with rolling back, go to CSTATE_ABORTED.
556  *
557  * But if everything is ok we are ready for future transactions: if this
558  * is a serialization or deadlock error and we can re-execute the
559  * transaction from the very beginning, go to CSTATE_RETRY; otherwise go
560  * to CSTATE_FAILURE.
561  *
562  * In CSTATE_RETRY report an error, set the same parameters for the
563  * transaction execution as in the previous tries and process the first
564  * transaction command in CSTATE_START_COMMAND.
565  *
566  * In CSTATE_FAILURE report a failure, set the parameters for the
567  * transaction execution as they were before the first run of this
568  * transaction (except for a random state) and go to CSTATE_END_TX to
569  * complete this transaction.
570  */
575 
576  /*
577  * CSTATE_END_TX performs end-of-transaction processing. It calculates
578  * latency, and logs the transaction. In --connect mode, it closes the
579  * current connection.
580  *
581  * Then either starts over in CSTATE_CHOOSE_SCRIPT, or enters
582  * CSTATE_FINISHED if we have no more work to do.
583  */
585 
586  /*
587  * Final states. CSTATE_ABORTED means that the script execution was
588  * aborted because a command failed, CSTATE_FINISHED means success.
589  */
593 
594 /*
595  * Connection state.
596  */
597 typedef struct
598 {
599  PGconn *con; /* connection handle to DB */
600  int id; /* client No. */
601  ConnectionStateEnum state; /* state machine's current state. */
602  ConditionalStack cstack; /* enclosing conditionals state */
603 
604  /*
605  * Separate randomness for each client. This is used for random functions
606  * PGBENCH_RANDOM_* during the execution of the script.
607  */
608  pg_prng_state cs_func_rs;
609 
610  int use_file; /* index in sql_script for this client */
611  int command; /* command number in script */
612  int num_syncs; /* number of ongoing sync commands */
613 
614  /* client variables */
615  Variables variables;
616 
617  /* various times about current transaction in microseconds */
618  pg_time_usec_t txn_scheduled; /* scheduled start time of transaction */
619  pg_time_usec_t sleep_until; /* scheduled start time of next cmd */
620  pg_time_usec_t txn_begin; /* used for measuring schedule lag times */
621  pg_time_usec_t stmt_begin; /* used for measuring statement latencies */
622 
623  /* whether client prepared each command of each script */
624  bool **prepared;
625 
626  /*
627  * For processing failures and repeating transactions with serialization
628  * or deadlock errors:
629  */
630  EStatus estatus; /* the error status of the current transaction
631  * execution; this is ESTATUS_NO_ERROR if
632  * there were no errors */
633  pg_prng_state random_state; /* random state */
634  uint32 tries; /* how many times have we already tried the
635  * current transaction? */
636 
637  /* per client collected stats */
638  int64 cnt; /* client transaction count, for -t; skipped
639  * and failed transactions are also counted
640  * here */
641 } CState;
642 
643 /*
644  * Thread state
645  */
646 typedef struct
647 {
648  int tid; /* thread id */
649  THREAD_T thread; /* thread handle */
650  CState *state; /* array of CState */
651  int nstate; /* length of state[] */
652 
653  /*
654  * Separate randomness for each thread. Each thread option uses its own
655  * random state to make all of them independent of each other and
656  * therefore deterministic at the thread level.
657  */
658  pg_prng_state ts_choose_rs; /* random state for selecting a script */
659  pg_prng_state ts_throttle_rs; /* random state for transaction throttling */
660  pg_prng_state ts_sample_rs; /* random state for log sampling */
661 
662  int64 throttle_trigger; /* previous/next throttling (us) */
663  FILE *logfile; /* where to log, or NULL */
664 
665  /* per thread collected stats in microseconds */
666  pg_time_usec_t create_time; /* thread creation time */
667  pg_time_usec_t started_time; /* thread is running */
668  pg_time_usec_t bench_start; /* thread is benchmarking */
669  pg_time_usec_t conn_duration; /* cumulated connection and disconnection
670  * delays */
671 
672  StatsData stats;
673  int64 latency_late; /* count executed but late transactions */
674 } TState;
675 
676 /*
677  * queries read from files
678  */
679 #define SQL_COMMAND 1
680 #define META_COMMAND 2
681 
682 /*
683  * max number of backslash command arguments or SQL variables,
684  * including the command or SQL statement itself
685  */
686 #define MAX_ARGS 256
687 
688 typedef enum MetaCommand
689 {
690  META_NONE, /* not a known meta-command */
691  META_SET, /* \set */
692  META_SETSHELL, /* \setshell */
693  META_SHELL, /* \shell */
694  META_SLEEP, /* \sleep */
695  META_GSET, /* \gset */
696  META_ASET, /* \aset */
697  META_IF, /* \if */
698  META_ELIF, /* \elif */
699  META_ELSE, /* \else */
700  META_ENDIF, /* \endif */
701  META_STARTPIPELINE, /* \startpipeline */
702  META_SYNCPIPELINE, /* \syncpipeline */
703  META_ENDPIPELINE, /* \endpipeline */
704 } MetaCommand;
705 
706 typedef enum QueryMode
707 {
708  QUERY_SIMPLE, /* simple query */
709  QUERY_EXTENDED, /* extended query */
710  QUERY_PREPARED, /* extended query with prepared statements */
712 } QueryMode;
713 
715 static const char *const QUERYMODE[] = {"simple", "extended", "prepared"};
716 
717 /*
718  * struct Command represents one command in a script.
719  *
720  * lines The raw, possibly multi-line command text. Variable substitution
721  * not applied.
722  * first_line A short, single-line extract of 'lines', for error reporting.
723  * type SQL_COMMAND or META_COMMAND
724  * meta The type of meta-command, with META_NONE/GSET/ASET if command
725  * is SQL.
726  * argc Number of arguments of the command, 0 if not yet processed.
727  * argv Command arguments, the first of which is the command or SQL
728  * string itself. For SQL commands, after post-processing
729  * argv[0] is the same as 'lines' with variables substituted.
730  * prepname The name that this command is prepared under, in prepare mode
731  * varprefix SQL commands terminated with \gset or \aset have this set
732  * to a non NULL value. If nonempty, it's used to prefix the
733  * variable name that receives the value.
734  * aset do gset on all possible queries of a combined query (\;).
735  * expr Parsed expression, if needed.
736  * stats Time spent in this command.
737  * retries Number of retries after a serialization or deadlock error in the
738  * current command.
739  * failures Number of errors in the current command that were not retried.
740  */
741 typedef struct Command
742 {
744  char *first_line;
745  int type;
747  int argc;
748  char *argv[MAX_ARGS];
749  char *prepname;
750  char *varprefix;
753  int64 retries;
754  int64 failures;
755 } Command;
756 
757 typedef struct ParsedScript
758 {
759  const char *desc; /* script descriptor (eg, file name) */
760  int weight; /* selection weight */
761  Command **commands; /* NULL-terminated array of Commands */
762  StatsData stats; /* total time spent in script */
763 } ParsedScript;
764 
765 static ParsedScript sql_script[MAX_SCRIPTS]; /* SQL script files */
766 static int num_scripts; /* number of scripts in sql_script[] */
767 static int64 total_weight = 0;
768 
769 static bool verbose_errors = false; /* print verbose messages of all errors */
770 
771 static bool exit_on_abort = false; /* exit when any client is aborted */
772 
773 /* Builtin test scripts */
774 typedef struct BuiltinScript
775 {
776  const char *name; /* very short name for -b ... */
777  const char *desc; /* short description */
778  const char *script; /* actual pgbench script */
779 } BuiltinScript;
780 
781 static const BuiltinScript builtin_script[] =
782 {
783  {
784  "tpcb-like",
785  "<builtin: TPC-B (sort of)>",
786  "\\set aid random(1, " CppAsString2(naccounts) " * :scale)\n"
787  "\\set bid random(1, " CppAsString2(nbranches) " * :scale)\n"
788  "\\set tid random(1, " CppAsString2(ntellers) " * :scale)\n"
789  "\\set delta random(-5000, 5000)\n"
790  "BEGIN;\n"
791  "UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;\n"
792  "SELECT abalance FROM pgbench_accounts WHERE aid = :aid;\n"
793  "UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;\n"
794  "UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;\n"
795  "INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);\n"
796  "END;\n"
797  },
798  {
799  "simple-update",
800  "<builtin: simple update>",
801  "\\set aid random(1, " CppAsString2(naccounts) " * :scale)\n"
802  "\\set bid random(1, " CppAsString2(nbranches) " * :scale)\n"
803  "\\set tid random(1, " CppAsString2(ntellers) " * :scale)\n"
804  "\\set delta random(-5000, 5000)\n"
805  "BEGIN;\n"
806  "UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;\n"
807  "SELECT abalance FROM pgbench_accounts WHERE aid = :aid;\n"
808  "INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);\n"
809  "END;\n"
810  },
811  {
812  "select-only",
813  "<builtin: select only>",
814  "\\set aid random(1, " CppAsString2(naccounts) " * :scale)\n"
815  "SELECT abalance FROM pgbench_accounts WHERE aid = :aid;\n"
816  }
817 };
818 
819 
820 /* Function prototypes */
821 static void setNullValue(PgBenchValue *pv);
822 static void setBoolValue(PgBenchValue *pv, bool bval);
823 static void setIntValue(PgBenchValue *pv, int64 ival);
824 static void setDoubleValue(PgBenchValue *pv, double dval);
825 static bool evaluateExpr(CState *st, PgBenchExpr *expr,
826  PgBenchValue *retval);
828 static void doLog(TState *thread, CState *st,
829  StatsData *agg, bool skipped, double latency, double lag);
830 static void processXactStats(TState *thread, CState *st, pg_time_usec_t *now,
831  bool skipped, StatsData *agg);
832 static void addScript(const ParsedScript *script);
834 static void finishCon(CState *st);
835 static void setalarm(int seconds);
836 static socket_set *alloc_socket_set(int count);
837 static void free_socket_set(socket_set *sa);
838 static void clear_socket_set(socket_set *sa);
839 static void add_socket_to_set(socket_set *sa, int fd, int idx);
840 static int wait_on_socket_set(socket_set *sa, int64 usecs);
841 static bool socket_has_input(socket_set *sa, int fd, int idx);
842 
843 /* callback used to build rows for COPY during data loading */
844 typedef void (*initRowMethod) (PQExpBufferData *sql, int64 curr);
845 
846 /* callback functions for our flex lexer */
847 static const PsqlScanCallbacks pgbench_callbacks = {
848  NULL, /* don't need get_variable functionality */
849 };
850 
851 static inline pg_time_usec_t
852 pg_time_now(void)
853 {
854  instr_time now;
855 
857 
859 }
860 
861 static inline void
863 {
864  if ((*now) == 0)
865  (*now) = pg_time_now();
866 }
867 
868 #define PG_TIME_GET_DOUBLE(t) (0.000001 * (t))
869 
870 static void
871 usage(void)
872 {
873  printf("%s is a benchmarking tool for PostgreSQL.\n\n"
874  "Usage:\n"
875  " %s [OPTION]... [DBNAME]\n"
876  "\nInitialization options:\n"
877  " -i, --initialize invokes initialization mode\n"
878  " -I, --init-steps=[" ALL_INIT_STEPS "]+ (default \"" DEFAULT_INIT_STEPS "\")\n"
879  " run selected initialization steps, in the specified order\n"
880  " d: drop any existing pgbench tables\n"
881  " t: create the tables used by the standard pgbench scenario\n"
882  " g: generate data, client-side\n"
883  " G: generate data, server-side\n"
884  " v: invoke VACUUM on the standard tables\n"
885  " p: create primary key indexes on the standard tables\n"
886  " f: create foreign keys between the standard tables\n"
887  " -F, --fillfactor=NUM set fill factor\n"
888  " -n, --no-vacuum do not run VACUUM during initialization\n"
889  " -q, --quiet quiet logging (one message each 5 seconds)\n"
890  " -s, --scale=NUM scaling factor\n"
891  " --foreign-keys create foreign key constraints between tables\n"
892  " --index-tablespace=TABLESPACE\n"
893  " create indexes in the specified tablespace\n"
894  " --partition-method=(range|hash)\n"
895  " partition pgbench_accounts with this method (default: range)\n"
896  " --partitions=NUM partition pgbench_accounts into NUM parts (default: 0)\n"
897  " --tablespace=TABLESPACE create tables in the specified tablespace\n"
898  " --unlogged-tables create tables as unlogged tables\n"
899  "\nOptions to select what to run:\n"
900  " -b, --builtin=NAME[@W] add builtin script NAME weighted at W (default: 1)\n"
901  " (use \"-b list\" to list available scripts)\n"
902  " -f, --file=FILENAME[@W] add script FILENAME weighted at W (default: 1)\n"
903  " -N, --skip-some-updates skip updates of pgbench_tellers and pgbench_branches\n"
904  " (same as \"-b simple-update\")\n"
905  " -S, --select-only perform SELECT-only transactions\n"
906  " (same as \"-b select-only\")\n"
907  "\nBenchmarking options:\n"
908  " -c, --client=NUM number of concurrent database clients (default: 1)\n"
909  " -C, --connect establish new connection for each transaction\n"
910  " -D, --define=VARNAME=VALUE\n"
911  " define variable for use by custom script\n"
912  " -j, --jobs=NUM number of threads (default: 1)\n"
913  " -l, --log write transaction times to log file\n"
914  " -L, --latency-limit=NUM count transactions lasting more than NUM ms as late\n"
915  " -M, --protocol=simple|extended|prepared\n"
916  " protocol for submitting queries (default: simple)\n"
917  " -n, --no-vacuum do not run VACUUM before tests\n"
918  " -P, --progress=NUM show thread progress report every NUM seconds\n"
919  " -r, --report-per-command report latencies, failures, and retries per command\n"
920  " -R, --rate=NUM target rate in transactions per second\n"
921  " -s, --scale=NUM report this scale factor in output\n"
922  " -t, --transactions=NUM number of transactions each client runs (default: 10)\n"
923  " -T, --time=NUM duration of benchmark test in seconds\n"
924  " -v, --vacuum-all vacuum all four standard tables before tests\n"
925  " --aggregate-interval=NUM aggregate data over NUM seconds\n"
926  " --exit-on-abort exit when any client is aborted\n"
927  " --failures-detailed report the failures grouped by basic types\n"
928  " --log-prefix=PREFIX prefix for transaction time log file\n"
929  " (default: \"pgbench_log\")\n"
930  " --max-tries=NUM max number of tries to run transaction (default: 1)\n"
931  " --progress-timestamp use Unix epoch timestamps for progress\n"
932  " --random-seed=SEED set random seed (\"time\", \"rand\", integer)\n"
933  " --sampling-rate=NUM fraction of transactions to log (e.g., 0.01 for 1%%)\n"
934  " --show-script=NAME show builtin script code, then exit\n"
935  " --verbose-errors print messages of all errors\n"
936  "\nCommon options:\n"
937  " --debug print debugging output\n"
938  " -d, --dbname=DBNAME database name to connect to\n"
939  " -h, --host=HOSTNAME database server host or socket directory\n"
940  " -p, --port=PORT database server port number\n"
941  " -U, --username=USERNAME connect as specified database user\n"
942  " -V, --version output version information, then exit\n"
943  " -?, --help show this help, then exit\n"
944  "\n"
945  "Report bugs to <%s>.\n"
946  "%s home page: <%s>\n",
947  progname, progname, PACKAGE_BUGREPORT, PACKAGE_NAME, PACKAGE_URL);
948 }
949 
950 /* return whether str matches "^\s*[-+]?[0-9]+$" */
951 static bool
952 is_an_int(const char *str)
953 {
954  const char *ptr = str;
955 
956  /* skip leading spaces; cast is consistent with strtoint64 */
957  while (*ptr && isspace((unsigned char) *ptr))
958  ptr++;
959 
960  /* skip sign */
961  if (*ptr == '+' || *ptr == '-')
962  ptr++;
963 
964  /* at least one digit */
965  if (*ptr && !isdigit((unsigned char) *ptr))
966  return false;
967 
968  /* eat all digits */
969  while (*ptr && isdigit((unsigned char) *ptr))
970  ptr++;
971 
972  /* must have reached end of string */
973  return *ptr == '\0';
974 }
975 
976 
977 /*
978  * strtoint64 -- convert a string to 64-bit integer
979  *
980  * This function is a slightly modified version of pg_strtoint64() from
981  * src/backend/utils/adt/numutils.c.
982  *
983  * The function returns whether the conversion worked, and if so
984  * "*result" is set to the result.
985  *
986  * If not errorOK, an error message is also printed out on errors.
987  */
988 bool
989 strtoint64(const char *str, bool errorOK, int64 *result)
990 {
991  const char *ptr = str;
992  int64 tmp = 0;
993  bool neg = false;
994 
995  /*
996  * Do our own scan, rather than relying on sscanf which might be broken
997  * for long long.
998  *
999  * As INT64_MIN can't be stored as a positive 64 bit integer, accumulate
1000  * value as a negative number.
1001  */
1002 
1003  /* skip leading spaces */
1004  while (*ptr && isspace((unsigned char) *ptr))
1005  ptr++;
1006 
1007  /* handle sign */
1008  if (*ptr == '-')
1009  {
1010  ptr++;
1011  neg = true;
1012  }
1013  else if (*ptr == '+')
1014  ptr++;
1015 
1016  /* require at least one digit */
1017  if (unlikely(!isdigit((unsigned char) *ptr)))
1018  goto invalid_syntax;
1019 
1020  /* process digits */
1021  while (*ptr && isdigit((unsigned char) *ptr))
1022  {
1023  int8 digit = (*ptr++ - '0');
1024 
1025  if (unlikely(pg_mul_s64_overflow(tmp, 10, &tmp)) ||
1026  unlikely(pg_sub_s64_overflow(tmp, digit, &tmp)))
1027  goto out_of_range;
1028  }
1029 
1030  /* allow trailing whitespace, but not other trailing chars */
1031  while (*ptr != '\0' && isspace((unsigned char) *ptr))
1032  ptr++;
1033 
1034  if (unlikely(*ptr != '\0'))
1035  goto invalid_syntax;
1036 
1037  if (!neg)
1038  {
1039  if (unlikely(tmp == PG_INT64_MIN))
1040  goto out_of_range;
1041  tmp = -tmp;
1042  }
1043 
1044  *result = tmp;
1045  return true;
1046 
1047 out_of_range:
1048  if (!errorOK)
1049  pg_log_error("value \"%s\" is out of range for type bigint", str);
1050  return false;
1051 
1052 invalid_syntax:
1053  if (!errorOK)
1054  pg_log_error("invalid input syntax for type bigint: \"%s\"", str);
1055  return false;
1056 }
1057 
1058 /* convert string to double, detecting overflows/underflows */
1059 bool
1060 strtodouble(const char *str, bool errorOK, double *dv)
1061 {
1062  char *end;
1063 
1064  errno = 0;
1065  *dv = strtod(str, &end);
1066 
1067  if (unlikely(errno != 0))
1068  {
1069  if (!errorOK)
1070  pg_log_error("value \"%s\" is out of range for type double", str);
1071  return false;
1072  }
1073 
1074  if (unlikely(end == str || *end != '\0'))
1075  {
1076  if (!errorOK)
1077  pg_log_error("invalid input syntax for type double: \"%s\"", str);
1078  return false;
1079  }
1080  return true;
1081 }
1082 
1083 /*
1084  * Initialize a prng state struct.
1085  *
1086  * We derive the seed from base_random_sequence, which must be set up already.
1087  */
1088 static void
1090 {
1092 }
1093 
1094 
1095 /*
1096  * random number generator: uniform distribution from min to max inclusive.
1097  *
1098  * Although the limits are expressed as int64, you can't generate the full
1099  * int64 range in one call, because the difference of the limits mustn't
1100  * overflow int64. This is not checked.
1101  */
1102 static int64
1103 getrand(pg_prng_state *state, int64 min, int64 max)
1104 {
1105  return min + (int64) pg_prng_uint64_range(state, 0, max - min);
1106 }
1107 
1108 /*
1109  * random number generator: exponential distribution from min to max inclusive.
1110  * the parameter is so that the density of probability for the last cut-off max
1111  * value is exp(-parameter).
1112  */
1113 static int64
1114 getExponentialRand(pg_prng_state *state, int64 min, int64 max,
1115  double parameter)
1116 {
1117  double cut,
1118  uniform,
1119  rand;
1120 
1121  /* abort if wrong parameter, but must really be checked beforehand */
1122  Assert(parameter > 0.0);
1123  cut = exp(-parameter);
1124  /* pg_prng_double value in [0, 1), uniform in (0, 1] */
1125  uniform = 1.0 - pg_prng_double(state);
1126 
1127  /*
1128  * inner expression in (cut, 1] (if parameter > 0), rand in [0, 1)
1129  */
1130  Assert((1.0 - cut) != 0.0);
1131  rand = -log(cut + (1.0 - cut) * uniform) / parameter;
1132  /* return int64 random number within between min and max */
1133  return min + (int64) ((max - min + 1) * rand);
1134 }
1135 
1136 /* random number generator: gaussian distribution from min to max inclusive */
1137 static int64
1138 getGaussianRand(pg_prng_state *state, int64 min, int64 max,
1139  double parameter)
1140 {
1141  double stdev;
1142  double rand;
1143 
1144  /* abort if parameter is too low, but must really be checked beforehand */
1145  Assert(parameter >= MIN_GAUSSIAN_PARAM);
1146 
1147  /*
1148  * Get normally-distributed random number in the range -parameter <= stdev
1149  * < parameter.
1150  *
1151  * This loop is executed until the number is in the expected range.
1152  *
1153  * As the minimum parameter is 2.0, the probability of looping is low:
1154  * sqrt(-2 ln(r)) <= 2 => r >= e^{-2} ~ 0.135, then when taking the
1155  * average sinus multiplier as 2/pi, we have a 8.6% looping probability in
1156  * the worst case. For a parameter value of 5.0, the looping probability
1157  * is about e^{-5} * 2 / pi ~ 0.43%.
1158  */
1159  do
1160  {
1161  stdev = pg_prng_double_normal(state);
1162  }
1163  while (stdev < -parameter || stdev >= parameter);
1164 
1165  /* stdev is in [-parameter, parameter), normalization to [0,1) */
1166  rand = (stdev + parameter) / (parameter * 2.0);
1167 
1168  /* return int64 random number within between min and max */
1169  return min + (int64) ((max - min + 1) * rand);
1170 }
1171 
1172 /*
1173  * random number generator: generate a value, such that the series of values
1174  * will approximate a Poisson distribution centered on the given value.
1175  *
1176  * Individual results are rounded to integers, though the center value need
1177  * not be one.
1178  */
1179 static int64
1180 getPoissonRand(pg_prng_state *state, double center)
1181 {
1182  /*
1183  * Use inverse transform sampling to generate a value > 0, such that the
1184  * expected (i.e. average) value is the given argument.
1185  */
1186  double uniform;
1187 
1188  /* pg_prng_double value in [0, 1), uniform in (0, 1] */
1189  uniform = 1.0 - pg_prng_double(state);
1190 
1191  return (int64) (-log(uniform) * center + 0.5);
1192 }
1193 
1194 /*
1195  * Computing zipfian using rejection method, based on
1196  * "Non-Uniform Random Variate Generation",
1197  * Luc Devroye, p. 550-551, Springer 1986.
1198  *
1199  * This works for s > 1.0, but may perform badly for s very close to 1.0.
1200  */
1201 static int64
1202 computeIterativeZipfian(pg_prng_state *state, int64 n, double s)
1203 {
1204  double b = pow(2.0, s - 1.0);
1205  double x,
1206  t,
1207  u,
1208  v;
1209 
1210  /* Ensure n is sane */
1211  if (n <= 1)
1212  return 1;
1213 
1214  while (true)
1215  {
1216  /* random variates */
1217  u = pg_prng_double(state);
1218  v = pg_prng_double(state);
1219 
1220  x = floor(pow(u, -1.0 / (s - 1.0)));
1221 
1222  t = pow(1.0 + 1.0 / x, s - 1.0);
1223  /* reject if too large or out of bound */
1224  if (v * x * (t - 1.0) / (b - 1.0) <= t / b && x <= n)
1225  break;
1226  }
1227  return (int64) x;
1228 }
1229 
1230 /* random number generator: zipfian distribution from min to max inclusive */
1231 static int64
1232 getZipfianRand(pg_prng_state *state, int64 min, int64 max, double s)
1233 {
1234  int64 n = max - min + 1;
1235 
1236  /* abort if parameter is invalid */
1238 
1239  return min - 1 + computeIterativeZipfian(state, n, s);
1240 }
1241 
1242 /*
1243  * FNV-1a hash function
1244  */
1245 static int64
1246 getHashFnv1a(int64 val, uint64 seed)
1247 {
1248  int64 result;
1249  int i;
1250 
1251  result = FNV_OFFSET_BASIS ^ seed;
1252  for (i = 0; i < 8; ++i)
1253  {
1254  int32 octet = val & 0xff;
1255 
1256  val = val >> 8;
1257  result = result ^ octet;
1258  result = result * FNV_PRIME;
1259  }
1260 
1261  return result;
1262 }
1263 
1264 /*
1265  * Murmur2 hash function
1266  *
1267  * Based on original work of Austin Appleby
1268  * https://github.com/aappleby/smhasher/blob/master/src/MurmurHash2.cpp
1269  */
1270 static int64
1271 getHashMurmur2(int64 val, uint64 seed)
1272 {
1273  uint64 result = seed ^ MM2_MUL_TIMES_8; /* sizeof(int64) */
1274  uint64 k = (uint64) val;
1275 
1276  k *= MM2_MUL;
1277  k ^= k >> MM2_ROT;
1278  k *= MM2_MUL;
1279 
1280  result ^= k;
1281  result *= MM2_MUL;
1282 
1283  result ^= result >> MM2_ROT;
1284  result *= MM2_MUL;
1285  result ^= result >> MM2_ROT;
1286 
1287  return (int64) result;
1288 }
1289 
1290 /*
1291  * Pseudorandom permutation function
1292  *
1293  * For small sizes, this generates each of the (size!) possible permutations
1294  * of integers in the range [0, size) with roughly equal probability. Once
1295  * the size is larger than 20, the number of possible permutations exceeds the
1296  * number of distinct states of the internal pseudorandom number generator,
1297  * and so not all possible permutations can be generated, but the permutations
1298  * chosen should continue to give the appearance of being random.
1299  *
1300  * THIS FUNCTION IS NOT CRYPTOGRAPHICALLY SECURE.
1301  * DO NOT USE FOR SUCH PURPOSE.
1302  */
1303 static int64
1304 permute(const int64 val, const int64 isize, const int64 seed)
1305 {
1306  /* using a high-end PRNG is probably overkill */
1308  uint64 size;
1309  uint64 v;
1310  int masklen;
1311  uint64 mask;
1312  int i;
1313 
1314  if (isize < 2)
1315  return 0; /* nothing to permute */
1316 
1317  /* Initialize prng state using the seed */
1318  pg_prng_seed(&state, (uint64) seed);
1319 
1320  /* Computations are performed on unsigned values */
1321  size = (uint64) isize;
1322  v = (uint64) val % size;
1323 
1324  /* Mask to work modulo largest power of 2 less than or equal to size */
1325  masklen = pg_leftmost_one_pos64(size);
1326  mask = (((uint64) 1) << masklen) - 1;
1327 
1328  /*
1329  * Permute the input value by applying several rounds of pseudorandom
1330  * bijective transformations. The intention here is to distribute each
1331  * input uniformly randomly across the range, and separate adjacent inputs
1332  * approximately uniformly randomly from each other, leading to a fairly
1333  * random overall choice of permutation.
1334  *
1335  * To separate adjacent inputs, we multiply by a random number modulo
1336  * (mask + 1), which is a power of 2. For this to be a bijection, the
1337  * multiplier must be odd. Since this is known to lead to less randomness
1338  * in the lower bits, we also apply a rotation that shifts the topmost bit
1339  * into the least significant bit. In the special cases where size <= 3,
1340  * mask = 1 and each of these operations is actually a no-op, so we also
1341  * XOR the value with a different random number to inject additional
1342  * randomness. Since the size is generally not a power of 2, we apply
1343  * this bijection on overlapping upper and lower halves of the input.
1344  *
1345  * To distribute the inputs uniformly across the range, we then also apply
1346  * a random offset modulo the full range.
1347  *
1348  * Taken together, these operations resemble a modified linear
1349  * congruential generator, as is commonly used in pseudorandom number
1350  * generators. The number of rounds is fairly arbitrary, but six has been
1351  * found empirically to give a fairly good tradeoff between performance
1352  * and uniform randomness. For small sizes it selects each of the (size!)
1353  * possible permutations with roughly equal probability. For larger
1354  * sizes, not all permutations can be generated, but the intended random
1355  * spread is still produced.
1356  */
1357  for (i = 0; i < 6; i++)
1358  {
1359  uint64 m,
1360  r,
1361  t;
1362 
1363  /* Random multiply (by an odd number), XOR and rotate of lower half */
1364  m = (pg_prng_uint64(&state) & mask) | 1;
1365  r = pg_prng_uint64(&state) & mask;
1366  if (v <= mask)
1367  {
1368  v = ((v * m) ^ r) & mask;
1369  v = ((v << 1) & mask) | (v >> (masklen - 1));
1370  }
1371 
1372  /* Random multiply (by an odd number), XOR and rotate of upper half */
1373  m = (pg_prng_uint64(&state) & mask) | 1;
1374  r = pg_prng_uint64(&state) & mask;
1375  t = size - 1 - v;
1376  if (t <= mask)
1377  {
1378  t = ((t * m) ^ r) & mask;
1379  t = ((t << 1) & mask) | (t >> (masklen - 1));
1380  v = size - 1 - t;
1381  }
1382 
1383  /* Random offset */
1384  r = pg_prng_uint64_range(&state, 0, size - 1);
1385  v = (v + r) % size;
1386  }
1387 
1388  return (int64) v;
1389 }
1390 
1391 /*
1392  * Initialize the given SimpleStats struct to all zeroes
1393  */
1394 static void
1396 {
1397  memset(ss, 0, sizeof(SimpleStats));
1398 }
1399 
1400 /*
1401  * Accumulate one value into a SimpleStats struct.
1402  */
1403 static void
1404 addToSimpleStats(SimpleStats *ss, double val)
1405 {
1406  if (ss->count == 0 || val < ss->min)
1407  ss->min = val;
1408  if (ss->count == 0 || val > ss->max)
1409  ss->max = val;
1410  ss->count++;
1411  ss->sum += val;
1412  ss->sum2 += val * val;
1413 }
1414 
1415 /*
1416  * Merge two SimpleStats objects
1417  */
1418 static void
1420 {
1421  if (acc->count == 0 || ss->min < acc->min)
1422  acc->min = ss->min;
1423  if (acc->count == 0 || ss->max > acc->max)
1424  acc->max = ss->max;
1425  acc->count += ss->count;
1426  acc->sum += ss->sum;
1427  acc->sum2 += ss->sum2;
1428 }
1429 
1430 /*
1431  * Initialize a StatsData struct to mostly zeroes, with its start time set to
1432  * the given value.
1433  */
1434 static void
1436 {
1437  sd->start_time = start;
1438  sd->cnt = 0;
1439  sd->skipped = 0;
1440  sd->retries = 0;
1441  sd->retried = 0;
1442  sd->serialization_failures = 0;
1443  sd->deadlock_failures = 0;
1444  initSimpleStats(&sd->latency);
1445  initSimpleStats(&sd->lag);
1446 }
1447 
1448 /*
1449  * Accumulate one additional item into the given stats object.
1450  */
1451 static void
1452 accumStats(StatsData *stats, bool skipped, double lat, double lag,
1453  EStatus estatus, int64 tries)
1454 {
1455  /* Record the skipped transaction */
1456  if (skipped)
1457  {
1458  /* no latency to record on skipped transactions */
1459  stats->skipped++;
1460  return;
1461  }
1462 
1463  /*
1464  * Record the number of retries regardless of whether the transaction was
1465  * successful or failed.
1466  */
1467  if (tries > 1)
1468  {
1469  stats->retries += (tries - 1);
1470  stats->retried++;
1471  }
1472 
1473  switch (estatus)
1474  {
1475  /* Record the successful transaction */
1476  case ESTATUS_NO_ERROR:
1477  stats->cnt++;
1478 
1479  addToSimpleStats(&stats->latency, lat);
1480 
1481  /* and possibly the same for schedule lag */
1482  if (throttle_delay)
1483  addToSimpleStats(&stats->lag, lag);
1484  break;
1485 
1486  /* Record the failed transaction */
1488  stats->serialization_failures++;
1489  break;
1491  stats->deadlock_failures++;
1492  break;
1493  default:
1494  /* internal error which should never occur */
1495  pg_fatal("unexpected error status: %d", estatus);
1496  }
1497 }
1498 
1499 /* call PQexec() and exit() on failure */
1500 static void
1501 executeStatement(PGconn *con, const char *sql)
1502 {
1503  PGresult *res;
1504 
1505  res = PQexec(con, sql);
1507  {
1508  pg_log_error("query failed: %s", PQerrorMessage(con));
1509  pg_log_error_detail("Query was: %s", sql);
1510  exit(1);
1511  }
1512  PQclear(res);
1513 }
1514 
1515 /* call PQexec() and complain, but without exiting, on failure */
1516 static void
1517 tryExecuteStatement(PGconn *con, const char *sql)
1518 {
1519  PGresult *res;
1520 
1521  res = PQexec(con, sql);
1523  {
1524  pg_log_error("%s", PQerrorMessage(con));
1525  pg_log_error_detail("(ignoring this error and continuing anyway)");
1526  }
1527  PQclear(res);
1528 }
1529 
1530 /* set up a connection to the backend */
1531 static PGconn *
1532 doConnect(void)
1533 {
1534  PGconn *conn;
1535  bool new_pass;
1536  static char *password = NULL;
1537 
1538  /*
1539  * Start the connection. Loop until we have a password if requested by
1540  * backend.
1541  */
1542  do
1543  {
1544 #define PARAMS_ARRAY_SIZE 7
1545 
1546  const char *keywords[PARAMS_ARRAY_SIZE];
1547  const char *values[PARAMS_ARRAY_SIZE];
1548 
1549  keywords[0] = "host";
1550  values[0] = pghost;
1551  keywords[1] = "port";
1552  values[1] = pgport;
1553  keywords[2] = "user";
1554  values[2] = username;
1555  keywords[3] = "password";
1556  values[3] = password;
1557  keywords[4] = "dbname";
1558  values[4] = dbName;
1559  keywords[5] = "fallback_application_name";
1560  values[5] = progname;
1561  keywords[6] = NULL;
1562  values[6] = NULL;
1563 
1564  new_pass = false;
1565 
1566  conn = PQconnectdbParams(keywords, values, true);
1567 
1568  if (!conn)
1569  {
1570  pg_log_error("connection to database \"%s\" failed", dbName);
1571  return NULL;
1572  }
1573 
1574  if (PQstatus(conn) == CONNECTION_BAD &&
1576  !password)
1577  {
1578  PQfinish(conn);
1579  password = simple_prompt("Password: ", false);
1580  new_pass = true;
1581  }
1582  } while (new_pass);
1583 
1584  /* check to see that the backend connection was successfully made */
1585  if (PQstatus(conn) == CONNECTION_BAD)
1586  {
1588  PQfinish(conn);
1589  return NULL;
1590  }
1591 
1592  return conn;
1593 }
1594 
1595 /* qsort comparator for Variable array */
1596 static int
1597 compareVariableNames(const void *v1, const void *v2)
1598 {
1599  return strcmp(((const Variable *) v1)->name,
1600  ((const Variable *) v2)->name);
1601 }
1602 
1603 /* Locate a variable by name; returns NULL if unknown */
1604 static Variable *
1605 lookupVariable(Variables *variables, char *name)
1606 {
1607  Variable key;
1608 
1609  /* On some versions of Solaris, bsearch of zero items dumps core */
1610  if (variables->nvars <= 0)
1611  return NULL;
1612 
1613  /* Sort if we have to */
1614  if (!variables->vars_sorted)
1615  {
1616  qsort(variables->vars, variables->nvars, sizeof(Variable),
1618  variables->vars_sorted = true;
1619  }
1620 
1621  /* Now we can search */
1622  key.name = name;
1623  return (Variable *) bsearch(&key,
1624  variables->vars,
1625  variables->nvars,
1626  sizeof(Variable),
1628 }
1629 
1630 /* Get the value of a variable, in string form; returns NULL if unknown */
1631 static char *
1632 getVariable(Variables *variables, char *name)
1633 {
1634  Variable *var;
1635  char stringform[64];
1636 
1637  var = lookupVariable(variables, name);
1638  if (var == NULL)
1639  return NULL; /* not found */
1640 
1641  if (var->svalue)
1642  return var->svalue; /* we have it in string form */
1643 
1644  /* We need to produce a string equivalent of the value */
1645  Assert(var->value.type != PGBT_NO_VALUE);
1646  if (var->value.type == PGBT_NULL)
1647  snprintf(stringform, sizeof(stringform), "NULL");
1648  else if (var->value.type == PGBT_BOOLEAN)
1649  snprintf(stringform, sizeof(stringform),
1650  "%s", var->value.u.bval ? "true" : "false");
1651  else if (var->value.type == PGBT_INT)
1652  snprintf(stringform, sizeof(stringform),
1653  INT64_FORMAT, var->value.u.ival);
1654  else if (var->value.type == PGBT_DOUBLE)
1655  snprintf(stringform, sizeof(stringform),
1656  "%.*g", DBL_DIG, var->value.u.dval);
1657  else /* internal error, unexpected type */
1658  Assert(0);
1659  var->svalue = pg_strdup(stringform);
1660  return var->svalue;
1661 }
1662 
1663 /* Try to convert variable to a value; return false on failure */
1664 static bool
1666 {
1667  size_t slen;
1668 
1669  if (var->value.type != PGBT_NO_VALUE)
1670  return true; /* no work */
1671 
1672  slen = strlen(var->svalue);
1673 
1674  if (slen == 0)
1675  /* what should it do on ""? */
1676  return false;
1677 
1678  if (pg_strcasecmp(var->svalue, "null") == 0)
1679  {
1680  setNullValue(&var->value);
1681  }
1682 
1683  /*
1684  * accept prefixes such as y, ye, n, no... but not for "o". 0/1 are
1685  * recognized later as an int, which is converted to bool if needed.
1686  */
1687  else if (pg_strncasecmp(var->svalue, "true", slen) == 0 ||
1688  pg_strncasecmp(var->svalue, "yes", slen) == 0 ||
1689  pg_strcasecmp(var->svalue, "on") == 0)
1690  {
1691  setBoolValue(&var->value, true);
1692  }
1693  else if (pg_strncasecmp(var->svalue, "false", slen) == 0 ||
1694  pg_strncasecmp(var->svalue, "no", slen) == 0 ||
1695  pg_strcasecmp(var->svalue, "off") == 0 ||
1696  pg_strcasecmp(var->svalue, "of") == 0)
1697  {
1698  setBoolValue(&var->value, false);
1699  }
1700  else if (is_an_int(var->svalue))
1701  {
1702  /* if it looks like an int, it must be an int without overflow */
1703  int64 iv;
1704 
1705  if (!strtoint64(var->svalue, false, &iv))
1706  return false;
1707 
1708  setIntValue(&var->value, iv);
1709  }
1710  else /* type should be double */
1711  {
1712  double dv;
1713 
1714  if (!strtodouble(var->svalue, true, &dv))
1715  {
1716  pg_log_error("malformed variable \"%s\" value: \"%s\"",
1717  var->name, var->svalue);
1718  return false;
1719  }
1720  setDoubleValue(&var->value, dv);
1721  }
1722  return true;
1723 }
1724 
1725 /*
1726  * Check whether a variable's name is allowed.
1727  *
1728  * We allow any non-ASCII character, as well as ASCII letters, digits, and
1729  * underscore.
1730  *
1731  * Keep this in sync with the definitions of variable name characters in
1732  * "src/fe_utils/psqlscan.l", "src/bin/psql/psqlscanslash.l" and
1733  * "src/bin/pgbench/exprscan.l". Also see parseVariable(), below.
1734  *
1735  * Note: this static function is copied from "src/bin/psql/variables.c"
1736  * but changed to disallow variable names starting with a digit.
1737  */
1738 static bool
1739 valid_variable_name(const char *name)
1740 {
1741  const unsigned char *ptr = (const unsigned char *) name;
1742 
1743  /* Mustn't be zero-length */
1744  if (*ptr == '\0')
1745  return false;
1746 
1747  /* must not start with [0-9] */
1748  if (IS_HIGHBIT_SET(*ptr) ||
1749  strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
1750  "_", *ptr) != NULL)
1751  ptr++;
1752  else
1753  return false;
1754 
1755  /* remaining characters can include [0-9] */
1756  while (*ptr)
1757  {
1758  if (IS_HIGHBIT_SET(*ptr) ||
1759  strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
1760  "_0123456789", *ptr) != NULL)
1761  ptr++;
1762  else
1763  return false;
1764  }
1765 
1766  return true;
1767 }
1768 
1769 /*
1770  * Make sure there is enough space for 'needed' more variable in the variables
1771  * array.
1772  */
1773 static void
1774 enlargeVariables(Variables *variables, int needed)
1775 {
1776  /* total number of variables required now */
1777  needed += variables->nvars;
1778 
1779  if (variables->max_vars < needed)
1780  {
1781  variables->max_vars = needed + VARIABLES_ALLOC_MARGIN;
1782  variables->vars = (Variable *)
1783  pg_realloc(variables->vars, variables->max_vars * sizeof(Variable));
1784  }
1785 }
1786 
1787 /*
1788  * Lookup a variable by name, creating it if need be.
1789  * Caller is expected to assign a value to the variable.
1790  * Returns NULL on failure (bad name).
1791  */
1792 static Variable *
1793 lookupCreateVariable(Variables *variables, const char *context, char *name)
1794 {
1795  Variable *var;
1796 
1797  var = lookupVariable(variables, name);
1798  if (var == NULL)
1799  {
1800  /*
1801  * Check for the name only when declaring a new variable to avoid
1802  * overhead.
1803  */
1804  if (!valid_variable_name(name))
1805  {
1806  pg_log_error("%s: invalid variable name: \"%s\"", context, name);
1807  return NULL;
1808  }
1809 
1810  /* Create variable at the end of the array */
1811  enlargeVariables(variables, 1);
1812 
1813  var = &(variables->vars[variables->nvars]);
1814 
1815  var->name = pg_strdup(name);
1816  var->svalue = NULL;
1817  /* caller is expected to initialize remaining fields */
1818 
1819  variables->nvars++;
1820  /* we don't re-sort the array till we have to */
1821  variables->vars_sorted = false;
1822  }
1823 
1824  return var;
1825 }
1826 
1827 /* Assign a string value to a variable, creating it if need be */
1828 /* Returns false on failure (bad name) */
1829 static bool
1830 putVariable(Variables *variables, const char *context, char *name,
1831  const char *value)
1832 {
1833  Variable *var;
1834  char *val;
1835 
1836  var = lookupCreateVariable(variables, context, name);
1837  if (!var)
1838  return false;
1839 
1840  /* dup then free, in case value is pointing at this variable */
1841  val = pg_strdup(value);
1842 
1843  free(var->svalue);
1844  var->svalue = val;
1845  var->value.type = PGBT_NO_VALUE;
1846 
1847  return true;
1848 }
1849 
1850 /* Assign a value to a variable, creating it if need be */
1851 /* Returns false on failure (bad name) */
1852 static bool
1853 putVariableValue(Variables *variables, const char *context, char *name,
1854  const PgBenchValue *value)
1855 {
1856  Variable *var;
1857 
1858  var = lookupCreateVariable(variables, context, name);
1859  if (!var)
1860  return false;
1861 
1862  free(var->svalue);
1863  var->svalue = NULL;
1864  var->value = *value;
1865 
1866  return true;
1867 }
1868 
1869 /* Assign an integer value to a variable, creating it if need be */
1870 /* Returns false on failure (bad name) */
1871 static bool
1872 putVariableInt(Variables *variables, const char *context, char *name,
1873  int64 value)
1874 {
1875  PgBenchValue val;
1876 
1877  setIntValue(&val, value);
1878  return putVariableValue(variables, context, name, &val);
1879 }
1880 
1881 /*
1882  * Parse a possible variable reference (:varname).
1883  *
1884  * "sql" points at a colon. If what follows it looks like a valid
1885  * variable name, return a malloc'd string containing the variable name,
1886  * and set *eaten to the number of characters consumed (including the colon).
1887  * Otherwise, return NULL.
1888  */
1889 static char *
1890 parseVariable(const char *sql, int *eaten)
1891 {
1892  int i = 1; /* starting at 1 skips the colon */
1893  char *name;
1894 
1895  /* keep this logic in sync with valid_variable_name() */
1896  if (IS_HIGHBIT_SET(sql[i]) ||
1897  strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
1898  "_", sql[i]) != NULL)
1899  i++;
1900  else
1901  return NULL;
1902 
1903  while (IS_HIGHBIT_SET(sql[i]) ||
1904  strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
1905  "_0123456789", sql[i]) != NULL)
1906  i++;
1907 
1908  name = pg_malloc(i);
1909  memcpy(name, &sql[1], i - 1);
1910  name[i - 1] = '\0';
1911 
1912  *eaten = i;
1913  return name;
1914 }
1915 
1916 static char *
1917 replaceVariable(char **sql, char *param, int len, char *value)
1918 {
1919  int valueln = strlen(value);
1920 
1921  if (valueln > len)
1922  {
1923  size_t offset = param - *sql;
1924 
1925  *sql = pg_realloc(*sql, strlen(*sql) - len + valueln + 1);
1926  param = *sql + offset;
1927  }
1928 
1929  if (valueln != len)
1930  memmove(param + valueln, param + len, strlen(param + len) + 1);
1931  memcpy(param, value, valueln);
1932 
1933  return param + valueln;
1934 }
1935 
1936 static char *
1937 assignVariables(Variables *variables, char *sql)
1938 {
1939  char *p,
1940  *name,
1941  *val;
1942 
1943  p = sql;
1944  while ((p = strchr(p, ':')) != NULL)
1945  {
1946  int eaten;
1947 
1948  name = parseVariable(p, &eaten);
1949  if (name == NULL)
1950  {
1951  while (*p == ':')
1952  {
1953  p++;
1954  }
1955  continue;
1956  }
1957 
1958  val = getVariable(variables, name);
1959  free(name);
1960  if (val == NULL)
1961  {
1962  p++;
1963  continue;
1964  }
1965 
1966  p = replaceVariable(&sql, p, eaten, val);
1967  }
1968 
1969  return sql;
1970 }
1971 
1972 static void
1973 getQueryParams(Variables *variables, const Command *command,
1974  const char **params)
1975 {
1976  int i;
1977 
1978  for (i = 0; i < command->argc - 1; i++)
1979  params[i] = getVariable(variables, command->argv[i + 1]);
1980 }
1981 
1982 static char *
1984 {
1985  if (pval->type == PGBT_NO_VALUE)
1986  return "none";
1987  else if (pval->type == PGBT_NULL)
1988  return "null";
1989  else if (pval->type == PGBT_INT)
1990  return "int";
1991  else if (pval->type == PGBT_DOUBLE)
1992  return "double";
1993  else if (pval->type == PGBT_BOOLEAN)
1994  return "boolean";
1995  else
1996  {
1997  /* internal error, should never get there */
1998  Assert(false);
1999  return NULL;
2000  }
2001 }
2002 
2003 /* get a value as a boolean, or tell if there is a problem */
2004 static bool
2005 coerceToBool(PgBenchValue *pval, bool *bval)
2006 {
2007  if (pval->type == PGBT_BOOLEAN)
2008  {
2009  *bval = pval->u.bval;
2010  return true;
2011  }
2012  else /* NULL, INT or DOUBLE */
2013  {
2014  pg_log_error("cannot coerce %s to boolean", valueTypeName(pval));
2015  *bval = false; /* suppress uninitialized-variable warnings */
2016  return false;
2017  }
2018 }
2019 
2020 /*
2021  * Return true or false from an expression for conditional purposes.
2022  * Non zero numerical values are true, zero and NULL are false.
2023  */
2024 static bool
2025 valueTruth(PgBenchValue *pval)
2026 {
2027  switch (pval->type)
2028  {
2029  case PGBT_NULL:
2030  return false;
2031  case PGBT_BOOLEAN:
2032  return pval->u.bval;
2033  case PGBT_INT:
2034  return pval->u.ival != 0;
2035  case PGBT_DOUBLE:
2036  return pval->u.dval != 0.0;
2037  default:
2038  /* internal error, unexpected type */
2039  Assert(0);
2040  return false;
2041  }
2042 }
2043 
2044 /* get a value as an int, tell if there is a problem */
2045 static bool
2046 coerceToInt(PgBenchValue *pval, int64 *ival)
2047 {
2048  if (pval->type == PGBT_INT)
2049  {
2050  *ival = pval->u.ival;
2051  return true;
2052  }
2053  else if (pval->type == PGBT_DOUBLE)
2054  {
2055  double dval = rint(pval->u.dval);
2056 
2057  if (isnan(dval) || !FLOAT8_FITS_IN_INT64(dval))
2058  {
2059  pg_log_error("double to int overflow for %f", dval);
2060  return false;
2061  }
2062  *ival = (int64) dval;
2063  return true;
2064  }
2065  else /* BOOLEAN or NULL */
2066  {
2067  pg_log_error("cannot coerce %s to int", valueTypeName(pval));
2068  return false;
2069  }
2070 }
2071 
2072 /* get a value as a double, or tell if there is a problem */
2073 static bool
2074 coerceToDouble(PgBenchValue *pval, double *dval)
2075 {
2076  if (pval->type == PGBT_DOUBLE)
2077  {
2078  *dval = pval->u.dval;
2079  return true;
2080  }
2081  else if (pval->type == PGBT_INT)
2082  {
2083  *dval = (double) pval->u.ival;
2084  return true;
2085  }
2086  else /* BOOLEAN or NULL */
2087  {
2088  pg_log_error("cannot coerce %s to double", valueTypeName(pval));
2089  return false;
2090  }
2091 }
2092 
2093 /* assign a null value */
2094 static void
2096 {
2097  pv->type = PGBT_NULL;
2098  pv->u.ival = 0;
2099 }
2100 
2101 /* assign a boolean value */
2102 static void
2103 setBoolValue(PgBenchValue *pv, bool bval)
2104 {
2105  pv->type = PGBT_BOOLEAN;
2106  pv->u.bval = bval;
2107 }
2108 
2109 /* assign an integer value */
2110 static void
2111 setIntValue(PgBenchValue *pv, int64 ival)
2112 {
2113  pv->type = PGBT_INT;
2114  pv->u.ival = ival;
2115 }
2116 
2117 /* assign a double value */
2118 static void
2119 setDoubleValue(PgBenchValue *pv, double dval)
2120 {
2121  pv->type = PGBT_DOUBLE;
2122  pv->u.dval = dval;
2123 }
2124 
2125 static bool
2127 {
2128  return func == PGBENCH_AND || func == PGBENCH_OR || func == PGBENCH_CASE;
2129 }
2130 
2131 /* lazy evaluation of some functions */
2132 static bool
2133 evalLazyFunc(CState *st,
2135 {
2136  PgBenchValue a1,
2137  a2;
2138  bool ba1,
2139  ba2;
2140 
2141  Assert(isLazyFunc(func) && args != NULL && args->next != NULL);
2142 
2143  /* args points to first condition */
2144  if (!evaluateExpr(st, args->expr, &a1))
2145  return false;
2146 
2147  /* second condition for AND/OR and corresponding branch for CASE */
2148  args = args->next;
2149 
2150  switch (func)
2151  {
2152  case PGBENCH_AND:
2153  if (a1.type == PGBT_NULL)
2154  {
2155  setNullValue(retval);
2156  return true;
2157  }
2158 
2159  if (!coerceToBool(&a1, &ba1))
2160  return false;
2161 
2162  if (!ba1)
2163  {
2164  setBoolValue(retval, false);
2165  return true;
2166  }
2167 
2168  if (!evaluateExpr(st, args->expr, &a2))
2169  return false;
2170 
2171  if (a2.type == PGBT_NULL)
2172  {
2173  setNullValue(retval);
2174  return true;
2175  }
2176  else if (!coerceToBool(&a2, &ba2))
2177  return false;
2178  else
2179  {
2180  setBoolValue(retval, ba2);
2181  return true;
2182  }
2183 
2184  return true;
2185 
2186  case PGBENCH_OR:
2187 
2188  if (a1.type == PGBT_NULL)
2189  {
2190  setNullValue(retval);
2191  return true;
2192  }
2193 
2194  if (!coerceToBool(&a1, &ba1))
2195  return false;
2196 
2197  if (ba1)
2198  {
2199  setBoolValue(retval, true);
2200  return true;
2201  }
2202 
2203  if (!evaluateExpr(st, args->expr, &a2))
2204  return false;
2205 
2206  if (a2.type == PGBT_NULL)
2207  {
2208  setNullValue(retval);
2209  return true;
2210  }
2211  else if (!coerceToBool(&a2, &ba2))
2212  return false;
2213  else
2214  {
2215  setBoolValue(retval, ba2);
2216  return true;
2217  }
2218 
2219  case PGBENCH_CASE:
2220  /* when true, execute branch */
2221  if (valueTruth(&a1))
2222  return evaluateExpr(st, args->expr, retval);
2223 
2224  /* now args contains next condition or final else expression */
2225  args = args->next;
2226 
2227  /* final else case? */
2228  if (args->next == NULL)
2229  return evaluateExpr(st, args->expr, retval);
2230 
2231  /* no, another when, proceed */
2232  return evalLazyFunc(st, PGBENCH_CASE, args, retval);
2233 
2234  default:
2235  /* internal error, cannot get here */
2236  Assert(0);
2237  break;
2238  }
2239  return false;
2240 }
2241 
2242 /* maximum number of function arguments */
2243 #define MAX_FARGS 16
2244 
2245 /*
2246  * Recursive evaluation of standard functions,
2247  * which do not require lazy evaluation.
2248  */
2249 static bool
2252  PgBenchValue *retval)
2253 {
2254  /* evaluate all function arguments */
2255  int nargs = 0;
2256  PgBenchExprLink *l = args;
2257  bool has_null = false;
2258 
2259  /*
2260  * This value is double braced to workaround GCC bug 53119, which seems to
2261  * exist at least on gcc (Debian 4.7.2-5) 4.7.2, 32-bit.
2262  */
2263  PgBenchValue vargs[MAX_FARGS] = {{0}};
2264 
2265  for (nargs = 0; nargs < MAX_FARGS && l != NULL; nargs++, l = l->next)
2266  {
2267  if (!evaluateExpr(st, l->expr, &vargs[nargs]))
2268  return false;
2269  has_null |= vargs[nargs].type == PGBT_NULL;
2270  }
2271 
2272  if (l != NULL)
2273  {
2274  pg_log_error("too many function arguments, maximum is %d", MAX_FARGS);
2275  return false;
2276  }
2277 
2278  /* NULL arguments */
2279  if (has_null && func != PGBENCH_IS && func != PGBENCH_DEBUG)
2280  {
2281  setNullValue(retval);
2282  return true;
2283  }
2284 
2285  /* then evaluate function */
2286  switch (func)
2287  {
2288  /* overloaded operators */
2289  case PGBENCH_ADD:
2290  case PGBENCH_SUB:
2291  case PGBENCH_MUL:
2292  case PGBENCH_DIV:
2293  case PGBENCH_MOD:
2294  case PGBENCH_EQ:
2295  case PGBENCH_NE:
2296  case PGBENCH_LE:
2297  case PGBENCH_LT:
2298  {
2299  PgBenchValue *lval = &vargs[0],
2300  *rval = &vargs[1];
2301 
2302  Assert(nargs == 2);
2303 
2304  /* overloaded type management, double if some double */
2305  if ((lval->type == PGBT_DOUBLE ||
2306  rval->type == PGBT_DOUBLE) && func != PGBENCH_MOD)
2307  {
2308  double ld,
2309  rd;
2310 
2311  if (!coerceToDouble(lval, &ld) ||
2312  !coerceToDouble(rval, &rd))
2313  return false;
2314 
2315  switch (func)
2316  {
2317  case PGBENCH_ADD:
2318  setDoubleValue(retval, ld + rd);
2319  return true;
2320 
2321  case PGBENCH_SUB:
2322  setDoubleValue(retval, ld - rd);
2323  return true;
2324 
2325  case PGBENCH_MUL:
2326  setDoubleValue(retval, ld * rd);
2327  return true;
2328 
2329  case PGBENCH_DIV:
2330  setDoubleValue(retval, ld / rd);
2331  return true;
2332 
2333  case PGBENCH_EQ:
2334  setBoolValue(retval, ld == rd);
2335  return true;
2336 
2337  case PGBENCH_NE:
2338  setBoolValue(retval, ld != rd);
2339  return true;
2340 
2341  case PGBENCH_LE:
2342  setBoolValue(retval, ld <= rd);
2343  return true;
2344 
2345  case PGBENCH_LT:
2346  setBoolValue(retval, ld < rd);
2347  return true;
2348 
2349  default:
2350  /* cannot get here */
2351  Assert(0);
2352  }
2353  }
2354  else /* we have integer operands, or % */
2355  {
2356  int64 li,
2357  ri,
2358  res;
2359 
2360  if (!coerceToInt(lval, &li) ||
2361  !coerceToInt(rval, &ri))
2362  return false;
2363 
2364  switch (func)
2365  {
2366  case PGBENCH_ADD:
2367  if (pg_add_s64_overflow(li, ri, &res))
2368  {
2369  pg_log_error("bigint add out of range");
2370  return false;
2371  }
2372  setIntValue(retval, res);
2373  return true;
2374 
2375  case PGBENCH_SUB:
2376  if (pg_sub_s64_overflow(li, ri, &res))
2377  {
2378  pg_log_error("bigint sub out of range");
2379  return false;
2380  }
2381  setIntValue(retval, res);
2382  return true;
2383 
2384  case PGBENCH_MUL:
2385  if (pg_mul_s64_overflow(li, ri, &res))
2386  {
2387  pg_log_error("bigint mul out of range");
2388  return false;
2389  }
2390  setIntValue(retval, res);
2391  return true;
2392 
2393  case PGBENCH_EQ:
2394  setBoolValue(retval, li == ri);
2395  return true;
2396 
2397  case PGBENCH_NE:
2398  setBoolValue(retval, li != ri);
2399  return true;
2400 
2401  case PGBENCH_LE:
2402  setBoolValue(retval, li <= ri);
2403  return true;
2404 
2405  case PGBENCH_LT:
2406  setBoolValue(retval, li < ri);
2407  return true;
2408 
2409  case PGBENCH_DIV:
2410  case PGBENCH_MOD:
2411  if (ri == 0)
2412  {
2413  pg_log_error("division by zero");
2414  return false;
2415  }
2416  /* special handling of -1 divisor */
2417  if (ri == -1)
2418  {
2419  if (func == PGBENCH_DIV)
2420  {
2421  /* overflow check (needed for INT64_MIN) */
2422  if (li == PG_INT64_MIN)
2423  {
2424  pg_log_error("bigint div out of range");
2425  return false;
2426  }
2427  else
2428  setIntValue(retval, -li);
2429  }
2430  else
2431  setIntValue(retval, 0);
2432  return true;
2433  }
2434  /* else divisor is not -1 */
2435  if (func == PGBENCH_DIV)
2436  setIntValue(retval, li / ri);
2437  else /* func == PGBENCH_MOD */
2438  setIntValue(retval, li % ri);
2439 
2440  return true;
2441 
2442  default:
2443  /* cannot get here */
2444  Assert(0);
2445  }
2446  }
2447 
2448  Assert(0);
2449  return false; /* NOTREACHED */
2450  }
2451 
2452  /* integer bitwise operators */
2453  case PGBENCH_BITAND:
2454  case PGBENCH_BITOR:
2455  case PGBENCH_BITXOR:
2456  case PGBENCH_LSHIFT:
2457  case PGBENCH_RSHIFT:
2458  {
2459  int64 li,
2460  ri;
2461 
2462  if (!coerceToInt(&vargs[0], &li) || !coerceToInt(&vargs[1], &ri))
2463  return false;
2464 
2465  if (func == PGBENCH_BITAND)
2466  setIntValue(retval, li & ri);
2467  else if (func == PGBENCH_BITOR)
2468  setIntValue(retval, li | ri);
2469  else if (func == PGBENCH_BITXOR)
2470  setIntValue(retval, li ^ ri);
2471  else if (func == PGBENCH_LSHIFT)
2472  setIntValue(retval, li << ri);
2473  else if (func == PGBENCH_RSHIFT)
2474  setIntValue(retval, li >> ri);
2475  else /* cannot get here */
2476  Assert(0);
2477 
2478  return true;
2479  }
2480 
2481  /* logical operators */
2482  case PGBENCH_NOT:
2483  {
2484  bool b;
2485 
2486  if (!coerceToBool(&vargs[0], &b))
2487  return false;
2488 
2489  setBoolValue(retval, !b);
2490  return true;
2491  }
2492 
2493  /* no arguments */
2494  case PGBENCH_PI:
2495  setDoubleValue(retval, M_PI);
2496  return true;
2497 
2498  /* 1 overloaded argument */
2499  case PGBENCH_ABS:
2500  {
2501  PgBenchValue *varg = &vargs[0];
2502 
2503  Assert(nargs == 1);
2504 
2505  if (varg->type == PGBT_INT)
2506  {
2507  int64 i = varg->u.ival;
2508 
2509  setIntValue(retval, i < 0 ? -i : i);
2510  }
2511  else
2512  {
2513  double d = varg->u.dval;
2514 
2515  Assert(varg->type == PGBT_DOUBLE);
2516  setDoubleValue(retval, d < 0.0 ? -d : d);
2517  }
2518 
2519  return true;
2520  }
2521 
2522  case PGBENCH_DEBUG:
2523  {
2524  PgBenchValue *varg = &vargs[0];
2525 
2526  Assert(nargs == 1);
2527 
2528  fprintf(stderr, "debug(script=%d,command=%d): ",
2529  st->use_file, st->command + 1);
2530 
2531  if (varg->type == PGBT_NULL)
2532  fprintf(stderr, "null\n");
2533  else if (varg->type == PGBT_BOOLEAN)
2534  fprintf(stderr, "boolean %s\n", varg->u.bval ? "true" : "false");
2535  else if (varg->type == PGBT_INT)
2536  fprintf(stderr, "int " INT64_FORMAT "\n", varg->u.ival);
2537  else if (varg->type == PGBT_DOUBLE)
2538  fprintf(stderr, "double %.*g\n", DBL_DIG, varg->u.dval);
2539  else /* internal error, unexpected type */
2540  Assert(0);
2541 
2542  *retval = *varg;
2543 
2544  return true;
2545  }
2546 
2547  /* 1 double argument */
2548  case PGBENCH_DOUBLE:
2549  case PGBENCH_SQRT:
2550  case PGBENCH_LN:
2551  case PGBENCH_EXP:
2552  {
2553  double dval;
2554 
2555  Assert(nargs == 1);
2556 
2557  if (!coerceToDouble(&vargs[0], &dval))
2558  return false;
2559 
2560  if (func == PGBENCH_SQRT)
2561  dval = sqrt(dval);
2562  else if (func == PGBENCH_LN)
2563  dval = log(dval);
2564  else if (func == PGBENCH_EXP)
2565  dval = exp(dval);
2566  /* else is cast: do nothing */
2567 
2568  setDoubleValue(retval, dval);
2569  return true;
2570  }
2571 
2572  /* 1 int argument */
2573  case PGBENCH_INT:
2574  {
2575  int64 ival;
2576 
2577  Assert(nargs == 1);
2578 
2579  if (!coerceToInt(&vargs[0], &ival))
2580  return false;
2581 
2582  setIntValue(retval, ival);
2583  return true;
2584  }
2585 
2586  /* variable number of arguments */
2587  case PGBENCH_LEAST:
2588  case PGBENCH_GREATEST:
2589  {
2590  bool havedouble;
2591  int i;
2592 
2593  Assert(nargs >= 1);
2594 
2595  /* need double result if any input is double */
2596  havedouble = false;
2597  for (i = 0; i < nargs; i++)
2598  {
2599  if (vargs[i].type == PGBT_DOUBLE)
2600  {
2601  havedouble = true;
2602  break;
2603  }
2604  }
2605  if (havedouble)
2606  {
2607  double extremum;
2608 
2609  if (!coerceToDouble(&vargs[0], &extremum))
2610  return false;
2611  for (i = 1; i < nargs; i++)
2612  {
2613  double dval;
2614 
2615  if (!coerceToDouble(&vargs[i], &dval))
2616  return false;
2617  if (func == PGBENCH_LEAST)
2618  extremum = Min(extremum, dval);
2619  else
2620  extremum = Max(extremum, dval);
2621  }
2622  setDoubleValue(retval, extremum);
2623  }
2624  else
2625  {
2626  int64 extremum;
2627 
2628  if (!coerceToInt(&vargs[0], &extremum))
2629  return false;
2630  for (i = 1; i < nargs; i++)
2631  {
2632  int64 ival;
2633 
2634  if (!coerceToInt(&vargs[i], &ival))
2635  return false;
2636  if (func == PGBENCH_LEAST)
2637  extremum = Min(extremum, ival);
2638  else
2639  extremum = Max(extremum, ival);
2640  }
2641  setIntValue(retval, extremum);
2642  }
2643  return true;
2644  }
2645 
2646  /* random functions */
2647  case PGBENCH_RANDOM:
2651  {
2652  int64 imin,
2653  imax,
2654  delta;
2655 
2656  Assert(nargs >= 2);
2657 
2658  if (!coerceToInt(&vargs[0], &imin) ||
2659  !coerceToInt(&vargs[1], &imax))
2660  return false;
2661 
2662  /* check random range */
2663  if (unlikely(imin > imax))
2664  {
2665  pg_log_error("empty range given to random");
2666  return false;
2667  }
2668  else if (unlikely(pg_sub_s64_overflow(imax, imin, &delta) ||
2669  pg_add_s64_overflow(delta, 1, &delta)))
2670  {
2671  /* prevent int overflows in random functions */
2672  pg_log_error("random range is too large");
2673  return false;
2674  }
2675 
2676  if (func == PGBENCH_RANDOM)
2677  {
2678  Assert(nargs == 2);
2679  setIntValue(retval, getrand(&st->cs_func_rs, imin, imax));
2680  }
2681  else /* gaussian & exponential */
2682  {
2683  double param;
2684 
2685  Assert(nargs == 3);
2686 
2687  if (!coerceToDouble(&vargs[2], &param))
2688  return false;
2689 
2690  if (func == PGBENCH_RANDOM_GAUSSIAN)
2691  {
2692  if (param < MIN_GAUSSIAN_PARAM)
2693  {
2694  pg_log_error("gaussian parameter must be at least %f (not %f)",
2695  MIN_GAUSSIAN_PARAM, param);
2696  return false;
2697  }
2698 
2699  setIntValue(retval,
2701  imin, imax, param));
2702  }
2703  else if (func == PGBENCH_RANDOM_ZIPFIAN)
2704  {
2705  if (param < MIN_ZIPFIAN_PARAM || param > MAX_ZIPFIAN_PARAM)
2706  {
2707  pg_log_error("zipfian parameter must be in range [%.3f, %.0f] (not %f)",
2709  return false;
2710  }
2711 
2712  setIntValue(retval,
2713  getZipfianRand(&st->cs_func_rs, imin, imax, param));
2714  }
2715  else /* exponential */
2716  {
2717  if (param <= 0.0)
2718  {
2719  pg_log_error("exponential parameter must be greater than zero (not %f)",
2720  param);
2721  return false;
2722  }
2723 
2724  setIntValue(retval,
2726  imin, imax, param));
2727  }
2728  }
2729 
2730  return true;
2731  }
2732 
2733  case PGBENCH_POW:
2734  {
2735  PgBenchValue *lval = &vargs[0];
2736  PgBenchValue *rval = &vargs[1];
2737  double ld,
2738  rd;
2739 
2740  Assert(nargs == 2);
2741 
2742  if (!coerceToDouble(lval, &ld) ||
2743  !coerceToDouble(rval, &rd))
2744  return false;
2745 
2746  setDoubleValue(retval, pow(ld, rd));
2747 
2748  return true;
2749  }
2750 
2751  case PGBENCH_IS:
2752  {
2753  Assert(nargs == 2);
2754 
2755  /*
2756  * note: this simple implementation is more permissive than
2757  * SQL
2758  */
2759  setBoolValue(retval,
2760  vargs[0].type == vargs[1].type &&
2761  vargs[0].u.bval == vargs[1].u.bval);
2762  return true;
2763  }
2764 
2765  /* hashing */
2766  case PGBENCH_HASH_FNV1A:
2767  case PGBENCH_HASH_MURMUR2:
2768  {
2769  int64 val,
2770  seed;
2771 
2772  Assert(nargs == 2);
2773 
2774  if (!coerceToInt(&vargs[0], &val) ||
2775  !coerceToInt(&vargs[1], &seed))
2776  return false;
2777 
2778  if (func == PGBENCH_HASH_MURMUR2)
2779  setIntValue(retval, getHashMurmur2(val, seed));
2780  else if (func == PGBENCH_HASH_FNV1A)
2781  setIntValue(retval, getHashFnv1a(val, seed));
2782  else
2783  /* cannot get here */
2784  Assert(0);
2785 
2786  return true;
2787  }
2788 
2789  case PGBENCH_PERMUTE:
2790  {
2791  int64 val,
2792  size,
2793  seed;
2794 
2795  Assert(nargs == 3);
2796 
2797  if (!coerceToInt(&vargs[0], &val) ||
2798  !coerceToInt(&vargs[1], &size) ||
2799  !coerceToInt(&vargs[2], &seed))
2800  return false;
2801 
2802  if (size <= 0)
2803  {
2804  pg_log_error("permute size parameter must be greater than zero");
2805  return false;
2806  }
2807 
2808  setIntValue(retval, permute(val, size, seed));
2809  return true;
2810  }
2811 
2812  default:
2813  /* cannot get here */
2814  Assert(0);
2815  /* dead code to avoid a compiler warning */
2816  return false;
2817  }
2818 }
2819 
2820 /* evaluate some function */
2821 static bool
2822 evalFunc(CState *st,
2824 {
2825  if (isLazyFunc(func))
2826  return evalLazyFunc(st, func, args, retval);
2827  else
2828  return evalStandardFunc(st, func, args, retval);
2829 }
2830 
2831 /*
2832  * Recursive evaluation of an expression in a pgbench script
2833  * using the current state of variables.
2834  * Returns whether the evaluation was ok,
2835  * the value itself is returned through the retval pointer.
2836  */
2837 static bool
2838 evaluateExpr(CState *st, PgBenchExpr *expr, PgBenchValue *retval)
2839 {
2840  switch (expr->etype)
2841  {
2842  case ENODE_CONSTANT:
2843  {
2844  *retval = expr->u.constant;
2845  return true;
2846  }
2847 
2848  case ENODE_VARIABLE:
2849  {
2850  Variable *var;
2851 
2852  if ((var = lookupVariable(&st->variables, expr->u.variable.varname)) == NULL)
2853  {
2854  pg_log_error("undefined variable \"%s\"", expr->u.variable.varname);
2855  return false;
2856  }
2857 
2858  if (!makeVariableValue(var))
2859  return false;
2860 
2861  *retval = var->value;
2862  return true;
2863  }
2864 
2865  case ENODE_FUNCTION:
2866  return evalFunc(st,
2867  expr->u.function.function,
2868  expr->u.function.args,
2869  retval);
2870 
2871  default:
2872  /* internal error which should never occur */
2873  pg_fatal("unexpected enode type in evaluation: %d", expr->etype);
2874  }
2875 }
2876 
2877 /*
2878  * Convert command name to meta-command enum identifier
2879  */
2881 getMetaCommand(const char *cmd)
2882 {
2883  MetaCommand mc;
2884 
2885  if (cmd == NULL)
2886  mc = META_NONE;
2887  else if (pg_strcasecmp(cmd, "set") == 0)
2888  mc = META_SET;
2889  else if (pg_strcasecmp(cmd, "setshell") == 0)
2890  mc = META_SETSHELL;
2891  else if (pg_strcasecmp(cmd, "shell") == 0)
2892  mc = META_SHELL;
2893  else if (pg_strcasecmp(cmd, "sleep") == 0)
2894  mc = META_SLEEP;
2895  else if (pg_strcasecmp(cmd, "if") == 0)
2896  mc = META_IF;
2897  else if (pg_strcasecmp(cmd, "elif") == 0)
2898  mc = META_ELIF;
2899  else if (pg_strcasecmp(cmd, "else") == 0)
2900  mc = META_ELSE;
2901  else if (pg_strcasecmp(cmd, "endif") == 0)
2902  mc = META_ENDIF;
2903  else if (pg_strcasecmp(cmd, "gset") == 0)
2904  mc = META_GSET;
2905  else if (pg_strcasecmp(cmd, "aset") == 0)
2906  mc = META_ASET;
2907  else if (pg_strcasecmp(cmd, "startpipeline") == 0)
2908  mc = META_STARTPIPELINE;
2909  else if (pg_strcasecmp(cmd, "syncpipeline") == 0)
2910  mc = META_SYNCPIPELINE;
2911  else if (pg_strcasecmp(cmd, "endpipeline") == 0)
2912  mc = META_ENDPIPELINE;
2913  else
2914  mc = META_NONE;
2915  return mc;
2916 }
2917 
2918 /*
2919  * Run a shell command. The result is assigned to the variable if not NULL.
2920  * Return true if succeeded, or false on error.
2921  */
2922 static bool
2923 runShellCommand(Variables *variables, char *variable, char **argv, int argc)
2924 {
2925  char command[SHELL_COMMAND_SIZE];
2926  int i,
2927  len = 0;
2928  FILE *fp;
2929  char res[64];
2930  char *endptr;
2931  int retval;
2932 
2933  /*----------
2934  * Join arguments with whitespace separators. Arguments starting with
2935  * exactly one colon are treated as variables:
2936  * name - append a string "name"
2937  * :var - append a variable named 'var'
2938  * ::name - append a string ":name"
2939  *----------
2940  */
2941  for (i = 0; i < argc; i++)
2942  {
2943  char *arg;
2944  int arglen;
2945 
2946  if (argv[i][0] != ':')
2947  {
2948  arg = argv[i]; /* a string literal */
2949  }
2950  else if (argv[i][1] == ':')
2951  {
2952  arg = argv[i] + 1; /* a string literal starting with colons */
2953  }
2954  else if ((arg = getVariable(variables, argv[i] + 1)) == NULL)
2955  {
2956  pg_log_error("%s: undefined variable \"%s\"", argv[0], argv[i]);
2957  return false;
2958  }
2959 
2960  arglen = strlen(arg);
2961  if (len + arglen + (i > 0 ? 1 : 0) >= SHELL_COMMAND_SIZE - 1)
2962  {
2963  pg_log_error("%s: shell command is too long", argv[0]);
2964  return false;
2965  }
2966 
2967  if (i > 0)
2968  command[len++] = ' ';
2969  memcpy(command + len, arg, arglen);
2970  len += arglen;
2971  }
2972 
2973  command[len] = '\0';
2974 
2975  fflush(NULL); /* needed before either system() or popen() */
2976 
2977  /* Fast path for non-assignment case */
2978  if (variable == NULL)
2979  {
2980  if (system(command))
2981  {
2982  if (!timer_exceeded)
2983  pg_log_error("%s: could not launch shell command", argv[0]);
2984  return false;
2985  }
2986  return true;
2987  }
2988 
2989  /* Execute the command with pipe and read the standard output. */
2990  if ((fp = popen(command, "r")) == NULL)
2991  {
2992  pg_log_error("%s: could not launch shell command", argv[0]);
2993  return false;
2994  }
2995  if (fgets(res, sizeof(res), fp) == NULL)
2996  {
2997  if (!timer_exceeded)
2998  pg_log_error("%s: could not read result of shell command", argv[0]);
2999  (void) pclose(fp);
3000  return false;
3001  }
3002  if (pclose(fp) < 0)
3003  {
3004  pg_log_error("%s: could not run shell command: %m", argv[0]);
3005  return false;
3006  }
3007 
3008  /* Check whether the result is an integer and assign it to the variable */
3009  retval = (int) strtol(res, &endptr, 10);
3010  while (*endptr != '\0' && isspace((unsigned char) *endptr))
3011  endptr++;
3012  if (*res == '\0' || *endptr != '\0')
3013  {
3014  pg_log_error("%s: shell command must return an integer (not \"%s\")", argv[0], res);
3015  return false;
3016  }
3017  if (!putVariableInt(variables, "setshell", variable, retval))
3018  return false;
3019 
3020  pg_log_debug("%s: shell parameter name: \"%s\", value: \"%s\"", argv[0], argv[1], res);
3021 
3022  return true;
3023 }
3024 
3025 /*
3026  * Report the abortion of the client when processing SQL commands.
3027  */
3028 static void
3029 commandFailed(CState *st, const char *cmd, const char *message)
3030 {
3031  pg_log_error("client %d aborted in command %d (%s) of script %d; %s",
3032  st->id, st->command, cmd, st->use_file, message);
3033 }
3034 
3035 /*
3036  * Report the error in the command while the script is executing.
3037  */
3038 static void
3039 commandError(CState *st, const char *message)
3040 {
3042  pg_log_info("client %d got an error in command %d (SQL) of script %d; %s",
3043  st->id, st->command, st->use_file, message);
3044 }
3045 
3046 /* return a script number with a weighted choice. */
3047 static int
3048 chooseScript(TState *thread)
3049 {
3050  int i = 0;
3051  int64 w;
3052 
3053  if (num_scripts == 1)
3054  return 0;
3055 
3056  w = getrand(&thread->ts_choose_rs, 0, total_weight - 1);
3057  do
3058  {
3059  w -= sql_script[i++].weight;
3060  } while (w >= 0);
3061 
3062  return i - 1;
3063 }
3064 
3065 /*
3066  * Allocate space for CState->prepared: we need one boolean for each command
3067  * of each script.
3068  */
3069 static void
3071 {
3072  Assert(st->prepared == NULL);
3073 
3074  st->prepared = pg_malloc(sizeof(bool *) * num_scripts);
3075  for (int i = 0; i < num_scripts; i++)
3076  {
3077  ParsedScript *script = &sql_script[i];
3078  int numcmds;
3079 
3080  for (numcmds = 0; script->commands[numcmds] != NULL; numcmds++)
3081  ;
3082  st->prepared[i] = pg_malloc0(sizeof(bool) * numcmds);
3083  }
3084 }
3085 
3086 /*
3087  * Prepare the SQL command from st->use_file at command_num.
3088  */
3089 static void
3090 prepareCommand(CState *st, int command_num)
3091 {
3092  Command *command = sql_script[st->use_file].commands[command_num];
3093 
3094  /* No prepare for non-SQL commands */
3095  if (command->type != SQL_COMMAND)
3096  return;
3097 
3098  if (!st->prepared)
3099  allocCStatePrepared(st);
3100 
3101  if (!st->prepared[st->use_file][command_num])
3102  {
3103  PGresult *res;
3104 
3105  pg_log_debug("client %d preparing %s", st->id, command->prepname);
3106  res = PQprepare(st->con, command->prepname,
3107  command->argv[0], command->argc - 1, NULL);
3109  pg_log_error("%s", PQerrorMessage(st->con));
3110  PQclear(res);
3111  st->prepared[st->use_file][command_num] = true;
3112  }
3113 }
3114 
3115 /*
3116  * Prepare all the commands in the script that come after the \startpipeline
3117  * that's at position st->command, and the first \endpipeline we find.
3118  *
3119  * This sets the ->prepared flag for each relevant command as well as the
3120  * \startpipeline itself, but doesn't move the st->command counter.
3121  */
3122 static void
3124 {
3125  int j;
3126  Command **commands = sql_script[st->use_file].commands;
3127 
3128  Assert(commands[st->command]->type == META_COMMAND &&
3129  commands[st->command]->meta == META_STARTPIPELINE);
3130 
3131  if (!st->prepared)
3132  allocCStatePrepared(st);
3133 
3134  /*
3135  * We set the 'prepared' flag on the \startpipeline itself to flag that we
3136  * don't need to do this next time without calling prepareCommand(), even
3137  * though we don't actually prepare this command.
3138  */
3139  if (st->prepared[st->use_file][st->command])
3140  return;
3141 
3142  for (j = st->command + 1; commands[j] != NULL; j++)
3143  {
3144  if (commands[j]->type == META_COMMAND &&
3145  commands[j]->meta == META_ENDPIPELINE)
3146  break;
3147 
3148  prepareCommand(st, j);
3149  }
3150 
3151  st->prepared[st->use_file][st->command] = true;
3152 }
3153 
3154 /* Send a SQL command, using the chosen querymode */
3155 static bool
3156 sendCommand(CState *st, Command *command)
3157 {
3158  int r;
3159 
3160  if (querymode == QUERY_SIMPLE)
3161  {
3162  char *sql;
3163 
3164  sql = pg_strdup(command->argv[0]);
3165  sql = assignVariables(&st->variables, sql);
3166 
3167  pg_log_debug("client %d sending %s", st->id, sql);
3168  r = PQsendQuery(st->con, sql);
3169  free(sql);
3170  }
3171  else if (querymode == QUERY_EXTENDED)
3172  {
3173  const char *sql = command->argv[0];
3174  const char *params[MAX_ARGS];
3175 
3176  getQueryParams(&st->variables, command, params);
3177 
3178  pg_log_debug("client %d sending %s", st->id, sql);
3179  r = PQsendQueryParams(st->con, sql, command->argc - 1,
3180  NULL, params, NULL, NULL, 0);
3181  }
3182  else if (querymode == QUERY_PREPARED)
3183  {
3184  const char *params[MAX_ARGS];
3185 
3186  prepareCommand(st, st->command);
3187  getQueryParams(&st->variables, command, params);
3188 
3189  pg_log_debug("client %d sending %s", st->id, command->prepname);
3190  r = PQsendQueryPrepared(st->con, command->prepname, command->argc - 1,
3191  params, NULL, NULL, 0);
3192  }
3193  else /* unknown sql mode */
3194  r = 0;
3195 
3196  if (r == 0)
3197  {
3198  pg_log_debug("client %d could not send %s", st->id, command->argv[0]);
3199  return false;
3200  }
3201  else
3202  return true;
3203 }
3204 
3205 /*
3206  * Get the error status from the error code.
3207  */
3208 static EStatus
3209 getSQLErrorStatus(const char *sqlState)
3210 {
3211  if (sqlState != NULL)
3212  {
3213  if (strcmp(sqlState, ERRCODE_T_R_SERIALIZATION_FAILURE) == 0)
3215  else if (strcmp(sqlState, ERRCODE_T_R_DEADLOCK_DETECTED) == 0)
3216  return ESTATUS_DEADLOCK_ERROR;
3217  }
3218 
3219  return ESTATUS_OTHER_SQL_ERROR;
3220 }
3221 
3222 /*
3223  * Returns true if this type of error can be retried.
3224  */
3225 static bool
3226 canRetryError(EStatus estatus)
3227 {
3228  return (estatus == ESTATUS_SERIALIZATION_ERROR ||
3229  estatus == ESTATUS_DEADLOCK_ERROR);
3230 }
3231 
3232 /*
3233  * Process query response from the backend.
3234  *
3235  * If varprefix is not NULL, it's the variable name prefix where to store
3236  * the results of the *last* command (META_GSET) or *all* commands
3237  * (META_ASET).
3238  *
3239  * Returns true if everything is A-OK, false if any error occurs.
3240  */
3241 static bool
3242 readCommandResponse(CState *st, MetaCommand meta, char *varprefix)
3243 {
3244  PGresult *res;
3245  PGresult *next_res;
3246  int qrynum = 0;
3247 
3248  /*
3249  * varprefix should be set only with \gset or \aset, and \endpipeline and
3250  * SQL commands do not need it.
3251  */
3252  Assert((meta == META_NONE && varprefix == NULL) ||
3253  ((meta == META_ENDPIPELINE) && varprefix == NULL) ||
3254  ((meta == META_GSET || meta == META_ASET) && varprefix != NULL));
3255 
3256  res = PQgetResult(st->con);
3257 
3258  while (res != NULL)
3259  {
3260  bool is_last;
3261 
3262  /* peek at the next result to know whether the current is last */
3263  next_res = PQgetResult(st->con);
3264  is_last = (next_res == NULL);
3265 
3266  switch (PQresultStatus(res))
3267  {
3268  case PGRES_COMMAND_OK: /* non-SELECT commands */
3269  case PGRES_EMPTY_QUERY: /* may be used for testing no-op overhead */
3270  if (is_last && meta == META_GSET)
3271  {
3272  pg_log_error("client %d script %d command %d query %d: expected one row, got %d",
3273  st->id, st->use_file, st->command, qrynum, 0);
3275  goto error;
3276  }
3277  break;
3278 
3279  case PGRES_TUPLES_OK:
3280  if ((is_last && meta == META_GSET) || meta == META_ASET)
3281  {
3282  int ntuples = PQntuples(res);
3283 
3284  if (meta == META_GSET && ntuples != 1)
3285  {
3286  /* under \gset, report the error */
3287  pg_log_error("client %d script %d command %d query %d: expected one row, got %d",
3288  st->id, st->use_file, st->command, qrynum, PQntuples(res));
3290  goto error;
3291  }
3292  else if (meta == META_ASET && ntuples <= 0)
3293  {
3294  /* coldly skip empty result under \aset */
3295  break;
3296  }
3297 
3298  /* store results into variables */
3299  for (int fld = 0; fld < PQnfields(res); fld++)
3300  {
3301  char *varname = PQfname(res, fld);
3302 
3303  /* allocate varname only if necessary, freed below */
3304  if (*varprefix != '\0')
3305  varname = psprintf("%s%s", varprefix, varname);
3306 
3307  /* store last row result as a string */
3308  if (!putVariable(&st->variables, meta == META_ASET ? "aset" : "gset", varname,
3309  PQgetvalue(res, ntuples - 1, fld)))
3310  {
3311  /* internal error */
3312  pg_log_error("client %d script %d command %d query %d: error storing into variable %s",
3313  st->id, st->use_file, st->command, qrynum, varname);
3315  goto error;
3316  }
3317 
3318  if (*varprefix != '\0')
3319  pg_free(varname);
3320  }
3321  }
3322  /* otherwise the result is simply thrown away by PQclear below */
3323  break;
3324 
3325  case PGRES_PIPELINE_SYNC:
3326  pg_log_debug("client %d pipeline ending, ongoing syncs: %d",
3327  st->id, st->num_syncs);
3328  st->num_syncs--;
3329  if (st->num_syncs == 0 && PQexitPipelineMode(st->con) != 1)
3330  pg_log_error("client %d failed to exit pipeline mode: %s", st->id,
3331  PQerrorMessage(st->con));
3332  break;
3333 
3334  case PGRES_NONFATAL_ERROR:
3335  case PGRES_FATAL_ERROR:
3337  PG_DIAG_SQLSTATE));
3338  if (canRetryError(st->estatus))
3339  {
3340  if (verbose_errors)
3341  commandError(st, PQerrorMessage(st->con));
3342  goto error;
3343  }
3344  /* fall through */
3345 
3346  default:
3347  /* anything else is unexpected */
3348  pg_log_error("client %d script %d aborted in command %d query %d: %s",
3349  st->id, st->use_file, st->command, qrynum,
3350  PQerrorMessage(st->con));
3351  goto error;
3352  }
3353 
3354  PQclear(res);
3355  qrynum++;
3356  res = next_res;
3357  }
3358 
3359  if (qrynum == 0)
3360  {
3361  pg_log_error("client %d command %d: no results", st->id, st->command);
3362  return false;
3363  }
3364 
3365  return true;
3366 
3367 error:
3368  PQclear(res);
3369  PQclear(next_res);
3370  do
3371  {
3372  res = PQgetResult(st->con);
3373  PQclear(res);
3374  } while (res);
3375 
3376  return false;
3377 }
3378 
3379 /*
3380  * Parse the argument to a \sleep command, and return the requested amount
3381  * of delay, in microseconds. Returns true on success, false on error.
3382  */
3383 static bool
3384 evaluateSleep(Variables *variables, int argc, char **argv, int *usecs)
3385 {
3386  char *var;
3387  int usec;
3388 
3389  if (*argv[1] == ':')
3390  {
3391  if ((var = getVariable(variables, argv[1] + 1)) == NULL)
3392  {
3393  pg_log_error("%s: undefined variable \"%s\"", argv[0], argv[1] + 1);
3394  return false;
3395  }
3396 
3397  usec = atoi(var);
3398 
3399  /* Raise an error if the value of a variable is not a number */
3400  if (usec == 0 && !isdigit((unsigned char) *var))
3401  {
3402  pg_log_error("%s: invalid sleep time \"%s\" for variable \"%s\"",
3403  argv[0], var, argv[1] + 1);
3404  return false;
3405  }
3406  }
3407  else
3408  usec = atoi(argv[1]);
3409 
3410  if (argc > 2)
3411  {
3412  if (pg_strcasecmp(argv[2], "ms") == 0)
3413  usec *= 1000;
3414  else if (pg_strcasecmp(argv[2], "s") == 0)
3415  usec *= 1000000;
3416  }
3417  else
3418  usec *= 1000000;
3419 
3420  *usecs = usec;
3421  return true;
3422 }
3423 
3424 
3425 /*
3426  * Returns true if the error can be retried.
3427  */
3428 static bool
3430 {
3432 
3433  /* We can only retry serialization or deadlock errors. */
3434  if (!canRetryError(st->estatus))
3435  return false;
3436 
3437  /*
3438  * We must have at least one option to limit the retrying of transactions
3439  * that got an error.
3440  */
3442 
3443  /*
3444  * We cannot retry the error if we have reached the maximum number of
3445  * tries.
3446  */
3447  if (max_tries && st->tries >= max_tries)
3448  return false;
3449 
3450  /*
3451  * We cannot retry the error if we spent too much time on this
3452  * transaction.
3453  */
3454  if (latency_limit)
3455  {
3457  if (*now - st->txn_scheduled > latency_limit)
3458  return false;
3459  }
3460 
3461  /*
3462  * We cannot retry the error if the benchmark duration is over.
3463  */
3464  if (timer_exceeded)
3465  return false;
3466 
3467  /* OK */
3468  return true;
3469 }
3470 
3471 /*
3472  * Read results and discard it until a sync point.
3473  */
3474 static int
3476 {
3477  /* send a sync */
3478  if (!PQpipelineSync(st->con))
3479  {
3480  pg_log_error("client %d aborted: failed to send a pipeline sync",
3481  st->id);
3482  return 0;
3483  }
3484 
3485  /* receive PGRES_PIPELINE_SYNC and null following it */
3486  for (;;)
3487  {
3488  PGresult *res = PQgetResult(st->con);
3489 
3491  {
3492  PQclear(res);
3493  res = PQgetResult(st->con);
3494  Assert(res == NULL);
3495  break;
3496  }
3497  PQclear(res);
3498  }
3499 
3500  /* exit pipeline */
3501  if (PQexitPipelineMode(st->con) != 1)
3502  {
3503  pg_log_error("client %d aborted: failed to exit pipeline mode for rolling back the failed transaction",
3504  st->id);
3505  return 0;
3506  }
3507  return 1;
3508 }
3509 
3510 /*
3511  * Get the transaction status at the end of a command especially for
3512  * checking if we are in a (failed) transaction block.
3513  */
3514 static TStatus
3516 {
3517  PGTransactionStatusType tx_status;
3518 
3519  tx_status = PQtransactionStatus(con);
3520  switch (tx_status)
3521  {
3522  case PQTRANS_IDLE:
3523  return TSTATUS_IDLE;
3524  case PQTRANS_INTRANS:
3525  case PQTRANS_INERROR:
3526  return TSTATUS_IN_BLOCK;
3527  case PQTRANS_UNKNOWN:
3528  /* PQTRANS_UNKNOWN is expected given a broken connection */
3529  if (PQstatus(con) == CONNECTION_BAD)
3530  return TSTATUS_CONN_ERROR;
3531  /* fall through */
3532  case PQTRANS_ACTIVE:
3533  default:
3534 
3535  /*
3536  * We cannot find out whether we are in a transaction block or
3537  * not. Internal error which should never occur.
3538  */
3539  pg_log_error("unexpected transaction status %d", tx_status);
3540  return TSTATUS_OTHER_ERROR;
3541  }
3542 
3543  /* not reached */
3544  Assert(false);
3545  return TSTATUS_OTHER_ERROR;
3546 }
3547 
3548 /*
3549  * Print verbose messages of an error
3550  */
3551 static void
3552 printVerboseErrorMessages(CState *st, pg_time_usec_t *now, bool is_retry)
3553 {
3554  static PQExpBuffer buf = NULL;
3555 
3556  if (buf == NULL)
3557  buf = createPQExpBuffer();
3558  else
3560 
3561  printfPQExpBuffer(buf, "client %d ", st->id);
3562  appendPQExpBufferStr(buf, (is_retry ?
3563  "repeats the transaction after the error" :
3564  "ends the failed transaction"));
3565  appendPQExpBuffer(buf, " (try %u", st->tries);
3566 
3567  /* Print max_tries if it is not unlimited. */
3568  if (max_tries)
3569  appendPQExpBuffer(buf, "/%u", max_tries);
3570 
3571  /*
3572  * If the latency limit is used, print a percentage of the current
3573  * transaction latency from the latency limit.
3574  */
3575  if (latency_limit)
3576  {
3578  appendPQExpBuffer(buf, ", %.3f%% of the maximum time of tries was used",
3579  (100.0 * (*now - st->txn_scheduled) / latency_limit));
3580  }
3581  appendPQExpBufferStr(buf, ")\n");
3582 
3583  pg_log_info("%s", buf->data);
3584 }
3585 
3586 /*
3587  * Advance the state machine of a connection.
3588  */
3589 static void
3590 advanceConnectionState(TState *thread, CState *st, StatsData *agg)
3591 {
3592 
3593  /*
3594  * gettimeofday() isn't free, so we get the current timestamp lazily the
3595  * first time it's needed, and reuse the same value throughout this
3596  * function after that. This also ensures that e.g. the calculated
3597  * latency reported in the log file and in the totals are the same. Zero
3598  * means "not set yet". Reset "now" when we execute shell commands or
3599  * expressions, which might take a non-negligible amount of time, though.
3600  */
3601  pg_time_usec_t now = 0;
3602 
3603  /*
3604  * Loop in the state machine, until we have to wait for a result from the
3605  * server or have to sleep for throttling or \sleep.
3606  *
3607  * Note: In the switch-statement below, 'break' will loop back here,
3608  * meaning "continue in the state machine". Return is used to return to
3609  * the caller, giving the thread the opportunity to advance another
3610  * client.
3611  */
3612  for (;;)
3613  {
3614  Command *command;
3615 
3616  switch (st->state)
3617  {
3618  /* Select transaction (script) to run. */
3619  case CSTATE_CHOOSE_SCRIPT:
3620  st->use_file = chooseScript(thread);
3622 
3623  /* reset transaction variables to default values */
3624  st->estatus = ESTATUS_NO_ERROR;
3625  st->tries = 1;
3626 
3627  pg_log_debug("client %d executing script \"%s\"",
3628  st->id, sql_script[st->use_file].desc);
3629 
3630  /*
3631  * If time is over, we're done; otherwise, get ready to start
3632  * a new transaction, or to get throttled if that's requested.
3633  */
3636  break;
3637 
3638  /* Start new transaction (script) */
3639  case CSTATE_START_TX:
3641 
3642  /* establish connection if needed, i.e. under --connect */
3643  if (st->con == NULL)
3644  {
3646 
3647  if ((st->con = doConnect()) == NULL)
3648  {
3649  /*
3650  * as the bench is already running, we do not abort
3651  * the process
3652  */
3653  pg_log_error("client %d aborted while establishing connection", st->id);
3654  st->state = CSTATE_ABORTED;
3655  break;
3656  }
3657 
3658  /* reset now after connection */
3659  now = pg_time_now();
3660 
3661  thread->conn_duration += now - start;
3662 
3663  /* Reset session-local state */
3664  pg_free(st->prepared);
3665  st->prepared = NULL;
3666  }
3667 
3668  /*
3669  * It is the first try to run this transaction. Remember the
3670  * random state: maybe it will get an error and we will need
3671  * to run it again.
3672  */
3673  st->random_state = st->cs_func_rs;
3674 
3675  /* record transaction start time */
3676  st->txn_begin = now;
3677 
3678  /*
3679  * When not throttling, this is also the transaction's
3680  * scheduled start time.
3681  */
3682  if (!throttle_delay)
3683  st->txn_scheduled = now;
3684 
3685  /* Begin with the first command */
3687  st->command = 0;
3688  break;
3689 
3690  /*
3691  * Handle throttling once per transaction by sleeping.
3692  */
3694 
3695  /*
3696  * Generate a delay such that the series of delays will
3697  * approximate a Poisson distribution centered on the
3698  * throttle_delay time.
3699  *
3700  * If transactions are too slow or a given wait is shorter
3701  * than a transaction, the next transaction will start right
3702  * away.
3703  */
3704  Assert(throttle_delay > 0);
3705 
3706  thread->throttle_trigger +=
3708  st->txn_scheduled = thread->throttle_trigger;
3709 
3710  /*
3711  * If --latency-limit is used, and this slot is already late
3712  * so that the transaction will miss the latency limit even if
3713  * it completed immediately, skip this time slot and loop to
3714  * reschedule.
3715  */
3716  if (latency_limit)
3717  {
3719 
3720  if (thread->throttle_trigger < now - latency_limit)
3721  {
3722  processXactStats(thread, st, &now, true, agg);
3723 
3724  /*
3725  * Finish client if -T or -t was exceeded.
3726  *
3727  * Stop counting skipped transactions under -T as soon
3728  * as the timer is exceeded. Because otherwise it can
3729  * take a very long time to count all of them
3730  * especially when quite a lot of them happen with
3731  * unrealistically high rate setting in -R, which
3732  * would prevent pgbench from ending immediately.
3733  * Because of this behavior, note that there is no
3734  * guarantee that all skipped transactions are counted
3735  * under -T though there is under -t. This is OK in
3736  * practice because it's very unlikely to happen with
3737  * realistic setting.
3738  */
3739  if (timer_exceeded || (nxacts > 0 && st->cnt >= nxacts))
3740  st->state = CSTATE_FINISHED;
3741 
3742  /* Go back to top of loop with CSTATE_PREPARE_THROTTLE */
3743  break;
3744  }
3745  }
3746 
3747  /*
3748  * stop client if next transaction is beyond pgbench end of
3749  * execution; otherwise, throttle it.
3750  */
3751  st->state = end_time > 0 && st->txn_scheduled > end_time ?
3753  break;
3754 
3755  /*
3756  * Wait until it's time to start next transaction.
3757  */
3758  case CSTATE_THROTTLE:
3760 
3761  if (now < st->txn_scheduled)
3762  return; /* still sleeping, nothing to do here */
3763 
3764  /* done sleeping, but don't start transaction if we're done */
3766  break;
3767 
3768  /*
3769  * Send a command to server (or execute a meta-command)
3770  */
3771  case CSTATE_START_COMMAND:
3772  command = sql_script[st->use_file].commands[st->command];
3773 
3774  /*
3775  * Transition to script end processing if done, but close up
3776  * shop if a pipeline is open at this point.
3777  */
3778  if (command == NULL)
3779  {
3780  if (PQpipelineStatus(st->con) == PQ_PIPELINE_OFF)
3781  st->state = CSTATE_END_TX;
3782  else
3783  {
3784  pg_log_error("client %d aborted: end of script reached with pipeline open",
3785  st->id);
3786  st->state = CSTATE_ABORTED;
3787  }
3788 
3789  break;
3790  }
3791 
3792  /* record begin time of next command, and initiate it */
3793  if (report_per_command)
3794  {
3796  st->stmt_begin = now;
3797  }
3798 
3799  /* Execute the command */
3800  if (command->type == SQL_COMMAND)
3801  {
3802  /* disallow \aset and \gset in pipeline mode */
3803  if (PQpipelineStatus(st->con) != PQ_PIPELINE_OFF)
3804  {
3805  if (command->meta == META_GSET)
3806  {
3807  commandFailed(st, "gset", "\\gset is not allowed in pipeline mode");
3808  st->state = CSTATE_ABORTED;
3809  break;
3810  }
3811  else if (command->meta == META_ASET)
3812  {
3813  commandFailed(st, "aset", "\\aset is not allowed in pipeline mode");
3814  st->state = CSTATE_ABORTED;
3815  break;
3816  }
3817  }
3818 
3819  if (!sendCommand(st, command))
3820  {
3821  commandFailed(st, "SQL", "SQL command send failed");
3822  st->state = CSTATE_ABORTED;
3823  }
3824  else
3825  {
3826  /* Wait for results, unless in pipeline mode */
3827  if (PQpipelineStatus(st->con) == PQ_PIPELINE_OFF)
3828  st->state = CSTATE_WAIT_RESULT;
3829  else
3830  st->state = CSTATE_END_COMMAND;
3831  }
3832  }
3833  else if (command->type == META_COMMAND)
3834  {
3835  /*-----
3836  * Possible state changes when executing meta commands:
3837  * - on errors CSTATE_ABORTED
3838  * - on sleep CSTATE_SLEEP
3839  * - else CSTATE_END_COMMAND
3840  */
3841  st->state = executeMetaCommand(st, &now);
3842  if (st->state == CSTATE_ABORTED)
3844  }
3845 
3846  /*
3847  * We're now waiting for an SQL command to complete, or
3848  * finished processing a metacommand, or need to sleep, or
3849  * something bad happened.
3850  */
3851  Assert(st->state == CSTATE_WAIT_RESULT ||
3852  st->state == CSTATE_END_COMMAND ||
3853  st->state == CSTATE_SLEEP ||
3854  st->state == CSTATE_ABORTED);
3855  break;
3856 
3857  /*
3858  * non executed conditional branch
3859  */
3860  case CSTATE_SKIP_COMMAND:
3862  /* quickly skip commands until something to do... */
3863  while (true)
3864  {
3865  command = sql_script[st->use_file].commands[st->command];
3866 
3867  /* cannot reach end of script in that state */
3868  Assert(command != NULL);
3869 
3870  /*
3871  * if this is conditional related, update conditional
3872  * state
3873  */
3874  if (command->type == META_COMMAND &&
3875  (command->meta == META_IF ||
3876  command->meta == META_ELIF ||
3877  command->meta == META_ELSE ||
3878  command->meta == META_ENDIF))
3879  {
3880  switch (conditional_stack_peek(st->cstack))
3881  {
3882  case IFSTATE_FALSE:
3883  if (command->meta == META_IF ||
3884  command->meta == META_ELIF)
3885  {
3886  /* we must evaluate the condition */
3888  }
3889  else if (command->meta == META_ELSE)
3890  {
3891  /* we must execute next command */
3895  st->command++;
3896  }
3897  else if (command->meta == META_ENDIF)
3898  {
3901  if (conditional_active(st->cstack))
3903 
3904  /*
3905  * else state remains in
3906  * CSTATE_SKIP_COMMAND
3907  */
3908  st->command++;
3909  }
3910  break;
3911 
3912  case IFSTATE_IGNORED:
3913  case IFSTATE_ELSE_FALSE:
3914  if (command->meta == META_IF)
3916  IFSTATE_IGNORED);
3917  else if (command->meta == META_ENDIF)
3918  {
3921  if (conditional_active(st->cstack))
3923  }
3924  /* could detect "else" & "elif" after "else" */
3925  st->command++;
3926  break;
3927 
3928  case IFSTATE_NONE:
3929  case IFSTATE_TRUE:
3930  case IFSTATE_ELSE_TRUE:
3931  default:
3932 
3933  /*
3934  * inconsistent if inactive, unreachable dead
3935  * code
3936  */
3937  Assert(false);
3938  }
3939  }
3940  else
3941  {
3942  /* skip and consider next */
3943  st->command++;
3944  }
3945 
3946  if (st->state != CSTATE_SKIP_COMMAND)
3947  /* out of quick skip command loop */
3948  break;
3949  }
3950  break;
3951 
3952  /*
3953  * Wait for the current SQL command to complete
3954  */
3955  case CSTATE_WAIT_RESULT:
3956  pg_log_debug("client %d receiving", st->id);
3957 
3958  /*
3959  * Only check for new network data if we processed all data
3960  * fetched prior. Otherwise we end up doing a syscall for each
3961  * individual pipelined query, which has a measurable
3962  * performance impact.
3963  */
3964  if (PQisBusy(st->con) && !PQconsumeInput(st->con))
3965  {
3966  /* there's something wrong */
3967  commandFailed(st, "SQL", "perhaps the backend died while processing");
3968  st->state = CSTATE_ABORTED;
3969  break;
3970  }
3971  if (PQisBusy(st->con))
3972  return; /* don't have the whole result yet */
3973 
3974  /* store or discard the query results */
3975  if (readCommandResponse(st,
3978  {
3979  /*
3980  * outside of pipeline mode: stop reading results.
3981  * pipeline mode: continue reading results until an
3982  * end-of-pipeline response.
3983  */
3984  if (PQpipelineStatus(st->con) != PQ_PIPELINE_ON)
3985  st->state = CSTATE_END_COMMAND;
3986  }
3987  else if (canRetryError(st->estatus))
3988  st->state = CSTATE_ERROR;
3989  else
3990  st->state = CSTATE_ABORTED;
3991  break;
3992 
3993  /*
3994  * Wait until sleep is done. This state is entered after a
3995  * \sleep metacommand. The behavior is similar to
3996  * CSTATE_THROTTLE, but proceeds to CSTATE_START_COMMAND
3997  * instead of CSTATE_START_TX.
3998  */
3999  case CSTATE_SLEEP:
4001  if (now < st->sleep_until)
4002  return; /* still sleeping, nothing to do here */
4003  /* Else done sleeping. */
4004  st->state = CSTATE_END_COMMAND;
4005  break;
4006 
4007  /*
4008  * End of command: record stats and proceed to next command.
4009  */
4010  case CSTATE_END_COMMAND:
4011 
4012  /*
4013  * command completed: accumulate per-command execution times
4014  * in thread-local data structure, if per-command latencies
4015  * are requested.
4016  */
4017  if (report_per_command)
4018  {
4020 
4021  command = sql_script[st->use_file].commands[st->command];
4022  /* XXX could use a mutex here, but we choose not to */
4023  addToSimpleStats(&command->stats,
4025  }
4026 
4027  /* Go ahead with next command, to be executed or skipped */
4028  st->command++;
4029  st->state = conditional_active(st->cstack) ?
4031  break;
4032 
4033  /*
4034  * Clean up after an error.
4035  */
4036  case CSTATE_ERROR:
4037  {
4038  TStatus tstatus;
4039 
4041 
4042  /* Clear the conditional stack */
4044 
4045  /* Read and discard until a sync point in pipeline mode */
4046  if (PQpipelineStatus(st->con) != PQ_PIPELINE_OFF)
4047  {
4048  if (!discardUntilSync(st))
4049  {
4050  st->state = CSTATE_ABORTED;
4051  break;
4052  }
4053  }
4054 
4055  /*
4056  * Check if we have a (failed) transaction block or not,
4057  * and roll it back if any.
4058  */
4059  tstatus = getTransactionStatus(st->con);
4060  if (tstatus == TSTATUS_IN_BLOCK)
4061  {
4062  /* Try to rollback a (failed) transaction block. */
4063  if (!PQsendQuery(st->con, "ROLLBACK"))
4064  {
4065  pg_log_error("client %d aborted: failed to send sql command for rolling back the failed transaction",
4066  st->id);
4067  st->state = CSTATE_ABORTED;
4068  }
4069  else
4071  }
4072  else if (tstatus == TSTATUS_IDLE)
4073  {
4074  /*
4075  * If time is over, we're done; otherwise, check if we
4076  * can retry the error.
4077  */
4080  }
4081  else
4082  {
4083  if (tstatus == TSTATUS_CONN_ERROR)
4084  pg_log_error("perhaps the backend died while processing");
4085 
4086  pg_log_error("client %d aborted while receiving the transaction status", st->id);
4087  st->state = CSTATE_ABORTED;
4088  }
4089  break;
4090  }
4091 
4092  /*
4093  * Wait for the rollback command to complete
4094  */
4096  {
4097  PGresult *res;
4098 
4099  pg_log_debug("client %d receiving", st->id);
4100  if (!PQconsumeInput(st->con))
4101  {
4102  pg_log_error("client %d aborted while rolling back the transaction after an error; perhaps the backend died while processing",
4103  st->id);
4104  st->state = CSTATE_ABORTED;
4105  break;
4106  }
4107  if (PQisBusy(st->con))
4108  return; /* don't have the whole result yet */
4109 
4110  /*
4111  * Read and discard the query result;
4112  */
4113  res = PQgetResult(st->con);
4114  switch (PQresultStatus(res))
4115  {
4116  case PGRES_COMMAND_OK:
4117  /* OK */
4118  PQclear(res);
4119  /* null must be returned */
4120  res = PQgetResult(st->con);
4121  Assert(res == NULL);
4122 
4123  /*
4124  * If time is over, we're done; otherwise, check
4125  * if we can retry the error.
4126  */
4129  break;
4130  default:
4131  pg_log_error("client %d aborted while rolling back the transaction after an error; %s",
4132  st->id, PQerrorMessage(st->con));
4133  PQclear(res);
4134  st->state = CSTATE_ABORTED;
4135  break;
4136  }
4137  break;
4138  }
4139 
4140  /*
4141  * Retry the transaction after an error.
4142  */
4143  case CSTATE_RETRY:
4144  command = sql_script[st->use_file].commands[st->command];
4145 
4146  /*
4147  * Inform that the transaction will be retried after the
4148  * error.
4149  */
4150  if (verbose_errors)
4151  printVerboseErrorMessages(st, &now, true);
4152 
4153  /* Count tries and retries */
4154  st->tries++;
4155  command->retries++;
4156 
4157  /*
4158  * Reset the random state as they were at the beginning of the
4159  * transaction.
4160  */
4161  st->cs_func_rs = st->random_state;
4162 
4163  /* Process the first transaction command. */
4164  st->command = 0;
4165  st->estatus = ESTATUS_NO_ERROR;
4167  break;
4168 
4169  /*
4170  * Record a failed transaction.
4171  */
4172  case CSTATE_FAILURE:
4173  command = sql_script[st->use_file].commands[st->command];
4174 
4175  /* Accumulate the failure. */
4176  command->failures++;
4177 
4178  /*
4179  * Inform that the failed transaction will not be retried.
4180  */
4181  if (verbose_errors)
4182  printVerboseErrorMessages(st, &now, false);
4183 
4184  /* End the failed transaction. */
4185  st->state = CSTATE_END_TX;
4186  break;
4187 
4188  /*
4189  * End of transaction (end of script, really).
4190  */
4191  case CSTATE_END_TX:
4192  {
4193  TStatus tstatus;
4194 
4195  /* transaction finished: calculate latency and do log */
4196  processXactStats(thread, st, &now, false, agg);
4197 
4198  /*
4199  * missing \endif... cannot happen if CheckConditional was
4200  * okay
4201  */
4203 
4204  /*
4205  * We must complete all the transaction blocks that were
4206  * started in this script.
4207  */
4208  tstatus = getTransactionStatus(st->con);
4209  if (tstatus == TSTATUS_IN_BLOCK)
4210  {
4211  pg_log_error("client %d aborted: end of script reached without completing the last transaction",
4212  st->id);
4213  st->state = CSTATE_ABORTED;
4214  break;
4215  }
4216  else if (tstatus != TSTATUS_IDLE)
4217  {
4218  if (tstatus == TSTATUS_CONN_ERROR)
4219  pg_log_error("perhaps the backend died while processing");
4220 
4221  pg_log_error("client %d aborted while receiving the transaction status", st->id);
4222  st->state = CSTATE_ABORTED;
4223  break;
4224  }
4225 
4226  if (is_connect)
4227  {
4229 
4231  finishCon(st);
4232  now = pg_time_now();
4233  thread->conn_duration += now - start;
4234  }
4235 
4236  if ((st->cnt >= nxacts && duration <= 0) || timer_exceeded)
4237  {
4238  /* script completed */
4239  st->state = CSTATE_FINISHED;
4240  break;
4241  }
4242 
4243  /* next transaction (script) */
4245 
4246  /*
4247  * Ensure that we always return on this point, so as to
4248  * avoid an infinite loop if the script only contains meta
4249  * commands.
4250  */
4251  return;
4252  }
4253 
4254  /*
4255  * Final states. Close the connection if it's still open.
4256  */
4257  case CSTATE_ABORTED:
4258  case CSTATE_FINISHED:
4259 
4260  /*
4261  * Don't measure the disconnection delays here even if in
4262  * CSTATE_FINISHED and -C/--connect option is specified.
4263  * Because in this case all the connections that this thread
4264  * established are closed at the end of transactions and the
4265  * disconnection delays should have already been measured at
4266  * that moment.
4267  *
4268  * In CSTATE_ABORTED state, the measurement is no longer
4269  * necessary because we cannot report complete results anyways
4270  * in this case.
4271  */
4272  finishCon(st);
4273  return;
4274  }
4275  }
4276 }
4277 
4278 /*
4279  * Subroutine for advanceConnectionState -- initiate or execute the current
4280  * meta command, and return the next state to set.
4281  *
4282  * *now is updated to the current time, unless the command is expected to
4283  * take no time to execute.
4284  */
4287 {
4288  Command *command = sql_script[st->use_file].commands[st->command];
4289  int argc;
4290  char **argv;
4291 
4292  Assert(command != NULL && command->type == META_COMMAND);
4293 
4294  argc = command->argc;
4295  argv = command->argv;
4296 
4298  {
4300 
4301  initPQExpBuffer(&buf);
4302 
4303  printfPQExpBuffer(&buf, "client %d executing \\%s", st->id, argv[0]);
4304  for (int i = 1; i < argc; i++)
4305  appendPQExpBuffer(&buf, " %s", argv[i]);
4306 
4307  pg_log_debug("%s", buf.data);
4308 
4309  termPQExpBuffer(&buf);
4310  }
4311 
4312  if (command->meta == META_SLEEP)
4313  {
4314  int usec;
4315 
4316  /*
4317  * A \sleep doesn't execute anything, we just get the delay from the
4318  * argument, and enter the CSTATE_SLEEP state. (The per-command
4319  * latency will be recorded in CSTATE_SLEEP state, not here, after the
4320  * delay has elapsed.)
4321  */
4322  if (!evaluateSleep(&st->variables, argc, argv, &usec))
4323  {
4324  commandFailed(st, "sleep", "execution of meta-command failed");
4325  return CSTATE_ABORTED;
4326  }
4327 
4329  st->sleep_until = (*now) + usec;
4330  return CSTATE_SLEEP;
4331  }
4332  else if (command->meta == META_SET)
4333  {
4334  PgBenchExpr *expr = command->expr;
4335  PgBenchValue result;
4336 
4337  if (!evaluateExpr(st, expr, &result))
4338  {
4339  commandFailed(st, argv[0], "evaluation of meta-command failed");
4340  return CSTATE_ABORTED;
4341  }
4342 
4343  if (!putVariableValue(&st->variables, argv[0], argv[1], &result))
4344  {
4345  commandFailed(st, "set", "assignment of meta-command failed");
4346  return CSTATE_ABORTED;
4347  }
4348  }
4349  else if (command->meta == META_IF)
4350  {
4351  /* backslash commands with an expression to evaluate */
4352  PgBenchExpr *expr = command->expr;
4353  PgBenchValue result;
4354  bool cond;
4355 
4356  if (!evaluateExpr(st, expr, &result))
4357  {
4358  commandFailed(st, argv[0], "evaluation of meta-command failed");
4359  return CSTATE_ABORTED;
4360  }
4361 
4362  cond = valueTruth(&result);
4364  }
4365  else if (command->meta == META_ELIF)
4366  {
4367  /* backslash commands with an expression to evaluate */
4368  PgBenchExpr *expr = command->expr;
4369  PgBenchValue result;
4370  bool cond;
4371 
4373  {
4374  /* elif after executed block, skip eval and wait for endif. */
4376  return CSTATE_END_COMMAND;
4377  }
4378 
4379  if (!evaluateExpr(st, expr, &result))
4380  {
4381  commandFailed(st, argv[0], "evaluation of meta-command failed");
4382  return CSTATE_ABORTED;
4383  }
4384 
4385  cond = valueTruth(&result);
4388  }
4389  else if (command->meta == META_ELSE)
4390  {
4391  switch (conditional_stack_peek(st->cstack))
4392  {
4393  case IFSTATE_TRUE:
4395  break;
4396  case IFSTATE_FALSE: /* inconsistent if active */
4397  case IFSTATE_IGNORED: /* inconsistent if active */
4398  case IFSTATE_NONE: /* else without if */
4399  case IFSTATE_ELSE_TRUE: /* else after else */
4400  case IFSTATE_ELSE_FALSE: /* else after else */
4401  default:
4402  /* dead code if conditional check is ok */
4403  Assert(false);
4404  }
4405  }
4406  else if (command->meta == META_ENDIF)
4407  {
4410  }
4411  else if (command->meta == META_SETSHELL)
4412  {
4413  if (!runShellCommand(&st->variables, argv[1], argv + 2, argc - 2))
4414  {
4415  commandFailed(st, "setshell", "execution of meta-command failed");
4416  return CSTATE_ABORTED;
4417  }
4418  }
4419  else if (command->meta == META_SHELL)
4420  {
4421  if (!runShellCommand(&st->variables, NULL, argv + 1, argc - 1))
4422  {
4423  commandFailed(st, "shell", "execution of meta-command failed");
4424  return CSTATE_ABORTED;
4425  }
4426  }
4427  else if (command->meta == META_STARTPIPELINE)
4428  {
4429  /*
4430  * In pipeline mode, we use a workflow based on libpq pipeline
4431  * functions.
4432  */
4433  if (querymode == QUERY_SIMPLE)
4434  {
4435  commandFailed(st, "startpipeline", "cannot use pipeline mode with the simple query protocol");
4436  return CSTATE_ABORTED;
4437  }
4438 
4439  /*
4440  * If we're in prepared-query mode, we need to prepare all the
4441  * commands that are inside the pipeline before we actually start the
4442  * pipeline itself. This solves the problem that running BEGIN
4443  * ISOLATION LEVEL SERIALIZABLE in a pipeline would fail due to a
4444  * snapshot having been acquired by the prepare within the pipeline.
4445  */
4446  if (querymode == QUERY_PREPARED)
4448 
4449  if (PQpipelineStatus(st->con) != PQ_PIPELINE_OFF)
4450  {
4451  commandFailed(st, "startpipeline", "already in pipeline mode");
4452  return CSTATE_ABORTED;
4453  }
4454  if (PQenterPipelineMode(st->con) == 0)
4455  {
4456  commandFailed(st, "startpipeline", "failed to enter pipeline mode");
4457  return CSTATE_ABORTED;
4458  }
4459  }
4460  else if (command->meta == META_SYNCPIPELINE)
4461  {
4462  if (PQpipelineStatus(st->con) != PQ_PIPELINE_ON)
4463  {
4464  commandFailed(st, "syncpipeline", "not in pipeline mode");
4465  return CSTATE_ABORTED;
4466  }
4467  if (PQsendPipelineSync(st->con) == 0)
4468  {
4469  commandFailed(st, "syncpipeline", "failed to send a pipeline sync");
4470  return CSTATE_ABORTED;
4471  }
4472  st->num_syncs++;
4473  }
4474  else if (command->meta == META_ENDPIPELINE)
4475  {
4476  if (PQpipelineStatus(st->con) != PQ_PIPELINE_ON)
4477  {
4478  commandFailed(st, "endpipeline", "not in pipeline mode");
4479  return CSTATE_ABORTED;
4480  }
4481  if (!PQpipelineSync(st->con))
4482  {
4483  commandFailed(st, "endpipeline", "failed to send a pipeline sync");
4484  return CSTATE_ABORTED;
4485  }
4486  st->num_syncs++;
4487  /* Now wait for the PGRES_PIPELINE_SYNC and exit pipeline mode there */
4488  /* collect pending results before getting out of pipeline mode */
4489  return CSTATE_WAIT_RESULT;
4490  }
4491 
4492  /*
4493  * executing the expression or shell command might have taken a
4494  * non-negligible amount of time, so reset 'now'
4495  */
4496  *now = 0;
4497 
4498  return CSTATE_END_COMMAND;
4499 }
4500 
4501 /*
4502  * Return the number of failed transactions.
4503  */
4504 static int64
4505 getFailures(const StatsData *stats)
4506 {
4507  return (stats->serialization_failures +
4508  stats->deadlock_failures);
4509 }
4510 
4511 /*
4512  * Return a string constant representing the result of a transaction
4513  * that is not successfully processed.
4514  */
4515 static const char *
4516 getResultString(bool skipped, EStatus estatus)
4517 {
4518  if (skipped)
4519  return "skipped";
4520  else if (failures_detailed)
4521  {
4522  switch (estatus)
4523  {
4525  return "serialization";
4527  return "deadlock";
4528  default:
4529  /* internal error which should never occur */
4530  pg_fatal("unexpected error status: %d", estatus);
4531  }
4532  }
4533  else
4534  return "failed";
4535 }
4536 
4537 /*
4538  * Print log entry after completing one transaction.
4539  *
4540  * We print Unix-epoch timestamps in the log, so that entries can be
4541  * correlated against other logs.
4542  *
4543  * XXX We could obtain the time from the caller and just shift it here, to
4544  * avoid the cost of an extra call to pg_time_now().
4545  */
4546 static void
4547 doLog(TState *thread, CState *st,
4548  StatsData *agg, bool skipped, double latency, double lag)
4549 {
4550  FILE *logfile = thread->logfile;
4552 
4553  Assert(use_log);
4554 
4555  /*
4556  * Skip the log entry if sampling is enabled and this row doesn't belong
4557  * to the random sample.
4558  */
4559  if (sample_rate != 0.0 &&
4561  return;
4562 
4563  /* should we aggregate the results or not? */
4564  if (agg_interval > 0)
4565  {
4567 
4568  /*
4569  * Loop until we reach the interval of the current moment, and print
4570  * any empty intervals in between (this may happen with very low tps,
4571  * e.g. --rate=0.1).
4572  */
4573 
4574  while ((next = agg->start_time + agg_interval * INT64CONST(1000000)) <= now)
4575  {
4576  double lag_sum = 0.0;
4577  double lag_sum2 = 0.0;
4578  double lag_min = 0.0;
4579  double lag_max = 0.0;
4580  int64 skipped = 0;
4581  int64 serialization_failures = 0;
4582  int64 deadlock_failures = 0;
4583  int64 retried = 0;
4584  int64 retries = 0;
4585 
4586  /* print aggregated report to logfile */
4587  fprintf(logfile, INT64_FORMAT " " INT64_FORMAT " %.0f %.0f %.0f %.0f",
4588  agg->start_time / 1000000, /* seconds since Unix epoch */
4589  agg->cnt,
4590  agg->latency.sum,
4591  agg->latency.sum2,
4592  agg->latency.min,
4593  agg->latency.max);
4594 
4595  if (throttle_delay)
4596  {
4597  lag_sum = agg->lag.sum;
4598  lag_sum2 = agg->lag.sum2;
4599  lag_min = agg->lag.min;
4600  lag_max = agg->lag.max;
4601  }
4602  fprintf(logfile, " %.0f %.0f %.0f %.0f",
4603  lag_sum,
4604  lag_sum2,
4605  lag_min,
4606  lag_max);
4607 
4608  if (latency_limit)
4609  skipped = agg->skipped;
4610  fprintf(logfile, " " INT64_FORMAT, skipped);
4611 
4612  if (max_tries != 1)
4613  {
4614  retried = agg->retried;
4615  retries = agg->retries;
4616  }
4617  fprintf(logfile, " " INT64_FORMAT " " INT64_FORMAT, retried, retries);
4618 
4619  if (failures_detailed)
4620  {
4621  serialization_failures = agg->serialization_failures;
4622  deadlock_failures = agg->deadlock_failures;
4623  }
4625  serialization_failures,
4626  deadlock_failures);
4627 
4628  fputc('\n', logfile);
4629 
4630  /* reset data and move to next interval */
4631  initStats(agg, next);
4632  }
4633 
4634  /* accumulate the current transaction */
4635  accumStats(agg, skipped, latency, lag, st->estatus, st->tries);
4636  }
4637  else
4638  {
4639  /* no, print raw transactions */
4640  if (!skipped && st->estatus == ESTATUS_NO_ERROR)
4641  fprintf(logfile, "%d " INT64_FORMAT " %.0f %d " INT64_FORMAT " "
4642  INT64_FORMAT,
4643  st->id, st->cnt, latency, st->use_file,
4644  now / 1000000, now % 1000000);
4645  else
4646  fprintf(logfile, "%d " INT64_FORMAT " %s %d " INT64_FORMAT " "
4647  INT64_FORMAT,
4648  st->id, st->cnt, getResultString(skipped, st->estatus),
4649  st->use_file, now / 1000000, now % 1000000);
4650 
4651  if (throttle_delay)
4652  fprintf(logfile, " %.0f", lag);
4653  if (max_tries != 1)
4654  fprintf(logfile, " %u", st->tries - 1);
4655  fputc('\n', logfile);
4656  }
4657 }
4658 
4659 /*
4660  * Accumulate and report statistics at end of a transaction.
4661  *
4662  * (This is also called when a transaction is late and thus skipped.
4663  * Note that even skipped and failed transactions are counted in the CState
4664  * "cnt" field.)
4665  */
4666 static void
4668  bool skipped, StatsData *agg)
4669 {
4670  double latency = 0.0,
4671  lag = 0.0;
4672  bool detailed = progress || throttle_delay || latency_limit ||
4674 
4675  if (detailed && !skipped && st->estatus == ESTATUS_NO_ERROR)
4676  {
4678 
4679  /* compute latency & lag */
4680  latency = (*now) - st->txn_scheduled;
4681  lag = st->txn_begin - st->txn_scheduled;
4682  }
4683 
4684  /* keep detailed thread stats */
4685  accumStats(&thread->stats, skipped, latency, lag, st->estatus, st->tries);
4686 
4687  /* count transactions over the latency limit, if needed */
4688  if (latency_limit && latency > latency_limit)
4689  thread->latency_late++;
4690 
4691  /* client stat is just counting */
4692  st->cnt++;
4693 
4694  if (use_log)
4695  doLog(thread, st, agg, skipped, latency, lag);
4696 
4697  /* XXX could use a mutex here, but we choose not to */
4698  if (per_script_stats)
4699  accumStats(&sql_script[st->use_file].stats, skipped, latency, lag,
4700  st->estatus, st->tries);
4701 }
4702 
4703 
4704 /* discard connections */
4705 static void
4706 disconnect_all(CState *state, int length)
4707 {
4708  int i;
4709 
4710  for (i = 0; i < length; i++)
4711  finishCon(&state[i]);
4712 }
4713 
4714 /*
4715  * Remove old pgbench tables, if any exist
4716  */
4717 static void
4718 initDropTables(PGconn *con)
4719 {
4720  fprintf(stderr, "dropping old tables...\n");
4721 
4722  /*
4723  * We drop all the tables in one command, so that whether there are
4724  * foreign key dependencies or not doesn't matter.
4725  */
4726  executeStatement(con, "drop table if exists "
4727  "pgbench_accounts, "
4728  "pgbench_branches, "
4729  "pgbench_history, "
4730  "pgbench_tellers");
4731 }
4732 
4733 /*
4734  * Create "pgbench_accounts" partitions if needed.
4735  *
4736  * This is the larger table of pgbench default tpc-b like schema
4737  * with a known size, so we choose to partition it.
4738  */
4739 static void
4741 {
4742  PQExpBufferData query;
4743 
4744  /* we must have to create some partitions */
4745  Assert(partitions > 0);
4746 
4747  fprintf(stderr, "creating %d partitions...\n", partitions);
4748 
4749  initPQExpBuffer(&query);
4750 
4751  for (int p = 1; p <= partitions; p++)
4752  {
4754  {
4755  int64 part_size = (naccounts * (int64) scale + partitions - 1) / partitions;
4756 
4757  printfPQExpBuffer(&query,
4758  "create%s table pgbench_accounts_%d\n"
4759  " partition of pgbench_accounts\n"
4760  " for values from (",
4761  unlogged_tables ? " unlogged" : "", p);
4762 
4763  /*
4764  * For RANGE, we use open-ended partitions at the beginning and
4765  * end to allow any valid value for the primary key. Although the
4766  * actual minimum and maximum values can be derived from the
4767  * scale, it is more generic and the performance is better.
4768  */
4769  if (p == 1)
4770  appendPQExpBufferStr(&query, "minvalue");
4771  else
4772  appendPQExpBuffer(&query, INT64_FORMAT, (p - 1) * part_size + 1);
4773 
4774  appendPQExpBufferStr(&query, ") to (");
4775 
4776  if (p < partitions)
4777  appendPQExpBuffer(&query, INT64_FORMAT, p * part_size + 1);
4778  else
4779  appendPQExpBufferStr(&query, "maxvalue");
4780 
4781  appendPQExpBufferChar(&query, ')');
4782  }
4783  else if (partition_method == PART_HASH)
4784  printfPQExpBuffer(&query,
4785  "create%s table pgbench_accounts_%d\n"
4786  " partition of pgbench_accounts\n"
4787  " for values with (modulus %d, remainder %d)",
4788  unlogged_tables ? " unlogged" : "", p,
4789  partitions, p - 1);
4790  else /* cannot get there */
4791  Assert(0);
4792 
4793  /*
4794  * Per ddlinfo in initCreateTables, fillfactor is needed on table
4795  * pgbench_accounts.
4796  */
4797  appendPQExpBuffer(&query, " with (fillfactor=%d)", fillfactor);
4798 
4799  executeStatement(con, query.data);
4800  }
4801 
4802  termPQExpBuffer(&query);
4803 }
4804 
4805 /*
4806  * Create pgbench's standard tables
4807  */
4808 static void
4810 {
4811  /*
4812  * Note: TPC-B requires at least 100 bytes per row, and the "filler"
4813  * fields in these table declarations were intended to comply with that.
4814  * The pgbench_accounts table complies with that because the "filler"
4815  * column is set to blank-padded empty string. But for all other tables
4816  * the columns default to NULL and so don't actually take any space. We
4817  * could fix that by giving them non-null default values. However, that
4818  * would completely break comparability of pgbench results with prior
4819  * versions. Since pgbench has never pretended to be fully TPC-B compliant
4820  * anyway, we stick with the historical behavior.
4821  */
4822  struct ddlinfo
4823  {
4824  const char *table; /* table name */
4825  const char *smcols; /* column decls if accountIDs are 32 bits */
4826  const char *bigcols; /* column decls if accountIDs are 64 bits */
4827  int declare_fillfactor;
4828  };
4829  static const struct ddlinfo DDLs[] = {
4830  {
4831  "pgbench_history",
4832  "tid int,bid int,aid int,delta int,mtime timestamp,filler char(22)",
4833  "tid int,bid int,aid bigint,delta int,mtime timestamp,filler char(22)",
4834  0
4835  },
4836  {
4837  "pgbench_tellers",
4838  "tid int not null,bid int,tbalance int,filler char(84)",
4839  "tid int not null,bid int,tbalance int,filler char(84)",
4840  1
4841  },
4842  {
4843  "pgbench_accounts",
4844  "aid int not null,bid int,abalance int,filler char(84)",
4845  "aid bigint not null,bid int,abalance int,filler char(84)",
4846  1
4847  },
4848  {
4849  "pgbench_branches",
4850  "bid int not null,bbalance int,filler char(88)",
4851  "bid int not null,bbalance int,filler char(88)",
4852  1
4853  }
4854  };
4855  int i;
4856  PQExpBufferData query;
4857 
4858  fprintf(stderr, "creating tables...\n");
4859 
4860  initPQExpBuffer(&query);
4861 
4862  for (i = 0; i < lengthof(DDLs); i++)
4863  {
4864  const struct ddlinfo *ddl = &DDLs[i];
4865 
4866  /* Construct new create table statement. */
4867  printfPQExpBuffer(&query, "create%s table %s(%s)",
4868  unlogged_tables ? " unlogged" : "",
4869  ddl->table,
4870  (scale >= SCALE_32BIT_THRESHOLD) ? ddl->bigcols : ddl->smcols);
4871 
4872  /* Partition pgbench_accounts table */
4873  if (partition_method != PART_NONE && strcmp(ddl->table, "pgbench_accounts") == 0)
4874  appendPQExpBuffer(&query,
4875  " partition by %s (aid)", PARTITION_METHOD[partition_method]);
4876  else if (ddl->declare_fillfactor)
4877  {
4878  /* fillfactor is only expected on actual tables */
4879  appendPQExpBuffer(&query, " with (fillfactor=%d)", fillfactor);
4880  }
4881 
4882  if (tablespace != NULL)
4883  {
4884  char *escape_tablespace;
4885 
4886  escape_tablespace = PQescapeIdentifier(con, tablespace, strlen(tablespace));
4887  appendPQExpBuffer(&query, " tablespace %s", escape_tablespace);
4888  PQfreemem(escape_tablespace);
4889  }
4890 
4891  executeStatement(con, query.data);
4892  }
4893 
4894  termPQExpBuffer(&query);
4895 
4896  if (partition_method != PART_NONE)
4897  createPartitions(con);
4898 }
4899 
4900 /*
4901  * Truncate away any old data, in one command in case there are foreign keys
4902  */
4903 static void
4905 {
4906  executeStatement(con, "truncate table "
4907  "pgbench_accounts, "
4908  "pgbench_branches, "
4909  "pgbench_history, "
4910  "pgbench_tellers");
4911 }
4912 
4913 static void
4914 initBranch(PQExpBufferData *sql, int64 curr)
4915 {
4916  /* "filler" column uses NULL */
4917  printfPQExpBuffer(sql,
4918  INT64_FORMAT "\t0\t\\N\n",
4919  curr + 1);
4920 }
4921 
4922 static void
4923 initTeller(PQExpBufferData *sql, int64 curr)
4924 {
4925  /* "filler" column uses NULL */
4926  printfPQExpBuffer(sql,
4927  INT64_FORMAT "\t" INT64_FORMAT "\t0\t\\N\n",
4928  curr + 1, curr / ntellers + 1);
4929 }
4930 
4931 static void
4932 initAccount(PQExpBufferData *sql, int64 curr)
4933 {
4934  /* "filler" column defaults to blank padded empty string */
4935  printfPQExpBuffer(sql,
4936  INT64_FORMAT "\t" INT64_FORMAT "\t0\t\n",
4937  curr + 1, curr / naccounts + 1);
4938 }
4939 
4940 static void
4941 initPopulateTable(PGconn *con, const char *table, int64 base,
4942  initRowMethod init_row)
4943 {
4944  int n;
4945  int64 k;
4946  int chars = 0;
4947  PGresult *res;
4948  PQExpBufferData sql;
4949  char copy_statement[256];
4950  const char *copy_statement_fmt = "copy %s from stdin";
4951  int64 total = base * scale;
4952 
4953  /* used to track elapsed time and estimate of the remaining time */
4955  int log_interval = 1;
4956 
4957  /* Stay on the same line if reporting to a terminal */
4958  char eol = isatty(fileno(stderr)) ? '\r' : '\n';
4959 
4960  initPQExpBuffer(&sql);
4961 
4962  /*
4963  * Use COPY with FREEZE on v14 and later for all the tables except
4964  * pgbench_accounts when it is partitioned.
4965  */
4966  if (PQserverVersion(con) >= 140000)
4967  {
4968  if (strcmp(table, "pgbench_accounts") != 0 ||
4969  partitions == 0)
4970  copy_statement_fmt = "copy %s from stdin with (freeze on)";
4971  }
4972 
4973  n = pg_snprintf(copy_statement, sizeof(copy_statement), copy_statement_fmt, table);
4974  if (n >= sizeof(copy_statement))
4975  pg_fatal("invalid buffer size: must be at least %d characters long", n);
4976  else if (n == -1)
4977  pg_fatal("invalid format string");
4978 
4979  res = PQexec(con, copy_statement);
4980 
4982  pg_fatal("unexpected copy in result: %s", PQerrorMessage(con));
4983  PQclear(res);
4984 
4985  start = pg_time_now();
4986 
4987  for (k = 0; k < total; k++)
4988  {
4989  int64 j = k + 1;
4990 
4991  init_row(&sql, k);
4992  if (PQputline(con, sql.data))
4993  pg_fatal("PQputline failed");
4994 
4995  if (CancelRequested)
4996  break;
4997 
4998  /*
4999  * If we want to stick with the original logging, print a message each
5000  * 100k inserted rows.
5001  */
5002  if ((!use_quiet) && (j % 100000 == 0))
5003  {
5004  double elapsed_sec = PG_TIME_GET_DOUBLE(pg_time_now() - start);
5005  double remaining_sec = ((double) total - j) * elapsed_sec / j;
5006 
5007  chars = fprintf(stderr, INT64_FORMAT " of " INT64_FORMAT " tuples (%d%%) of %s done (elapsed %.2f s, remaining %.2f s)%c",
5008  j, total,
5009  (int) ((j * 100) / total),
5010  table, elapsed_sec, remaining_sec, eol);
5011  }
5012  /* let's not call the timing for each row, but only each 100 rows */
5013  else if (use_quiet && (j % 100 == 0))
5014  {
5015  double elapsed_sec = PG_TIME_GET_DOUBLE(pg_time_now() - start);
5016  double remaining_sec = ((double) total - j) * elapsed_sec / j;
5017 
5018  /* have we reached the next interval (or end)? */
5019  if ((j == total) || (elapsed_sec >= log_interval * LOG_STEP_SECONDS))
5020  {
5021  chars = fprintf(stderr, INT64_FORMAT " of " INT64_FORMAT " tuples (%d%%) of %s done (elapsed %.2f s, remaining %.2f s)%c",
5022  j, total,
5023  (int) ((j * 100) / total),
5024  table, elapsed_sec, remaining_sec, eol);
5025 
5026  /* skip to the next interval */
5027  log_interval = (int) ceil(elapsed_sec / LOG_STEP_SECONDS);
5028  }
5029  }
5030  }
5031 
5032  if (chars != 0 && eol != '\n')
5033  fprintf(stderr, "%*c\r", chars - 1, ' '); /* Clear the current line */
5034 
5035  if (PQputline(con, "\\.\n"))
5036  pg_fatal("very last PQputline failed");
5037  if (PQendcopy(con))
5038  pg_fatal("PQendcopy failed");
5039 
5040  termPQExpBuffer(&sql);
5041 }
5042 
5043 /*
5044  * Fill the standard tables with some data generated and sent from the client.
5045  *
5046  * The filler column is NULL in pgbench_branches and pgbench_tellers, and is
5047  * a blank-padded string in pgbench_accounts.
5048  */
5049 static void
5051 {
5052  fprintf(stderr, "generating data (client-side)...\n");
5053 
5054  /*
5055  * we do all of this in one transaction to enable the backend's
5056  * data-loading optimizations
5057  */
5058  executeStatement(con, "begin");
5059 
5060  /* truncate away any old data */
5061  initTruncateTables(con);
5062 
5063  /*
5064  * fill branches, tellers, accounts in that order in case foreign keys
5065  * already exist
5066  */
5067  initPopulateTable(con, "pgbench_branches", nbranches, initBranch);
5068  initPopulateTable(con, "pgbench_tellers", ntellers, initTeller);
5069  initPopulateTable(con, "pgbench_accounts", naccounts, initAccount);
5070 
5071  executeStatement(con, "commit");
5072 }
5073 
5074 /*
5075  * Fill the standard tables with some data generated on the server
5076  *
5077  * As already the case with the client-side data generation, the filler
5078  * column defaults to NULL in pgbench_branches and pgbench_tellers,
5079  * and is a blank-padded string in pgbench_accounts.
5080  */
5081 static void
5083 {
5084  PQExpBufferData sql;
5085 
5086  fprintf(stderr, "generating data (server-side)...\n");
5087 
5088  /*
5089  * we do all of this in one transaction to enable the backend's
5090  * data-loading optimizations
5091  */
5092  executeStatement(con, "begin");
5093 
5094  /* truncate away any old data */
5095  initTruncateTables(con);
5096 
5097  initPQExpBuffer(&sql);
5098 
5099  printfPQExpBuffer(&sql,
5100  "insert into pgbench_branches(bid,bbalance) "
5101  "select bid, 0 "
5102  "from generate_series(1, %d) as bid", nbranches * scale);
5103  executeStatement(con, sql.data);
5104 
5105  printfPQExpBuffer(&sql,
5106  "insert into pgbench_tellers(tid,bid,tbalance) "
5107  "select tid, (tid - 1) / %d + 1, 0 "
5108  "from generate_series(1, %d) as tid", ntellers, ntellers * scale);
5109  executeStatement(con, sql.data);
5110 
5111  printfPQExpBuffer(&sql,
5112  "insert into pgbench_accounts(aid,bid,abalance,filler) "
5113  "select aid, (aid - 1) / %d + 1, 0, '' "
5114  "from generate_series(1, " INT64_FORMAT ") as aid",
5115  naccounts, (int64) naccounts * scale);
5116  executeStatement(con, sql.data);
5117 
5118  termPQExpBuffer(&sql);
5119 
5120  executeStatement(con, "commit");
5121 }
5122 
5123 /*
5124  * Invoke vacuum on the standard tables
5125  */
5126 static void
5127 initVacuum(PGconn *con)
5128 {
5129  fprintf(stderr, "vacuuming...\n");
5130  executeStatement(con, "vacuum analyze pgbench_branches");
5131  executeStatement(con, "vacuum analyze pgbench_tellers");
5132  executeStatement(con, "vacuum analyze pgbench_accounts");
5133  executeStatement(con, "vacuum analyze pgbench_history");
5134 }
5135 
5136 /*
5137  * Create primary keys on the standard tables
5138  */
5139 static void
5140 initCreatePKeys(PGconn *con)
5141 {
5142  static const char *const DDLINDEXes[] = {
5143  "alter table pgbench_branches add primary key (bid)",
5144  "alter table pgbench_tellers add primary key (tid)",
5145  "alter table pgbench_accounts add primary key (aid)"
5146  };
5147  int i;
5148  PQExpBufferData query;
5149 
5150  fprintf(stderr, "creating primary keys...\n");
5151  initPQExpBuffer(&query);
5152 
5153  for (i = 0; i < lengthof(DDLINDEXes); i++)
5154  {
5155  resetPQExpBuffer(&query);
5156  appendPQExpBufferStr(&query, DDLINDEXes[i]);
5157 
5158  if (index_tablespace != NULL)
5159  {
5160  char *escape_tablespace;
5161 
5162  escape_tablespace = PQescapeIdentifier(con, index_tablespace,
5163  strlen(index_tablespace));
5164  appendPQExpBuffer(&query, " using index tablespace %s", escape_tablespace);
5165  PQfreemem(escape_tablespace);
5166  }
5167 
5168  executeStatement(con, query.data);
5169  }
5170 
5171  termPQExpBuffer(&query);
5172 }
5173 
5174 /*
5175  * Create foreign key constraints between the standard tables
5176  */
5177 static void
5178 initCreateFKeys(PGconn *con)
5179 {
5180  static const char *const DDLKEYs[] = {
5181  "alter table pgbench_tellers add constraint pgbench_tellers_bid_fkey foreign key (bid) references pgbench_branches",
5182  "alter table pgbench_accounts add constraint pgbench_accounts_bid_fkey foreign key (bid) references pgbench_branches",
5183  "alter table pgbench_history add constraint pgbench_history_bid_fkey foreign key (bid) references pgbench_branches",
5184  "alter table pgbench_history add constraint pgbench_history_tid_fkey foreign key (tid) references pgbench_tellers",
5185  "alter table pgbench_history add constraint pgbench_history_aid_fkey foreign key (aid) references pgbench_accounts"
5186  };
5187  int i;
5188 
5189  fprintf(stderr, "creating foreign keys...\n");
5190  for (i = 0; i < lengthof(DDLKEYs); i++)
5191  {
5192  executeStatement(con, DDLKEYs[i]);
5193  }
5194 }
5195 
5196 /*
5197  * Validate an initialization-steps string
5198  *
5199  * (We could just leave it to runInitSteps() to fail if there are wrong
5200  * characters, but since initialization can take awhile, it seems friendlier
5201  * to check during option parsing.)
5202  */
5203 static void
5204 checkInitSteps(const char *initialize_steps)
5205 {
5206  if (initialize_steps[0] == '\0')
5207  pg_fatal("no initialization steps specified");
5208 
5209  for (const char *step = initialize_steps; *step != '\0'; step++)
5210  {
5211  if (strchr(ALL_INIT_STEPS " ", *step) == NULL)
5212  {
5213  pg_log_error("unrecognized initialization step \"%c\"", *step);
5214  pg_log_error_detail("Allowed step characters are: \"" ALL_INIT_STEPS "\".");
5215  exit(1);
5216  }
5217  }
5218 }
5219 
5220 /*
5221  * Invoke each initialization step in the given string
5222  */
5223 static void
5224 runInitSteps(const char *initialize_steps)
5225 {
5226  PQExpBufferData stats;
5227  PGconn *con;
5228  const char *step;
5229  double run_time = 0.0;
5230  bool first = true;
5231 
5232  initPQExpBuffer(&stats);
5233 
5234  if ((con = doConnect()) == NULL)
5235  pg_fatal("could not create connection for initialization");
5236 
5237  setup_cancel_handler(NULL);
5238  SetCancelConn(con);
5239 
5240  for (step = initialize_steps; *step != '\0'; step++)
5241  {
5242  char *op = NULL;
5244 
5245  switch (*step)
5246  {
5247  case 'd':
5248  op = "drop tables";
5249  initDropTables(con);
5250  break;
5251  case 't':
5252  op = "create tables";
5253  initCreateTables(con);
5254  break;
5255  case 'g':
5256  op = "client-side generate";
5258  break;
5259  case 'G':
5260  op = "server-side generate";
5262  break;
5263  case 'v':
5264  op = "vacuum";
5265  initVacuum(con);
5266  break;
5267  case 'p':
5268  op = "primary keys";
5269  initCreatePKeys(con);
5270  break;
5271  case 'f':
5272  op = "foreign keys";
5273  initCreateFKeys(con);
5274  break;
5275  case ' ':
5276  break; /* ignore */
5277  default:
5278  pg_log_error("unrecognized initialization step \"%c\"", *step);
5279  PQfinish(con);
5280  exit(1);
5281  }
5282 
5283  if (op != NULL)
5284  {
5285  double elapsed_sec = PG_TIME_GET_DOUBLE(pg_time_now() - start);
5286 
5287  if (!first)
5288  appendPQExpBufferStr(&stats, ", ");
5289  else
5290  first = false;
5291 
5292  appendPQExpBuffer(&stats, "%s %.2f s", op, elapsed_sec);
5293 
5294  run_time += elapsed_sec;
5295  }
5296  }
5297 
5298  fprintf(stderr, "done in %.2f s (%s).\n", run_time, stats.data);
5299  ResetCancelConn();
5300  PQfinish(con);
5301  termPQExpBuffer(&stats);
5302 }
5303 
5304 /*
5305  * Extract pgbench table information into global variables scale,
5306  * partition_method and partitions.
5307  */
5308 static void
5309 GetTableInfo(PGconn *con, bool scale_given)
5310 {
5311  PGresult *res;
5312 
5313  /*
5314  * get the scaling factor that should be same as count(*) from
5315  * pgbench_branches if this is not a custom query
5316  */
5317  res = PQexec(con, "select count(*) from pgbench_branches");
5319  {
5320  char *sqlState = PQresultErrorField(res, PG_DIAG_SQLSTATE);
5321 
5322  pg_log_error("could not count number of branches: %s", PQerrorMessage(con));
5323 
5324  if (sqlState && strcmp(sqlState, ERRCODE_UNDEFINED_TABLE) == 0)
5325  pg_log_error_hint("Perhaps you need to do initialization (\"pgbench -i\") in database \"%s\".",
5326  PQdb(con));
5327 
5328  exit(1);
5329  }
5330  scale = atoi(PQgetvalue(res, 0, 0));
5331  if (scale < 0)
5332  pg_fatal("invalid count(*) from pgbench_branches: \"%s\"",
5333  PQgetvalue(res, 0, 0));
5334  PQclear(res);
5335 
5336  /* warn if we override user-given -s switch */
5337  if (scale_given)
5338  pg_log_warning("scale option ignored, using count from pgbench_branches table (%d)",
5339  scale);
5340 
5341  /*
5342  * Get the partition information for the first "pgbench_accounts" table
5343  * found in search_path.
5344  *
5345  * The result is empty if no "pgbench_accounts" is found.
5346  *
5347  * Otherwise, it always returns one row even if the table is not
5348  * partitioned (in which case the partition strategy is NULL).
5349  *
5350  * The number of partitions can be 0 even for partitioned tables, if no
5351  * partition is attached.
5352  *
5353  * We assume no partitioning on any failure, so as to avoid failing on an
5354  * old version without "pg_partitioned_table".
5355  */
5356  res = PQexec(con,
5357  "select o.n, p.partstrat, pg_catalog.count(i.inhparent) "
5358  "from pg_catalog.pg_class as c "
5359  "join pg_catalog.pg_namespace as n on (n.oid = c.relnamespace) "
5360  "cross join lateral (select pg_catalog.array_position(pg_catalog.current_schemas(true), n.nspname)) as o(n) "
5361  "left join pg_catalog.pg_partitioned_table as p on (p.partrelid = c.oid) "
5362  "left join pg_catalog.pg_inherits as i on (c.oid = i.inhparent) "
5363  "where c.relname = 'pgbench_accounts' and o.n is not null "
5364  "group by 1, 2 "
5365  "order by 1 asc "
5366  "limit 1");
5367 
5369  {
5370  /* probably an older version, coldly assume no partitioning */
5372  partitions = 0;
5373  }
5374  else if (PQntuples(res) == 0)
5375  {
5376  /*
5377  * This case is unlikely as pgbench already found "pgbench_branches"
5378  * above to compute the scale.
5379  */
5380  pg_log_error("no pgbench_accounts table found in \"search_path\"");
5381  pg_log_error_hint("Perhaps you need to do initialization (\"pgbench -i\") in database \"%s\".", PQdb(con));
5382  exit(1);
5383  }
5384  else /* PQntuples(res) == 1 */
5385  {
5386  /* normal case, extract partition information */
5387  if (PQgetisnull(res, 0, 1))
5389  else
5390  {
5391  char *ps = PQgetvalue(res, 0, 1);
5392 
5393  /* column must be there */
5394  Assert(ps != NULL);
5395 
5396  if (strcmp(ps, "r") == 0)
5398  else if (strcmp(ps, "h") == 0)
5400  else
5401  {
5402  /* possibly a newer version with new partition method */
5403  pg_fatal("unexpected partition method: \"%s\"", ps);
5404  }
5405  }
5406 
5407  partitions = atoi(PQgetvalue(res, 0, 2));
5408  }
5409 
5410  PQclear(res);
5411 }
5412 
5413 /*
5414  * Replace :param with $n throughout the command's SQL text, which
5415  * is a modifiable string in cmd->lines.
5416  */
5417 static bool
5418 parseQuery(Command *cmd)
5419 {
5420  char *sql,
5421  *p;
5422 
5423  cmd->argc = 1;
5424 
5425  p = sql = pg_strdup(cmd->lines.data);
5426  while ((p = strchr(p, ':')) != NULL)
5427  {
5428  char var[13];
5429  char *name;
5430  int eaten;
5431 
5432  name = parseVariable(p, &eaten);
5433  if (name == NULL)
5434  {
5435  while (*p == ':')
5436  {
5437  p++;
5438  }
5439  continue;
5440  }
5441 
5442  /*
5443  * cmd->argv[0] is the SQL statement itself, so the max number of
5444  * arguments is one less than MAX_ARGS
5445  */
5446  if (cmd->argc >= MAX_ARGS)
5447  {
5448  pg_log_error("statement has too many arguments (maximum is %d): %s",
5449  MAX_ARGS - 1, cmd->lines.data);
5450  pg_free(name);
5451  return false;
5452  }
5453 
5454  sprintf(var, "$%d", cmd->argc);
5455  p = replaceVariable(&sql, p, eaten, var);
5456 
5457  cmd->argv[cmd->argc] = name;
5458  cmd->argc++;
5459  }
5460 
5461  Assert(cmd->argv[0] == NULL);
5462  cmd->argv[0] = sql;
5463  return true;
5464 }
5465 
5466 /*
5467  * syntax error while parsing a script (in practice, while parsing a
5468  * backslash command, because we don't detect syntax errors in SQL)
5469  *
5470  * source: source of script (filename or builtin-script ID)
5471  * lineno: line number within script (count from 1)
5472  * line: whole line of backslash command, if available
5473  * command: backslash command name, if available
5474  * msg: the actual error message
5475  * more: optional extra message
5476  * column: zero-based column number, or -1 if unknown
5477  */
5478 void
5479 syntax_error(const char *source, int lineno,
5480  const char *line, const char *command,
5481  const char *msg, const char *more, int column)
5482 {
5484 
5485  initPQExpBuffer(&buf);
5486 
5487  printfPQExpBuffer(&buf, "%s:%d: %s", source, lineno, msg);
5488  if (more != NULL)
5489  appendPQExpBuffer(&buf, " (%s)", more);
5490  if (column >= 0 && line == NULL)
5491  appendPQExpBuffer(&buf, " at column %d", column + 1);
5492  if (command != NULL)
5493  appendPQExpBuffer(&buf, " in command \"%s\"", command);
5494 
5495  pg_log_error("%s", buf.data);
5496 
5497  termPQExpBuffer(&buf);
5498 
5499  if (line != NULL)
5500  {
5501  fprintf(stderr, "%s\n", line);
5502  if (column >= 0)
5503  fprintf(stderr, "%*c error found here\n", column + 1, '^');
5504  }
5505 
5506  exit(1);
5507 }
5508 
5509 /*
5510  * Return a pointer to the start of the SQL command, after skipping over
5511  * whitespace and "--" comments.
5512  * If the end of the string is reached, return NULL.
5513  */
5514 static char *
5515 skip_sql_comments(char *sql_command)
5516 {
5517  char *p = sql_command;
5518 
5519  /* Skip any leading whitespace, as well as "--" style comments */
5520  for (;;)
5521  {
5522  if (isspace((unsigned char) *p))
5523  p++;
5524  else if (strncmp(p, "--", 2) == 0)
5525  {
5526  p = strchr(p, '\n');
5527  if (p == NULL)
5528  return NULL;
5529  p++;
5530  }
5531  else
5532  break;
5533  }
5534 
5535  /* NULL if there's nothing but whitespace and comments */
5536  if (*p == '\0')
5537  return NULL;
5538 
5539  return p;
5540 }
5541 
5542 /*
5543  * Parse a SQL command; return a Command struct, or NULL if it's a comment
5544  *
5545  * On entry, psqlscan.l has collected the command into "buf", so we don't
5546  * really need to do much here except check for comments and set up a Command
5547  * struct.
5548  */
5549 static Command *
5551 {
5552  Command *my_command;
5553  char *p = skip_sql_comments(buf->data);
5554 
5555  if (p == NULL)
5556  return NULL;
5557 
5558  /* Allocate and initialize Command structure */
5559  my_command = (Command *) pg_malloc(sizeof(Command));
5560  initPQExpBuffer(&my_command->lines);
5561  appendPQExpBufferStr(&my_command->lines, p);
5562  my_command->first_line = NULL; /* this is set later */
5563  my_command->type = SQL_COMMAND;
5564  my_command->meta = META_NONE;
5565  my_command->argc = 0;
5566  my_command->retries = 0;
5567  my_command->failures = 0;
5568  memset(my_command->argv, 0, sizeof(my_command->argv));
5569  my_command->varprefix = NULL; /* allocated later, if needed */
5570  my_command->expr = NULL;
5571  initSimpleStats(&my_command->stats);
5572  my_command->prepname = NULL; /* set later, if needed */
5573 
5574  return my_command;
5575 }
5576 
5577 /* Free a Command structure and associated data */
5578 static void
5579 free_command(Command *command)
5580 {
5581  termPQExpBuffer(&command->lines);
5582  pg_free(command->first_line);
5583  for (int i = 0; i < command->argc; i++)
5584  pg_free(command->argv[i]);
5585  pg_free(command->varprefix);
5586 
5587  /*
5588  * It should also free expr recursively, but this is currently not needed
5589  * as only gset commands (which do not have an expression) are freed.
5590  */
5591  pg_free(command);
5592 }
5593 
5594 /*
5595  * Once an SQL command is fully parsed, possibly by accumulating several
5596  * parts, complete other fields of the Command structure.
5597  */
5598 static void
5599 postprocess_sql_command(Command *my_command)
5600 {
5601  char buffer[128];
5602  static int prepnum = 0;
5603 
5604  Assert(my_command->type == SQL_COMMAND);
5605 
5606  /* Save the first line for error display. */
5607  strlcpy(buffer, my_command->lines.data, sizeof(buffer));
5608  buffer[strcspn(buffer, "\n\r")] = '\0';
5609  my_command->first_line = pg_strdup(buffer);
5610 
5611  /* Parse query and generate prepared statement name, if necessary */
5612  switch (querymode)
5613  {
5614  case QUERY_SIMPLE:
5615  my_command->argv[0] = my_command->lines.data;
5616  my_command->argc++;
5617  break;
5618  case QUERY_PREPARED:
5619  my_command->prepname = psprintf("P_%d", prepnum++);
5620  /* fall through */
5621  case QUERY_EXTENDED:
5622  if (!parseQuery(my_command))
5623  exit(1);
5624  break;
5625  default:
5626  exit(1);
5627  }
5628 }
5629 
5630 /*
5631  * Parse a backslash command; return a Command struct, or NULL if comment
5632  *
5633  * At call, we have scanned only the initial backslash.
5634  */
5635 static Command *
5636 process_backslash_command(PsqlScanState sstate, const char *source)
5637 {
5638  Command *my_command;
5639  PQExpBufferData word_buf;
5640  int word_offset;
5641  int offsets[MAX_ARGS]; /* offsets of argument words */
5642  int start_offset;
5643  int lineno;
5644  int j;
5645 
5646  initPQExpBuffer(&word_buf);
5647 
5648  /* Remember location of the backslash */
5649  start_offset = expr_scanner_offset(sstate) - 1;
5650  lineno = expr_scanner_get_lineno(sstate, start_offset);
5651 
5652  /* Collect first word of command */
5653  if (!expr_lex_one_word(sstate, &word_buf, &word_offset))
5654  {
5655  termPQExpBuffer(&word_buf);
5656  return NULL;
5657  }
5658 
5659  /* Allocate and initialize Command structure */
5660  my_command = (Command *) pg_malloc0(sizeof(Command));
5661  my_command->type = META_COMMAND;
5662  my_command->argc = 0;
5663  initSimpleStats(&my_command->stats);
5664 
5665  /* Save first word (command name) */
5666  j = 0;
5667  offsets[j] = word_offset;
5668  my_command->argv[j++] = pg_strdup(word_buf.data);
5669  my_command->argc++;
5670 
5671  /* ... and convert it to enum form */
5672  my_command->meta = getMetaCommand(my_command->argv[0]);
5673 
5674  if (my_command->meta == META_SET ||
5675  my_command->meta == META_IF ||
5676  my_command->meta == META_ELIF)
5677  {
5679 
5680  /* For \set, collect var name */
5681  if (my_command->meta == META_SET)
5682  {
5683  if (!expr_lex_one_word(sstate, &word_buf, &word_offset))
5684  syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
5685  "missing argument", NULL, -1);
5686 
5687  offsets[j] = word_offset;
5688  my_command->argv[j++] = pg_strdup(word_buf.data);
5689  my_command->argc++;
5690  }
5691 
5692  /* then for all parse the expression */
5693  yyscanner = expr_scanner_init(sstate, source, lineno, start_offset,
5694  my_command->argv[0]);
5695 
5696  if (expr_yyparse(yyscanner) != 0)
5697  {
5698  /* dead code: exit done from syntax_error called by yyerror */
5699  exit(1);
5700  }
5701 
5702  my_command->expr = expr_parse_result;
5703 
5704  /* Save line, trimming any trailing newline */
5705  my_command->first_line =
5707  start_offset,
5708  expr_scanner_offset(sstate),
5709  true);
5710 
5712 
5713  termPQExpBuffer(&word_buf);
5714 
5715  return my_command;
5716  }
5717 
5718  /* For all other commands, collect remaining words. */
5719  while (expr_lex_one_word(sstate, &word_buf, &word_offset))
5720  {
5721  /*
5722  * my_command->argv[0] is the command itself, so the max number of
5723  * arguments is one less than MAX_ARGS
5724  */
5725  if (j >= MAX_ARGS)
5726  syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
5727  "too many arguments", NULL, -1);
5728 
5729  offsets[j] = word_offset;
5730  my_command->argv[j++] = pg_strdup(word_buf.data);
5731  my_command->argc++;
5732  }
5733 
5734  /* Save line, trimming any trailing newline */
5735  my_command->first_line =
5737  start_offset,
5738  expr_scanner_offset(sstate),
5739  true);
5740 
5741  if (my_command->meta == META_SLEEP)
5742  {
5743  if (my_command->argc < 2)
5744  syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
5745  "missing argument", NULL, -1);
5746 
5747  if (my_command->argc > 3)
5748  syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
5749  "too many arguments", NULL,
5750  offsets[3] - start_offset);
5751 
5752  /*
5753  * Split argument into number and unit to allow "sleep 1ms" etc. We
5754  * don't have to terminate the number argument with null because it
5755  * will be parsed with atoi, which ignores trailing non-digit
5756  * characters.
5757  */
5758  if (my_command->argv[1][0] != ':')
5759  {
5760  char *c = my_command->argv[1];
5761  bool have_digit = false;
5762 
5763  /* Skip sign */
5764  if (*c == '+' || *c == '-')
5765  c++;
5766 
5767  /* Require at least one digit */
5768  if (*c && isdigit((unsigned char) *c))
5769  have_digit = true;
5770 
5771  /* Eat all digits */
5772  while (*c && isdigit((unsigned char) *c))
5773  c++;
5774 
5775  if (*c)
5776  {
5777  if (my_command->argc == 2 && have_digit)
5778  {
5779  my_command->argv[2] = c;
5780  offsets[2] = offsets[1] + (c - my_command->argv[1]);
5781  my_command->argc = 3;
5782  }
5783  else
5784  {
5785  /*
5786  * Raise an error if argument starts with non-digit
5787  * character (after sign).
5788  */
5789  syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
5790  "invalid sleep time, must be an integer",
5791  my_command->argv[1], offsets[1] - start_offset);
5792  }
5793  }
5794  }
5795 
5796  if (my_command->argc == 3)
5797  {
5798  if (pg_strcasecmp(my_command->argv[2], "us") != 0 &&
5799  pg_strcasecmp(my_command->argv[2], "ms") != 0 &&
5800  pg_strcasecmp(my_command->argv[2], "s") != 0)
5801  syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
5802  "unrecognized time unit, must be us, ms or s",
5803  my_command->argv[2], offsets[2] - start_offset);
5804  }
5805  }
5806  else if (my_command->meta == META_SETSHELL)
5807  {
5808  if (my_command->argc < 3)
5809  syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
5810  "missing argument", NULL, -1);
5811  }
5812  else if (my_command->meta == META_SHELL)
5813  {
5814  if (my_command->argc < 2)
5815  syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
5816  "missing command", NULL, -1);
5817  }
5818  else if (my_command->meta == META_ELSE || my_command->meta == META_ENDIF ||
5819  my_command->meta == META_STARTPIPELINE ||
5820  my_command->meta == META_ENDPIPELINE ||
5821  my_command->meta == META_SYNCPIPELINE)
5822  {
5823  if (my_command->argc != 1)
5824  syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
5825  "unexpected argument", NULL, -1);
5826  }
5827  else if (my_command->meta == META_GSET || my_command->meta == META_ASET)
5828  {
5829  if (my_command->argc > 2)
5830  syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
5831  "too many arguments", NULL, -1);
5832  }
5833  else
5834  {
5835  /* my_command->meta == META_NONE */
5836  syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
5837  "invalid command", NULL, -1);
5838  }
5839 
5840  termPQExpBuffer(&word_buf);
5841 
5842  return my_command;
5843 }
5844 
5845 static void
5846 ConditionError(const char *desc, int cmdn, const char *msg)
5847 {
5848  pg_fatal("condition error in script \"%s\" command %d: %s",
5849  desc, cmdn, msg);
5850 }
5851 
5852 /*
5853  * Partial evaluation of conditionals before recording and running the script.
5854  */
5855 static void
5857 {
5858  /* statically check conditional structure */
5860  int i;
5861 
5862  for (i = 0; ps->commands[i] != NULL; i++)
5863  {
5864  Command *cmd = ps->commands[i];
5865 
5866  if (cmd->type == META_COMMAND)
5867  {
5868  switch (cmd->meta)
5869  {
5870  case META_IF:
5872  break;
5873  case META_ELIF:
5874  if (conditional_stack_empty(cs))
5875  ConditionError(ps->desc, i + 1, "\\elif without matching \\if");
5877  ConditionError(ps->desc, i + 1, "\\elif after \\else");
5878  break;
5879  case META_ELSE:
5880  if (conditional_stack_empty(cs))
5881  ConditionError(ps->desc, i + 1, "\\else without matching \\if");
5883  ConditionError(ps->desc, i + 1, "\\else after \\else");
5885  break;
5886  case META_ENDIF:
5887  if (!conditional_stack_pop(cs))
5888  ConditionError(ps->desc, i + 1, "\\endif without matching \\if");
5889  break;
5890  default:
5891  /* ignore anything else... */
5892  break;
5893  }
5894  }
5895  }
5896  if (!conditional_stack_empty(cs))
5897  ConditionError(ps->desc, i + 1, "\\if without matching \\endif");
5899 }
5900 
5901 /*
5902  * Parse a script (either the contents of a file, or a built-in script)
5903  * and add it to the list of scripts.
5904  */
5905 static void
5906 ParseScript(const char *script, const char *desc, int weight)
5907 {
5908  ParsedScript ps;
5909  PsqlScanState sstate;
5910  PQExpBufferData line_buf;
5911  int alloc_num;
5912  int index;
5913  int lineno;
5914  int start_offset;
5915 
5916 #define COMMANDS_ALLOC_NUM 128
5917  alloc_num = COMMANDS_ALLOC_NUM;
5918 
5919  /* Initialize all fields of ps */
5920  ps.desc = desc;
5921  ps.weight = weight;
5922  ps.commands = (Command **) pg_malloc(sizeof(Command *) * alloc_num);
5923  initStats(&ps.stats, 0);
5924 
5925  /* Prepare to parse script */
5927 
5928  /*
5929  * Ideally, we'd scan scripts using the encoding and stdstrings settings
5930  * we get from a DB connection. However, without major rearrangement of
5931  * pgbench's argument parsing, we can't have a DB connection at the time
5932  * we parse scripts. Using SQL_ASCII (encoding 0) should work well enough
5933  * with any backend-safe encoding, though conceivably we could be fooled
5934  * if a script file uses a client-only encoding. We also assume that
5935  * stdstrings should be true, which is a bit riskier.
5936  */
5937  psql_scan_setup(sstate, script, strlen(script), 0, true);
5938  start_offset = expr_scanner_offset(sstate) - 1;
5939 
5940  initPQExpBuffer(&line_buf);
5941 
5942  index = 0;
5943 
5944  for (;;)
5945  {
5946  PsqlScanResult sr;
5947  promptStatus_t prompt;
5948  Command *command = NULL;
5949 
5950  resetPQExpBuffer(&line_buf);
5951  lineno = expr_scanner_get_lineno(sstate, start_offset);
5952 
5953  sr = psql_scan(sstate, &line_buf, &prompt);
5954 
5955  /* If we collected a new SQL command, process that */
5956  command = create_sql_command(&line_buf, desc);
5957 
5958  /* store new command */
5959  if (command)
5960  ps.commands[index++] = command;
5961 
5962  /* If we reached a backslash, process that */
5963  if (sr == PSCAN_BACKSLASH)
5964  {
5965  command = process_backslash_command(sstate, desc);
5966 
5967  if (command)
5968  {
5969  /*
5970  * If this is gset or aset, merge into the preceding command.
5971  * (We don't use a command slot in this case).
5972  */
5973  if (command->meta == META_GSET || command->meta == META_ASET)
5974  {
5975  Command *cmd;
5976 
5977  if (index == 0)
5978  syntax_error(desc, lineno, NULL, NULL,
5979  "\\gset must follow an SQL command",
5980  NULL, -1);
5981 
5982  cmd = ps.commands[index - 1];
5983 
5984  if (cmd->type != SQL_COMMAND ||
5985  cmd->varprefix != NULL)
5986  syntax_error(desc, lineno, NULL, NULL,
5987  "\\gset must follow an SQL command",
5988  cmd->first_line, -1);
5989 
5990  /* get variable prefix */
5991  if (command->argc <= 1 || command->argv[1][0] == '\0')
5992  cmd->varprefix = pg_strdup("");
5993  else
5994  cmd->varprefix = pg_strdup(command->argv[1]);
5995 
5996  /* update the sql command meta */
5997  cmd->meta = command->meta;
5998 
5999  /* cleanup unused command */
6000  free_command(command);
6001 
6002  continue;
6003  }
6004 
6005  /* Attach any other backslash command as a new command */
6006  ps.commands[index++] = command;
6007  }
6008  }
6009 
6010  /*
6011  * Since we used a command slot, allocate more if needed. Note we
6012  * always allocate one more in order to accommodate the NULL
6013  * terminator below.
6014  */
6015  if (index >= alloc_num)
6016  {
6017  alloc_num += COMMANDS_ALLOC_NUM;
6018  ps.commands = (Command **)
6019  pg_realloc(ps.commands, sizeof(Command *) * alloc_num);
6020  }
6021 
6022  /* Done if we reached EOF */
6023  if (sr == PSCAN_INCOMPLETE || sr == PSCAN_EOL)
6024  break;
6025  }
6026 
6027  ps.commands[index] = NULL;
6028 
6029  addScript(&ps);
6030 
6031  termPQExpBuffer(&line_buf);
6032  psql_scan_finish(sstate);
6033  psql_scan_destroy(sstate);
6034 }
6035 
6036 /*
6037  * Read the entire contents of file fd, and return it in a malloc'd buffer.
6038  *
6039  * The buffer will typically be larger than necessary, but we don't care
6040  * in this program, because we'll free it as soon as we've parsed the script.
6041  */
6042 static char *
6043 read_file_contents(FILE *fd)
6044 {
6045  char *buf;
6046  size_t buflen = BUFSIZ;
6047  size_t used = 0;
6048 
6049  buf = (char *) pg_malloc(buflen);
6050 
6051  for (;;)
6052  {
6053  size_t nread;
6054 
6055  nread = fread(buf + used, 1, BUFSIZ, fd);
6056  used += nread;
6057  /* If fread() read less than requested, must be EOF or error */
6058  if (nread < BUFSIZ)
6059  break;
6060  /* Enlarge buf so we can read some more */
6061  buflen += BUFSIZ;
6062  buf = (char *) pg_realloc(buf, buflen);
6063  }
6064  /* There is surely room for a terminator */
6065  buf[used] = '\0';
6066 
6067  return buf;
6068 }
6069 
6070 /*
6071  * Given a file name, read it and add its script to the list.
6072  * "-" means to read stdin.
6073  * NB: filename must be storage that won't disappear.
6074  */
6075 static void
6076 process_file(const char *filename, int weight)
6077 {
6078  FILE *fd;
6079  char *buf;
6080 
6081  /* Slurp the file contents into "buf" */
6082  if (strcmp(filename, "-") == 0)
6083  fd = stdin;
6084  else if ((fd = fopen(filename, "r")) == NULL)
6085  pg_fatal("could not open file \"%s\": %m", filename);
6086 
6088 
6089  if (ferror(fd))
6090  pg_fatal("could not read file \"%s\": %m", filename);
6091 
6092  if (fd != stdin)
6093  fclose(fd);
6094 
6095  ParseScript(buf, filename, weight);
6096 
6097  free(buf);
6098 }
6099 
6100 /* Parse the given builtin script and add it to the list. */
6101 static void
6102 process_builtin(const BuiltinScript *bi, int weight)
6103 {
6104  ParseScript(bi->script, bi->desc, weight);
6105 }
6106 
6107 /* show available builtin scripts */
6108 static void
6110 {
6111  int i;
6112 
6113  fprintf(stderr, "Available builtin scripts:\n");
6114  for (i = 0; i < lengthof(builtin_script); i++)
6115  fprintf(stderr, " %13s: %s\n", builtin_script[i].name, builtin_script[i].desc);
6116  fprintf(stderr, "\n");
6117 }
6118 
6119 /* return builtin script "name" if unambiguous, fails if not found */
6120 static const BuiltinScript *
6121 findBuiltin(const char *name)
6122 {
6123  int i,
6124  found = 0,
6125  len = strlen(name);
6126  const BuiltinScript *result = NULL;
6127 
6128  for (i = 0; i < lengthof(builtin_script); i++)
6129  {
6130  if (strncmp(builtin_script[i].name, name, len) == 0)
6131  {
6132  result = &builtin_script[i];
6133  found++;
6134  }
6135  }
6136 
6137  /* ok, unambiguous result */
6138  if (found == 1)
6139  return result;
6140 
6141  /* error cases */
6142  if (found == 0)
6143  pg_log_error("no builtin script found for name \"%s\"", name);
6144  else /* found > 1 */
6145  pg_log_error("ambiguous builtin name: %d builtin scripts found for prefix \"%s\"", found, name);
6146 
6148  exit(1);
6149 }
6150 
6151 /*
6152  * Determine the weight specification from a script option (-b, -f), if any,
6153  * and return it as an integer (1 is returned if there's no weight). The
6154  * script name is returned in *script as a malloc'd string.
6155  */
6156 static int
6157 parseScriptWeight(const char *option, char **script)
6158 {
6159  char *sep;
6160  int weight;
6161 
6162  if ((sep = strrchr(option, WSEP)))
6163  {
6164  int namelen = sep - option;
6165  long wtmp;
6166  char *badp;
6167 
6168  /* generate the script name */
6169  *script = pg_malloc(namelen + 1);
6170  strncpy(*script, option, namelen);
6171  (*script)[namelen] = '\0';
6172 
6173  /* process digits of the weight spec */
6174  errno = 0;
6175  wtmp = strtol(sep + 1, &badp, 10);
6176  if (errno != 0 || badp == sep + 1 || *badp != '\0')
6177  pg_fatal("invalid weight specification: %s", sep);
6178  if (wtmp > INT_MAX || wtmp < 0)
6179  pg_fatal("weight specification out of range (0 .. %d): %lld",
6180  INT_MAX, (long long) wtmp);
6181  weight = wtmp;
6182  }
6183  else
6184  {
6185  *script = pg_strdup(option);
6186  weight = 1;
6187  }
6188 
6189  return weight;
6190 }
6191 
6192 /* append a script to the list of scripts to process */
6193 static void
6194 addScript(const ParsedScript *script)
6195 {
6196  if (script->commands == NULL || script->commands[0] == NULL)
6197  pg_fatal("empty command list for script \"%s\"", script->desc);
6198 
6199  if (num_scripts >= MAX_SCRIPTS)
6200  pg_fatal("at most %d SQL scripts are allowed", MAX_SCRIPTS);
6201 
6202  CheckConditional(script);
6203 
6204  sql_script[num_scripts] = *script;
6205  num_scripts++;
6206 }
6207 
6208 /*
6209  * Print progress report.
6210  *
6211  * On entry, *last and *last_report contain the statistics and time of last
6212  * progress report. On exit, they are updated with the new stats.
6213  */
6214 static void
6215 printProgressReport(TState *threads, int64 test_start, pg_time_usec_t now,
6216  StatsData *last, int64 *last_report)
6217 {
6218  /* generate and show report */
6219  pg_time_usec_t run = now - *last_report;
6220  int64 cnt,
6221  failures,
6222  retried;
6223  double tps,
6224  total_run,
6225  latency,
6226  sqlat,
6227  lag,
6228  stdev;
6229  char tbuf[315];
6230  StatsData cur;
6231 
6232  /*
6233  * Add up the statistics of all threads.
6234  *
6235  * XXX: No locking. There is no guarantee that we get an atomic snapshot
6236  * of the transaction count and latencies, so these figures can well be
6237  * off by a small amount. The progress report's purpose is to give a
6238  * quick overview of how the test is going, so that shouldn't matter too
6239  * much. (If a read from a 64-bit integer is not atomic, you might get a
6240  * "torn" read and completely bogus latencies though!)
6241  */
6242  initStats(&cur, 0);
6243  for (int i = 0; i < nthreads; i++)
6244  {
6245  mergeSimpleStats(&cur.latency, &threads[i].stats.latency);
6246  mergeSimpleStats(&cur.lag, &threads[i].stats.lag);
6247  cur.cnt += threads[i].stats.cnt;
6248  cur.skipped += threads[i].stats.skipped;
6249  cur.retries += threads[i].stats.retries;
6250  cur.retried += threads[i].stats.retried;
6251  cur.serialization_failures +=
6252  threads[i].stats.serialization_failures;
6253  cur.deadlock_failures += threads[i].stats.deadlock_failures;
6254  }
6255 
6256  /* we count only actually executed transactions */
6257  cnt = cur.cnt - last->cnt;
6258  total_run = (now - test_start) / 1000000.0;
6259  tps = 1000000.0 * cnt / run;
6260  if (cnt > 0)
6261  {
6262  latency = 0.001 * (cur.latency.sum - last->latency.sum) / cnt;
6263  sqlat = 1.0 * (cur.latency.sum2 - last->latency.sum2) / cnt;
6264  stdev = 0.001 * sqrt(sqlat - 1000000.0 * latency * latency);
6265  lag = 0.001 * (cur.lag.sum - last->lag.sum) / cnt;
6266  }
6267  else
6268  {
6269  latency = sqlat = stdev = lag = 0;
6270  }
6271  failures = getFailures(&cur) - getFailures(last);
6272  retried = cur.retried - last->retried;
6273 
6274  if (progress_timestamp)
6275  {
6276  snprintf(tbuf, sizeof(tbuf), "%.3f s",
6278  }
6279  else
6280  {
6281  /* round seconds are expected, but the thread may be late */
6282  snprintf(tbuf, sizeof(tbuf), "%.1f s", total_run);
6283  }
6284 
6285  fprintf(stderr,
6286  "progress: %s, %.1f tps, lat %.3f ms stddev %.3f, " INT64_FORMAT " failed",
6287  tbuf, tps, latency, stdev, failures);
6288 
6289  if (throttle_delay)
6290  {
6291  fprintf(stderr, ", lag %.3f ms", lag);
6292  if (latency_limit)
6293  fprintf(stderr, ", " INT64_FORMAT " skipped",
6294  cur.skipped - last->skipped);
6295  }
6296 
6297  /* it can be non-zero only if max_tries is not equal to one */
6298  if (max_tries != 1)
6299  fprintf(stderr,
6300  ", " INT64_FORMAT " retried, " INT64_FORMAT " retries",
6301  retried, cur.retries - last->retries);
6302  fprintf(stderr, "\n");
6303 
6304  *last = cur;
6305  *last_report = now;
6306 }
6307 
6308 static void
6309 printSimpleStats(const char *prefix, SimpleStats *ss)
6310 {
6311  if (ss->count > 0)
6312  {
6313  double latency = ss->sum / ss->count;
6314  double stddev = sqrt(ss->sum2 / ss->count - latency * latency);
6315 
6316  printf("%s average = %.3f ms\n", prefix, 0.001 * latency);
6317  printf("%s stddev = %.3f ms\n", prefix, 0.001 * stddev);
6318  }
6319 }
6320 
6321 /* print version banner */
6322 static void
6323 printVersion(PGconn *con)
6324 {
6325  int server_ver = PQserverVersion(con);
6326  int client_ver = PG_VERSION_NUM;
6327 
6328  if (server_ver != client_ver)
6329  {
6330  const char *server_version;
6331  char sverbuf[32];
6332 
6333  /* Try to get full text form, might include "devel" etc */
6334  server_version = PQparameterStatus(con, "server_version");
6335  /* Otherwise fall back on server_ver */
6336  if (!server_version)
6337  {
6338  formatPGVersionNumber(server_ver, true,
6339  sverbuf, sizeof(sverbuf));
6340  server_version = sverbuf;
6341  }
6342 
6343  printf(_("%s (%s, server %s)\n"),
6344  "pgbench", PG_VERSION, server_version);
6345  }
6346  /* For version match, only print pgbench version */
6347  else
6348  printf("%s (%s)\n", "pgbench", PG_VERSION);
6349  fflush(stdout);
6350 }
6351 
6352 /* print out results */
6353 static void
6354 printResults(StatsData *total,
6355  pg_time_usec_t total_duration, /* benchmarking time */
6356  pg_time_usec_t conn_total_duration, /* is_connect */
6357  pg_time_usec_t conn_elapsed_duration, /* !is_connect */
6358  int64 latency_late)
6359 {
6360  /* tps is about actually executed transactions during benchmarking */
6361  int64 failures = getFailures(total);
6362  int64 total_cnt = total->cnt + total->skipped + failures;
6363  double bench_duration = PG_TIME_GET_DOUBLE(total_duration);
6364  double tps = total->cnt / bench_duration;
6365 
6366  /* Report test parameters. */
6367  printf("transaction type: %s\n",
6368  num_scripts == 1 ? sql_script[0].desc : "multiple scripts");
6369  printf("scaling factor: %d\n", scale);
6370  /* only print partitioning information if some partitioning was detected */
6371  if (partition_method != PART_NONE)
6372  printf("partition method: %s\npartitions: %d\n",
6374  printf("query mode: %s\n", QUERYMODE[querymode]);
6375  printf("number of clients: %d\n", nclients);
6376  printf("number of threads: %d\n", nthreads);
6377 
6378  if (max_tries)
6379  printf("maximum number of tries: %u\n", max_tries);
6380 
6381  if (duration <= 0)
6382  {
6383  printf("number of transactions per client: %d\n", nxacts);
6384  printf("number of transactions actually processed: " INT64_FORMAT "/%d\n",
6385  total->cnt, nxacts * nclients);
6386  }
6387  else
6388  {
6389  printf("duration: %d s\n", duration);
6390  printf("number of transactions actually processed: " INT64_FORMAT "\n",
6391  total->cnt);
6392  }
6393 
6394  printf("number of failed transactions: " INT64_FORMAT " (%.3f%%)\n",
6395  failures, 100.0 * failures / total_cnt);
6396 
6397  if (failures_detailed)
6398  {
6399  printf("number of serialization failures: " INT64_FORMAT " (%.3f%%)\n",
6400  total->serialization_failures,
6401  100.0 * total->serialization_failures / total_cnt);
6402  printf("number of deadlock failures: " INT64_FORMAT " (%.3f%%)\n",
6403  total->deadlock_failures,
6404  100.0 * total->deadlock_failures / total_cnt);
6405  }
6406 
6407  /* it can be non-zero only if max_tries is not equal to one */
6408  if (max_tries != 1)
6409  {
6410  printf("number of transactions retried: " INT64_FORMAT " (%.3f%%)\n",
6411  total->retried, 100.0 * total->retried / total_cnt);
6412  printf("total number of retries: " INT64_FORMAT "\n", total->retries);
6413  }
6414 
6415  /* Remaining stats are nonsensical if we failed to execute any xacts */
6416  if (total->cnt + total->skipped <= 0)
6417  return;
6418 
6420  printf("number of transactions skipped: " INT64_FORMAT " (%.3f%%)\n",
6421  total->skipped, 100.0 * total->skipped / total_cnt);
6422 
6423  if (latency_limit)
6424  printf("number of transactions above the %.1f ms latency limit: " INT64_FORMAT "/" INT64_FORMAT " (%.3f%%)\n",
6425  latency_limit / 1000.0, latency_late, total->cnt,
6426  (total->cnt > 0) ? 100.0 * latency_late / total->cnt : 0.0);
6427 
6429  printSimpleStats("latency", &total->latency);
6430  else
6431  {
6432  /* no measurement, show average latency computed from run time */
6433  printf("latency average = %.3f ms%s\n",
6434  0.001 * total_duration * nclients / total_cnt,
6435  failures > 0 ? " (including failures)" : "");
6436  }
6437 
6438  if (throttle_delay)
6439  {
6440  /*
6441  * Report average transaction lag under rate limit throttling. This
6442  * is the delay between scheduled and actual start times for the
6443  * transaction. The measured lag may be caused by thread/client load,
6444  * the database load, or the Poisson throttling process.
6445  */
6446  printf("rate limit schedule lag: avg %.3f (max %.3f) ms\n",
6447  0.001 * total->lag.sum / total->cnt, 0.001 * total->lag.max);
6448  }
6449 
6450  /*
6451  * Under -C/--connect, each transaction incurs a significant connection
6452  * cost, it would not make much sense to ignore it in tps, and it would
6453  * not be tps anyway.
6454  *
6455  * Otherwise connections are made just once at the beginning of the run
6456  * and should not impact performance but for very short run, so they are
6457  * (right)fully ignored in tps.
6458  */
6459  if (is_connect)
6460  {
6461  printf("average connection time = %.3f ms\n", 0.001 * conn_total_duration / (total->cnt + failures));
6462  printf("tps = %f (including reconnection times)\n", tps);
6463  }
6464  else
6465  {
6466  printf("initial connection time = %.3f ms\n", 0.001 * conn_elapsed_duration);
6467  printf("tps = %f (without initial connection time)\n", tps);
6468  }
6469 
6470  /* Report per-script/command statistics */
6472  {
6473  int i;
6474 
6475  for (i = 0; i < num_scripts; i++)
6476  {
6477  if (per_script_stats)
6478  {
6479  StatsData *sstats = &sql_script[i].stats;
6480  int64 script_failures = getFailures(sstats);
6481  int64 script_total_cnt =
6482  sstats->cnt + sstats->skipped + script_failures;
6483 
6484  printf("SQL script %d: %s\n"
6485  " - weight: %d (targets %.1f%% of total)\n"
6486  " - " INT64_FORMAT " transactions (%.1f%% of total, tps = %f)\n",
6487  i + 1, sql_script[i].desc,
6488  sql_script[i].weight,
6489  100.0 * sql_script[i].weight / total_weight,
6490  sstats->cnt,
6491  100.0 * sstats->cnt / total->cnt,
6492  sstats->cnt / bench_duration);
6493 
6494  printf(" - number of failed transactions: " INT64_FORMAT " (%.3f%%)\n",
6495  script_failures,
6496  100.0 * script_failures / script_total_cnt);
6497 
6498  if (failures_detailed)
6499  {
6500  printf(" - number of serialization failures: " INT64_FORMAT " (%.3f%%)\n",
6501  sstats->serialization_failures,
6502  (100.0 * sstats->serialization_failures /
6503  script_total_cnt));
6504  printf(" - number of deadlock failures: " INT64_FORMAT " (%.3f%%)\n",
6505  sstats->deadlock_failures,
6506  (100.0 * sstats->deadlock_failures /
6507  script_total_cnt));
6508  }
6509 
6510  /* it can be non-zero only if max_tries is not equal to one */
6511  if (max_tries != 1)
6512  {
6513  printf(" - number of transactions retried: " INT64_FORMAT " (%.3f%%)\n",
6514  sstats->retried,
6515  100.0 * sstats->retried / script_total_cnt);
6516  printf(" - total number of retries: " INT64_FORMAT "\n",
6517  sstats->retries);
6518  }
6519 
6520  if (throttle_delay && latency_limit && script_total_cnt > 0)
6521  printf(" - number of transactions skipped: " INT64_FORMAT " (%.3f%%)\n",
6522  sstats->skipped,
6523  100.0 * sstats->skipped / script_total_cnt);
6524 
6525  printSimpleStats(" - latency", &sstats->latency);
6526  }
6527 
6528  /*
6529  * Report per-command statistics: latencies, retries after errors,
6530  * failures (errors without retrying).
6531  */
6532  if (report_per_command)
6533  {
6534  Command **commands;
6535 
6536  printf("%sstatement latencies in milliseconds%s:\n",
6537  per_script_stats ? " - " : "",
6538  (max_tries == 1 ?
6539  " and failures" :
6540  ", failures and retries"));
6541 
6542  for (commands = sql_script[i].commands;
6543  *commands != NULL;
6544  commands++)
6545  {
6546  SimpleStats *cstats = &(*commands)->stats;
6547 
6548  if (max_tries == 1)
6549  printf(" %11.3f %10" INT64_MODIFIER "d %s\n",
6550  (cstats->count > 0) ?
6551  1000.0 * cstats->sum / cstats->count : 0.0,
6552  (*commands)->failures,
6553  (*commands)->first_line);
6554  else
6555  printf(" %11.3f %10" INT64_MODIFIER "d %10" INT64_MODIFIER "d %s\n",
6556  (cstats->count > 0) ?
6557  1000.0 * cstats->sum / cstats->count : 0.0,
6558  (*commands)->failures,
6559  (*commands)->retries,
6560  (*commands)->first_line);
6561  }
6562  }
6563  }
6564  }
6565 }
6566 
6567 /*
6568  * Set up a random seed according to seed parameter (NULL means default),
6569  * and initialize base_random_sequence for use in initializing other sequences.
6570  */
6571 static bool
6572 set_random_seed(const char *seed)
6573 {
6574  uint64 iseed;
6575 
6576  if (seed == NULL || strcmp(seed, "time") == 0)
6577  {
6578  /* rely on current time */
6579  iseed = pg_time_now();
6580  }
6581  else if (strcmp(seed, "rand") == 0)
6582  {
6583  /* use some "strong" random source */
6584  if (!pg_strong_random(&iseed, sizeof(iseed)))
6585  {
6586  pg_log_error("could not generate random seed");
6587  return false;
6588  }
6589  }
6590  else
6591  {
6592  /* parse unsigned-int seed value */
6593  unsigned long ulseed;
6594  char garbage;
6595 
6596  /* Don't try to use UINT64_FORMAT here; it might not work for sscanf */
6597  if (sscanf(seed, "%lu%c", &ulseed, &garbage) != 1)
6598  {
6599  pg_log_error("unrecognized random seed option \"%s\"", seed);
6600  pg_log_error_detail("Expecting an unsigned integer, \"time\" or \"rand\".");
6601  return false;
6602  }
6603  iseed = (uint64) ulseed;
6604  }
6605 
6606  if (seed != NULL)
6607  pg_log_info("setting random seed to %llu", (unsigned long long) iseed);
6608 
6609  random_seed = iseed;
6610 
6611  /* Initialize base_random_sequence using seed */
6612  pg_prng_seed(&base_random_sequence, (uint64) iseed);
6613 
6614  return true;
6615 }
6616 
6617 int
6618 main(int argc, char **argv)
6619 {
6620  static struct option long_options[] = {
6621  /* systematic long/short named options */
6622  {"builtin", required_argument, NULL, 'b'},
6623  {"client", required_argument, NULL, 'c'},
6624  {"connect", no_argument, NULL, 'C'},
6625  {"dbname", required_argument, NULL, 'd'},
6626  {"define", required_argument, NULL, 'D'},
6627  {"file", required_argument, NULL, 'f'},
6628  {"fillfactor", required_argument, NULL, 'F'},
6629  {"host", required_argument, NULL, 'h'},
6630  {"initialize", no_argument, NULL, 'i'},
6631  {"init-steps", required_argument, NULL, 'I'},
6632  {"jobs", required_argument, NULL, 'j'},
6633  {"log", no_argument, NULL, 'l'},
6634  {"latency-limit", required_argument, NULL, 'L'},
6635  {"no-vacuum", no_argument, NULL, 'n'},
6636  {"port", required_argument, NULL, 'p'},
6637  {"progress", required_argument, NULL, 'P'},
6638  {"protocol", required_argument, NULL, 'M'},
6639  {"quiet", no_argument, NULL, 'q'},
6640  {"report-per-command", no_argument, NULL, 'r'},
6641  {"rate", required_argument, NULL, 'R'},
6642  {"scale", required_argument, NULL, 's'},
6643  {"select-only", no_argument, NULL, 'S'},
6644  {"skip-some-updates", no_argument, NULL, 'N'},
6645  {"time", required_argument, NULL, 'T'},
6646  {"transactions", required_argument, NULL, 't'},
6647  {"username", required_argument, NULL, 'U'},
6648  {"vacuum-all", no_argument, NULL, 'v'},
6649  /* long-named only options */
6650  {"unlogged-tables", no_argument, NULL, 1},
6651  {"tablespace", required_argument, NULL, 2},
6652  {"index-tablespace", required_argument, NULL, 3},
6653  {"sampling-rate", required_argument, NULL, 4},
6654  {"aggregate-interval", required_argument, NULL, 5},
6655  {"progress-timestamp", no_argument, NULL, 6},
6656  {"log-prefix", required_argument, NULL, 7},
6657  {"foreign-keys", no_argument, NULL, 8},
6658  {"random-seed", required_argument, NULL, 9},
6659  {"show-script", required_argument, NULL, 10},
6660  {"partitions", required_argument, NULL, 11},
6661  {"partition-method", required_argument, NULL, 12},
6662  {"failures-detailed", no_argument, NULL, 13},
6663  {"max-tries", required_argument, NULL, 14},
6664  {"verbose-errors", no_argument, NULL, 15},
6665  {"exit-on-abort", no_argument, NULL, 16},
6666  {"debug", no_argument, NULL, 17},
6667  {NULL, 0, NULL, 0}
6668  };
6669 
6670  int c;
6671  bool is_init_mode = false; /* initialize mode? */
6672  char *initialize_steps = NULL;
6673  bool foreign_keys = false;
6674  bool is_no_vacuum = false;
6675  bool do_vacuum_accounts = false; /* vacuum accounts table? */
6676  int optindex;
6677  bool scale_given = false;
6678 
6679  bool benchmarking_option_set = false;
6680  bool initialization_option_set = false;
6681  bool internal_script_used = false;
6682 
6683  CState *state; /* status of clients */
6684  TState *threads; /* array of thread */
6685 
6687  start_time, /* start up time */
6688  bench_start = 0, /* first recorded benchmarking time */
6689  conn_total_duration; /* cumulated connection time in
6690  * threads */
6691  int64 latency_late = 0;
6692  StatsData stats;
6693  int weight;
6694 
6695  int i;
6696  int nclients_dealt;
6697 
6698 #ifdef HAVE_GETRLIMIT
6699  struct rlimit rlim;
6700 #endif
6701 
6702  PGconn *con;
6703  char *env;
6704 
6705  int exit_code = 0;
6706  struct timeval tv;
6707 
6708  /*
6709  * Record difference between Unix time and instr_time time. We'll use
6710  * this for logging and aggregation.
6711  */
6712  gettimeofday(&tv, NULL);
6713  epoch_shift = tv.tv_sec * INT64CONST(1000000) + tv.tv_usec - pg_time_now();
6714 
6715  pg_logging_init(argv[0]);
6716  progname = get_progname(argv[0]);
6717 
6718  if (argc > 1)
6719  {
6720  if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
6721  {
6722  usage();
6723  exit(0);
6724  }
6725  if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
6726  {
6727  puts("pgbench (PostgreSQL) " PG_VERSION);
6728  exit(0);
6729  }
6730  }
6731 
6732  state = (CState *) pg_malloc0(sizeof(CState));
6733 
6734  /* set random seed early, because it may be used while parsing scripts. */
6735  if (!set_random_seed(getenv("PGBENCH_RANDOM_SEED")))
6736  pg_fatal("error while setting random seed from PGBENCH_RANDOM_SEED environment variable");
6737 
6738  while ((c = getopt_long(argc, argv, "b:c:Cd:D:f:F:h:iI:j:lL:M:nNp:P:qrR:s:St:T:U:v", long_options, &optindex)) != -1)
6739  {
6740  char *script;
6741 
6742  switch (c)
6743  {
6744  case 'b':
6745  if (strcmp(optarg, "list") == 0)
6746  {
6748  exit(0);
6749  }
6750  weight = parseScriptWeight(optarg, &script);
6751  process_builtin(findBuiltin(script), weight);
6752  benchmarking_option_set = true;
6753  internal_script_used = true;
6754  break;
6755  case 'c':
6756  benchmarking_option_set = true;
6757  if (!option_parse_int(optarg, "-c/--clients", 1, INT_MAX,
6758  &nclients))
6759  {
6760  exit(1);
6761  }
6762 #ifdef HAVE_GETRLIMIT
6763  if (getrlimit(RLIMIT_NOFILE, &rlim) == -1)
6764  pg_fatal("getrlimit failed: %m");
6765  if (rlim.rlim_cur < nclients + 3)
6766  {
6767  pg_log_error("need at least %d open files, but system limit is %ld",
6768  nclients + 3, (long) rlim.rlim_cur);
6769  pg_log_error_hint("Reduce number of clients, or use limit/ulimit to increase the system limit.");
6770  exit(1);
6771  }
6772 #endif /* HAVE_GETRLIMIT */
6773  break;
6774  case 'C':
6775  benchmarking_option_set = true;
6776  is_connect = true;
6777  break;
6778  case 'd':
6779  dbName = pg_strdup(optarg);
6780  break;
6781  case 'D':
6782  {
6783  char *p;
6784 
6785  benchmarking_option_set = true;
6786 
6787  if ((p = strchr(optarg, '=')) == NULL || p == optarg || *(p + 1) == '\0')
6788  pg_fatal("invalid variable definition: \"%s\"", optarg);
6789 
6790  *p++ = '\0';
6791  if (!putVariable(&state[0].variables, "option", optarg, p))
6792  exit(1);
6793  }
6794  break;
6795  case 'f':
6796  weight = parseScriptWeight(optarg, &script);
6797  process_file(script, weight);
6798  benchmarking_option_set = true;
6799  break;
6800  case 'F':
6801  initialization_option_set = true;
6802  if (!option_parse_int(optarg, "-F/--fillfactor", 10, 100,
6803  &fillfactor))
6804  exit(1);
6805  break;
6806  case 'h':
6807  pghost = pg_strdup(optarg);
6808  break;
6809  case 'i':
6810  is_init_mode = true;
6811  break;
6812  case 'I':
6813  pg_free(initialize_steps);
6814  initialize_steps = pg_strdup(optarg);
6815  checkInitSteps(initialize_steps);
6816  initialization_option_set = true;
6817  break;
6818  case 'j': /* jobs */
6819  benchmarking_option_set = true;
6820  if (!option_parse_int(optarg, "-j/--jobs", 1, INT_MAX,
6821  &nthreads))
6822  {
6823  exit(1);
6824  }
6825  break;
6826  case 'l':
6827  benchmarking_option_set = true;
6828  use_log = true;
6829  break;
6830  case 'L':
6831  {
6832  double limit_ms = atof(optarg);
6833 
6834  if (limit_ms <= 0.0)
6835  pg_fatal("invalid latency limit: \"%s\"", optarg);
6836  benchmarking_option_set = true;
6837  latency_limit = (int64) (limit_ms * 1000);
6838  }
6839  break;
6840  case 'M':
6841  benchmarking_option_set = true;
6842  for (querymode = 0; querymode < NUM_QUERYMODE; querymode++)
6843  if (strcmp(optarg, QUERYMODE[querymode]) == 0)
6844  break;
6845  if (querymode >= NUM_QUERYMODE)
6846  pg_fatal("invalid query mode (-M): \"%s\"", optarg);
6847  break;
6848  case 'n':
6849  is_no_vacuum = true;
6850  break;
6851  case 'N':
6852  process_builtin(findBuiltin("simple-update"), 1);
6853  benchmarking_option_set = true;
6854  internal_script_used = true;
6855  break;
6856  case 'p':
6857  pgport = pg_strdup(optarg);
6858  break;
6859  case 'P':
6860  benchmarking_option_set = true;
6861  if (!option_parse_int(optarg, "-P/--progress", 1, INT_MAX,
6862  &progress))
6863  exit(1);
6864  break;
6865  case 'q':
6866  initialization_option_set = true;
6867  use_quiet = true;
6868  break;
6869  case 'r':
6870  benchmarking_option_set = true;
6871  report_per_command = true;
6872  break;
6873  case 'R':
6874  {
6875  /* get a double from the beginning of option value */
6876  double throttle_value = atof(optarg);
6877 
6878  benchmarking_option_set = true;
6879 
6880  if (throttle_value <= 0.0)
6881  pg_fatal("invalid rate limit: \"%s\"", optarg);
6882  /* Invert rate limit into per-transaction delay in usec */
6883  throttle_delay = 1000000.0 / throttle_value;
6884  }
6885  break;
6886  case 's':
6887  scale_given = true;
6888  if (!option_parse_int(optarg, "-s/--scale", 1, INT_MAX,
6889  &scale))
6890  exit(1);
6891  break;
6892  case 'S':
6893  process_builtin(findBuiltin("select-only"), 1);
6894  benchmarking_option_set = true;
6895  internal_script_used = true;
6896  break;
6897  case 't':
6898  benchmarking_option_set = true;
6899  if (!option_parse_int(optarg, "-t/--transactions", 1, INT_MAX,
6900  &nxacts))
6901  exit(1);
6902  break;
6903  case 'T':
6904  benchmarking_option_set = true;
6905  if (!option_parse_int(optarg, "-T/--time", 1, INT_MAX,
6906  &duration))
6907  exit(1);
6908  break;
6909  case 'U':
6911  break;
6912  case 'v':
6913  benchmarking_option_set = true;
6914  do_vacuum_accounts = true;
6915  break;
6916  case 1: /* unlogged-tables */
6917  initialization_option_set = true;
6918  unlogged_tables = true;
6919  break;
6920  case 2: /* tablespace */
6921  initialization_option_set = true;
6923  break;
6924  case 3: /* index-tablespace */
6925  initialization_option_set = true;
6927  break;
6928  case 4: /* sampling-rate */
6929  benchmarking_option_set = true;
6930  sample_rate = atof(optarg);
6931  if (sample_rate <= 0.0 || sample_rate > 1.0)
6932  pg_fatal("invalid sampling rate: \"%s\"", optarg);
6933  break;
6934  case 5: /* aggregate-interval */
6935  benchmarking_option_set = true;
6936  if (!option_parse_int(optarg, "--aggregate-interval", 1, INT_MAX,
6937  &agg_interval))
6938  exit(1);
6939  break;
6940  case 6: /* progress-timestamp */
6941  progress_timestamp = true;
6942  benchmarking_option_set = true;
6943  break;
6944  case 7: /* log-prefix */
6945  benchmarking_option_set = true;
6947  break;
6948  case 8: /* foreign-keys */
6949  initialization_option_set = true;
6950  foreign_keys = true;
6951  break;
6952  case 9: /* random-seed */
6953  benchmarking_option_set = true;
6954  if (!set_random_seed(optarg))
6955  pg_fatal("error while setting random seed from --random-seed option");
6956  break;
6957  case 10: /* list */
6958  {
6959  const BuiltinScript *s = findBuiltin(optarg);
6960 
6961  fprintf(stderr, "-- %s: %s\n%s\n", s->name, s->desc, s->script);
6962  exit(0);
6963  }
6964  break;
6965  case 11: /* partitions */
6966  initialization_option_set = true;
6967  if (!option_parse_int(optarg, "--partitions", 0, INT_MAX,
6968  &partitions))
6969  exit(1);
6970  break;
6971  case 12: /* partition-method */
6972  initialization_option_set = true;
6973  if (pg_strcasecmp(optarg, "range") == 0)
6975  else if (pg_strcasecmp(optarg, "hash") == 0)
6977  else
6978  pg_fatal("invalid partition method, expecting \"range\" or \"hash\", got: \"%s\"",
6979  optarg);
6980  break;
6981  case 13: /* failures-detailed */
6982  benchmarking_option_set = true;
6983  failures_detailed = true;
6984  break;
6985  case 14: /* max-tries */
6986  {
6987  int32 max_tries_arg = atoi(optarg);
6988 
6989  if (max_tries_arg < 0)
6990  pg_fatal("invalid number of maximum tries: \"%s\"", optarg);
6991 
6992  benchmarking_option_set = true;
6993  max_tries = (uint32) max_tries_arg;
6994  }
6995  break;
6996  case 15: /* verbose-errors */
6997  benchmarking_option_set = true;
6998  verbose_errors = true;
6999  break;
7000  case 16: /* exit-on-abort */
7001  benchmarking_option_set = true;
7002  exit_on_abort = true;
7003  break;
7004  case 17: /* debug */
7006  break;
7007  default:
7008  /* getopt_long already emitted a complaint */
7009  pg_log_error_hint("Try \"%s --help\" for more information.", progname);
7010  exit(1);
7011  }
7012  }
7013 
7014  /* set default script if none */
7015  if (num_scripts == 0 && !is_init_mode)
7016  {
7017  process_builtin(findBuiltin("tpcb-like"), 1);
7018  benchmarking_option_set = true;
7019  internal_script_used = true;
7020  }
7021 
7022  /* complete SQL command initialization and compute total weight */
7023  for (i = 0; i < num_scripts; i++)
7024  {
7025  Command **commands = sql_script[i].commands;
7026 
7027  for (int j = 0; commands[j] != NULL; j++)
7028  if (commands[j]->type == SQL_COMMAND)
7029  postprocess_sql_command(commands[j]);
7030 
7031  /* cannot overflow: weight is 32b, total_weight 64b */
7033  }
7034 
7035  if (total_weight == 0 && !is_init_mode)
7036  pg_fatal("total script weight must not be zero");
7037 
7038  /* show per script stats if several scripts are used */
7039  if (num_scripts > 1)
7040  per_script_stats = true;
7041 
7042  /*
7043  * Don't need more threads than there are clients. (This is not merely an
7044  * optimization; throttle_delay is calculated incorrectly below if some
7045  * threads have no clients assigned to them.)
7046  */
7047  if (nthreads > nclients)
7048  nthreads = nclients;
7049 
7050  /*
7051  * Convert throttle_delay to a per-thread delay time. Note that this
7052  * might be a fractional number of usec, but that's OK, since it's just
7053  * the center of a Poisson distribution of delays.
7054  */
7056 
7057  if (dbName == NULL)
7058  {
7059  if (argc > optind)
7060  dbName = argv[optind++];
7061  else
7062  {
7063  if ((env = getenv("PGDATABASE")) != NULL && *env != '\0')
7064  dbName = env;
7065  else if ((env = getenv("PGUSER")) != NULL && *env != '\0')
7066  dbName = env;
7067  else
7069  }
7070  }
7071 
7072  if (optind < argc)
7073  {
7074  pg_log_error("too many command-line arguments (first is \"%s\")",
7075  argv[optind]);
7076  pg_log_error_hint("Try \"%s --help\" for more information.", progname);
7077  exit(1);
7078  }
7079 
7080  if (is_init_mode)
7081  {
7082  if (benchmarking_option_set)
7083  pg_fatal("some of the specified options cannot be used in initialization (-i) mode");
7084 
7085  if (partitions == 0 && partition_method != PART_NONE)
7086  pg_fatal("--partition-method requires greater than zero --partitions");
7087 
7088  /* set default method */
7089  if (partitions > 0 && partition_method == PART_NONE)
7091 
7092  if (initialize_steps == NULL)
7093  initialize_steps = pg_strdup(DEFAULT_INIT_STEPS);
7094 
7095  if (is_no_vacuum)
7096  {
7097  /* Remove any vacuum step in initialize_steps */
7098  char *p;
7099 
7100  while ((p = strchr(initialize_steps, 'v')) != NULL)
7101  *p = ' ';
7102  }
7103 
7104  if (foreign_keys)
7105  {
7106  /* Add 'f' to end of initialize_steps, if not already there */
7107  if (strchr(initialize_steps, 'f') == NULL)
7108  {
7109  initialize_steps = (char *)
7110  pg_realloc(initialize_steps,
7111  strlen(initialize_steps) + 2);
7112  strcat(initialize_steps, "f");
7113  }
7114  }
7115 
7116  runInitSteps(initialize_steps);
7117  exit(0);
7118  }
7119  else
7120  {
7121  if (initialization_option_set)
7122  pg_fatal("some of the specified options cannot be used in benchmarking mode");
7123  }
7124 
7125  if (nxacts > 0 && duration > 0)
7126  pg_fatal("specify either a number of transactions (-t) or a duration (-T), not both");
7127 
7128  /* Use DEFAULT_NXACTS if neither nxacts nor duration is specified. */
7129  if (nxacts <= 0 && duration <= 0)
7131 
7132  /* --sampling-rate may be used only with -l */
7133  if (sample_rate > 0.0 && !use_log)
7134  pg_fatal("log sampling (--sampling-rate) is allowed only when logging transactions (-l)");
7135 
7136  /* --sampling-rate may not be used with --aggregate-interval */
7137  if (sample_rate > 0.0 && agg_interval > 0)
7138  pg_fatal("log sampling (--sampling-rate) and aggregation (--aggregate-interval) cannot be used at the same time");
7139 
7140  if (agg_interval > 0 && !use_log)
7141  pg_fatal("log aggregation is allowed only when actually logging transactions");
7142 
7143  if (!use_log && logfile_prefix)
7144  pg_fatal("log file prefix (--log-prefix) is allowed only when logging transactions (-l)");
7145 
7146  if (duration > 0 && agg_interval > duration)
7147  pg_fatal("number of seconds for aggregation (%d) must not be higher than test duration (%d)", agg_interval, duration);
7148 
7149  if (duration > 0 && agg_interval > 0 && duration % agg_interval != 0)
7150  pg_fatal("duration (%d) must be a multiple of aggregation interval (%d)", duration, agg_interval);
7151 
7152  if (progress_timestamp && progress == 0)
7153  pg_fatal("--progress-timestamp is allowed only under --progress");
7154 
7155  if (!max_tries)
7156  {
7157  if (!latency_limit && duration <= 0)
7158  pg_fatal("an unlimited number of transaction tries can only be used with --latency-limit or a duration (-T)");
7159  }
7160 
7161  /*
7162  * save main process id in the global variable because process id will be
7163  * changed after fork.
7164  */
7165  main_pid = (int) getpid();
7166 
7167  if (nclients > 1)
7168  {
7169  state = (CState *) pg_realloc(state, sizeof(CState) * nclients);
7170  memset(state + 1, 0, sizeof(CState) * (nclients - 1));
7171 
7172  /* copy any -D switch values to all clients */
7173  for (i = 1; i < nclients; i++)
7174  {
7175  int j;
7176 
7177  state[i].id = i;
7178  for (j = 0; j < state[0].variables.nvars; j++)
7179  {
7180  Variable *var = &state[0].variables.vars[j];
7181 
7182  if (var->value.type != PGBT_NO_VALUE)
7183  {
7184  if (!putVariableValue(&state[i].variables, "startup",
7185  var->name, &var->value))
7186  exit(1);
7187  }
7188  else
7189  {
7190  if (!putVariable(&state[i].variables, "startup",
7191  var->name, var->svalue))
7192  exit(1);
7193  }
7194  }
7195  }
7196  }
7197 
7198  /* other CState initializations */
7199  for (i = 0; i < nclients; i++)
7200  {
7201  state[i].cstack = conditional_stack_create();
7202  initRandomState(&state[i].cs_func_rs);
7203  }
7204 
7205  /* opening connection... */
7206  con = doConnect();
7207  if (con == NULL)
7208  pg_fatal("could not create connection for setup");
7209 
7210  /* report pgbench and server versions */
7211  printVersion(con);
7212 
7213  pg_log_debug("pghost: %s pgport: %s nclients: %d %s: %d dbName: %s",
7214  PQhost(con), PQport(con), nclients,
7215  duration <= 0 ? "nxacts" : "duration",
7216  duration <= 0 ? nxacts : duration, PQdb(con));
7217 
7218  if (internal_script_used)
7219  GetTableInfo(con, scale_given);
7220 
7221  /*
7222  * :scale variables normally get -s or database scale, but don't override
7223  * an explicit -D switch
7224  */
7225  if (lookupVariable(&state[0].variables, "scale") == NULL)
7226  {
7227  for (i = 0; i < nclients; i++)
7228  {
7229  if (!putVariableInt(&state[i].variables, "startup", "scale", scale))
7230  exit(1);
7231  }
7232  }
7233 
7234  /*
7235  * Define a :client_id variable that is unique per connection. But don't
7236  * override an explicit -D switch.
7237  */
7238  if (lookupVariable(&state[0].variables, "client_id") == NULL)
7239  {
7240  for (i = 0; i < nclients; i++)
7241  if (!putVariableInt(&state[i].variables, "startup", "client_id", i))
7242  exit(1);
7243  }
7244 
7245  /* set default seed for hash functions */
7246  if (lookupVariable(&state[0].variables, "default_seed") == NULL)
7247  {
7248  uint64 seed = pg_prng_uint64(&base_random_sequence);
7249 
7250  for (i = 0; i < nclients; i++)
7251  if (!putVariableInt(&state[i].variables, "startup", "default_seed",
7252  (int64) seed))
7253  exit(1);
7254  }
7255 
7256  /* set random seed unless overwritten */
7257  if (lookupVariable(&state[0].variables, "random_seed") == NULL)
7258  {
7259  for (i = 0; i < nclients; i++)
7260  if (!putVariableInt(&state[i].variables, "startup", "random_seed",
7261  random_seed))
7262  exit(1);
7263  }
7264 
7265  if (!is_no_vacuum)
7266  {
7267  fprintf(stderr, "starting vacuum...");
7268  tryExecuteStatement(con, "vacuum pgbench_branches");
7269  tryExecuteStatement(con, "vacuum pgbench_tellers");
7270  tryExecuteStatement(con, "truncate pgbench_history");
7271  fprintf(stderr, "end.\n");
7272 
7273  if (do_vacuum_accounts)
7274  {
7275  fprintf(stderr, "starting vacuum pgbench_accounts...");
7276  tryExecuteStatement(con, "vacuum analyze pgbench_accounts");
7277  fprintf(stderr, "end.\n");
7278  }
7279  }
7280  PQfinish(con);
7281 
7282  /* set up thread data structures */
7283  threads = (TState *) pg_malloc(sizeof(TState) * nthreads);
7284  nclients_dealt = 0;
7285 
7286  for (i = 0; i < nthreads; i++)
7287  {
7288  TState *thread = &threads[i];
7289 
7290  thread->tid = i;
7291  thread->state = &state[nclients_dealt];
7292  thread->nstate =
7293  (nclients - nclients_dealt + nthreads - i - 1) / (nthreads - i);
7294  initRandomState(&thread->ts_choose_rs);
7295  initRandomState(&thread->ts_throttle_rs);
7296  initRandomState(&thread->ts_sample_rs);
7297  thread->logfile = NULL; /* filled in later */
7298  thread->latency_late = 0;
7299  initStats(&thread->stats, 0);
7300 
7301  nclients_dealt += thread->nstate;
7302  }
7303 
7304  /* all clients must be assigned to a thread */
7305  Assert(nclients_dealt == nclients);
7306 
7307  /* get start up time for the whole computation */
7308  start_time = pg_time_now();
7309 
7310  /* set alarm if duration is specified. */
7311  if (duration > 0)
7312  setalarm(duration);
7313 
7315  if (errno != 0)
7316  pg_fatal("could not initialize barrier: %m");
7317 
7318  /* start all threads but thread 0 which is executed directly later */
7319  for (i = 1; i < nthreads; i++)
7320  {
7321  TState *thread = &threads[i];
7322 
7323  thread->create_time = pg_time_now();
7324  errno = THREAD_CREATE(&thread->thread, threadRun, thread);
7325 
7326  if (errno != 0)
7327  pg_fatal("could not create thread: %m");
7328  }
7329 
7330  /* compute when to stop */
7331  threads[0].create_time = pg_time_now();
7332  if (duration > 0)
7333  end_time = threads[0].create_time + (int64) 1000000 * duration;
7334 
7335  /* run thread 0 directly */
7336  (void) threadRun(&threads[0]);
7337 
7338  /* wait for other threads and accumulate results */
7339  initStats(&stats, 0);
7340  conn_total_duration = 0;
7341 
7342  for (i = 0; i < nthreads; i++)
7343  {
7344  TState *thread = &threads[i];
7345 
7346  if (i > 0)
7347  THREAD_JOIN(thread->thread);
7348 
7349  for (int j = 0; j < thread->nstate; j++)
7350  if (thread->state[j].state != CSTATE_FINISHED)
7351  exit_code = 2;
7352 
7353  /* aggregate thread level stats */
7354  mergeSimpleStats(&stats.latency, &thread->stats.latency);
7355  mergeSimpleStats(&stats.lag, &thread->stats.lag);
7356  stats.cnt += thread->stats.cnt;
7357  stats.skipped += thread->stats.skipped;
7358  stats.retries += thread->stats.retries;
7359  stats.retried += thread->stats.retried;
7361  stats.deadlock_failures += thread->stats.deadlock_failures;
7362  latency_late += thread->latency_late;
7363  conn_total_duration += thread->conn_duration;
7364 
7365  /* first recorded benchmarking start time */
7366  if (bench_start == 0 || thread->bench_start < bench_start)
7367  bench_start = thread->bench_start;
7368  }
7369 
7370  /*
7371  * All connections should be already closed in threadRun(), so this
7372  * disconnect_all() will be a no-op, but clean up the connections just to
7373  * be sure. We don't need to measure the disconnection delays here.
7374  */
7376 
7377  /*
7378  * Beware that performance of short benchmarks with many threads and
7379  * possibly long transactions can be deceptive because threads do not
7380  * start and finish at the exact same time. The total duration computed
7381  * here encompasses all transactions so that tps shown is somehow slightly
7382  * underestimated.
7383  */
7384  printResults(&stats, pg_time_now() - bench_start, conn_total_duration,
7385  bench_start - start_time, latency_late);
7386 
7388 
7389  if (exit_code != 0)
7390  pg_log_error("Run was aborted; the above results are incomplete.");
7391 
7392  return exit_code;
7393 }
7394 
7396 threadRun(void *arg)
7397 {
7398  TState *thread = (TState *) arg;
7399  CState *state = thread->state;
7401  int nstate = thread->nstate;
7402  int remains = nstate; /* number of remaining clients */
7403  socket_set *sockets = alloc_socket_set(nstate);
7404  int64 thread_start,
7405  last_report,
7406  next_report;
7407  StatsData last,
7408  aggs;
7409 
7410  /* open log file if requested */
7411  if (use_log)
7412  {
7413  char logpath[MAXPGPATH];
7414  char *prefix = logfile_prefix ? logfile_prefix : "pgbench_log";
7415 
7416  if (thread->tid == 0)
7417  snprintf(logpath, sizeof(logpath), "%s.%d", prefix, main_pid);
7418  else
7419  snprintf(logpath, sizeof(logpath), "%s.%d.%d", prefix, main_pid, thread->tid);
7420 
7421  thread->logfile = fopen(logpath, "w");
7422 
7423  if (thread->logfile == NULL)
7424  pg_fatal("could not open logfile \"%s\": %m", logpath);
7425  }
7426 
7427  /* explicitly initialize the state machines */
7428  for (int i = 0; i < nstate; i++)
7430 
7431  /* READY */
7433 
7434  thread_start = pg_time_now();
7435  thread->started_time = thread_start;
7436  thread->conn_duration = 0;
7437  last_report = thread_start;
7438  next_report = last_report + (int64) 1000000 * progress;
7439 
7440  /* STEADY */
7441  if (!is_connect)
7442  {
7443  /* make connections to the database before starting */
7444  for (int i = 0; i < nstate; i++)
7445  {
7446  if ((state[i].con = doConnect()) == NULL)
7447  {
7448  /* coldly abort on initial connection failure */
7449  pg_fatal("could not create connection for client %d",
7450  state[i].id);
7451  }
7452  }
7453  }
7454 
7455  /* GO */
7457 
7458  start = pg_time_now();
7459  thread->bench_start = start;
7460  thread->throttle_trigger = start;
7461 
7462  /*
7463  * The log format currently has Unix epoch timestamps with whole numbers
7464  * of seconds. Round the first aggregate's start time down to the nearest
7465  * Unix epoch second (the very first aggregate might really have started a
7466  * fraction of a second later, but later aggregates are measured from the
7467  * whole number time that is actually logged).
7468  */
7469  initStats(&aggs, (start + epoch_shift) / 1000000 * 1000000);
7470  last = aggs;
7471 
7472  /* loop till all clients have terminated */
7473  while (remains > 0)
7474  {
7475  int nsocks; /* number of sockets to be waited for */
7476  pg_time_usec_t min_usec;
7477  pg_time_usec_t now = 0; /* set this only if needed */
7478 
7479  /*
7480  * identify which client sockets should be checked for input, and
7481  * compute the nearest time (if any) at which we need to wake up.
7482  */
7483  clear_socket_set(sockets);
7484  nsocks = 0;
7485  min_usec = PG_INT64_MAX;
7486  for (int i = 0; i < nstate; i++)
7487  {
7488  CState *st = &state[i];
7489 
7490  if (st->state == CSTATE_SLEEP || st->state == CSTATE_THROTTLE)
7491  {
7492  /* a nap from the script, or under throttling */
7493  pg_time_usec_t this_usec;
7494 
7495  /* get current time if needed */
7497 
7498  /* min_usec should be the minimum delay across all clients */
7499  this_usec = (st->state == CSTATE_SLEEP ?
7500  st->sleep_until : st->txn_scheduled) - now;
7501  if (min_usec > this_usec)
7502  min_usec = this_usec;
7503  }
7504  else if (st->state == CSTATE_WAIT_RESULT ||
7506  {
7507  /*
7508  * waiting for result from server - nothing to do unless the
7509  * socket is readable
7510  */
7511  int sock = PQsocket(st->con);
7512 
7513  if (sock < 0)
7514  {
7515  pg_log_error("invalid socket: %s", PQerrorMessage(st->con));
7516  goto done;
7517  }
7518 
7519  add_socket_to_set(sockets, sock, nsocks++);
7520  }
7521  else if (st->state != CSTATE_ABORTED &&
7522  st->state != CSTATE_FINISHED)
7523  {
7524  /*
7525  * This client thread is ready to do something, so we don't
7526  * want to wait. No need to examine additional clients.
7527  */
7528  min_usec = 0;
7529  break;
7530  }
7531  }
7532 
7533  /* also wake up to print the next progress report on time */
7534  if (progress && min_usec > 0 && thread->tid == 0)
7535  {
7537 
7538  if (now >= next_report)
7539  min_usec = 0;
7540  else if ((next_report - now) < min_usec)
7541  min_usec = next_report - now;
7542  }
7543 
7544  /*
7545  * If no clients are ready to execute actions, sleep until we receive
7546  * data on some client socket or the timeout (if any) elapses.
7547  */
7548  if (min_usec > 0)
7549  {
7550  int rc = 0;
7551 
7552  if (min_usec != PG_INT64_MAX)
7553  {
7554  if (nsocks > 0)
7555  {
7556  rc = wait_on_socket_set(sockets, min_usec);
7557  }
7558  else /* nothing active, simple sleep */
7559  {
7560  pg_usleep(min_usec);
7561  }
7562  }
7563  else /* no explicit delay, wait without timeout */
7564  {
7565  rc = wait_on_socket_set(sockets, 0);
7566  }
7567 
7568  if (rc < 0)
7569  {
7570  if (errno == EINTR)
7571  {
7572  /* On EINTR, go back to top of loop */
7573  continue;
7574  }
7575  /* must be something wrong */
7576  pg_log_error("%s() failed: %m", SOCKET_WAIT_METHOD);
7577  goto done;
7578  }
7579  }
7580  else
7581  {
7582  /* min_usec <= 0, i.e. something needs to be executed now */
7583 
7584  /* If we didn't wait, don't try to read any data */
7585  clear_socket_set(sockets);
7586  }
7587 
7588  /* ok, advance the state machine of each connection */
7589  nsocks = 0;
7590  for (int i = 0; i < nstate; i++)
7591  {
7592  CState *st = &state[i];
7593 
7594  if (st->state == CSTATE_WAIT_RESULT ||
7596  {
7597  /* don't call advanceConnectionState unless data is available */
7598  int sock = PQsocket(st->con);
7599 
7600  if (sock < 0)
7601  {
7602  pg_log_error("invalid socket: %s", PQerrorMessage(st->con));
7603  goto done;
7604  }
7605 
7606  if (!socket_has_input(sockets, sock, nsocks++))
7607  continue;
7608  }
7609  else if (st->state == CSTATE_FINISHED ||
7610  st->state == CSTATE_ABORTED)
7611  {
7612  /* this client is done, no need to consider it anymore */
7613  continue;
7614  }
7615 
7616  advanceConnectionState(thread, st, &aggs);
7617 
7618  /*
7619  * If --exit-on-abort is used, the program is going to exit when
7620  * any client is aborted.
7621  */
7622  if (exit_on_abort && st->state == CSTATE_ABORTED)
7623  goto done;
7624 
7625  /*
7626  * If advanceConnectionState changed client to finished state,
7627  * that's one fewer client that remains.
7628  */
7629  else if (st->state == CSTATE_FINISHED ||
7630  st->state == CSTATE_ABORTED)
7631  remains--;
7632  }
7633 
7634  /* progress report is made by thread 0 for all threads */
7635  if (progress && thread->tid == 0)
7636  {
7637  pg_time_usec_t now2 = pg_time_now();
7638 
7639  if (now2 >= next_report)
7640  {
7641  /*
7642  * Horrible hack: this relies on the thread pointer we are
7643  * passed to be equivalent to threads[0], that is the first
7644  * entry of the threads array. That is why this MUST be done
7645  * by thread 0 and not any other.
7646  */
7647  printProgressReport(thread, thread_start, now2,
7648  &last, &last_report);
7649 
7650  /*
7651  * Ensure that the next report is in the future, in case
7652  * pgbench/postgres got stuck somewhere.
7653  */
7654  do
7655  {
7656  next_report += (int64) 1000000 * progress;
7657  } while (now2 >= next_report);
7658  }
7659  }
7660  }
7661 
7662 done:
7663  if (exit_on_abort)
7664  {
7665  /*
7666  * Abort if any client is not finished, meaning some error occurred.
7667  */
7668  for (int i = 0; i < nstate; i++)
7669  {
7670  if (state[i].state != CSTATE_FINISHED)
7671  {
7672  pg_log_error("Run was aborted due to an error in thread %d",
7673  thread->tid);
7674  exit(2);
7675  }
7676  }
7677  }
7678 
7679  disconnect_all(state, nstate);
7680 
7681  if (thread->logfile)
7682  {
7683  if (agg_interval > 0)
7684  {
7685  /* log aggregated but not yet reported transactions */
7686  doLog(thread, state, &aggs, false, 0, 0);
7687  }
7688  fclose(thread->logfile);
7689  thread->logfile = NULL;
7690  }
7691  free_socket_set(sockets);
7693 }
7694 
7695 static void
7696 finishCon(CState *st)
7697 {
7698  if (st->con != NULL)
7699  {
7700  PQfinish(st->con);
7701  st->con = NULL;
7702  }
7703 }
7704 
7705 /*
7706  * Support for duration option: set timer_exceeded after so many seconds.
7707  */
7708 
7709 #ifndef WIN32
7710 
7711 static void
7713 {
7714  timer_exceeded = true;
7715 }
7716 
7717 static void
7718 setalarm(int seconds)
7719 {
7721  alarm(seconds);
7722 }
7723 
7724 #else /* WIN32 */
7725 
7726 static VOID CALLBACK
7727 win32_timer_callback(PVOID lpParameter, BOOLEAN TimerOrWaitFired)
7728 {
7729  timer_exceeded = true;
7730 }
7731 
7732 static void
7733 setalarm(int seconds)
7734 {
7735  HANDLE queue;
7736  HANDLE timer;
7737 
7738  /* This function will be called at most once, so we can cheat a bit. */
7739  queue = CreateTimerQueue();
7740  if (seconds > ((DWORD) -1) / 1000 ||
7741  !CreateTimerQueueTimer(&timer, queue,
7742  win32_timer_callback, NULL, seconds * 1000, 0,
7743  WT_EXECUTEINTIMERTHREAD | WT_EXECUTEONLYONCE))
7744  pg_fatal("failed to set timer");
7745 }
7746 
7747 #endif /* WIN32 */
7748 
7749 
7750 /*
7751  * These functions provide an abstraction layer that hides the syscall
7752  * we use to wait for input on a set of sockets.
7753  *
7754  * Currently there are two implementations, based on ppoll(2) and select(2).
7755  * ppoll() is preferred where available due to its typically higher ceiling
7756  * on the number of usable sockets. We do not use the more-widely-available
7757  * poll(2) because it only offers millisecond timeout resolution, which could
7758  * be problematic with high --rate settings.
7759  *
7760  * Function APIs:
7761  *
7762  * alloc_socket_set: allocate an empty socket set with room for up to
7763  * "count" sockets.
7764  *
7765  * free_socket_set: deallocate a socket set.
7766  *
7767  * clear_socket_set: reset a socket set to empty.
7768  *
7769  * add_socket_to_set: add socket with indicated FD to slot "idx" in the
7770  * socket set. Slots must be filled in order, starting with 0.
7771  *
7772  * wait_on_socket_set: wait for input on any socket in set, or for timeout
7773  * to expire. timeout is measured in microseconds; 0 means wait forever.
7774  * Returns result code of underlying syscall (>=0 if OK, else see errno).
7775  *
7776  * socket_has_input: after waiting, call this to see if given socket has
7777  * input. fd and idx parameters should match some previous call to
7778  * add_socket_to_set.
7779  *
7780  * Note that wait_on_socket_set destructively modifies the state of the
7781  * socket set. After checking for input, caller must apply clear_socket_set
7782  * and add_socket_to_set again before waiting again.
7783  */
7784 
7785 #ifdef POLL_USING_PPOLL
7786 
7787 static socket_set *
7788 alloc_socket_set(int count)
7789 {
7790  socket_set *sa;
7791 
7792  sa = (socket_set *) pg_malloc0(offsetof(socket_set, pollfds) +
7793  sizeof(struct pollfd) * count);
7794  sa->maxfds = count;
7795  sa->curfds = 0;
7796  return sa;
7797 }
7798 
7799 static void
7801 {
7802  pg_free(sa);
7803 }
7804 
7805 static void
7807 {
7808  sa->curfds = 0;
7809 }
7810 
7811 static void
7812 add_socket_to_set(socket_set *sa, int fd, int idx)
7813 {
7814  Assert(idx < sa->maxfds && idx == sa->curfds);
7815  sa->pollfds[idx].fd = fd;
7816  sa->pollfds[idx].events = POLLIN;
7817  sa->pollfds[idx].revents = 0;
7818  sa->curfds++;
7819 }
7820 
7821 static int
7822 wait_on_socket_set(socket_set *sa, int64 usecs)
7823 {
7824  if (usecs > 0)
7825  {
7826  struct timespec timeout;
7827 
7828  timeout.tv_sec = usecs / 1000000;
7829  timeout.tv_nsec = (usecs % 1000000) * 1000;
7830  return ppoll(sa->pollfds, sa->curfds, &timeout, NULL);
7831  }
7832  else
7833  {
7834  return ppoll(sa->pollfds, sa->curfds, NULL, NULL);
7835  }
7836 }
7837 
7838 static bool
7839 socket_has_input(socket_set *sa, int fd, int idx)
7840 {
7841  /*
7842  * In some cases, threadRun will apply clear_socket_set and then try to
7843  * apply socket_has_input anyway with arguments that it used before that,
7844  * or might've used before that except that it exited its setup loop
7845  * early. Hence, if the socket set is empty, silently return false
7846  * regardless of the parameters. If it's not empty, we can Assert that
7847  * the parameters match a previous call.
7848  */
7849  if (sa->curfds == 0)
7850  return false;
7851 
7852  Assert(idx < sa->curfds && sa->pollfds[idx].fd == fd);
7853  return (sa->pollfds[idx].revents & POLLIN) != 0;
7854 }
7855 
7856 #endif /* POLL_USING_PPOLL */
7857 
7858 #ifdef POLL_USING_SELECT
7859 
7860 static socket_set *
7861 alloc_socket_set(int count)
7862 {
7863  return (socket_set *) pg_malloc0(sizeof(socket_set));
7864 }
7865 
7866 static void
7868 {
7869  pg_free(sa);
7870 }
7871 
7872 static void
7874 {
7875  FD_ZERO(&sa->fds);
7876  sa->maxfd = -1;
7877 }
7878 
7879 static void
7880 add_socket_to_set(socket_set *sa, int fd, int idx)
7881 {
7882  /* See connect_slot() for background on this code. */
7883 #ifdef WIN32
7884  if (sa->fds.fd_count + 1 >= FD_SETSIZE)
7885  {
7886  pg_log_error("too many concurrent database clients for this platform: %d",
7887  sa->fds.fd_count + 1);
7888  exit(1);
7889  }
7890 #else
7891  if (fd < 0 || fd >= FD_SETSIZE)
7892  {
7893  pg_log_error("socket file descriptor out of range for select(): %d",
7894  fd);
7895  pg_log_error_hint("Try fewer concurrent database clients.");
7896  exit(1);
7897  }
7898 #endif
7899  FD_SET(fd, &sa->fds);
7900  if (fd > sa->maxfd)
7901  sa->maxfd = fd;
7902 }
7903 
7904 static int
7905 wait_on_socket_set(socket_set *sa, int64 usecs)
7906 {
7907  if (usecs > 0)
7908  {
7909  struct timeval timeout;
7910 
7911  timeout.tv_sec = usecs / 1000000;
7912  timeout.tv_usec = usecs % 1000000;
7913  return select(sa->maxfd + 1, &sa->fds, NULL, NULL, &timeout);
7914  }
7915  else
7916  {
7917  return select(sa->maxfd + 1, &sa->fds, NULL, NULL, NULL);
7918  }
7919 }
7920 
7921 static bool
7922 socket_has_input(socket_set *sa, int fd, int idx)
7923 {
7924  return (FD_ISSET(fd, &sa->fds) != 0);
7925 }
7926 
7927 #endif /* POLL_USING_SELECT */
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:259
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1619
static int32 next
Definition: blutils.c:221
static Datum values[MAXATTR]
Definition: bootstrap.c:150
unsigned int uint32
Definition: c.h:506
signed char int8
Definition: c.h:492
#define Min(x, y)
Definition: c.h:1004
#define IS_HIGHBIT_SET(ch)
Definition: c.h:1155
signed int int32
Definition: c.h:494
#define Max(x, y)
Definition: c.h:998
#define INT64_FORMAT
Definition: c.h:548
#define SIGNAL_ARGS
Definition: c.h:1345
#define Assert(condition)
Definition: c.h:858
#define FLEXIBLE_ARRAY_MEMBER
Definition: c.h:398
#define FLOAT8_FITS_IN_INT64(num)
Definition: c.h:1092
#define CppAsString2(x)
Definition: c.h:327
#define PG_INT64_MAX
Definition: c.h:592
#define PG_INT64_MIN
Definition: c.h:591
#define unlikely(x)
Definition: c.h:311
#define lengthof(array)
Definition: c.h:788
volatile sig_atomic_t CancelRequested
Definition: cancel.c:59
void ResetCancelConn(void)
Definition: cancel.c:107
void SetCancelConn(PGconn *conn)
Definition: cancel.c:77
void setup_cancel_handler(void(*query_cancel_callback)(void))
Definition: cancel.c:183
ifState conditional_stack_peek(ConditionalStack cstack)
Definition: conditional.c:106
void conditional_stack_push(ConditionalStack cstack, ifState new_state)
Definition: conditional.c:53
ConditionalStack conditional_stack_create(void)
Definition: conditional.c:18
bool conditional_stack_pop(ConditionalStack cstack)
Definition: conditional.c:69
void conditional_stack_destroy(ConditionalStack cstack)
Definition: conditional.c:43
bool conditional_active(ConditionalStack cstack)
Definition: conditional.c:140
void conditional_stack_reset(ConditionalStack cstack)
Definition: conditional.c:30
bool conditional_stack_poke(ConditionalStack cstack, ifState new_state)
Definition: conditional.c:118
bool conditional_stack_empty(ConditionalStack cstack)
Definition: conditional.c:130
@ IFSTATE_FALSE
Definition: conditional.h:34
@ IFSTATE_ELSE_TRUE
Definition: conditional.h:40
@ IFSTATE_IGNORED
Definition: conditional.h:37
@ IFSTATE_TRUE
Definition: conditional.h:32
@ IFSTATE_NONE
Definition: conditional.h:31
@ IFSTATE_ELSE_FALSE
Definition: conditional.h:42
struct cursor * cur
Definition: ecpg.c:28
#define _(x)
Definition: elog.c:90
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:7136
int PQserverVersion(const PGconn *conn)
Definition: fe-connect.c:7161
char * PQhost(const PGconn *conn)
Definition: fe-connect.c:7050
PGconn * PQconnectdbParams(const char *const *keywords, const char *const *values, int expand_dbname)
Definition: fe-connect.c:689
char * PQdb(const PGconn *conn)
Definition: fe-connect.c:7017
PGTransactionStatusType PQtransactionStatus(const PGconn *conn)
Definition: fe-connect.c:7126
int PQconnectionNeedsPassword(const PGconn *conn)
Definition: fe-connect.c:7222
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:7171
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:7118
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4892
char * PQport(const PGconn *conn)
Definition: fe-connect.c:7086
PGpipelineStatus PQpipelineStatus(const PGconn *conn)
Definition: fe-connect.c:7213
int PQsocket(const PGconn *conn)
Definition: fe-connect.c:7197
int PQsendQueryParams(PGconn *conn, const char *command, int nParams, const Oid *paramTypes, const char *const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat)
Definition: fe-exec.c:1492
void PQfreemem(void *ptr)
Definition: fe-exec.c:4032
PGresult * PQprepare(PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes)
Definition: fe-exec.c:2306
int PQexitPipelineMode(PGconn *conn)
Definition: fe-exec.c:3073
char * PQescapeIdentifier(PGconn *conn, const char *str, size_t len)
Definition: fe-exec.c:4310
int PQenterPipelineMode(PGconn *conn)
Definition: fe-exec.c:3042
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3411
int PQendcopy(PGconn *conn)
Definition: fe-exec.c:2949
int PQsendPipelineSync(PGconn *conn)
Definition: fe-exec.c:3282
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3481
int PQputline(PGconn *conn, const char *string)
Definition: fe-exec.c:2918
char * PQfname(const PGresult *res, int field_num)
Definition: fe-exec.c:3567
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:2262
int PQconsumeInput(PGconn *conn)
Definition: fe-exec.c:1984
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3876
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3901
int PQsendQuery(PGconn *conn, const char *query)
Definition: fe-exec.c:1416
int PQpipelineSync(PGconn *conn)
Definition: fe-exec.c:3272
int PQisBusy(PGconn *conn)
Definition: fe-exec.c:2031
int PQsendQueryPrepared(PGconn *conn, const char *stmtName, int nParams, const char *const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat)
Definition: fe-exec.c:1633
char * PQresultErrorField(const PGresult *res, int fieldcode)
Definition: fe-exec.c:3466
int PQnfields(const PGresult *res)
Definition: fe-exec.c:3489
PGresult * PQgetResult(PGconn *conn)
Definition: fe-exec.c:2062
void * pg_realloc(void *ptr, size_t size)
Definition: fe_memutils.c:65
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
void pg_free(void *ptr)
Definition: fe_memutils.c:105
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex)
Definition: getopt_long.c:60
#define no_argument
Definition: getopt_long.h:24
#define required_argument
Definition: getopt_long.h:25
return str start
const char * str
#define free(a)
Definition: header.h:65
static const FormData_pg_attribute a1
Definition: heap.c:142
static const FormData_pg_attribute a2
Definition: heap.c:156
struct parser_state ps
long val
Definition: informix.c:670
static struct @155 value
#define INSTR_TIME_SET_CURRENT(t)
Definition: instr_time.h:122
#define INSTR_TIME_GET_MICROSEC(t)
Definition: instr_time.h:194
static bool pg_mul_s64_overflow(int64 a, int64 b, int64 *result)
Definition: int.h:219
static bool pg_sub_s64_overflow(int64 a, int64 b, int64 *result)
Definition: int.h:188
static bool pg_add_s64_overflow(int64 a, int64 b, int64 *result)
Definition: int.h:161
int b
Definition: isn.c:70
int x
Definition: isn.c:71
int j
Definition: isn.c:74
int i
Definition: isn.c:73
@ CONNECTION_BAD
Definition: libpq-fe.h:61
@ PGRES_COPY_IN
Definition: libpq-fe.h:106
@ PGRES_COMMAND_OK
Definition: libpq-fe.h:99
@ PGRES_FATAL_ERROR
Definition: libpq-fe.h:110
@ PGRES_EMPTY_QUERY
Definition: libpq-fe.h:98
@ PGRES_PIPELINE_SYNC
Definition: libpq-fe.h:113
@ PGRES_NONFATAL_ERROR
Definition: libpq-fe.h:109
@ PGRES_TUPLES_OK
Definition: libpq-fe.h:102
PGTransactionStatusType
Definition: libpq-fe.h:120
@ PQTRANS_INTRANS
Definition: libpq-fe.h:123
@ PQTRANS_IDLE
Definition: libpq-fe.h:121
@ PQTRANS_ACTIVE
Definition: libpq-fe.h:122
@ PQTRANS_UNKNOWN
Definition: libpq-fe.h:125
@ PQTRANS_INERROR
Definition: libpq-fe.h:124
@ PQ_PIPELINE_OFF
Definition: libpq-fe.h:161
@ PQ_PIPELINE_ON
Definition: libpq-fe.h:162
static void const char fflush(stdout)
exit(1)
void pg_logging_increase_verbosity(void)
Definition: logging.c:184
void pg_logging_init(const char *argv0)
Definition: logging.c:83
enum pg_log_level __pg_log_level
Definition: logging.c:21
#define pg_log_error(...)
Definition: logging.h:106
#define pg_log_error_hint(...)
Definition: logging.h:112
#define pg_log_info(...)
Definition: logging.h:124
@ PG_LOG_DEBUG
Definition: logging.h:26
#define pg_log_error_detail(...)
Definition: logging.h:109
#define pg_log_debug(...)
Definition: logging.h:133
bool option_parse_int(const char *optarg, const char *optname, int min_range, int max_range, int *result)
Definition: option_utils.c:50
void * arg
#define pg_fatal(...)
static int pg_leftmost_one_pos64(uint64 word)
Definition: pg_bitutils.h:72
#define MAXPGPATH
const void size_t len
static time_t start_time
Definition: pg_ctl.c:95
static int server_version
Definition: pg_dumpall.c:110
static char * filename
Definition: pg_dumpall.c:119
PGDLLIMPORT int optind
Definition: getopt.c:50
PGDLLIMPORT char * optarg
Definition: getopt.c:52
double pg_prng_double(pg_prng_state *state)
Definition: pg_prng.c:268
uint64 pg_prng_uint64_range(pg_prng_state *state, uint64 rmin, uint64 rmax)
Definition: pg_prng.c:144
uint64 pg_prng_uint64(pg_prng_state *state)
Definition: pg_prng.c:134
void pg_prng_seed(pg_prng_state *state, uint64 seed)
Definition: pg_prng.c:89
double pg_prng_double_normal(pg_prng_state *state)
Definition: pg_prng.c:290
static FILE * logfile
Definition: pg_regress.c:127
static rewind_source * source
Definition: pg_rewind.c:89
static char * buf
Definition: pg_test_fsync.c:73
void syntax_error(const char *source, int lineno, const char *line, const char *command, const char *msg, const char *more, int column)
Definition: pgbench.c:5478
static Variable * lookupVariable(Variables *variables, char *name)
Definition: pgbench.c:1604
static QueryMode querymode
Definition: pgbench.c:713
static char * index_tablespace
Definition: pgbench.c:217
static void printResults(StatsData *total, pg_time_usec_t total_duration, pg_time_usec_t conn_total_duration, pg_time_usec_t conn_elapsed_duration, int64 latency_late)
Definition: pgbench.c:6353
MetaCommand
Definition: pgbench.c:688
@ META_ELSE
Definition: pgbench.c:698
@ META_SETSHELL
Definition: pgbench.c:691
@ META_ENDIF
Definition: pgbench.c:699
@ META_SHELL
Definition: pgbench.c:692
@ META_STARTPIPELINE
Definition: pgbench.c:700
@ META_SET
Definition: pgbench.c:690
@ META_ELIF
Definition: pgbench.c:697
@ META_SYNCPIPELINE
Definition: pgbench.c:701
@ META_SLEEP
Definition: pgbench.c:693
@ META_NONE
Definition: pgbench.c:689
@ META_IF
Definition: pgbench.c:696
@ META_ENDPIPELINE
Definition: pgbench.c:702
@ META_ASET
Definition: pgbench.c:695
@ META_GSET
Definition: pgbench.c:694
static bool putVariableInt(Variables *variables, const char *context, char *name, int64 value)
Definition: pgbench.c:1871
static char * read_file_contents(FILE *fd)
Definition: pgbench.c:6042
static pg_time_usec_t pg_time_now(void)
Definition: pgbench.c:851
bool strtodouble(const char *str, bool errorOK, double *dv)
Definition: pgbench.c:1059
static void accumStats(StatsData *stats, bool skipped, double lat, double lag, EStatus estatus, int64 tries)
Definition: pgbench.c:1451
#define THREAD_FUNC_CC
Definition: pgbench.c:146
#define THREAD_FUNC_RETURN_TYPE
Definition: pgbench.c:144
static void initCreatePKeys(PGconn *con)
Definition: pgbench.c:5139
static uint32 max_tries
Definition: pgbench.c:289
static void GetTableInfo(PGconn *con, bool scale_given)
Definition: pgbench.c:5308
#define MM2_MUL_TIMES_8
Definition: pgbench.c:86
static void printVerboseErrorMessages(CState *st, pg_time_usec_t *now, bool is_retry)
Definition: pgbench.c:3551
static void initRandomState(pg_prng_state *state)
Definition: pgbench.c:1088
static bool isLazyFunc(PgBenchFunction func)
Definition: pgbench.c:2125
static double throttle_delay
Definition: pgbench.c:203
static bool per_script_stats
Definition: pgbench.c:260
static int64 getZipfianRand(pg_prng_state *state, int64 min, int64 max, double s)
Definition: pgbench.c:1231
#define THREAD_BARRIER_WAIT(barrier)
Definition: pgbench.c:154
#define MM2_ROT
Definition: pgbench.c:87
static const BuiltinScript * findBuiltin(const char *name)
Definition: pgbench.c:6120
static void setIntValue(PgBenchValue *pv, int64 ival)
Definition: pgbench.c:2110
static char * getVariable(Variables *variables, char *name)
Definition: pgbench.c:1631
static int64 latency_limit
Definition: pgbench.c:211
QueryMode
Definition: pgbench.c:706
@ QUERY_PREPARED
Definition: pgbench.c:709
@ NUM_QUERYMODE
Definition: pgbench.c:710
@ QUERY_SIMPLE
Definition: pgbench.c:707
@ QUERY_EXTENDED
Definition: pgbench.c:708
static bool use_log
Definition: pgbench.c:256
static THREAD_FUNC_RETURN_TYPE THREAD_FUNC_CC threadRun(void *arg)
Definition: pgbench.c:7395
#define MAX_ARGS
Definition: pgbench.c:685
#define SHELL_COMMAND_SIZE
Definition: pgbench.c:348
static void setalarm(int seconds)
Definition: pgbench.c:7717
static int nthreads
Definition: pgbench.c:264
struct BuiltinScript BuiltinScript
static void initTeller(PQExpBufferData *sql, int64 curr)
Definition: pgbench.c:4922
static TStatus getTransactionStatus(PGconn *con)
Definition: pgbench.c:3514
static int64 end_time
Definition: pgbench.c:175
static bool exit_on_abort
Definition: pgbench.c:770
static bool coerceToInt(PgBenchValue *pval, int64 *ival)
Definition: pgbench.c:2045
static void setNullValue(PgBenchValue *pv)
Definition: pgbench.c:2094
#define SOCKET_WAIT_METHOD
Definition: pgbench.c:106
static bool doRetry(CState *st, pg_time_usec_t *now)
Definition: pgbench.c:3428
static bool evalLazyFunc(CState *st, PgBenchFunction func, PgBenchExprLink *args, PgBenchValue *retval)
Definition: pgbench.c:2132
#define ERRCODE_T_R_DEADLOCK_DETECTED
Definition: pgbench.c:77
static int64 getExponentialRand(pg_prng_state *state, int64 min, int64 max, double parameter)
Definition: pgbench.c:1113
static void free_socket_set(socket_set *sa)
Definition: pgbench.c:7866
static void CheckConditional(const ParsedScript *ps)
Definition: pgbench.c:5855
static bool sendCommand(CState *st, Command *command)
Definition: pgbench.c:3155
static void doLog(TState *thread, CState *st, StatsData *agg, bool skipped, double latency, double lag)
Definition: pgbench.c:4546
#define COMMANDS_ALLOC_NUM
#define ERRCODE_T_R_SERIALIZATION_FAILURE
Definition: pgbench.c:76
static void prepareCommandsInPipeline(CState *st)
Definition: pgbench.c:3122
int main(int argc, char **argv)
Definition: pgbench.c:6617
TStatus
Definition: pgbench.c:469
@ TSTATUS_CONN_ERROR
Definition: pgbench.c:472
@ TSTATUS_IDLE
Definition: pgbench.c:470
@ TSTATUS_IN_BLOCK
Definition: pgbench.c:471
@ TSTATUS_OTHER_ERROR
Definition: pgbench.c:473
static Variable * lookupCreateVariable(Variables *variables, const char *context, char *name)
Definition: pgbench.c:1792
static int agg_interval
Definition: pgbench.c:258
static bool putVariable(Variables *variables, const char *context, char *name, const char *value)
Definition: pgbench.c:1829
static int nclients
Definition: pgbench.c:263
static int scale
Definition: pgbench.c:181
static void finishCon(CState *st)
Definition: pgbench.c:7695
static int compareVariableNames(const void *v1, const void *v2)
Definition: pgbench.c:1596
#define MAX_SCRIPTS
Definition: pgbench.c:347
static const char * getResultString(bool skipped, EStatus estatus)
Definition: pgbench.c:4515
static void printVersion(PGconn *con)
Definition: pgbench.c:6322
static void initBranch(PQExpBufferData *sql, int64 curr)
Definition: pgbench.c:4913
#define WSEP
Definition: pgbench.c:301
struct socket_set socket_set
static bool evaluateExpr(CState *st, PgBenchExpr *expr, PgBenchValue *retval)
Definition: pgbench.c:2837
static bool parseQuery(Command *cmd)
Definition: pgbench.c:5417
#define DEFAULT_NXACTS
Definition: pgbench.c:166
static void initStats(StatsData *sd, pg_time_usec_t start)
Definition: pgbench.c:1434
static pg_prng_state base_random_sequence
Definition: pgbench.c:477
static void setDoubleValue(PgBenchValue *pv, double dval)
Definition: pgbench.c:2118
static void checkInitSteps(const char *initialize_steps)
Definition: pgbench.c:5203
static int progress
Definition: pgbench.c:261
static void createPartitions(PGconn *con)
Definition: pgbench.c:4739
static void initDropTables(PGconn *con)
Definition: pgbench.c:4717
int64 pg_time_usec_t
Definition: pgbench.c:370
static bool is_connect
Definition: pgbench.c:265
static void clear_socket_set(socket_set *sa)
Definition: pgbench.c:7872
static void free_command(Command *command)
Definition: pgbench.c:5578
static void postprocess_sql_command(Command *my_command)
Definition: pgbench.c:5598
static bool progress_timestamp
Definition: pgbench.c:262
static const char *const QUERYMODE[]
Definition: pgbench.c:714
ConnectionStateEnum
Definition: pgbench.c:486
@ CSTATE_START_TX
Definition: pgbench.c:505
@ CSTATE_END_TX
Definition: pgbench.c:583
@ CSTATE_RETRY
Definition: pgbench.c:572
@ CSTATE_FINISHED
Definition: pgbench.c:590
@ CSTATE_SKIP_COMMAND
Definition: pgbench.c:545
@ CSTATE_THROTTLE
Definition: pgbench.c:515
@ CSTATE_FAILURE
Definition: pgbench.c:573
@ CSTATE_START_COMMAND
Definition: pgbench.c:541
@ CSTATE_END_COMMAND
Definition: pgbench.c:544
@ CSTATE_WAIT_RESULT
Definition: pgbench.c:542
@ CSTATE_CHOOSE_SCRIPT
Definition: pgbench.c:493
@ CSTATE_WAIT_ROLLBACK_RESULT
Definition: pgbench.c:571
@ CSTATE_ABORTED
Definition: pgbench.c:589
@ CSTATE_PREPARE_THROTTLE
Definition: pgbench.c:514
@ CSTATE_SLEEP
Definition: pgbench.c:543
@ CSTATE_ERROR
Definition: pgbench.c:570
static int partitions
Definition: pgbench.c:223
#define ntellers
Definition: pgbench.c:244
static int nxacts
Definition: pgbench.c:173
static void handle_sig_alarm(SIGNAL_ARGS)
Definition: pgbench.c:7711
static double sample_rate
Definition: pgbench.c:197
static bool evalFunc(CState *st, PgBenchFunction func, PgBenchExprLink *args, PgBenchValue *retval)
Definition: pgbench.c:2821
static char * valueTypeName(PgBenchValue *pval)
Definition: pgbench.c:1982
static bool runShellCommand(Variables *variables, char *variable, char **argv, int argc)
Definition: pgbench.c:2922
#define MIN_ZIPFIAN_PARAM
Definition: pgbench.c:170
struct Command Command
#define PARAMS_ARRAY_SIZE
void(* initRowMethod)(PQExpBufferData *sql, int64 curr)
Definition: pgbench.c:843
static bool report_per_command
Definition: pgbench.c:266
static void initGenerateDataServerSide(PGconn *con)
Definition: pgbench.c:5081
static bool makeVariableValue(Variable *var)
Definition: pgbench.c:1664
static Command * process_backslash_command(PsqlScanState sstate, const char *source)
Definition: pgbench.c:5635
static MetaCommand getMetaCommand(const char *cmd)
Definition: pgbench.c:2880
static void mergeSimpleStats(SimpleStats *acc, SimpleStats *ss)
Definition: pgbench.c:1418
#define THREAD_JOIN(handle)
Definition: pgbench.c:149
static void printSimpleStats(const char *prefix, SimpleStats *ss)
Definition: pgbench.c:6308
#define THREAD_T
Definition: pgbench.c:143
#define ERRCODE_UNDEFINED_TABLE
Definition: pgbench.c:78
static void listAvailableScripts(void)
Definition: pgbench.c:6108
static char * logfile_prefix
Definition: pgbench.c:298
#define THREAD_BARRIER_T
Definition: pgbench.c:151
#define PG_TIME_GET_DOUBLE(t)
Definition: pgbench.c:867
#define ALL_INIT_STEPS
Definition: pgbench.c:163
static bool set_random_seed(const char *seed)
Definition: pgbench.c:6571
static void add_socket_to_set(socket_set *sa, int fd, int idx)
Definition: pgbench.c:7879
static int discardUntilSync(CState *st)
Definition: pgbench.c:3474
static EStatus getSQLErrorStatus(const char *sqlState)
Definition: pgbench.c:3208
static int64 total_weight
Definition: pgbench.c:766
#define THREAD_FUNC_RETURN
Definition: pgbench.c:145
static ConnectionStateEnum executeMetaCommand(CState *st, pg_time_usec_t *now)
Definition: pgbench.c:4285
#define VARIABLES_ALLOC_MARGIN
Definition: pgbench.c:310
static void initCreateFKeys(PGconn *con)
Definition: pgbench.c:5177
static const BuiltinScript builtin_script[]
Definition: pgbench.c:780
static int fillfactor
Definition: pgbench.c:187
static int64 getFailures(const StatsData *stats)
Definition: pgbench.c:4504
static ParsedScript sql_script[MAX_SCRIPTS]
Definition: pgbench.c:764
static bool canRetryError(EStatus estatus)
Definition: pgbench.c:3225
static void runInitSteps(const char *initialize_steps)
Definition: pgbench.c:5223
static int64 permute(const int64 val, const int64 isize, const int64 seed)
Definition: pgbench.c:1303
static void commandFailed(CState *st, const char *cmd, const char *message)
Definition: pgbench.c:3028
static int chooseScript(TState *thread)
Definition: pgbench.c:3047
static bool evalStandardFunc(CState *st, PgBenchFunction func, PgBenchExprLink *args, PgBenchValue *retval)
Definition: pgbench.c:2249
static void addScript(const ParsedScript *script)
Definition: pgbench.c:6193
static void setBoolValue(PgBenchValue *pv, bool bval)
Definition: pgbench.c:2102
static void initTruncateTables(PGconn *con)
Definition: pgbench.c:4903
bool strtoint64(const char *str, bool errorOK, int64 *result)
Definition: pgbench.c:988
EStatus
Definition: pgbench.c:455
@ ESTATUS_DEADLOCK_ERROR
Definition: pgbench.c:461
@ ESTATUS_META_COMMAND_ERROR
Definition: pgbench.c:457
@ ESTATUS_OTHER_SQL_ERROR
Definition: pgbench.c:462
@ ESTATUS_NO_ERROR
Definition: pgbench.c:456
@ ESTATUS_SERIALIZATION_ERROR
Definition: pgbench.c:460
struct StatsData StatsData
static int64 computeIterativeZipfian(pg_prng_state *state, int64 n, double s)
Definition: pgbench.c:1201
static void advanceConnectionState(TState *thread, CState *st, StatsData *agg)
Definition: pgbench.c:3589
static void ConditionError(const char *desc, int cmdn, const char *msg)
Definition: pgbench.c:5845
static bool evaluateSleep(Variables *variables, int argc, char **argv, int *usecs)
Definition: pgbench.c:3383
static void process_builtin(const BuiltinScript *bi, int weight)
Definition: pgbench.c:6101
static int parseScriptWeight(const char *option, char **script)
Definition: pgbench.c:6156
struct SimpleStats SimpleStats
struct ParsedScript ParsedScript
#define SQL_COMMAND
Definition: pgbench.c:678
static void initVacuum(PGconn *con)
Definition: pgbench.c:5126
static bool putVariableValue(Variables *variables, const char *context, char *name, const PgBenchValue *value)
Definition: pgbench.c:1852
static void initAccount(PQExpBufferData *sql, int64 curr)
Definition: pgbench.c:4931
static void commandError(CState *st, const char *message)
Definition: pgbench.c:3038
static char * assignVariables(Variables *variables, char *sql)
Definition: pgbench.c:1936
static void tryExecuteStatement(PGconn *con, const char *sql)
Definition: pgbench.c:1516
static bool valid_variable_name(const char *name)
Definition: pgbench.c:1738
static partition_method_t partition_method
Definition: pgbench.c:233
static int64 getrand(pg_prng_state *state, int64 min, int64 max)
Definition: pgbench.c:1102
static const char *const PARTITION_METHOD[]
Definition: pgbench.c:234
#define MAX_FARGS
Definition: pgbench.c:2242
static void getQueryParams(Variables *variables, const Command *command, const char **params)
Definition: pgbench.c:1972
static volatile sig_atomic_t timer_exceeded
Definition: pgbench.c:303
static char * skip_sql_comments(char *sql_command)
Definition: pgbench.c:5514
static const char * pghost
Definition: pgbench.c:294
static void enlargeVariables(Variables *variables, int needed)
Definition: pgbench.c:1773
static THREAD_BARRIER_T barrier
Definition: pgbench.c:480
static void printProgressReport(TState *threads, int64 test_start, pg_time_usec_t now, StatsData *last, int64 *last_report)
Definition: pgbench.c:6214
static void processXactStats(TState *thread, CState *st, pg_time_usec_t *now, bool skipped, StatsData *agg)
Definition: pgbench.c:4666
static const char * username
Definition: pgbench.c:296
static bool unlogged_tables
Definition: pgbench.c:192
static void initSimpleStats(SimpleStats *ss)
Definition: pgbench.c:1394
#define LOG_STEP_SECONDS
Definition: pgbench.c:165
static int64 getHashMurmur2(int64 val, uint64 seed)
Definition: pgbench.c:1270
static int duration
Definition: pgbench.c:174
static void process_file(const char *filename, int weight)
Definition: pgbench.c:6075
static int main_pid
Definition: pgbench.c:269
#define nbranches
Definition: pgbench.c:243
partition_method_t
Definition: pgbench.c:227
@ PART_NONE
Definition: pgbench.c:228
@ PART_RANGE
Definition: pgbench.c:229
@ PART_HASH
Definition: pgbench.c:230
static const PsqlScanCallbacks pgbench_callbacks
Definition: pgbench.c:846
static void ParseScript(const char *script, const char *desc, int weight)
Definition: pgbench.c:5905
static void prepareCommand(CState *st, int command_num)
Definition: pgbench.c:3089
#define naccounts
Definition: pgbench.c:245
#define THREAD_BARRIER_INIT(barrier, n)
Definition: pgbench.c:152
#define FNV_OFFSET_BASIS
Definition: pgbench.c:84
#define FNV_PRIME
Definition: pgbench.c:83
static bool socket_has_input(socket_set *sa, int fd, int idx)
Definition: pgbench.c:7921
static const char * progname
Definition: pgbench.c:299
static bool valueTruth(PgBenchValue *pval)
Definition: pgbench.c:2024
static int num_scripts
Definition: pgbench.c:765
static void usage(void)
Definition: pgbench.c:870
static bool is_an_int(const char *str)
Definition: pgbench.c:951
static void pg_time_now_lazy(pg_time_usec_t *now)
Definition: pgbench.c:861
#define MM2_MUL
Definition: pgbench.c:85
static int64 getGaussianRand(pg_prng_state *state, int64 min, int64 max, double parameter)
Definition: pgbench.c:1137
static void addToSimpleStats(SimpleStats *ss, double val)
Definition: pgbench.c:1403
static const char * pgport
Definition: pgbench.c:295
static void initPopulateTable(PGconn *con, const char *table, int64 base, initRowMethod init_row)
Definition: pgbench.c:4940
static void allocCStatePrepared(CState *st)
Definition: pgbench.c:3069
static void disconnect_all(CState *state, int length)
Definition: pgbench.c:4705
static Command * create_sql_command(PQExpBuffer buf, const char *source)
Definition: pgbench.c:5549
#define DEFAULT_INIT_STEPS
Definition: pgbench.c:162
static void initCreateTables(PGconn *con)
Definition: pgbench.c:4808
static bool verbose_errors
Definition: pgbench.c:768
static int64 random_seed
Definition: pgbench.c:237
#define MIN_GAUSSIAN_PARAM
Definition: pgbench.c:168
#define M_PI
Definition: pgbench.c:73
#define SCALE_32BIT_THRESHOLD
Definition: pgbench.c:254
static const char * dbName
Definition: pgbench.c:297
static int64 getPoissonRand(pg_prng_state *state, double center)
Definition: pgbench.c:1179
static int wait_on_socket_set(socket_set *sa, int64 usecs)
Definition: pgbench.c:7904
static void executeStatement(PGconn *con, const char *sql)
Definition: pgbench.c:1500
#define THREAD_CREATE(handle, function, arg)
Definition: pgbench.c:147
static int64 getHashFnv1a(int64 val, uint64 seed)
Definition: pgbench.c:1245
static char * parseVariable(const char *sql, int *eaten)
Definition: pgbench.c:1889
static char * tablespace
Definition: pgbench.c:216
static bool coerceToDouble(PgBenchValue *pval, double *dval)
Definition: pgbench.c:2073
static socket_set * alloc_socket_set(int count)
Definition: pgbench.c:7860
static bool failures_detailed
Definition: pgbench.c:291
static PGconn * doConnect(void)
Definition: pgbench.c:1531
static void initGenerateDataClientSide(PGconn *con)
Definition: pgbench.c:5049
#define META_COMMAND
Definition: pgbench.c:679
static bool use_quiet
Definition: pgbench.c:257
static bool readCommandResponse(CState *st, MetaCommand meta, char *varprefix)
Definition: pgbench.c:3241
static pg_time_usec_t epoch_shift
Definition: pgbench.c:449
static char * replaceVariable(char **sql, char *param, int len, char *value)
Definition: pgbench.c:1916
#define MAX_ZIPFIAN_PARAM
Definition: pgbench.c:171
static bool coerceToBool(PgBenchValue *pval, bool *bval)
Definition: pgbench.c:2004
#define THREAD_BARRIER_DESTROY(barrier)
Definition: pgbench.c:155
@ ENODE_VARIABLE
Definition: pgbench.h:60
@ ENODE_CONSTANT
Definition: pgbench.h:59
@ ENODE_FUNCTION
Definition: pgbench.h:61
@ PGBT_NO_VALUE
Definition: pgbench.h:36
@ PGBT_INT
Definition: pgbench.h:38
@ PGBT_NULL
Definition: pgbench.h:37
@ PGBT_DOUBLE
Definition: pgbench.h:39
@ PGBT_BOOLEAN
Definition: pgbench.h:40
int expr_scanner_offset(PsqlScanState state)
PgBenchFunction
Definition: pgbench.h:66
@ PGBENCH_DIV
Definition: pgbench.h:70
@ PGBENCH_AND
Definition: pgbench.h:87
@ PGBENCH_DOUBLE
Definition: pgbench.h:77
@ PGBENCH_LT
Definition: pgbench.h:98
@ PGBENCH_LN
Definition: pgbench.h:80
@ PGBENCH_RANDOM_EXPONENTIAL
Definition: pgbench.h:84
@ PGBENCH_RSHIFT
Definition: pgbench.h:94
@ PGBENCH_DEBUG
Definition: pgbench.h:72
@ PGBENCH_MOD
Definition: pgbench.h:71
@ PGBENCH_GREATEST
Definition: pgbench.h:75
@ PGBENCH_BITXOR
Definition: pgbench.h:92
@ PGBENCH_RANDOM_ZIPFIAN
Definition: pgbench.h:85
@ PGBENCH_INT
Definition: pgbench.h:76
@ PGBENCH_NE
Definition: pgbench.h:96
@ PGBENCH_OR
Definition: pgbench.h:88
@ PGBENCH_LE
Definition: pgbench.h:97
@ PGBENCH_EXP
Definition: pgbench.h:81
@ PGBENCH_PI
Definition: pgbench.h:78
@ PGBENCH_ADD
Definition: pgbench.h:67
@ PGBENCH_EQ
Definition: pgbench.h:95
@ PGBENCH_LSHIFT
Definition: pgbench.h:93
@ PGBENCH_RANDOM
Definition: pgbench.h:82
@ PGBENCH_POW
Definition: pgbench.h:86
@ PGBENCH_IS
Definition: pgbench.h:99
@ PGBENCH_SUB
Definition: pgbench.h:68
@ PGBENCH_HASH_MURMUR2
Definition: pgbench.h:102
@ PGBENCH_ABS
Definition: pgbench.h:73
@ PGBENCH_BITOR
Definition: pgbench.h:91
@ PGBENCH_SQRT
Definition: pgbench.h:79
@ PGBENCH_LEAST
Definition: pgbench.h:74
@ PGBENCH_PERMUTE
Definition: pgbench.h:103
@ PGBENCH_HASH_FNV1A
Definition: pgbench.h:101
@ PGBENCH_NOT
Definition: pgbench.h:89
@ PGBENCH_BITAND
Definition: pgbench.h:90
@ PGBENCH_RANDOM_GAUSSIAN
Definition: pgbench.h:83
@ PGBENCH_MUL
Definition: pgbench.h:69
@ PGBENCH_CASE
Definition: pgbench.h:100
bool expr_lex_one_word(PsqlScanState state, PQExpBuffer word_buf, int *offset)
int expr_yyparse(yyscan_t yyscanner)
int expr_scanner_get_lineno(PsqlScanState state, int offset)
PgBenchExpr * expr_parse_result
void expr_scanner_finish(yyscan_t yyscanner)
yyscan_t expr_scanner_init(PsqlScanState state, const char *source, int lineno, int start_offset, const char *command)
char * expr_scanner_get_substring(PsqlScanState state, int start_offset, int end_offset, bool chomp)
#define pg_log_warning(...)
Definition: pgfnames.c:24
static core_yyscan_t yyscanner
Definition: pl_scanner.c:106
int int pg_snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
bool pg_strong_random(void *buf, size_t len)
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
#define sprintf
Definition: port.h:240
const char * get_progname(const char *argv0)
Definition: path.c:574
pqsigfunc pqsignal(int signo, pqsigfunc func)
#define snprintf
Definition: port.h:238
#define fprintf
Definition: port.h:242
#define qsort(a, b, c, d)
Definition: port.h:453
#define printf(...)
Definition: port.h:244
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:56
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:235
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:72
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:90
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:146
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:265
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:378
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:367
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:129
char * c
static int fd(const char *x, int i)
Definition: preproc-init.c:105
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
PsqlScanResult
Definition: psqlscan.h:31
@ PSCAN_BACKSLASH
Definition: psqlscan.h:33
@ PSCAN_EOL
Definition: psqlscan.h:35
@ PSCAN_INCOMPLETE
Definition: psqlscan.h:34
enum _promptStatus promptStatus_t
void psql_scan_destroy(PsqlScanState state)
PsqlScanResult psql_scan(PsqlScanState state, PQExpBuffer query_buf, promptStatus_t *prompt)
PsqlScanState psql_scan_create(const PsqlScanCallbacks *callbacks)
void psql_scan_setup(PsqlScanState state, const char *line, int line_len, int encoding, bool std_strings)
void psql_scan_finish(PsqlScanState state)
void * yyscan_t
Definition: psqlscan_int.h:60
tree context
Definition: radixtree.h:1835
void pg_usleep(long microsec)
Definition: signal.c:53
static pg_noinline void Size size
Definition: slab.c:607
char * simple_prompt(const char *prompt, bool echo)
Definition: sprompt.c:38
static void error(void)
Definition: sql-dyntest.c:147
static char * password
Definition: streamutil.c:54
PGconn * conn
Definition: streamutil.c:55
char * formatPGVersionNumber(int version_number, bool include_minor, char *buf, size_t buflen)
Definition: string_utils.c:177
const char * desc
Definition: pgbench.c:776
const char * name
Definition: pgbench.c:775
const char * script
Definition: pgbench.c:777
int64 cnt
Definition: pgbench.c:637
int id
Definition: pgbench.c:599
pg_time_usec_t txn_scheduled
Definition: pgbench.c:617
pg_time_usec_t stmt_begin
Definition: pgbench.c:620
int command
Definition: pgbench.c:610
pg_time_usec_t sleep_until
Definition: pgbench.c:618
int use_file
Definition: pgbench.c:609
ConditionalStack cstack
Definition: pgbench.c:601
pg_prng_state random_state
Definition: pgbench.c:632
pg_time_usec_t txn_begin
Definition: pgbench.c:619
Variables variables
Definition: pgbench.c:614
EStatus estatus
Definition: pgbench.c:629
int num_syncs
Definition: pgbench.c:611
PGconn * con
Definition: pgbench.c:598
pg_prng_state cs_func_rs
Definition: pgbench.c:607
uint32 tries
Definition: pgbench.c:633
bool ** prepared
Definition: pgbench.c:623
ConnectionStateEnum state
Definition: pgbench.c:600
int64 retries
Definition: pgbench.c:752
char * varprefix
Definition: pgbench.c:749
int type
Definition: pgbench.c:744
PQExpBufferData lines
Definition: pgbench.c:742
MetaCommand meta
Definition: pgbench.c:745
SimpleStats stats
Definition: pgbench.c:751
PgBenchExpr * expr
Definition: pgbench.c:750
int64 failures
Definition: pgbench.c:753
char * argv[MAX_ARGS]
Definition: pgbench.c:747
char * first_line
Definition: pgbench.c:743
int argc
Definition: pgbench.c:746
char * prepname
Definition: pgbench.c:748
const char * desc
Definition: pgbench.c:758
int weight
Definition: pgbench.c:759
Command ** commands
Definition: pgbench.c:760
StatsData stats
Definition: pgbench.c:761
PgBenchValue constant
Definition: pgbench.h:115
PgBenchFunction function
Definition: pgbench.h:122
PgBenchExprType etype
Definition: pgbench.h:112
union PgBenchExpr::@37 u
struct PgBenchExpr::@37::@38 variable
PgBenchValueType type
Definition: pgbench.h:46
bool bval
Definition: pgbench.h:51
int64 ival
Definition: pgbench.h:49
union PgBenchValue::@36 u
double dval
Definition: pgbench.h:50
int64 count
Definition: pgbench.c:358
double sum
Definition: pgbench.c:361
double min
Definition: pgbench.c:359
double max
Definition: pgbench.c:360
double sum2
Definition: pgbench.c:362
int64 serialization_failures
Definition: pgbench.c:435
int64 cnt
Definition: pgbench.c:425
int64 retried
Definition: pgbench.c:431
int64 deadlock_failures
Definition: pgbench.c:438
int64 skipped
Definition: pgbench.c:427
pg_time_usec_t start_time
Definition: pgbench.c:378
SimpleStats lag
Definition: pgbench.c:442
int64 retries
Definition: pgbench.c:429
SimpleStats latency
Definition: pgbench.c:441
pg_time_usec_t create_time
Definition: pgbench.c:665
CState * state
Definition: pgbench.c:649
int tid
Definition: pgbench.c:647
int nstate
Definition: pgbench.c:650
int64 throttle_trigger
Definition: pgbench.c:661
pg_prng_state ts_throttle_rs
Definition: pgbench.c:658
pg_time_usec_t conn_duration
Definition: pgbench.c:668
pg_prng_state ts_choose_rs
Definition: pgbench.c:657
FILE * logfile
Definition: pgbench.c:662
StatsData stats
Definition: pgbench.c:671
THREAD_T thread
Definition: pgbench.c:648
pg_time_usec_t bench_start
Definition: pgbench.c:667
pg_prng_state ts_sample_rs
Definition: pgbench.c:659
int64 latency_late
Definition: pgbench.c:672
pg_time_usec_t started_time
Definition: pgbench.c:666
PgBenchValue value
Definition: pgbench.c:326
char * name
Definition: pgbench.c:324
char * svalue
Definition: pgbench.c:325
Variable * vars
Definition: pgbench.c:334
int nvars
Definition: pgbench.c:335
bool vars_sorted
Definition: pgbench.c:344
int max_vars
Definition: pgbench.c:342
Definition: type.h:95
int maxfd
Definition: pgbench.c:110
fd_set fds
Definition: pgbench.c:111
Definition: regguts.h:323
Definition: regcomp.c:281
const char * get_user_name_or_exit(const char *progname)
Definition: username.c:74
const char * type
const char * name
#define EINTR
Definition: win32_port.h:374
#define SIGALRM
Definition: win32_port.h:174
#define select(n, r, w, e, timeout)
Definition: win32_port.h:500
int gettimeofday(struct timeval *tp, void *tzp)
static char chars[TZ_MAX_CHARS]
Definition: zic.c:401