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