LCOV - differential code coverage report
Current view: top level - src/bin/pgbench - pgbench.c (source / functions) Coverage Total Hit UNC LBC UIC UBC GBC GIC GNC CBC EUB ECB DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 85.9 % 2837 2437 6 116 233 45 122 1358 106 851 230 1355 3 115
Current Date: 2023-04-08 15:15:32 Functions: 95.8 % 120 115 5 115 5 113 2
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

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

Generated by: LCOV version v1.16-55-g56c0a2a