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