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 17:13:01 Functions: 95.8 % 120 115 5 115 5 113 2
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 [..60] days: 97.5 % 40 39 1 23 16 2 23
Legend: Lines: hit not hit (60,120] days: 100.0 % 92 92 5 62 25 6
(120,180] days: 0.0 % 1 0 1
(180,240] days: 42.9 % 7 3 4 3
(240..) days: 85.4 % 2697 2303 1 116 232 45 122 1330 41 810 228 1326
Function coverage date bins:
[..60] days: 50.0 % 4 2 2 2
(240..) days: 48.3 % 234 113 5 113 5 111

 Age         Owner                  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 */
 2576 tgl                       852 ECB             : };
                                853                 : 
                                854                 : static inline pg_time_usec_t
  760 tmunro                    855 GIC        6227 : pg_time_now(void)
  760 tmunro                    856 ECB             : {
                                857                 :     instr_time  now;
                                858                 : 
  760 tmunro                    859 GIC        6227 :     INSTR_TIME_SET_CURRENT(now);
                                860                 : 
                                861            6227 :     return (pg_time_usec_t) INSTR_TIME_GET_MICROSEC(now);
  760 tmunro                    862 ECB             : }
                                863                 : 
                                864                 : static inline void
  760 tmunro                    865 CBC        5222 : pg_time_now_lazy(pg_time_usec_t *now)
  760 tmunro                    866 ECB             : {
  760 tmunro                    867 GIC        5222 :     if ((*now) == 0)
                                868            4200 :         (*now) = pg_time_now();
                                869            5222 : }
                                870                 : 
  760 tmunro                    871 ECB             : #define PG_TIME_GET_DOUBLE(t) (0.000001 * (t))
                                872                 : 
 8397 bruce                     873                 : static void
 3931 rhaas                     874 GIC           1 : usage(void)
                                875                 : {
 5154 peter_e                   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"
 1136 peter                     939 ECB             :            "Report bugs to <%s>.\n"
                                940                 :            "%s home page: <%s>\n",
                                941                 :            progname, progname, PACKAGE_BUGREPORT, PACKAGE_NAME, PACKAGE_URL);
 8485 ishii                     942 GIC           1 : }
 8485 ishii                     943 ECB             : 
                                944                 : /* return whether str matches "^\s*[-+]?[0-9]+$" */
 2568 rhaas                     945                 : static bool
 2568 rhaas                     946 GIC         422 : is_an_int(const char *str)
                                947                 : {
 2568 rhaas                     948 CBC         422 :     const char *ptr = str;
 2568 rhaas                     949 EUB             : 
                                950                 :     /* skip leading spaces; cast is consistent with strtoint64 */
 2568 rhaas                     951 GIC         422 :     while (*ptr && isspace((unsigned char) *ptr))
 2568 rhaas                     952 LBC           0 :         ptr++;
 2568 rhaas                     953 ECB             : 
                                954                 :     /* skip sign */
 2568 rhaas                     955 GIC         422 :     if (*ptr == '+' || *ptr == '-')
 2568 rhaas                     956 CBC           3 :         ptr++;
 2568 rhaas                     957 ECB             : 
                                958                 :     /* at least one digit */
 2568 rhaas                     959 GIC         422 :     if (*ptr && !isdigit((unsigned char) *ptr))
 2568 rhaas                     960 CBC           2 :         return false;
 2568 rhaas                     961 ECB             : 
                                962                 :     /* eat all digits */
 2568 rhaas                     963 GIC         895 :     while (*ptr && isdigit((unsigned char) *ptr))
 2568 rhaas                     964 CBC         475 :         ptr++;
                                965                 : 
                                966                 :     /* must have reached end of string */
 2568 rhaas                     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                 :  *
 1655 andres                    980 ECB             :  * If not errorOK, an error message is also printed out on errors.
                                981                 :  */
                                982                 : bool
 1655 andres                    983 CBC        1213 : strtoint64(const char *str, bool errorOK, int64 *result)
 3722 heikki.linnakangas        984 ECB             : {
 3722 heikki.linnakangas        985 GIC        1213 :     const char *ptr = str;
 1655 andres                    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.
 3722 heikki.linnakangas        995 ECB             :      */
 3722 heikki.linnakangas        996 EUB             : 
                                997                 :     /* skip leading spaces */
 3722 heikki.linnakangas        998 GIC        1213 :     while (*ptr && isspace((unsigned char) *ptr))
 3722 heikki.linnakangas        999 LBC           0 :         ptr++;
                               1000                 : 
 3722 heikki.linnakangas       1001 ECB             :     /* handle sign */
 3722 heikki.linnakangas       1002 CBC        1213 :     if (*ptr == '-')
                               1003                 :     {
                               1004               2 :         ptr++;
 1655 andres                   1005 GBC           2 :         neg = true;
                               1006                 :     }
 3722 heikki.linnakangas       1007 GIC        1211 :     else if (*ptr == '+')
 3722 heikki.linnakangas       1008 LBC           0 :         ptr++;
 3722 heikki.linnakangas       1009 EUB             : 
                               1010                 :     /* require at least one digit */
 1655 andres                   1011 GIC        1213 :     if (unlikely(!isdigit((unsigned char) *ptr)))
 1655 andres                   1012 LBC           0 :         goto invalid_syntax;
                               1013                 : 
 3722 heikki.linnakangas       1014 ECB             :     /* process digits */
 3722 heikki.linnakangas       1015 GIC        3729 :     while (*ptr && isdigit((unsigned char) *ptr))
 3722 heikki.linnakangas       1016 ECB             :     {
 1655 andres                   1017 CBC        2517 :         int8        digit = (*ptr++ - '0');
 3722 heikki.linnakangas       1018 ECB             : 
 1655 andres                   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;
 3722 heikki.linnakangas       1022 ECB             :     }
 3722 heikki.linnakangas       1023 EUB             : 
                               1024                 :     /* allow trailing whitespace, but not other trailing chars */
 3722 heikki.linnakangas       1025 CBC        1212 :     while (*ptr != '\0' && isspace((unsigned char) *ptr))
 3722 heikki.linnakangas       1026 UBC           0 :         ptr++;
                               1027                 : 
 1655 andres                   1028 CBC        1212 :     if (unlikely(*ptr != '\0'))
 1655 andres                   1029 UIC           0 :         goto invalid_syntax;
 1655 andres                   1030 ECB             : 
 1655 andres                   1031 GBC        1212 :     if (!neg)
 1655 andres                   1032 ECB             :     {
 1655 andres                   1033 GIC        1210 :         if (unlikely(tmp == PG_INT64_MIN))
 1655 andres                   1034 UIC           0 :             goto out_of_range;
 1655 andres                   1035 CBC        1210 :         tmp = -tmp;
 1655 andres                   1036 ECB             :     }
                               1037                 : 
 1655 andres                   1038 CBC        1212 :     *result = tmp;
                               1039            1212 :     return true;
 1655 andres                   1040 EUB             : 
 1655 andres                   1041 CBC           1 : out_of_range:
 1655 andres                   1042 GIC           1 :     if (!errorOK)
 1187 peter                    1043 UBC           0 :         pg_log_error("value \"%s\" is out of range for type bigint", str);
 1655 andres                   1044 GBC           1 :     return false;
 3722 heikki.linnakangas       1045 EUB             : 
 1655 andres                   1046 UBC           0 : invalid_syntax:
 1655 andres                   1047 UIC           0 :     if (!errorOK)
 1187 peter                    1048               0 :         pg_log_error("invalid input syntax for type bigint: \"%s\"", str);
 1655 andres                   1049               0 :     return false;
                               1050                 : }
 1655 andres                   1051 ECB             : 
                               1052                 : /* convert string to double, detecting overflows/underflows */
                               1053                 : bool
 1655 andres                   1054 GIC          66 : strtodouble(const char *str, bool errorOK, double *dv)
 1655 andres                   1055 ECB             : {
 1418 tgl                      1056                 :     char       *end;
                               1057                 : 
 1655 andres                   1058 CBC          66 :     errno = 0;
 1655 andres                   1059 GIC          66 :     *dv = strtod(str, &end);
 1655 andres                   1060 ECB             : 
 1655 andres                   1061 GBC          66 :     if (unlikely(errno != 0))
 1655 andres                   1062 ECB             :     {
 1655 andres                   1063 GIC           2 :         if (!errorOK)
 1187 peter                    1064 UIC           0 :             pg_log_error("value \"%s\" is out of range for type double", str);
 1655 andres                   1065 CBC           2 :         return false;
                               1066                 :     }
 1655 andres                   1067 ECB             : 
 1655 andres                   1068 GBC          64 :     if (unlikely(end == str || *end != '\0'))
 1655 andres                   1069 ECB             :     {
 1655 andres                   1070 GIC           2 :         if (!errorOK)
 1187 peter                    1071 LBC           0 :             pg_log_error("invalid input syntax for type double: \"%s\"", str);
 1655 andres                   1072 GIC           2 :         return false;
                               1073                 :     }
                               1074              62 :     return true;
                               1075                 : }
                               1076                 : 
                               1077                 : /*
                               1078                 :  * Initialize a prng state struct.
                               1079                 :  *
 1536 tgl                      1080 ECB             :  * We derive the seed from base_random_sequence, which must be set up already.
                               1081                 :  */
 1605 alvherre                 1082                 : static void
  497 tgl                      1083 CBC         308 : initRandomState(pg_prng_state *state)
                               1084                 : {
  497 tgl                      1085 GIC         308 :     pg_prng_seed(state, pg_prng_uint64(&base_random_sequence));
 1605 alvherre                 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
  497 tgl                      1094 ECB             :  * overflow int64.  This is not checked.
                               1095                 :  */
 3722 heikki.linnakangas       1096                 : static int64
  497 tgl                      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
 2669 rhaas                    1105 ECB             :  * value is exp(-parameter).
                               1106                 :  */
                               1107                 : static int64
  497 tgl                      1108 GIC           3 : getExponentialRand(pg_prng_state *state, int64 min, int64 max,
                               1109                 :                    double parameter)
                               1110                 : {
                               1111                 :     double      cut,
                               1112                 :                 uniform,
 2878 bruce                    1113 ECB             :                 rand;
                               1114                 : 
                               1115                 :     /* abort if wrong parameter, but must really be checked beforehand */
 2669 rhaas                    1116 CBC           3 :     Assert(parameter > 0.0);
 2669 rhaas                    1117 GIC           3 :     cut = exp(-parameter);
                               1118                 :     /* pg_prng_double value in [0, 1), uniform in (0, 1] */
  497 tgl                      1119               3 :     uniform = 1.0 - pg_prng_double(state);
                               1120                 : 
 3175 rhaas                    1121 ECB             :     /*
 2581                          1122                 :      * inner expression in (cut, 1] (if parameter > 0), rand in [0, 1)
                               1123                 :      */
 3175 rhaas                    1124 CBC           3 :     Assert((1.0 - cut) != 0.0);
 2669 rhaas                    1125 GIC           3 :     rand = -log(cut + (1.0 - cut) * uniform) / parameter;
                               1126                 :     /* return int64 random number within between min and max */
 2878 bruce                    1127               3 :     return min + (int64) ((max - min + 1) * rand);
                               1128                 : }
 3175 rhaas                    1129 ECB             : 
                               1130                 : /* random number generator: gaussian distribution from min to max inclusive */
                               1131                 : static int64
  497 tgl                      1132 GIC           3 : getGaussianRand(pg_prng_state *state, int64 min, int64 max,
                               1133                 :                 double parameter)
                               1134                 : {
                               1135                 :     double      stdev;
 3175 rhaas                    1136 ECB             :     double      rand;
                               1137                 : 
                               1138                 :     /* abort if parameter is too low, but must really be checked beforehand */
 2568 rhaas                    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%.
 3175 rhaas                    1152 ECB             :      */
                               1153                 :     do
                               1154                 :     {
   90 tgl                      1155 GNC           3 :         stdev = pg_prng_double_normal(state);
                               1156                 :     }
 2669 rhaas                    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                 : 
 3175 rhaas                    1162 ECB             :     /* return int64 random number within between min and max */
 2878 bruce                    1163 GIC           3 :     return min + (int64) ((max - min + 1) * rand);
 3175 rhaas                    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
  497 tgl                      1174 GIC         210 : getPoissonRand(pg_prng_state *state, double center)
 3132 heikki.linnakangas       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] */
  497 tgl                      1183 GIC         210 :     uniform = 1.0 - pg_prng_double(state);
 3132 heikki.linnakangas       1184 ECB             : 
 1657 tgl                      1185 GBC         210 :     return (int64) (-log(uniform) * center + 0.5);
                               1186                 : }
                               1187                 : 
                               1188                 : /*
                               1189                 :  * Computing zipfian using rejection method, based on
 1942 teodor                   1190 ECB             :  * "Non-Uniform Random Variate Generation",
                               1191                 :  * Luc Devroye, p. 550-551, Springer 1986.
                               1192                 :  *
 1469 tgl                      1193                 :  * This works for s > 1.0, but may perform badly for s very close to 1.0.
                               1194                 :  */
 1942 teodor                   1195                 : static int64
  497 tgl                      1196 GIC           3 : computeIterativeZipfian(pg_prng_state *state, int64 n, double s)
 1942 teodor                   1197 ECB             : {
 1942 teodor                   1198 CBC           3 :     double      b = pow(2.0, s - 1.0);
                               1199                 :     double      x,
 1942 teodor                   1200 ECB             :                 t,
                               1201                 :                 u,
                               1202                 :                 v;
                               1203                 : 
                               1204                 :     /* Ensure n is sane */
 1469 tgl                      1205 CBC           3 :     if (n <= 1)
 1469 tgl                      1206 UIC           0 :         return 1;
 1469 tgl                      1207 ECB             : 
                               1208                 :     while (true)
                               1209                 :     {
 1942 teodor                   1210                 :         /* random variates */
  497 tgl                      1211 GIC           3 :         u = pg_prng_double(state);
  497 tgl                      1212 CBC           3 :         v = pg_prng_double(state);
                               1213                 : 
 1942 teodor                   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)
 1942 teodor                   1219 CBC           3 :             break;
                               1220                 :     }
 1942 teodor                   1221 GIC           3 :     return (int64) x;
                               1222                 : }
                               1223                 : 
 1942 teodor                   1224 ECB             : /* random number generator: zipfian distribution from min to max inclusive */
                               1225                 : static int64
  497 tgl                      1226 GIC           3 : getZipfianRand(pg_prng_state *state, int64 min, int64 max, double s)
 1942 teodor                   1227 ECB             : {
 1942 teodor                   1228 GIC           3 :     int64       n = max - min + 1;
 1942 teodor                   1229 ECB             : 
                               1230                 :     /* abort if parameter is invalid */
 1469 tgl                      1231 CBC           3 :     Assert(MIN_ZIPFIAN_PARAM <= s && s <= MAX_ZIPFIAN_PARAM);
                               1232                 : 
  497 tgl                      1233 GIC           3 :     return min - 1 + computeIterativeZipfian(state, n, s);
 1942 teodor                   1234 ECB             : }
                               1235                 : 
                               1236                 : /*
                               1237                 :  * FNV-1a hash function
                               1238                 :  */
                               1239                 : static int64
 1845 teodor                   1240 GIC           1 : getHashFnv1a(int64 val, uint64 seed)
                               1241                 : {
                               1242                 :     int64       result;
                               1243                 :     int         i;
 1845 teodor                   1244 ECB             : 
 1845 teodor                   1245 GIC           1 :     result = FNV_OFFSET_BASIS ^ seed;
 1845 teodor                   1246 CBC           9 :     for (i = 0; i < 8; ++i)
 1845 teodor                   1247 ECB             :     {
 1809 tgl                      1248 GIC           8 :         int32       octet = val & 0xff;
 1845 teodor                   1249 ECB             : 
 1845 teodor                   1250 CBC           8 :         val = val >> 8;
                               1251               8 :         result = result ^ octet;
 1845 teodor                   1252 GIC           8 :         result = result * FNV_PRIME;
 1845 teodor                   1253 ECB             :     }
                               1254                 : 
 1845 teodor                   1255 GIC           1 :     return result;
 1845 teodor                   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
 1845 teodor                   1265 GIC           5 : getHashMurmur2(int64 val, uint64 seed)
                               1266                 : {
 1804 tgl                      1267               5 :     uint64      result = seed ^ MM2_MUL_TIMES_8;    /* sizeof(int64) */
 1809                          1268               5 :     uint64      k = (uint64) val;
                               1269                 : 
 1845 teodor                   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                 : 
 1845 teodor                   1277 CBC           5 :     result ^= result >> MM2_ROT;
 1845 teodor                   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                 :  *
  733 dean.a.rasheed           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
  733 dean.a.rasheed           1298 CBC          45 : permute(const int64 val, const int64 isize, const int64 seed)
  733 dean.a.rasheed           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                 : 
  733 dean.a.rasheed           1308 GIC          45 :     if (isize < 2)
                               1309               1 :         return 0;               /* nothing to permute */
                               1310                 : 
                               1311                 :     /* Initialize prng state using the seed */
  497 tgl                      1312              44 :     pg_prng_seed(&state, (uint64) seed);
                               1313                 : 
                               1314                 :     /* Computations are performed on unsigned values */
  733 dean.a.rasheed           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
  733 dean.a.rasheed           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                 :      */
  733 dean.a.rasheed           1351 CBC         308 :     for (i = 0; i < 6; i++)
  733 dean.a.rasheed           1352 ECB             :     {
                               1353                 :         uint64      m,
                               1354                 :                     r,
                               1355                 :                     t;
                               1356                 : 
                               1357                 :         /* Random multiply (by an odd number), XOR and rotate of lower half */
  497 tgl                      1358 CBC         264 :         m = (pg_prng_uint64(&state) & mask) | 1;
  497 tgl                      1359 GIC         264 :         r = pg_prng_uint64(&state) & mask;
  733 dean.a.rasheed           1360             264 :         if (v <= mask)
  733 dean.a.rasheed           1361 ECB             :         {
  733 dean.a.rasheed           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 */
  497 tgl                      1367             264 :         m = (pg_prng_uint64(&state) & mask) | 1;
  497 tgl                      1368 CBC         264 :         r = pg_prng_uint64(&state) & mask;
  733 dean.a.rasheed           1369 GIC         264 :         t = size - 1 - v;
  733 dean.a.rasheed           1370 CBC         264 :         if (t <= mask)
  733 dean.a.rasheed           1371 ECB             :         {
  733 dean.a.rasheed           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                 : 
  733 dean.a.rasheed           1377 ECB             :         /* Random offset */
  497 tgl                      1378 GIC         264 :         r = pg_prng_uint64_range(&state, 0, size - 1);
  733 dean.a.rasheed           1379 CBC         264 :         v = (v + r) % size;
  733 dean.a.rasheed           1380 ECB             :     }
                               1381                 : 
  733 dean.a.rasheed           1382 CBC          44 :     return (int64) v;
  733 dean.a.rasheed           1383 ECB             : }
                               1384                 : 
 2627 alvherre                 1385                 : /*
                               1386                 :  * Initialize the given SimpleStats struct to all zeroes
                               1387                 :  */
                               1388                 : static void
 2627 alvherre                 1389 GIC        1772 : initSimpleStats(SimpleStats *ss)
                               1390                 : {
                               1391            1772 :     memset(ss, 0, sizeof(SimpleStats));
 2627 alvherre                 1392 CBC        1772 : }
                               1393                 : 
 2627 alvherre                 1394 ECB             : /*
                               1395                 :  * Accumulate one value into a SimpleStats struct.
                               1396                 :  */
                               1397                 : static void
 2627 alvherre                 1398 CBC        4131 : addToSimpleStats(SimpleStats *ss, double val)
 2627 alvherre                 1399 ECB             : {
 2627 alvherre                 1400 CBC        4131 :     if (ss->count == 0 || val < ss->min)
                               1401             116 :         ss->min = val;
 2627 alvherre                 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 : }
 2627 alvherre                 1408 ECB             : 
                               1409                 : /*
                               1410                 :  * Merge two SimpleStats objects
                               1411                 :  */
                               1412                 : static void
 2627 alvherre                 1413 CBC         138 : mergeSimpleStats(SimpleStats *acc, SimpleStats *ss)
 2627 alvherre                 1414 ECB             : {
 2627 alvherre                 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;
 2627 alvherre                 1420 GIC         138 :     acc->sum += ss->sum;
                               1421             138 :     acc->sum2 += ss->sum2;
                               1422             138 : }
                               1423                 : 
                               1424                 : /*
 2627 alvherre                 1425 ECB             :  * Initialize a StatsData struct to mostly zeroes, with its start time set to
                               1426                 :  * the given value.
                               1427                 :  */
                               1428                 : static void
  760 tmunro                   1429 CBC         468 : initStats(StatsData *sd, pg_time_usec_t start)
                               1430                 : {
  760 tmunro                   1431 GIC         468 :     sd->start_time = start;
 2627 alvherre                 1432 CBC         468 :     sd->cnt = 0;
                               1433             468 :     sd->skipped = 0;
  382 ishii                    1434 GIC         468 :     sd->retries = 0;
                               1435             468 :     sd->retried = 0;
                               1436             468 :     sd->serialization_failures = 0;
                               1437             468 :     sd->deadlock_failures = 0;
 2627 alvherre                 1438             468 :     initSimpleStats(&sd->latency);
                               1439             468 :     initSimpleStats(&sd->lag);
 2627 alvherre                 1440 CBC         468 : }
                               1441                 : 
 2627 alvherre                 1442 ECB             : /*
                               1443                 :  * Accumulate one additional item into the given stats object.
                               1444                 :  */
                               1445                 : static void
  382 ishii                    1446 CBC        3538 : accumStats(StatsData *stats, bool skipped, double lat, double lag,
                               1447                 :            EStatus estatus, int64 tries)
                               1448                 : {
  382 ishii                    1449 ECB             :     /* Record the skipped transaction */
 2627 alvherre                 1450 CBC        3538 :     if (skipped)
                               1451                 :     {
 2627 alvherre                 1452 ECB             :         /* no latency to record on skipped transactions */
 2627 alvherre                 1453 GIC           9 :         stats->skipped++;
  382 ishii                    1454               9 :         return;
 2627 alvherre                 1455 ECB             :     }
  382 ishii                    1456                 : 
                               1457                 :     /*
                               1458                 :      * Record the number of retries regardless of whether the transaction was
                               1459                 :      * successful or failed.
  382 ishii                    1460 EUB             :      */
  382 ishii                    1461 GBC        3529 :     if (tries > 1)
 2627 alvherre                 1462 EUB             :     {
  382 ishii                    1463 GBC           2 :         stats->retries += (tries - 1);
                               1464               2 :         stats->retried++;
  382 ishii                    1465 EUB             :     }
 2627 alvherre                 1466                 : 
  382 ishii                    1467 GIC        3529 :     switch (estatus)
  382 ishii                    1468 EUB             :     {
                               1469                 :             /* Record the successful transaction */
  382 ishii                    1470 GIC        3529 :         case ESTATUS_NO_ERROR:
                               1471            3529 :             stats->cnt++;
                               1472                 : 
                               1473            3529 :             addToSimpleStats(&stats->latency, lat);
  382 ishii                    1474 ECB             : 
                               1475                 :             /* and possibly the same for schedule lag */
  382 ishii                    1476 GIC        3529 :             if (throttle_delay)
                               1477             201 :                 addToSimpleStats(&stats->lag, lag);
  382 ishii                    1478 CBC        3529 :             break;
  382 ishii                    1479 ECB             : 
                               1480                 :             /* Record the failed transaction */
  382 ishii                    1481 UBC           0 :         case ESTATUS_SERIALIZATION_ERROR:
                               1482               0 :             stats->serialization_failures++;
                               1483               0 :             break;
  382 ishii                    1484 UIC           0 :         case ESTATUS_DEADLOCK_ERROR:
  382 ishii                    1485 LBC           0 :             stats->deadlock_failures++;
                               1486               0 :             break;
  382 ishii                    1487 UIC           0 :         default:
                               1488                 :             /* internal error which should never occur */
  366 tgl                      1489               0 :             pg_fatal("unexpected error status: %d", estatus);
 2627 alvherre                 1490 ECB             :     }
                               1491                 : }
                               1492                 : 
                               1493                 : /* call PQexec() and exit() on failure */
 5847 ishii                    1494                 : static void
 5624 bruce                    1495 CBC          81 : executeStatement(PGconn *con, const char *sql)
                               1496                 : {
 5847 ishii                    1497 EUB             :     PGresult   *res;
                               1498                 : 
 5847 ishii                    1499 GIC          81 :     res = PQexec(con, sql);
 5847 ishii                    1500 CBC          81 :     if (PQresultStatus(res) != PGRES_COMMAND_OK)
 5847 ishii                    1501 ECB             :     {
  366 tgl                      1502 UIC           0 :         pg_log_error("query failed: %s", PQerrorMessage(con));
                               1503               0 :         pg_log_error_detail("Query was: %s", sql);
 5847 ishii                    1504               0 :         exit(1);
 5847 ishii                    1505 ECB             :     }
 5847 ishii                    1506 GIC          81 :     PQclear(res);
                               1507              81 : }
                               1508                 : 
                               1509                 : /* call PQexec() and complain, but without exiting, on failure */
                               1510                 : static void
 2889 sfrost                   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                 :     {
 1187 peter                    1518 UIC           0 :         pg_log_error("%s", PQerrorMessage(con));
  366 tgl                      1519               0 :         pg_log_error_detail("(ignoring this error and continuing anyway)");
                               1520                 :     }
 2889 sfrost                   1521 GIC          27 :     PQclear(res);
 2889 sfrost                   1522 CBC          27 : }
 2889 sfrost                   1523 ECB             : 
 7882 ishii                    1524                 : /* set up a connection to the backend */
 7836 bruce                    1525                 : static PGconn *
 6740 tgl                      1526 CBC         275 : doConnect(void)
 7882 ishii                    1527 ECB             : {
 5598 tgl                      1528                 :     PGconn     *conn;
                               1529                 :     bool        new_pass;
  948                          1530                 :     static char *password = NULL;
 7188 bruce                    1531                 : 
 5598 tgl                      1532                 :     /*
                               1533                 :      * Start the connection.  Loop until we have a password if requested by
                               1534                 :      * backend.
                               1535                 :      */
                               1536                 :     do
 7836 bruce                    1537                 :     {
                               1538                 : #define PARAMS_ARRAY_SIZE   7
 3931 rhaas                    1539                 : 
                               1540                 :         const char *keywords[PARAMS_ARRAY_SIZE];
                               1541                 :         const char *values[PARAMS_ARRAY_SIZE];
                               1542                 : 
 3931 rhaas                    1543 GBC         275 :         keywords[0] = "host";
                               1544             275 :         values[0] = pghost;
 3931 rhaas                    1545 GIC         275 :         keywords[1] = "port";
                               1546             275 :         values[1] = pgport;
 3931 rhaas                    1547 CBC         275 :         keywords[2] = "user";
  764 michael                  1548             275 :         values[2] = username;
 3931 rhaas                    1549 GBC         275 :         keywords[3] = "password";
  948 tgl                      1550 GIC         275 :         values[3] = password;
 3931 rhaas                    1551 GBC         275 :         keywords[4] = "dbname";
                               1552             275 :         values[4] = dbName;
                               1553             275 :         keywords[5] = "fallback_application_name";
 3931 rhaas                    1554 GIC         275 :         values[5] = progname;
 3931 rhaas                    1555 CBC         275 :         keywords[6] = NULL;
 3931 rhaas                    1556 GIC         275 :         values[6] = NULL;
                               1557                 : 
 5598 tgl                      1558 CBC         275 :         new_pass = false;
                               1559                 : 
 3931 rhaas                    1560             275 :         conn = PQconnectdbParams(keywords, values, true);
 3931 rhaas                    1561 ECB             : 
 5598 tgl                      1562 CBC         275 :         if (!conn)
                               1563                 :         {
 1187 peter                    1564 UIC           0 :             pg_log_error("connection to database \"%s\" failed", dbName);
 5598 tgl                      1565 LBC           0 :             return NULL;
                               1566                 :         }
                               1567                 : 
 5598 tgl                      1568 GIC         276 :         if (PQstatus(conn) == CONNECTION_BAD &&
                               1569               1 :             PQconnectionNeedsPassword(conn) &&
  948 tgl                      1570 LBC           0 :             !password)
                               1571                 :         {
 5598                          1572               0 :             PQfinish(conn);
  948                          1573               0 :             password = simple_prompt("Password: ", false);
 5598 tgl                      1574 UIC           0 :             new_pass = true;
                               1575                 :         }
 5598 tgl                      1576 GIC         275 :     } while (new_pass);
                               1577                 : 
 5598 tgl                      1578 ECB             :     /* check to see that the backend connection was successfully made */
 5598 tgl                      1579 GIC         275 :     if (PQstatus(conn) == CONNECTION_BAD)
                               1580                 :     {
  807                          1581               1 :         pg_log_error("%s", PQerrorMessage(conn));
 5598                          1582               1 :         PQfinish(conn);
 5598 tgl                      1583 CBC           1 :         return NULL;
 7836 bruce                    1584 ECB             :     }
                               1585                 : 
 5598 tgl                      1586 GIC         274 :     return conn;
 7882 ishii                    1587 ECB             : }
                               1588                 : 
 2529 tgl                      1589                 : /* qsort comparator for Variable array */
                               1590                 : static int
 2529 tgl                      1591 CBC       53126 : compareVariableNames(const void *v1, const void *v2)
                               1592                 : {
 6393 tgl                      1593 GIC      106252 :     return strcmp(((const Variable *) v1)->name,
                               1594           53126 :                   ((const Variable *) v2)->name);
 6401 ishii                    1595 ECB             : }
                               1596                 : 
 2529 tgl                      1597                 : /* Locate a variable by name; returns NULL if unknown */
                               1598                 : static Variable *
  382 ishii                    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)
 6393 tgl                      1605 CBC         154 :         return NULL;
                               1606                 : 
                               1607                 :     /* Sort if we have to */
  382 ishii                    1608 GIC        7600 :     if (!variables->vars_sorted)
                               1609                 :     {
   61 peter                    1610 GNC         926 :         qsort(variables->vars, variables->nvars, sizeof(Variable),
 2529 tgl                      1611 ECB             :               compareVariableNames);
  382 ishii                    1612 CBC         926 :         variables->vars_sorted = true;
                               1613                 :     }
 2529 tgl                      1614 ECB             : 
                               1615                 :     /* Now we can search */
 6385 tgl                      1616 GIC        7600 :     key.name = name;
   61 peter                    1617 GNC        7600 :     return (Variable *) bsearch(&key,
                               1618            7600 :                                 variables->vars,
  382 ishii                    1619 CBC        7600 :                                 variables->nvars,
 2529 tgl                      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 *
  382 ishii                    1626 GIC        2616 : getVariable(Variables *variables, char *name)
 2529 tgl                      1627 ECB             : {
                               1628                 :     Variable   *var;
                               1629                 :     char        stringform[64];
                               1630                 : 
  382 ishii                    1631 GBC        2616 :     var = lookupVariable(variables, name);
 2529 tgl                      1632 CBC        2616 :     if (var == NULL)
                               1633               4 :         return NULL;            /* not found */
                               1634                 : 
 1916 teodor                   1635 GIC        2612 :     if (var->svalue)
                               1636            1006 :         return var->svalue;      /* we have it in string form */
                               1637                 : 
 1916 teodor                   1638 ECB             :     /* We need to produce a string equivalent of the value */
 1916 teodor                   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");
 1916 teodor                   1642 CBC        1605 :     else if (var->value.type == PGBT_BOOLEAN)
 2529 tgl                      1643               1 :         snprintf(stringform, sizeof(stringform),
 1916 teodor                   1644 GIC           1 :                  "%s", var->value.u.bval ? "true" : "false");
 1916 teodor                   1645 CBC        1604 :     else if (var->value.type == PGBT_INT)
 2529 tgl                      1646 GIC        1602 :         snprintf(stringform, sizeof(stringform),
 1916 teodor                   1647 ECB             :                  INT64_FORMAT, var->value.u.ival);
 1916 teodor                   1648 GIC           2 :     else if (var->value.type == PGBT_DOUBLE)
 1916 teodor                   1649 GBC           2 :         snprintf(stringform, sizeof(stringform),
                               1650                 :                  "%.*g", DBL_DIG, var->value.u.dval);
 1809 tgl                      1651 ECB             :     else                        /* internal error, unexpected type */
 1916 teodor                   1652 UIC           0 :         Assert(0);
 1916 teodor                   1653 CBC        1606 :     var->svalue = pg_strdup(stringform);
 1916 teodor                   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)
 2529 tgl                      1660 ECB             : {
 1809                          1661                 :     size_t      slen;
 1916 teodor                   1662                 : 
 1916 teodor                   1663 GIC        1915 :     if (var->value.type != PGBT_NO_VALUE)
 2529 tgl                      1664 CBC        1490 :         return true;            /* no work */
                               1665                 : 
 1916 teodor                   1666             425 :     slen = strlen(var->svalue);
 1916 teodor                   1667 ECB             : 
 1916 teodor                   1668 CBC         425 :     if (slen == 0)
 1916 teodor                   1669 ECB             :         /* what should it do on ""? */
 1916 teodor                   1670 UIC           0 :         return false;
 1916 teodor                   1671 ECB             : 
 1916 teodor                   1672 GIC         425 :     if (pg_strcasecmp(var->svalue, "null") == 0)
 2529 tgl                      1673 ECB             :     {
 1916 teodor                   1674 GIC           1 :         setNullValue(&var->value);
                               1675                 :     }
                               1676                 : 
                               1677                 :     /*
 1809 tgl                      1678 ECB             :      * accept prefixes such as y, ye, n, no... but not for "o". 0/1 are
 1809 tgl                      1679 EUB             :      * recognized later as an int, which is converted to bool if needed.
                               1680                 :      */
 1916 teodor                   1681 CBC         847 :     else if (pg_strncasecmp(var->svalue, "true", slen) == 0 ||
 1916 teodor                   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                 :     }
 1916 teodor                   1687 CBC         846 :     else if (pg_strncasecmp(var->svalue, "false", slen) == 0 ||
 1916 teodor                   1688 GIC         846 :              pg_strncasecmp(var->svalue, "no", slen) == 0 ||
 1916 teodor                   1689 CBC         846 :              pg_strcasecmp(var->svalue, "off") == 0 ||
 1916 teodor                   1690 GIC         423 :              pg_strcasecmp(var->svalue, "of") == 0)
 1916 teodor                   1691 ECB             :     {
 1916 teodor                   1692 GIC           1 :         setBoolValue(&var->value, false);
 1916 teodor                   1693 ECB             :     }
 1916 teodor                   1694 GIC         422 :     else if (is_an_int(var->svalue))
 1916 teodor                   1695 ECB             :     {
                               1696                 :         /* if it looks like an int, it must be an int without overflow */
                               1697                 :         int64       iv;
                               1698                 : 
 1655 andres                   1699 GIC         419 :         if (!strtoint64(var->svalue, false, &iv))
 1655 andres                   1700 UIC           0 :             return false;
                               1701                 : 
 1655 andres                   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                 :         {
 1187 peter                    1710               2 :             pg_log_error("malformed variable \"%s\" value: \"%s\"",
                               1711                 :                          var->name, var->svalue);
 2529 tgl                      1712 CBC           2 :             return false;
                               1713                 :         }
 1916 teodor                   1714               1 :         setDoubleValue(&var->value, dv);
                               1715                 :     }
 2529 tgl                      1716 GIC         423 :     return true;
 6401 ishii                    1717 ECB             : }
 6401 ishii                    1718 EUB             : 
                               1719                 : /*
                               1720                 :  * Check whether a variable's name is allowed.
 2043 tgl                      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                 :  */
 4841 itagaki.takahiro         1732                 : static bool
 2043 tgl                      1733 CBC         991 : valid_variable_name(const char *name)
 4841 itagaki.takahiro         1734 ECB             : {
 2043 tgl                      1735 GIC         991 :     const unsigned char *ptr = (const unsigned char *) name;
 2043 tgl                      1736 ECB             : 
                               1737                 :     /* Mustn't be zero-length */
 2043 tgl                      1738 GIC         991 :     if (*ptr == '\0')
 2043 tgl                      1739 LBC           0 :         return false;
                               1740                 : 
                               1741                 :     /* must not start with [0-9] */
  816 tgl                      1742 GIC         991 :     if (IS_HIGHBIT_SET(*ptr) ||
                               1743             991 :         strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
                               1744             991 :                "_", *ptr) != NULL)
                               1745             989 :         ptr++;
                               1746                 :     else
  816 tgl                      1747 CBC           2 :         return false;
                               1748                 : 
                               1749                 :     /* remaining characters can include [0-9] */
 2043                          1750            6168 :     while (*ptr)
                               1751                 :     {
                               1752            5180 :         if (IS_HIGHBIT_SET(*ptr) ||
 2043 tgl                      1753 GIC        5180 :             strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
 2043 tgl                      1754 CBC        5180 :                    "_0123456789", *ptr) != NULL)
                               1755            5179 :             ptr++;
 2043 tgl                      1756 ECB             :         else
 4841 itagaki.takahiro         1757 GIC           1 :             return false;
 4841 itagaki.takahiro         1758 ECB             :     }
                               1759                 : 
 2043 tgl                      1760 GIC         988 :     return true;
                               1761                 : }
                               1762                 : 
                               1763                 : /*
                               1764                 :  * Make sure there is enough space for 'needed' more variable in the variables
                               1765                 :  * array.
  382 ishii                    1766 ECB             :  */
                               1767                 : static void
  382 ishii                    1768 GIC         988 : enlargeVariables(Variables *variables, int needed)
                               1769                 : {
  382 ishii                    1770 ECB             :     /* total number of variables required now */
  382 ishii                    1771 CBC         988 :     needed += variables->nvars;
                               1772                 : 
  382 ishii                    1773 GIC         988 :     if (variables->max_vars < needed)
                               1774                 :     {
                               1775             161 :         variables->max_vars = needed + VARIABLES_ALLOC_MARGIN;
                               1776             161 :         variables->vars = (Variable *)
  382 ishii                    1777 CBC         161 :             pg_realloc(variables->vars, variables->max_vars * sizeof(Variable));
                               1778                 :     }
                               1779             988 : }
  382 ishii                    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.
 2529 tgl                      1784                 :  * Returns NULL on failure (bad name).
                               1785                 :  */
                               1786                 : static Variable *
  382 ishii                    1787 GIC        2949 : lookupCreateVariable(Variables *variables, const char *context, char *name)
 6401 ishii                    1788 ECB             : {
 2529 tgl                      1789                 :     Variable   *var;
                               1790                 : 
  382 ishii                    1791 GIC        2949 :     var = lookupVariable(variables, name);
 6401 ishii                    1792 CBC        2949 :     if (var == NULL)
                               1793                 :     {
 4841 itagaki.takahiro         1794 ECB             :         /*
                               1795                 :          * Check for the name only when declaring a new variable to avoid
                               1796                 :          * overhead.
                               1797                 :          */
 2043 tgl                      1798 GIC         991 :         if (!valid_variable_name(name))
                               1799                 :         {
 1187 peter                    1800               3 :             pg_log_error("%s: invalid variable name: \"%s\"", context, name);
 2529 tgl                      1801               3 :             return NULL;
                               1802                 :         }
 4841 itagaki.takahiro         1803 ECB             : 
                               1804                 :         /* Create variable at the end of the array */
  382 ishii                    1805 GIC         988 :         enlargeVariables(variables, 1);
                               1806                 : 
                               1807             988 :         var = &(variables->vars[variables->nvars]);
                               1808                 : 
 3841 tgl                      1809 CBC         988 :         var->name = pg_strdup(name);
 1916 teodor                   1810             988 :         var->svalue = NULL;
 2529 tgl                      1811 ECB             :         /* caller is expected to initialize remaining fields */
                               1812                 : 
  382 ishii                    1813 GIC         988 :         variables->nvars++;
 2529 tgl                      1814 ECB             :         /* we don't re-sort the array till we have to */
  382 ishii                    1815 GIC         988 :         variables->vars_sorted = false;
 6401 ishii                    1816 ECB             :     }
 6052                          1817                 : 
 2529 tgl                      1818 CBC        2946 :     return var;
                               1819                 : }
 2529 tgl                      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
  382 ishii                    1824 GIC         863 : putVariable(Variables *variables, const char *context, char *name,
                               1825                 :             const char *value)
 2529 tgl                      1826 ECB             : {
                               1827                 :     Variable   *var;
                               1828                 :     char       *val;
                               1829                 : 
  382 ishii                    1830 GIC         863 :     var = lookupCreateVariable(variables, context, name);
 2529 tgl                      1831 CBC         863 :     if (!var)
                               1832               2 :         return false;
 2529 tgl                      1833 ECB             : 
                               1834                 :     /* dup then free, in case value is pointing at this variable */
 2529 tgl                      1835 CBC         861 :     val = pg_strdup(value);
 6052 ishii                    1836 ECB             : 
  297 peter                    1837 GNC         861 :     free(var->svalue);
 1916 teodor                   1838 CBC         861 :     var->svalue = val;
 1916 teodor                   1839 GIC         861 :     var->value.type = PGBT_NO_VALUE;
                               1840                 : 
 2529 tgl                      1841             861 :     return true;
                               1842                 : }
                               1843                 : 
 1916 teodor                   1844 ECB             : /* Assign a value to a variable, creating it if need be */
                               1845                 : /* Returns false on failure (bad name) */
                               1846                 : static bool
  382 ishii                    1847 GIC        2086 : putVariableValue(Variables *variables, const char *context, char *name,
                               1848                 :                  const PgBenchValue *value)
 2529 tgl                      1849 ECB             : {
                               1850                 :     Variable   *var;
                               1851                 : 
  382 ishii                    1852 GIC        2086 :     var = lookupCreateVariable(variables, context, name);
 2529 tgl                      1853            2086 :     if (!var)
                               1854               1 :         return false;
                               1855                 : 
  297 peter                    1856 GNC        2085 :     free(var->svalue);
 1916 teodor                   1857 GIC        2085 :     var->svalue = NULL;
                               1858            2085 :     var->value = *value;
                               1859                 : 
 6401 ishii                    1860            2085 :     return true;
 6401 ishii                    1861 ECB             : }
                               1862                 : 
 2529 tgl                      1863                 : /* Assign an integer value to a variable, creating it if need be */
                               1864                 : /* Returns false on failure (bad name) */
                               1865                 : static bool
  382 ishii                    1866 GIC         397 : putVariableInt(Variables *variables, const char *context, char *name,
  382 ishii                    1867 ECB             :                int64 value)
 2529 tgl                      1868                 : {
                               1869                 :     PgBenchValue val;
                               1870                 : 
 2529 tgl                      1871 GIC         397 :     setIntValue(&val, value);
  382 ishii                    1872 CBC         397 :     return putVariableValue(variables, context, name, &val);
                               1873                 : }
 2529 tgl                      1874 ECB             : 
 2043                          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,
  816                          1880                 :  * and set *eaten to the number of characters consumed (including the colon).
 2043                          1881                 :  * Otherwise, return NULL.
                               1882                 :  */
 5499 ishii                    1883                 : static char *
 5499 ishii                    1884 CBC        1664 : parseVariable(const char *sql, int *eaten)
                               1885                 : {
  816 tgl                      1886 GIC        1664 :     int         i = 1;          /* starting at 1 skips the colon */
                               1887                 :     char       *name;
 5499 ishii                    1888 ECB             : 
                               1889                 :     /* keep this logic in sync with valid_variable_name() */
  816 tgl                      1890 CBC        1664 :     if (IS_HIGHBIT_SET(sql[i]) ||
  816 tgl                      1891 GIC        1664 :         strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
  816 tgl                      1892 CBC        1664 :                "_", sql[i]) != NULL)
  816 tgl                      1893 GIC        1218 :         i++;
  816 tgl                      1894 ECB             :     else
  816 tgl                      1895 GIC         446 :         return NULL;
  816 tgl                      1896 ECB             : 
  816 tgl                      1897 CBC        6211 :     while (IS_HIGHBIT_SET(sql[i]) ||
  816 tgl                      1898 GIC        6211 :            strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
                               1899            6211 :                   "_0123456789", sql[i]) != NULL)
 5499 ishii                    1900 CBC        4993 :         i++;
 5499 ishii                    1901 ECB             : 
 3841 tgl                      1902 CBC        1218 :     name = pg_malloc(i);
 5499 ishii                    1903 GIC        1218 :     memcpy(name, &sql[1], i - 1);
 5499 ishii                    1904 CBC        1218 :     name[i - 1] = '\0';
                               1905                 : 
 5499 ishii                    1906 GIC        1218 :     *eaten = i;
                               1907            1218 :     return name;
 5499 ishii                    1908 ECB             : }
                               1909                 : 
                               1910                 : static char *
 5499 ishii                    1911 GIC        1217 : replaceVariable(char **sql, char *param, int len, char *value)
                               1912                 : {
 5050 bruce                    1913            1217 :     int         valueln = strlen(value);
 5499 ishii                    1914 ECB             : 
 5499 ishii                    1915 CBC        1217 :     if (valueln > len)
                               1916                 :     {
 5050 bruce                    1917 GIC         576 :         size_t      offset = param - *sql;
                               1918                 : 
 3841 tgl                      1919 CBC         576 :         *sql = pg_realloc(*sql, strlen(*sql) - len + valueln + 1);
 5499 ishii                    1920             576 :         param = *sql + offset;
                               1921                 :     }
 5499 ishii                    1922 ECB             : 
 5499 ishii                    1923 GIC        1217 :     if (valueln != len)
 5499 ishii                    1924 CBC        1180 :         memmove(param + valueln, param + len, strlen(param + len) + 1);
 2997 tgl                      1925 GIC        1217 :     memcpy(param, value, valueln);
 5499 ishii                    1926 ECB             : 
 5499 ishii                    1927 GIC        1217 :     return param + valueln;
                               1928                 : }
 5499 ishii                    1929 ECB             : 
 6401                          1930                 : static char *
  382 ishii                    1931 CBC        3333 : assignVariables(Variables *variables, char *sql)
                               1932                 : {
 6385 bruce                    1933 EUB             :     char       *p,
                               1934                 :                *name,
                               1935                 :                *val;
                               1936                 : 
 5499 ishii                    1937 CBC        3333 :     p = sql;
 5499 ishii                    1938 GIC        4700 :     while ((p = strchr(p, ':')) != NULL)
                               1939                 :     {
 5050 bruce                    1940 ECB             :         int         eaten;
                               1941                 : 
 5499 ishii                    1942 GIC        1367 :         name = parseVariable(p, &eaten);
                               1943            1367 :         if (name == NULL)
 6385 bruce                    1944 ECB             :         {
 5050 bruce                    1945 GIC        1290 :             while (*p == ':')
                               1946                 :             {
                               1947             860 :                 p++;
                               1948                 :             }
 6401 ishii                    1949 CBC         430 :             continue;
 5499 ishii                    1950 ECB             :         }
 6401                          1951                 : 
  382 ishii                    1952 GIC         937 :         val = getVariable(variables, name);
 6401                          1953             937 :         free(name);
 6401 ishii                    1954 CBC         937 :         if (val == NULL)
                               1955                 :         {
 5499 ishii                    1956 LBC           0 :             p++;
 5499 ishii                    1957 UBC           0 :             continue;
 6401 ishii                    1958 ECB             :         }
 6401 ishii                    1959 EUB             : 
 4623 tgl                      1960 CBC         937 :         p = replaceVariable(&sql, p, eaten, val);
 5499 ishii                    1961 EUB             :     }
 6401 ishii                    1962 ECB             : 
 5499 ishii                    1963 CBC        3333 :     return sql;
 5499 ishii                    1964 ECB             : }
 6401                          1965                 : 
                               1966                 : static void
  382 ishii                    1967 GIC        2272 : getQueryParams(Variables *variables, const Command *command,
                               1968                 :                const char **params)
 5499 ishii                    1969 EUB             : {
                               1970                 :     int         i;
                               1971                 : 
 5499 ishii                    1972 GIC        3946 :     for (i = 0; i < command->argc - 1; i++)
  382                          1973            1674 :         params[i] = getVariable(variables, command->argv[i + 1]);
 5499                          1974            2272 : }
                               1975                 : 
 1916 teodor                   1976 ECB             : static char *
 1916 teodor                   1977 GIC           4 : valueTypeName(PgBenchValue *pval)
 1916 teodor                   1978 ECB             : {
 1916 teodor                   1979 GIC           4 :     if (pval->type == PGBT_NO_VALUE)
 1916 teodor                   1980 LBC           0 :         return "none";
 1916 teodor                   1981 CBC           4 :     else if (pval->type == PGBT_NULL)
 1916 teodor                   1982 UIC           0 :         return "null";
 1916 teodor                   1983 GIC           4 :     else if (pval->type == PGBT_INT)
 1916 teodor                   1984 UIC           0 :         return "int";
 1916 teodor                   1985 CBC           4 :     else if (pval->type == PGBT_DOUBLE)
                               1986               1 :         return "double";
                               1987               3 :     else if (pval->type == PGBT_BOOLEAN)
 1916 teodor                   1988 GIC           3 :         return "boolean";
                               1989                 :     else
                               1990                 :     {
                               1991                 :         /* internal error, should never get there */
 1916 teodor                   1992 UIC           0 :         Assert(false);
                               1993                 :         return NULL;
                               1994                 :     }
                               1995                 : }
 1916 teodor                   1996 ECB             : 
                               1997                 : /* get a value as a boolean, or tell if there is a problem */
                               1998                 : static bool
 1916 teodor                   1999 GIC         108 : coerceToBool(PgBenchValue *pval, bool *bval)
 1916 teodor                   2000 ECB             : {
 1916 teodor                   2001 CBC         108 :     if (pval->type == PGBT_BOOLEAN)
 1916 teodor                   2002 ECB             :     {
 1916 teodor                   2003 CBC         107 :         *bval = pval->u.bval;
                               2004             107 :         return true;
 1916 teodor                   2005 ECB             :     }
 1809 tgl                      2006                 :     else                        /* NULL, INT or DOUBLE */
 1916 teodor                   2007                 :     {
 1187 peter                    2008 GBC           1 :         pg_log_error("cannot coerce %s to boolean", valueTypeName(pval));
 1880 tgl                      2009 GIC           1 :         *bval = false;          /* suppress uninitialized-variable warnings */
 1916 teodor                   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.
 1916 teodor                   2017 ECB             :  */
                               2018                 : static bool
 1916 teodor                   2019 CBC         432 : valueTruth(PgBenchValue *pval)
                               2020                 : {
                               2021             432 :     switch (pval->type)
 1916 teodor                   2022 ECB             :     {
 1916 teodor                   2023 GIC           1 :         case PGBT_NULL:
 1916 teodor                   2024 CBC           1 :             return false;
 1916 teodor                   2025 GIC          21 :         case PGBT_BOOLEAN:
 1916 teodor                   2026 CBC          21 :             return pval->u.bval;
 1916 teodor                   2027 GIC         409 :         case PGBT_INT:
 1916 teodor                   2028 CBC         409 :             return pval->u.ival != 0;
 1916 teodor                   2029 GIC           1 :         case PGBT_DOUBLE:
 1916 teodor                   2030 CBC           1 :             return pval->u.dval != 0.0;
 1916 teodor                   2031 LBC           0 :         default:
                               2032                 :             /* internal error, unexpected type */
                               2033               0 :             Assert(0);
 1916 teodor                   2034 ECB             :             return false;
                               2035                 :     }
                               2036                 : }
                               2037                 : 
 2568 rhaas                    2038                 : /* get a value as an int, tell if there is a problem */
                               2039                 : static bool
 2568 rhaas                    2040 GIC        6568 : coerceToInt(PgBenchValue *pval, int64 *ival)
                               2041                 : {
                               2042            6568 :     if (pval->type == PGBT_INT)
                               2043                 :     {
                               2044            6564 :         *ival = pval->u.ival;
 2568 rhaas                    2045 CBC        6564 :         return true;
                               2046                 :     }
 1916 teodor                   2047               4 :     else if (pval->type == PGBT_DOUBLE)
                               2048                 :     {
 1249 tgl                      2049               2 :         double      dval = rint(pval->u.dval);
 2495 rhaas                    2050 ECB             : 
 1249 tgl                      2051 GIC           2 :         if (isnan(dval) || !FLOAT8_FITS_IN_INT64(dval))
 2568 rhaas                    2052 ECB             :         {
 1187 peter                    2053 GIC           1 :             pg_log_error("double to int overflow for %f", dval);
 2568 rhaas                    2054 CBC           1 :             return false;
 2568 rhaas                    2055 ECB             :         }
 2568 rhaas                    2056 GIC           1 :         *ival = (int64) dval;
                               2057               1 :         return true;
                               2058                 :     }
 1809 tgl                      2059 ECB             :     else                        /* BOOLEAN or NULL */
 1916 teodor                   2060                 :     {
 1187 peter                    2061 GIC           2 :         pg_log_error("cannot coerce %s to int", valueTypeName(pval));
 1916 teodor                   2062               2 :         return false;
                               2063                 :     }
                               2064                 : }
                               2065                 : 
 2568 rhaas                    2066 ECB             : /* get a value as a double, or tell if there is a problem */
                               2067                 : static bool
 2568 rhaas                    2068 CBC         104 : coerceToDouble(PgBenchValue *pval, double *dval)
 2568 rhaas                    2069 ECB             : {
 2568 rhaas                    2070 CBC         104 :     if (pval->type == PGBT_DOUBLE)
                               2071                 :     {
 2568 rhaas                    2072 GIC          73 :         *dval = pval->u.dval;
                               2073              73 :         return true;
 2568 rhaas                    2074 ECB             :     }
 1916 teodor                   2075 GIC          31 :     else if (pval->type == PGBT_INT)
 2568 rhaas                    2076 ECB             :     {
 2568 rhaas                    2077 CBC          30 :         *dval = (double) pval->u.ival;
                               2078              30 :         return true;
                               2079                 :     }
                               2080                 :     else                        /* BOOLEAN or NULL */
                               2081                 :     {
 1187 peter                    2082               1 :         pg_log_error("cannot coerce %s to double", valueTypeName(pval));
 1916 teodor                   2083 GIC           1 :         return false;
 1916 teodor                   2084 ECB             :     }
                               2085                 : }
                               2086                 : 
                               2087                 : /* assign a null value */
                               2088                 : static void
 1916 teodor                   2089 GIC           4 : setNullValue(PgBenchValue *pv)
 1916 teodor                   2090 ECB             : {
 1916 teodor                   2091 GIC           4 :     pv->type = PGBT_NULL;
 1916 teodor                   2092 CBC           4 :     pv->u.ival = 0;
                               2093               4 : }
 1916 teodor                   2094 ECB             : 
                               2095                 : /* assign a boolean value */
                               2096                 : static void
 1916 teodor                   2097 CBC         134 : setBoolValue(PgBenchValue *pv, bool bval)
                               2098                 : {
                               2099             134 :     pv->type = PGBT_BOOLEAN;
 1916 teodor                   2100 GIC         134 :     pv->u.bval = bval;
 2568 rhaas                    2101             134 : }
                               2102                 : 
                               2103                 : /* assign an integer value */
 2568 rhaas                    2104 ECB             : static void
 2568 rhaas                    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 */
 2568 rhaas                    2112 ECB             : static void
 2568 rhaas                    2113 GIC          39 : setDoubleValue(PgBenchValue *pv, double dval)
                               2114                 : {
 2568 rhaas                    2115 CBC          39 :     pv->type = PGBT_DOUBLE;
                               2116              39 :     pv->u.dval = dval;
 2568 rhaas                    2117 GIC          39 : }
                               2118                 : 
 1809 tgl                      2119 ECB             : static bool
 1809 tgl                      2120 GIC        3555 : isLazyFunc(PgBenchFunction func)
 1916 teodor                   2121 ECB             : {
 1916 teodor                   2122 GIC        3555 :     return func == PGBENCH_AND || func == PGBENCH_OR || func == PGBENCH_CASE;
 1916 teodor                   2123 ECB             : }
                               2124                 : 
                               2125                 : /* lazy evaluation of some functions */
 1916 teodor                   2126 EUB             : static bool
 1467 tgl                      2127 GBC          65 : evalLazyFunc(CState *st,
                               2128                 :              PgBenchFunction func, PgBenchExprLink *args, PgBenchValue *retval)
                               2129                 : {
 1809 tgl                      2130 ECB             :     PgBenchValue a1,
 1809 tgl                      2131 EUB             :                 a2;
                               2132                 :     bool        ba1,
 1809 tgl                      2133 ECB             :                 ba2;
                               2134                 : 
 1916 teodor                   2135 CBC          65 :     Assert(isLazyFunc(func) && args != NULL && args->next != NULL);
 1916 teodor                   2136 ECB             : 
                               2137                 :     /* args points to first condition */
 1467 tgl                      2138 GIC          65 :     if (!evaluateExpr(st, args->expr, &a1))
 1916 teodor                   2139 CBC           1 :         return false;
 1916 teodor                   2140 EUB             : 
                               2141                 :     /* second condition for AND/OR and corresponding branch for CASE */
 1916 teodor                   2142 CBC          64 :     args = args->next;
                               2143                 : 
 1916 teodor                   2144 GBC          64 :     switch (func)
 1916 teodor                   2145 EUB             :     {
 1809 tgl                      2146 GIC          44 :         case PGBENCH_AND:
 1809 tgl                      2147 CBC          44 :             if (a1.type == PGBT_NULL)
 1809 tgl                      2148 EUB             :             {
 1809 tgl                      2149 UIC           0 :                 setNullValue(retval);
                               2150               0 :                 return true;
 1809 tgl                      2151 ECB             :             }
 1916 teodor                   2152                 : 
 1809 tgl                      2153 GIC          44 :             if (!coerceToBool(&a1, &ba1))
 1809 tgl                      2154 UIC           0 :                 return false;
                               2155                 : 
 1809 tgl                      2156 GIC          44 :             if (!ba1)
 1809 tgl                      2157 ECB             :             {
 1809 tgl                      2158 GIC           3 :                 setBoolValue(retval, false);
 1809 tgl                      2159 CBC           3 :                 return true;
                               2160                 :             }
 1916 teodor                   2161 EUB             : 
 1467 tgl                      2162 GBC          41 :             if (!evaluateExpr(st, args->expr, &a2))
 1809 tgl                      2163 UIC           0 :                 return false;
                               2164                 : 
 1809 tgl                      2165 CBC          41 :             if (a2.type == PGBT_NULL)
 1809 tgl                      2166 EUB             :             {
 1809 tgl                      2167 UIC           0 :                 setNullValue(retval);
 1809 tgl                      2168 LBC           0 :                 return true;
                               2169                 :             }
 1809 tgl                      2170 CBC          41 :             else if (!coerceToBool(&a2, &ba2))
 1809 tgl                      2171 LBC           0 :                 return false;
                               2172                 :             else
                               2173                 :             {
 1809 tgl                      2174 CBC          41 :                 setBoolValue(retval, ba2);
 1809 tgl                      2175 GBC          41 :                 return true;
                               2176                 :             }
 1916 teodor                   2177 ECB             : 
                               2178                 :             return true;
 1916 teodor                   2179 EUB             : 
 1809 tgl                      2180 GBC           4 :         case PGBENCH_OR:
                               2181                 : 
 1809 tgl                      2182 CBC           4 :             if (a1.type == PGBT_NULL)
 1809 tgl                      2183 EUB             :             {
 1809 tgl                      2184 UIC           0 :                 setNullValue(retval);
                               2185               0 :                 return true;
 1809 tgl                      2186 ECB             :             }
 1916 teodor                   2187                 : 
 1809 tgl                      2188 GIC           4 :             if (!coerceToBool(&a1, &ba1))
 1809 tgl                      2189 UIC           0 :                 return false;
 1916 teodor                   2190 ECB             : 
 1809 tgl                      2191 GIC           4 :             if (ba1)
 1809 tgl                      2192 ECB             :             {
 1809 tgl                      2193 CBC           1 :                 setBoolValue(retval, true);
 1809 tgl                      2194 GIC           1 :                 return true;
                               2195                 :             }
 1916 teodor                   2196 ECB             : 
 1467 tgl                      2197 GIC           3 :             if (!evaluateExpr(st, args->expr, &a2))
 1809 tgl                      2198 UIC           0 :                 return false;
 1916 teodor                   2199 ECB             : 
 1809 tgl                      2200 CBC           3 :             if (a2.type == PGBT_NULL)
                               2201                 :             {
 1809 tgl                      2202 UIC           0 :                 setNullValue(retval);
 1809 tgl                      2203 LBC           0 :                 return true;
                               2204                 :             }
 1809 tgl                      2205 GBC           3 :             else if (!coerceToBool(&a2, &ba2))
 1809 tgl                      2206 UIC           0 :                 return false;
 1809 tgl                      2207 EUB             :             else
                               2208                 :             {
 1809 tgl                      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))
 1467                          2216              11 :                 return evaluateExpr(st, args->expr, retval);
                               2217                 : 
                               2218                 :             /* now args contains next condition or final else expression */
 1809                          2219               5 :             args = args->next;
                               2220                 : 
 1809 tgl                      2221 ECB             :             /* final else case? */
 1809 tgl                      2222 GIC           5 :             if (args->next == NULL)
 1467                          2223               3 :                 return evaluateExpr(st, args->expr, retval);
                               2224                 : 
                               2225                 :             /* no, another when, proceed */
 1467 tgl                      2226 CBC           2 :             return evalLazyFunc(st, PGBENCH_CASE, args, retval);
                               2227                 : 
 1809 tgl                      2228 LBC           0 :         default:
 1809 tgl                      2229 ECB             :             /* internal error, cannot get here */
 1809 tgl                      2230 UIC           0 :             Assert(0);
 1809 tgl                      2231 ECB             :             break;
                               2232                 :     }
 1916 teodor                   2233                 :     return false;
                               2234                 : }
                               2235                 : 
                               2236                 : /* maximum number of function arguments */
                               2237                 : #define MAX_FARGS 16
 2595 rhaas                    2238                 : 
                               2239                 : /*
 1916 teodor                   2240                 :  * Recursive evaluation of standard functions,
                               2241                 :  * which do not require lazy evaluation.
                               2242                 :  */
                               2243                 : static bool
 1467 tgl                      2244 GIC        3427 : evalStandardFunc(CState *st,
 1880 tgl                      2245 ECB             :                  PgBenchFunction func, PgBenchExprLink *args,
                               2246                 :                  PgBenchValue *retval)
 2960 rhaas                    2247                 : {
 2595                          2248                 :     /* evaluate all function arguments */
 1809 tgl                      2249 GIC        3427 :     int         nargs = 0;
                               2250                 :     PgBenchValue vargs[MAX_FARGS];
 2595 rhaas                    2251            3427 :     PgBenchExprLink *l = args;
 1809 tgl                      2252 CBC        3427 :     bool        has_null = false;
                               2253                 : 
 2595 rhaas                    2254 GIC       10244 :     for (nargs = 0; nargs < MAX_FARGS && l != NULL; nargs++, l = l->next)
 1916 teodor                   2255 ECB             :     {
 1467 tgl                      2256 GIC        6819 :         if (!evaluateExpr(st, l->expr, &vargs[nargs]))
 2595 rhaas                    2257               2 :             return false;
 1916 teodor                   2258            6817 :         has_null |= vargs[nargs].type == PGBT_NULL;
                               2259                 :     }
                               2260                 : 
 2595 rhaas                    2261            3425 :     if (l != NULL)
                               2262                 :     {
 1187 peter                    2263               1 :         pg_log_error("too many function arguments, maximum is %d", MAX_FARGS);
 2595 rhaas                    2264               1 :         return false;
 2595 rhaas                    2265 ECB             :     }
 2960                          2266                 : 
                               2267                 :     /* NULL arguments */
 1916 teodor                   2268 CBC        3424 :     if (has_null && func != PGBENCH_IS && func != PGBENCH_DEBUG)
                               2269                 :     {
 1916 teodor                   2270 GIC           3 :         setNullValue(retval);
 1916 teodor                   2271 CBC           3 :         return true;
 1916 teodor                   2272 ECB             :     }
                               2273                 : 
                               2274                 :     /* then evaluate function */
 2595 rhaas                    2275 GIC        3421 :     switch (func)
                               2276                 :     {
 2495 rhaas                    2277 ECB             :             /* overloaded operators */
 2595 rhaas                    2278 CBC        1689 :         case PGBENCH_ADD:
 2595 rhaas                    2279 ECB             :         case PGBENCH_SUB:
                               2280                 :         case PGBENCH_MUL:
                               2281                 :         case PGBENCH_DIV:
                               2282                 :         case PGBENCH_MOD:
 1916 teodor                   2283                 :         case PGBENCH_EQ:
                               2284                 :         case PGBENCH_NE:
                               2285                 :         case PGBENCH_LE:
                               2286                 :         case PGBENCH_LT:
 2960 rhaas                    2287                 :             {
 2495 rhaas                    2288 CBC        1689 :                 PgBenchValue *lval = &vargs[0],
                               2289            1689 :                            *rval = &vargs[1];
                               2290                 : 
 2595                          2291            1689 :                 Assert(nargs == 2);
 2595 rhaas                    2292 ECB             : 
 2568                          2293                 :                 /* overloaded type management, double if some double */
 2568 rhaas                    2294 GIC        1689 :                 if ((lval->type == PGBT_DOUBLE ||
 2568 rhaas                    2295 CBC        1689 :                      rval->type == PGBT_DOUBLE) && func != PGBENCH_MOD)
 2960 rhaas                    2296 ECB             :                 {
 2495                          2297                 :                     double      ld,
                               2298                 :                                 rd;
 2960                          2299                 : 
 2568 rhaas                    2300 CBC          31 :                     if (!coerceToDouble(lval, &ld) ||
                               2301              31 :                         !coerceToDouble(rval, &rd))
 2568 rhaas                    2302 GIC          31 :                         return false;
 2960 rhaas                    2303 ECB             : 
 2568 rhaas                    2304 CBC          31 :                     switch (func)
 2568 rhaas                    2305 ECB             :                     {
 2568 rhaas                    2306 GIC           1 :                         case PGBENCH_ADD:
 2568 rhaas                    2307 CBC           1 :                             setDoubleValue(retval, ld + rd);
                               2308               1 :                             return true;
 2960 rhaas                    2309 ECB             : 
 2568 rhaas                    2310 GIC          10 :                         case PGBENCH_SUB:
 2568 rhaas                    2311 CBC          10 :                             setDoubleValue(retval, ld - rd);
                               2312              10 :                             return true;
 2568 rhaas                    2313 ECB             : 
 2568 rhaas                    2314 GIC           8 :                         case PGBENCH_MUL:
 2568 rhaas                    2315 GBC           8 :                             setDoubleValue(retval, ld * rd);
 2568 rhaas                    2316 GIC           8 :                             return true;
 2568 rhaas                    2317 EUB             : 
 2568 rhaas                    2318 GIC           2 :                         case PGBENCH_DIV:
                               2319               2 :                             setDoubleValue(retval, ld / rd);
                               2320               2 :                             return true;
                               2321                 : 
 1916 teodor                   2322               4 :                         case PGBENCH_EQ:
                               2323               4 :                             setBoolValue(retval, ld == rd);
                               2324               4 :                             return true;
                               2325                 : 
 1916 teodor                   2326 CBC           2 :                         case PGBENCH_NE:
                               2327               2 :                             setBoolValue(retval, ld != rd);
                               2328               2 :                             return true;
                               2329                 : 
                               2330               2 :                         case PGBENCH_LE:
 1916 teodor                   2331 GIC           2 :                             setBoolValue(retval, ld <= rd);
 1916 teodor                   2332 CBC           2 :                             return true;
 1916 teodor                   2333 ECB             : 
 1916 teodor                   2334 GIC           2 :                         case PGBENCH_LT:
 1916 teodor                   2335 CBC           2 :                             setBoolValue(retval, ld < rd);
                               2336               2 :                             return true;
                               2337                 : 
 2568 rhaas                    2338 LBC           0 :                         default:
 2568 rhaas                    2339 ECB             :                             /* cannot get here */
 2568 rhaas                    2340 UIC           0 :                             Assert(0);
 2568 rhaas                    2341 ECB             :                     }
                               2342                 :                 }
                               2343                 :                 else            /* we have integer operands, or % */
                               2344                 :                 {
 2495                          2345                 :                     int64       li,
                               2346                 :                                 ri,
 1655 andres                   2347                 :                                 res;
 2568 rhaas                    2348                 : 
 2568 rhaas                    2349 GIC        1658 :                     if (!coerceToInt(lval, &li) ||
 2568 rhaas                    2350 CBC        1657 :                         !coerceToInt(rval, &ri))
                               2351            1658 :                         return false;
                               2352                 : 
                               2353            1657 :                     switch (func)
 2568 rhaas                    2354 ECB             :                     {
 2568 rhaas                    2355 GIC          44 :                         case PGBENCH_ADD:
 1655 andres                   2356 CBC          44 :                             if (pg_add_s64_overflow(li, ri, &res))
 1655 andres                   2357 ECB             :                             {
 1187 peter                    2358 GIC           1 :                                 pg_log_error("bigint add out of range");
 1655 andres                   2359 CBC           1 :                                 return false;
 1655 andres                   2360 ECB             :                             }
 1655 andres                   2361 CBC          43 :                             setIntValue(retval, res);
 2568 rhaas                    2362 GIC          43 :                             return true;
 2568 rhaas                    2363 ECB             : 
 2568 rhaas                    2364 CBC         149 :                         case PGBENCH_SUB:
 1655 andres                   2365             149 :                             if (pg_sub_s64_overflow(li, ri, &res))
                               2366                 :                             {
 1187 peter                    2367               1 :                                 pg_log_error("bigint sub out of range");
 1655 andres                   2368               1 :                                 return false;
 1655 andres                   2369 ECB             :                             }
 1655 andres                   2370 GIC         148 :                             setIntValue(retval, res);
 2568 rhaas                    2371 CBC         148 :                             return true;
 2568 rhaas                    2372 ECB             : 
 2568 rhaas                    2373 CBC        1406 :                         case PGBENCH_MUL:
 1655 andres                   2374 GIC        1406 :                             if (pg_mul_s64_overflow(li, ri, &res))
 1655 andres                   2375 ECB             :                             {
 1187 peter                    2376 GIC           1 :                                 pg_log_error("bigint mul out of range");
 1655 andres                   2377 CBC           1 :                                 return false;
                               2378                 :                             }
                               2379            1405 :                             setIntValue(retval, res);
 2568 rhaas                    2380            1405 :                             return true;
                               2381                 : 
 1916 teodor                   2382 GIC          27 :                         case PGBENCH_EQ:
 1916 teodor                   2383 CBC          27 :                             setBoolValue(retval, li == ri);
 1916 teodor                   2384 GIC          27 :                             return true;
 1916 teodor                   2385 ECB             : 
 1916 teodor                   2386 GIC           5 :                         case PGBENCH_NE:
                               2387               5 :                             setBoolValue(retval, li != ri);
 1916 teodor                   2388 CBC           5 :                             return true;
                               2389                 : 
                               2390               5 :                         case PGBENCH_LE:
                               2391               5 :                             setBoolValue(retval, li <= ri);
 1916 teodor                   2392 GIC           5 :                             return true;
                               2393                 : 
 1916 teodor                   2394 CBC          12 :                         case PGBENCH_LT:
 1916 teodor                   2395 GIC          12 :                             setBoolValue(retval, li < ri);
                               2396              12 :                             return true;
 1916 teodor                   2397 ECB             : 
 2568 rhaas                    2398 CBC           9 :                         case PGBENCH_DIV:
                               2399                 :                         case PGBENCH_MOD:
 2568 rhaas                    2400 GIC           9 :                             if (ri == 0)
 2568 rhaas                    2401 ECB             :                             {
 1187 peter                    2402 CBC           1 :                                 pg_log_error("division by zero");
 2568 rhaas                    2403 GIC           1 :                                 return false;
 2568 rhaas                    2404 ECB             :                             }
                               2405                 :                             /* special handling of -1 divisor */
 2568 rhaas                    2406 CBC           8 :                             if (ri == -1)
                               2407                 :                             {
 2568 rhaas                    2408 GBC           3 :                                 if (func == PGBENCH_DIV)
                               2409                 :                                 {
 2568 rhaas                    2410 EUB             :                                     /* overflow check (needed for INT64_MIN) */
 2568 rhaas                    2411 GIC           2 :                                     if (li == PG_INT64_MIN)
                               2412                 :                                     {
 1187 peter                    2413               1 :                                         pg_log_error("bigint div out of range");
 2568 rhaas                    2414               1 :                                         return false;
                               2415                 :                                     }
                               2416                 :                                     else
 2495                          2417               1 :                                         setIntValue(retval, -li);
                               2418                 :                                 }
 2595 rhaas                    2419 ECB             :                                 else
 2568 rhaas                    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);
 2568 rhaas                    2428 ECB             : 
 2595 rhaas                    2429 GBC           5 :                             return true;
                               2430                 : 
 2568 rhaas                    2431 LBC           0 :                         default:
 2568 rhaas                    2432 ECB             :                             /* cannot get here */
 2568 rhaas                    2433 LBC           0 :                             Assert(0);
 2568 rhaas                    2434 ECB             :                     }
 2595                          2435                 :                 }
 1804 tgl                      2436                 : 
 1803                          2437                 :                 Assert(0);
                               2438                 :                 return false;   /* NOTREACHED */
 2595 rhaas                    2439                 :             }
 2624                          2440                 : 
                               2441                 :             /* integer bitwise operators */
 1916 teodor                   2442 GBC          14 :         case PGBENCH_BITAND:
                               2443                 :         case PGBENCH_BITOR:
 1916 teodor                   2444 ECB             :         case PGBENCH_BITXOR:
                               2445                 :         case PGBENCH_LSHIFT:
                               2446                 :         case PGBENCH_RSHIFT:
                               2447                 :             {
 1809 tgl                      2448                 :                 int64       li,
                               2449                 :                             ri;
                               2450                 : 
 1916 teodor                   2451 GIC          14 :                 if (!coerceToInt(&vargs[0], &li) || !coerceToInt(&vargs[1], &ri))
 1916 teodor                   2452 LBC           0 :                     return false;
 1916 teodor                   2453 ECB             : 
 1916 teodor                   2454 GIC          14 :                 if (func == PGBENCH_BITAND)
 1916 teodor                   2455 CBC           1 :                     setIntValue(retval, li & ri);
                               2456              13 :                 else if (func == PGBENCH_BITOR)
 1916 teodor                   2457 GIC           2 :                     setIntValue(retval, li | ri);
                               2458              11 :                 else if (func == PGBENCH_BITXOR)
                               2459               3 :                     setIntValue(retval, li ^ ri);
 1916 teodor                   2460 CBC           8 :                 else if (func == PGBENCH_LSHIFT)
                               2461               7 :                     setIntValue(retval, li << ri);
                               2462               1 :                 else if (func == PGBENCH_RSHIFT)
 1916 teodor                   2463 GIC           1 :                     setIntValue(retval, li >> ri);
                               2464                 :                 else            /* cannot get here */
 1916 teodor                   2465 LBC           0 :                     Assert(0);
                               2466                 : 
 1916 teodor                   2467 CBC          14 :                 return true;
                               2468                 :             }
 1916 teodor                   2469 ECB             : 
                               2470                 :             /* logical operators */
 1916 teodor                   2471 CBC          16 :         case PGBENCH_NOT:
                               2472                 :             {
 1809 tgl                      2473 ECB             :                 bool        b;
                               2474                 : 
 1916 teodor                   2475 CBC          16 :                 if (!coerceToBool(&vargs[0], &b))
 1916 teodor                   2476 GIC           1 :                     return false;
                               2477                 : 
                               2478              15 :                 setBoolValue(retval, !b);
 1916 teodor                   2479 CBC          15 :                 return true;
                               2480                 :             }
 1916 teodor                   2481 ECB             : 
 2495 rhaas                    2482                 :             /* no arguments */
 2568 rhaas                    2483 GIC           1 :         case PGBENCH_PI:
                               2484               1 :             setDoubleValue(retval, M_PI);
 2568 rhaas                    2485 CBC           1 :             return true;
                               2486                 : 
                               2487                 :             /* 1 overloaded argument */
 2595                          2488               2 :         case PGBENCH_ABS:
                               2489                 :             {
 2568                          2490               2 :                 PgBenchValue *varg = &vargs[0];
                               2491                 : 
 2595                          2492               2 :                 Assert(nargs == 1);
                               2493                 : 
 2568                          2494               2 :                 if (varg->type == PGBT_INT)
 2568 rhaas                    2495 ECB             :                 {
 2495 rhaas                    2496 GIC           1 :                     int64       i = varg->u.ival;
 2495 rhaas                    2497 ECB             : 
 2568 rhaas                    2498 CBC           1 :                     setIntValue(retval, i < 0 ? -i : i);
 2568 rhaas                    2499 ECB             :                 }
 2595                          2500                 :                 else
 2568                          2501                 :                 {
 2495 rhaas                    2502 CBC           1 :                     double      d = varg->u.dval;
 2495 rhaas                    2503 ECB             : 
 2568 rhaas                    2504 CBC           1 :                     Assert(varg->type == PGBT_DOUBLE);
 2495 rhaas                    2505 GIC           1 :                     setDoubleValue(retval, d < 0.0 ? -d : d);
 2568 rhaas                    2506 EUB             :                 }
                               2507                 : 
 2595 rhaas                    2508 CBC           2 :                 return true;
                               2509                 :             }
 2595 rhaas                    2510 ECB             : 
 2595 rhaas                    2511 GIC          84 :         case PGBENCH_DEBUG:
                               2512                 :             {
 2568                          2513              84 :                 PgBenchValue *varg = &vargs[0];
 2495 rhaas                    2514 ECB             : 
 2568 rhaas                    2515 GIC          84 :                 Assert(nargs == 1);
                               2516                 : 
 2495                          2517              84 :                 fprintf(stderr, "debug(script=%d,command=%d): ",
 2386 heikki.linnakangas       2518              84 :                         st->use_file, st->command + 1);
                               2519                 : 
 1916 teodor                   2520              84 :                 if (varg->type == PGBT_NULL)
 1916 teodor                   2521 CBC           2 :                     fprintf(stderr, "null\n");
 1916 teodor                   2522 GIC          82 :                 else if (varg->type == PGBT_BOOLEAN)
 1916 teodor                   2523 CBC          19 :                     fprintf(stderr, "boolean %s\n", varg->u.bval ? "true" : "false");
                               2524              63 :                 else if (varg->type == PGBT_INT)
 2495 rhaas                    2525 GIC          47 :                     fprintf(stderr, "int " INT64_FORMAT "\n", varg->u.ival);
 1916 teodor                   2526 CBC          16 :                 else if (varg->type == PGBT_DOUBLE)
 2529 tgl                      2527              16 :                     fprintf(stderr, "double %.*g\n", DBL_DIG, varg->u.dval);
 1809 tgl                      2528 ECB             :                 else            /* internal error, unexpected type */
 1916 teodor                   2529 LBC           0 :                     Assert(0);
 2568 rhaas                    2530 ECB             : 
 2568 rhaas                    2531 CBC          84 :                 *retval = *varg;
                               2532                 : 
 2568 rhaas                    2533 GIC          84 :                 return true;
 2568 rhaas                    2534 ECB             :             }
                               2535                 : 
                               2536                 :             /* 1 double argument */
 2568 rhaas                    2537 GIC           5 :         case PGBENCH_DOUBLE:
                               2538                 :         case PGBENCH_SQRT:
 1916 teodor                   2539 ECB             :         case PGBENCH_LN:
                               2540                 :         case PGBENCH_EXP:
                               2541                 :             {
                               2542                 :                 double      dval;
 2495 rhaas                    2543                 : 
 2595 rhaas                    2544 GIC           5 :                 Assert(nargs == 1);
 2595 rhaas                    2545 ECB             : 
 2568 rhaas                    2546 CBC           5 :                 if (!coerceToDouble(&vargs[0], &dval))
 2568 rhaas                    2547 GIC           1 :                     return false;
 2568 rhaas                    2548 ECB             : 
 2568 rhaas                    2549 CBC           4 :                 if (func == PGBENCH_SQRT)
 2568 rhaas                    2550 GIC           1 :                     dval = sqrt(dval);
 1916 teodor                   2551               3 :                 else if (func == PGBENCH_LN)
                               2552               1 :                     dval = log(dval);
 1916 teodor                   2553 CBC           2 :                 else if (func == PGBENCH_EXP)
 1916 teodor                   2554 GIC           1 :                     dval = exp(dval);
                               2555                 :                 /* else is cast: do nothing */
                               2556                 : 
 2568 rhaas                    2557               4 :                 setDoubleValue(retval, dval);
                               2558               4 :                 return true;
 2568 rhaas                    2559 ECB             :             }
                               2560                 : 
                               2561                 :             /* 1 int argument */
 2568 rhaas                    2562 CBC           2 :         case PGBENCH_INT:
 2568 rhaas                    2563 ECB             :             {
                               2564                 :                 int64       ival;
 2495                          2565                 : 
 2568 rhaas                    2566 GIC           2 :                 Assert(nargs == 1);
 2595 rhaas                    2567 ECB             : 
 2568 rhaas                    2568 CBC           2 :                 if (!coerceToInt(&vargs[0], &ival))
 2568 rhaas                    2569 GIC           1 :                     return false;
                               2570                 : 
 2568 rhaas                    2571 CBC           1 :                 setIntValue(retval, ival);
 2595 rhaas                    2572 GIC           1 :                 return true;
                               2573                 :             }
                               2574                 : 
 2495 rhaas                    2575 ECB             :             /* variable number of arguments */
 2530 tgl                      2576 GBC           4 :         case PGBENCH_LEAST:
 2530 tgl                      2577 ECB             :         case PGBENCH_GREATEST:
                               2578                 :             {
                               2579                 :                 bool        havedouble;
                               2580                 :                 int         i;
 2595 rhaas                    2581                 : 
 2530 tgl                      2582 GBC           4 :                 Assert(nargs >= 1);
 2568 rhaas                    2583 ECB             : 
 2530 tgl                      2584                 :                 /* need double result if any input is double */
 2530 tgl                      2585 GIC           4 :                 havedouble = false;
 2530 tgl                      2586 CBC          14 :                 for (i = 0; i < nargs; i++)
                               2587                 :                 {
                               2588              12 :                     if (vargs[i].type == PGBT_DOUBLE)
                               2589                 :                     {
 2530 tgl                      2590 GIC           2 :                         havedouble = true;
                               2591               2 :                         break;
                               2592                 :                     }
                               2593                 :                 }
 2530 tgl                      2594 CBC           4 :                 if (havedouble)
 2595 rhaas                    2595 EUB             :                 {
 2530 tgl                      2596 ECB             :                     double      extremum;
                               2597                 : 
 2530 tgl                      2598 GIC           2 :                     if (!coerceToDouble(&vargs[0], &extremum))
 2568 rhaas                    2599 UIC           0 :                         return false;
 2530 tgl                      2600 CBC           6 :                     for (i = 1; i < nargs; i++)
 2530 tgl                      2601 EUB             :                     {
 2530 tgl                      2602 ECB             :                         double      dval;
                               2603                 : 
 2530 tgl                      2604 GIC           4 :                         if (!coerceToDouble(&vargs[i], &dval))
 2530 tgl                      2605 LBC           0 :                             return false;
 2530 tgl                      2606 GIC           4 :                         if (func == PGBENCH_LEAST)
 2530 tgl                      2607 CBC           2 :                             extremum = Min(extremum, dval);
                               2608                 :                         else
                               2609               2 :                             extremum = Max(extremum, dval);
                               2610                 :                     }
 2530 tgl                      2611 GIC           2 :                     setDoubleValue(retval, extremum);
                               2612                 :                 }
 2530 tgl                      2613 ECB             :                 else
                               2614                 :                 {
                               2615                 :                     int64       extremum;
                               2616                 : 
 2530 tgl                      2617 GIC           2 :                     if (!coerceToInt(&vargs[0], &extremum))
 2530 tgl                      2618 UIC           0 :                         return false;
 2530 tgl                      2619 GIC           8 :                     for (i = 1; i < nargs; i++)
                               2620                 :                     {
                               2621                 :                         int64       ival;
 2530 tgl                      2622 ECB             : 
 2530 tgl                      2623 GIC           6 :                         if (!coerceToInt(&vargs[i], &ival))
 2530 tgl                      2624 LBC           0 :                             return false;
 2530 tgl                      2625 CBC           6 :                         if (func == PGBENCH_LEAST)
                               2626               3 :                             extremum = Min(extremum, ival);
                               2627                 :                         else
 2530 tgl                      2628 GIC           3 :                             extremum = Max(extremum, ival);
 2530 tgl                      2629 ECB             :                     }
 2530 tgl                      2630 GIC           2 :                     setIntValue(retval, extremum);
 2530 tgl                      2631 ECB             :                 }
 2595 rhaas                    2632 CBC           4 :                 return true;
                               2633                 :             }
 2595 rhaas                    2634 ECB             : 
                               2635                 :             /* random functions */
 2568 rhaas                    2636 GIC        1533 :         case PGBENCH_RANDOM:
                               2637                 :         case PGBENCH_RANDOM_EXPONENTIAL:
 2568 rhaas                    2638 ECB             :         case PGBENCH_RANDOM_GAUSSIAN:
 1942 teodor                   2639                 :         case PGBENCH_RANDOM_ZIPFIAN:
                               2640                 :             {
                               2641                 :                 int64       imin,
  650 tgl                      2642                 :                             imax,
                               2643                 :                             delta;
 2568 rhaas                    2644                 : 
 2495 rhaas                    2645 CBC        1533 :                 Assert(nargs >= 2);
                               2646                 : 
 2495 rhaas                    2647 GIC        1533 :                 if (!coerceToInt(&vargs[0], &imin) ||
                               2648            1532 :                     !coerceToInt(&vargs[1], &imax))
 2568                          2649               1 :                     return false;
                               2650                 : 
 2495 rhaas                    2651 ECB             :                 /* check random range */
  650 tgl                      2652 GIC        1532 :                 if (unlikely(imin > imax))
 2568 rhaas                    2653 ECB             :                 {
 1187 peter                    2654 CBC           1 :                     pg_log_error("empty range given to random");
 2495 rhaas                    2655 GIC           1 :                     return false;
 2495 rhaas                    2656 ECB             :                 }
  650 tgl                      2657 GIC        1531 :                 else if (unlikely(pg_sub_s64_overflow(imax, imin, &delta) ||
  650 tgl                      2658 ECB             :                                   pg_add_s64_overflow(delta, 1, &delta)))
                               2659                 :                 {
 2495 rhaas                    2660                 :                     /* prevent int overflows in random functions */
 1187 peter                    2661 GIC           1 :                     pg_log_error("random range is too large");
 2495 rhaas                    2662 CBC           1 :                     return false;
                               2663                 :                 }
                               2664                 : 
                               2665            1530 :                 if (func == PGBENCH_RANDOM)
                               2666                 :                 {
 2495 rhaas                    2667 GIC        1517 :                     Assert(nargs == 2);
 1605 alvherre                 2668            1517 :                     setIntValue(retval, getrand(&st->cs_func_rs, imin, imax));
 2568 rhaas                    2669 ECB             :                 }
                               2670                 :                 else            /* gaussian & exponential */
                               2671                 :                 {
                               2672                 :                     double      param;
 2495                          2673                 : 
 2495 rhaas                    2674 GIC          13 :                     Assert(nargs == 3);
 2495 rhaas                    2675 ECB             : 
 2495 rhaas                    2676 GIC          13 :                     if (!coerceToDouble(&vargs[2], &param))
 2568                          2677               4 :                         return false;
 2495 rhaas                    2678 ECB             : 
 2495 rhaas                    2679 GIC          13 :                     if (func == PGBENCH_RANDOM_GAUSSIAN)
                               2680                 :                     {
                               2681               4 :                         if (param < MIN_GAUSSIAN_PARAM)
                               2682                 :                         {
 1187 peter                    2683 CBC           1 :                             pg_log_error("gaussian parameter must be at least %f (not %f)",
                               2684                 :                                          MIN_GAUSSIAN_PARAM, param);
 2495 rhaas                    2685               1 :                             return false;
                               2686                 :                         }
 2495 rhaas                    2687 ECB             : 
 2495 rhaas                    2688 GIC           3 :                         setIntValue(retval,
                               2689                 :                                     getGaussianRand(&st->cs_func_rs,
 1605 alvherre                 2690 ECB             :                                                     imin, imax, param));
                               2691                 :                     }
 1942 teodor                   2692 GIC           9 :                     else if (func == PGBENCH_RANDOM_ZIPFIAN)
                               2693                 :                     {
 1469 tgl                      2694               5 :                         if (param < MIN_ZIPFIAN_PARAM || param > MAX_ZIPFIAN_PARAM)
                               2695                 :                         {
 1187 peter                    2696 CBC           2 :                             pg_log_error("zipfian parameter must be in range [%.3f, %.0f] (not %f)",
                               2697                 :                                          MIN_ZIPFIAN_PARAM, MAX_ZIPFIAN_PARAM, param);
 1942 teodor                   2698 GIC           2 :                             return false;
 1942 teodor                   2699 ECB             :                         }
                               2700                 : 
 1942 teodor                   2701 CBC           3 :                         setIntValue(retval,
 1469 tgl                      2702 ECB             :                                     getZipfianRand(&st->cs_func_rs, imin, imax, param));
                               2703                 :                     }
                               2704                 :                     else        /* exponential */
                               2705                 :                     {
 2495 rhaas                    2706 CBC           4 :                         if (param <= 0.0)
                               2707                 :                         {
 1187 peter                    2708               1 :                             pg_log_error("exponential parameter must be greater than zero (not %f)",
 1187 peter                    2709 ECB             :                                          param);
 2495 rhaas                    2710 GBC           1 :                             return false;
                               2711                 :                         }
 2568 rhaas                    2712 ECB             : 
 2495 rhaas                    2713 GIC           3 :                         setIntValue(retval,
 1605 alvherre                 2714 ECB             :                                     getExponentialRand(&st->cs_func_rs,
                               2715                 :                                                        imin, imax, param));
                               2716                 :                     }
 2568 rhaas                    2717                 :                 }
                               2718                 : 
 2495 rhaas                    2719 CBC        1526 :                 return true;
                               2720                 :             }
                               2721                 : 
 1929 rhaas                    2722 GIC           9 :         case PGBENCH_POW:
                               2723                 :             {
                               2724               9 :                 PgBenchValue *lval = &vargs[0];
 1929 rhaas                    2725 CBC           9 :                 PgBenchValue *rval = &vargs[1];
 1929 rhaas                    2726 ECB             :                 double      ld,
                               2727                 :                             rd;
                               2728                 : 
 1929 rhaas                    2729 GIC           9 :                 Assert(nargs == 2);
                               2730                 : 
                               2731               9 :                 if (!coerceToDouble(lval, &ld) ||
 1929 rhaas                    2732 CBC           9 :                     !coerceToDouble(rval, &rd))
 1929 rhaas                    2733 UIC           0 :                     return false;
                               2734                 : 
 1929 rhaas                    2735 GIC           9 :                 setDoubleValue(retval, pow(ld, rd));
                               2736                 : 
                               2737               9 :                 return true;
 1929 rhaas                    2738 ECB             :             }
                               2739                 : 
 1916 teodor                   2740 CBC          10 :         case PGBENCH_IS:
 1916 teodor                   2741 ECB             :             {
 1916 teodor                   2742 GBC          10 :                 Assert(nargs == 2);
                               2743                 : 
 1809 tgl                      2744 ECB             :                 /*
                               2745                 :                  * note: this simple implementation is more permissive than
                               2746                 :                  * SQL
                               2747                 :                  */
 1916 teodor                   2748 GIC          10 :                 setBoolValue(retval,
                               2749              15 :                              vargs[0].type == vargs[1].type &&
 1916 teodor                   2750 GBC           5 :                              vargs[0].u.bval == vargs[1].u.bval);
 1916 teodor                   2751 GIC          10 :                 return true;
 1916 teodor                   2752 ECB             :             }
                               2753                 : 
                               2754                 :             /* hashing */
 1845 teodor                   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))
 1845 teodor                   2765 LBC           0 :                     return false;
 1845 teodor                   2766 EUB             : 
 1845 teodor                   2767 GIC           6 :                 if (func == PGBENCH_HASH_MURMUR2)
 1845 teodor                   2768 CBC           5 :                     setIntValue(retval, getHashMurmur2(val, seed));
 1845 teodor                   2769 GIC           1 :                 else if (func == PGBENCH_HASH_FNV1A)
 1845 teodor                   2770 CBC           1 :                     setIntValue(retval, getHashFnv1a(val, seed));
 1845 teodor                   2771 ECB             :                 else
                               2772                 :                     /* cannot get here */
 1845 teodor                   2773 UIC           0 :                     Assert(0);
 1845 teodor                   2774 ECB             : 
 1845 teodor                   2775 CBC           6 :                 return true;
                               2776                 :             }
                               2777                 : 
  733 dean.a.rasheed           2778 GBC          46 :         case PGBENCH_PERMUTE:
                               2779                 :             {
  733 dean.a.rasheed           2780 EUB             :                 int64       val,
                               2781                 :                             size,
                               2782                 :                             seed;
                               2783                 : 
  733 dean.a.rasheed           2784 GIC          46 :                 Assert(nargs == 3);
                               2785                 : 
                               2786              46 :                 if (!coerceToInt(&vargs[0], &val) ||
                               2787              46 :                     !coerceToInt(&vargs[1], &size) ||
  733 dean.a.rasheed           2788 CBC          46 :                     !coerceToInt(&vargs[2], &seed))
  733 dean.a.rasheed           2789 UIC           0 :                     return false;
                               2790                 : 
  733 dean.a.rasheed           2791 CBC          46 :                 if (size <= 0)
  733 dean.a.rasheed           2792 ECB             :                 {
  733 dean.a.rasheed           2793 GIC           1 :                     pg_log_error("permute size parameter must be greater than zero");
  733 dean.a.rasheed           2794 CBC           1 :                     return false;
                               2795                 :                 }
                               2796                 : 
  733 dean.a.rasheed           2797 GIC          45 :                 setIntValue(retval, permute(val, size, seed));
                               2798              45 :                 return true;
                               2799                 :             }
                               2800                 : 
 2595 rhaas                    2801 UIC           0 :         default:
                               2802                 :             /* cannot get here */
 2568                          2803               0 :             Assert(0);
 2568 rhaas                    2804 ECB             :             /* dead code to avoid a compiler warning */
                               2805                 :             return false;
 2595                          2806                 :     }
                               2807                 : }
                               2808                 : 
                               2809                 : /* evaluate some function */
 1916 teodor                   2810                 : static bool
 1467 tgl                      2811 CBC        3490 : evalFunc(CState *st,
                               2812                 :          PgBenchFunction func, PgBenchExprLink *args, PgBenchValue *retval)
                               2813                 : {
 1916 teodor                   2814            3490 :     if (isLazyFunc(func))
 1467 tgl                      2815 GIC          63 :         return evalLazyFunc(st, func, args, retval);
                               2816                 :     else
                               2817            3427 :         return evalStandardFunc(st, func, args, retval);
 1916 teodor                   2818 ECB             : }
                               2819                 : 
 2595 rhaas                    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
 1467 tgl                      2827 CBC        9069 : evaluateExpr(CState *st, PgBenchExpr *expr, PgBenchValue *retval)
 2595 rhaas                    2828 ECB             : {
 2595 rhaas                    2829 GIC        9069 :     switch (expr->etype)
                               2830                 :     {
 2568 rhaas                    2831 CBC        3662 :         case ENODE_CONSTANT:
 2595 rhaas                    2832 ECB             :             {
 2568 rhaas                    2833 GIC        3662 :                 *retval = expr->u.constant;
 2595                          2834            3662 :                 return true;
                               2835                 :             }
                               2836                 : 
 2595 rhaas                    2837 GBC        1917 :         case ENODE_VARIABLE:
                               2838                 :             {
 2529 tgl                      2839 EUB             :                 Variable   *var;
                               2840                 : 
  382 ishii                    2841 GIC        1917 :                 if ((var = lookupVariable(&st->variables, expr->u.variable.varname)) == NULL)
                               2842                 :                 {
 1187 peter                    2843               2 :                     pg_log_error("undefined variable \"%s\"", expr->u.variable.varname);
 2595 rhaas                    2844               2 :                     return false;
                               2845                 :                 }
                               2846                 : 
 1916 teodor                   2847 CBC        1915 :                 if (!makeVariableValue(var))
 2529 tgl                      2848 GIC           2 :                     return false;
                               2849                 : 
 1916 teodor                   2850            1913 :                 *retval = var->value;
 2595 rhaas                    2851 CBC        1913 :                 return true;
 2960 rhaas                    2852 EUB             :             }
 2960 rhaas                    2853 ECB             : 
 2595 rhaas                    2854 CBC        3490 :         case ENODE_FUNCTION:
 1467 tgl                      2855            3490 :             return evalFunc(st,
 2595 rhaas                    2856 ECB             :                             expr->u.function.function,
                               2857                 :                             expr->u.function.args,
                               2858                 :                             retval);
                               2859                 : 
 2960 rhaas                    2860 LBC           0 :         default:
 2568 rhaas                    2861 ECB             :             /* internal error which should never occur */
  366 tgl                      2862 LBC           0 :             pg_fatal("unexpected enode type in evaluation: %d", expr->etype);
 2960 rhaas                    2863 ECB             :     }
                               2864                 : }
                               2865                 : 
 1984 tgl                      2866                 : /*
                               2867                 :  * Convert command name to meta-command enum identifier
                               2868                 :  */
                               2869                 : static MetaCommand
 1984 tgl                      2870 CBC         467 : getMetaCommand(const char *cmd)
 1984 tgl                      2871 ECB             : {
                               2872                 :     MetaCommand mc;
                               2873                 : 
 1984 tgl                      2874 CBC         467 :     if (cmd == NULL)
 1984 tgl                      2875 LBC           0 :         mc = META_NONE;
 1984 tgl                      2876 CBC         467 :     else if (pg_strcasecmp(cmd, "set") == 0)
 1984 tgl                      2877 GIC         362 :         mc = META_SET;
 1984 tgl                      2878 CBC         105 :     else if (pg_strcasecmp(cmd, "setshell") == 0)
                               2879               4 :         mc = META_SETSHELL;
 1984 tgl                      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;
 1844 teodor                   2884              87 :     else if (pg_strcasecmp(cmd, "if") == 0)
                               2885              15 :         mc = META_IF;
                               2886              72 :     else if (pg_strcasecmp(cmd, "elif") == 0)
 1844 teodor                   2887 CBC           8 :         mc = META_ELIF;
 1844 teodor                   2888 GIC          64 :     else if (pg_strcasecmp(cmd, "else") == 0)
                               2889               8 :         mc = META_ELSE;
                               2890              56 :     else if (pg_strcasecmp(cmd, "endif") == 0)
 1844 teodor                   2891 CBC          12 :         mc = META_ENDIF;
 1550 alvherre                 2892 GIC          44 :     else if (pg_strcasecmp(cmd, "gset") == 0)
                               2893              29 :         mc = META_GSET;
 1101 michael                  2894              15 :     else if (pg_strcasecmp(cmd, "aset") == 0)
                               2895               3 :         mc = META_ASET;
  755 alvherre                 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
 1984 tgl                      2901               1 :         mc = META_NONE;
                               2902             467 :     return mc;
                               2903                 : }
                               2904                 : 
 4863 itagaki.takahiro         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
  382 ishii                    2910 CBC           6 : runShellCommand(Variables *variables, char *variable, char **argv, int argc)
                               2911                 : {
 4790 bruce                    2912 ECB             :     char        command[SHELL_COMMAND_SIZE];
                               2913                 :     int         i,
 4790 bruce                    2914 CBC           6 :                 len = 0;
                               2915                 :     FILE       *fp;
 4790 bruce                    2916 ECB             :     char        res[64];
                               2917                 :     char       *endptr;
                               2918                 :     int         retval;
                               2919                 : 
 4623 tgl                      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                 :      *----------
 4863 itagaki.takahiro         2927 EUB             :      */
 4863 itagaki.takahiro         2928 GBC          17 :     for (i = 0; i < argc; i++)
                               2929                 :     {
                               2930                 :         char       *arg;
 4790 bruce                    2931 ECB             :         int         arglen;
 4863 itagaki.takahiro         2932                 : 
 4863 itagaki.takahiro         2933 CBC          12 :         if (argv[i][0] != ':')
 4863 itagaki.takahiro         2934 ECB             :         {
 4790 bruce                    2935 GIC           9 :             arg = argv[i];      /* a string literal */
                               2936                 :         }
 4863 itagaki.takahiro         2937 CBC           3 :         else if (argv[i][1] == ':')
                               2938                 :         {
                               2939               1 :             arg = argv[i] + 1;  /* a string literal starting with colons */
                               2940                 :         }
  382 ishii                    2941 GIC           2 :         else if ((arg = getVariable(variables, argv[i] + 1)) == NULL)
 4863 itagaki.takahiro         2942 ECB             :         {
 1187 peter                    2943 GIC           1 :             pg_log_error("%s: undefined variable \"%s\"", argv[0], argv[i]);
 4863 itagaki.takahiro         2944 CBC           1 :             return false;
                               2945                 :         }
 4863 itagaki.takahiro         2946 ECB             : 
 4863 itagaki.takahiro         2947 CBC          11 :         arglen = strlen(arg);
                               2948              11 :         if (len + arglen + (i > 0 ? 1 : 0) >= SHELL_COMMAND_SIZE - 1)
                               2949                 :         {
 1187 peter                    2950 LBC           0 :             pg_log_error("%s: shell command is too long", argv[0]);
 4863 itagaki.takahiro         2951 UIC           0 :             return false;
                               2952                 :         }
                               2953                 : 
 4863 itagaki.takahiro         2954 CBC          11 :         if (i > 0)
 4863 itagaki.takahiro         2955 GIC           5 :             command[len++] = ' ';
 4863 itagaki.takahiro         2956 GBC          11 :         memcpy(command + len, arg, arglen);
                               2957              11 :         len += arglen;
                               2958                 :     }
 4863 itagaki.takahiro         2959 ECB             : 
 4863 itagaki.takahiro         2960 GIC           5 :     command[len] = '\0';
 4863 itagaki.takahiro         2961 ECB             : 
  223 tgl                      2962 GNC           5 :     fflush(NULL);               /* needed before either system() or popen() */
                               2963                 : 
 4863 itagaki.takahiro         2964 ECB             :     /* Fast path for non-assignment case */
 4863 itagaki.takahiro         2965 CBC           5 :     if (variable == NULL)
 4863 itagaki.takahiro         2966 ECB             :     {
 4863 itagaki.takahiro         2967 GIC           2 :         if (system(command))
 4863 itagaki.takahiro         2968 ECB             :         {
 4863 itagaki.takahiro         2969 GIC           1 :             if (!timer_exceeded)
 1187 peter                    2970 GBC           1 :                 pg_log_error("%s: could not launch shell command", argv[0]);
 4863 itagaki.takahiro         2971               1 :             return false;
                               2972                 :         }
 4863 itagaki.takahiro         2973 GIC           1 :         return true;
                               2974                 :     }
 4863 itagaki.takahiro         2975 ECB             : 
                               2976                 :     /* Execute the command with pipe and read the standard output. */
 4863 itagaki.takahiro         2977 CBC           3 :     if ((fp = popen(command, "r")) == NULL)
 4863 itagaki.takahiro         2978 ECB             :     {
 1187 peter                    2979 UIC           0 :         pg_log_error("%s: could not launch shell command", argv[0]);
 4863 itagaki.takahiro         2980 LBC           0 :         return false;
 4863 itagaki.takahiro         2981 ECB             :     }
 4863 itagaki.takahiro         2982 GIC           3 :     if (fgets(res, sizeof(res), fp) == NULL)
 4863 itagaki.takahiro         2983 ECB             :     {
 4863 itagaki.takahiro         2984 GBC           1 :         if (!timer_exceeded)
 1187 peter                    2985 GIC           1 :             pg_log_error("%s: could not read result of shell command", argv[0]);
 3036 tgl                      2986 CBC           1 :         (void) pclose(fp);
 4863 itagaki.takahiro         2987 GIC           1 :         return false;
 4863 itagaki.takahiro         2988 ECB             :     }
 4863 itagaki.takahiro         2989 GIC           2 :     if (pclose(fp) < 0)
                               2990                 :     {
  145 peter                    2991 UNC           0 :         pg_log_error("%s: could not run shell command: %m", argv[0]);
 4863 itagaki.takahiro         2992 UIC           0 :         return false;
                               2993                 :     }
                               2994                 : 
 4863 itagaki.takahiro         2995 ECB             :     /* Check whether the result is an integer and assign it to the variable */
 4863 itagaki.takahiro         2996 GIC           2 :     retval = (int) strtol(res, &endptr, 10);
 4863 itagaki.takahiro         2997 CBC           3 :     while (*endptr != '\0' && isspace((unsigned char) *endptr))
 4863 itagaki.takahiro         2998 GIC           1 :         endptr++;
 4863 itagaki.takahiro         2999 CBC           2 :     if (*res == '\0' || *endptr != '\0')
                               3000                 :     {
 1187 peter                    3001 GIC           1 :         pg_log_error("%s: shell command must return an integer (not \"%s\")", argv[0], res);
 4863 itagaki.takahiro         3002               1 :         return false;
                               3003                 :     }
  382 ishii                    3004               1 :     if (!putVariableInt(variables, "setshell", variable, retval))
 4863 itagaki.takahiro         3005 LBC           0 :         return false;
                               3006                 : 
 1187 peter                    3007 CBC           1 :     pg_log_debug("%s: shell parameter name: \"%s\", value: \"%s\"", argv[0], argv[1], res);
 1187 peter                    3008 ECB             : 
 4863 itagaki.takahiro         3009 GIC           1 :     return true;
 4863 itagaki.takahiro         3010 ECB             : }
                               3011                 : 
                               3012                 : /*
                               3013                 :  * Report the abortion of the client when processing SQL commands.
  382 ishii                    3014                 :  */
                               3015                 : static void
 1844 teodor                   3016 CBC          31 : commandFailed(CState *st, const char *cmd, const char *message)
                               3017                 : {
 1187 peter                    3018 GIC          31 :     pg_log_error("client %d aborted in command %d (%s) of script %d; %s",
 1187 peter                    3019 ECB             :                  st->id, st->command, cmd, st->use_file, message);
 4997 ishii                    3020 CBC          31 : }
                               3021                 : 
  382 ishii                    3022 ECB             : /*
                               3023                 :  * Report the error in the command while the script is executing.
                               3024                 :  */
                               3025                 : static void
  382 ishii                    3026 CBC           2 : commandError(CState *st, const char *message)
                               3027                 : {
                               3028               2 :     Assert(sql_script[st->use_file].commands[st->command]->type == SQL_COMMAND);
  382 ishii                    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
 2629 alvherre                 3035 CBC        2473 : chooseScript(TState *thread)
                               3036                 : {
 2577                          3037            2473 :     int         i = 0;
                               3038                 :     int64       w;
                               3039                 : 
 2629                          3040            2473 :     if (num_scripts == 1)
 2629 alvherre                 3041 GBC        1373 :         return 0;
                               3042                 : 
 1605 alvherre                 3043 GIC        1100 :     w = getrand(&thread->ts_choose_rs, 0, total_weight - 1);
                               3044                 :     do
                               3045                 :     {
 2577                          3046            2471 :         w -= sql_script[i++].weight;
 2577 alvherre                 3047 CBC        2471 :     } while (w >= 0);
                               3048                 : 
                               3049            1100 :     return i - 1;
 2629 alvherre                 3050 ECB             : }
                               3051                 : 
   47                          3052                 : /*
                               3053                 :  * Prepare the SQL command from st->use_file at command_num.
                               3054                 :  */
                               3055                 : static void
   47 alvherre                 3056 GIC        1760 : prepareCommand(CState *st, int command_num)
   47 alvherre                 3057 ECB             : {
   47 alvherre                 3058 GIC        1760 :     Command    *command = sql_script[st->use_file].commands[command_num];
                               3059                 : 
                               3060                 :     /* No prepare for non-SQL commands */
   47 alvherre                 3061 CBC        1760 :     if (command->type != SQL_COMMAND)
   47 alvherre                 3062 UIC           0 :         return;
                               3063                 : 
                               3064                 :     /*
   47 alvherre                 3065 ECB             :      * If not already done, allocate space for 'prepared' flags: one boolean
                               3066                 :      * for each command of each script.
                               3067                 :      */
   47 alvherre                 3068 CBC        1760 :     if (!st->prepared)
   47 alvherre                 3069 ECB             :     {
   47 alvherre                 3070 CBC          29 :         st->prepared = pg_malloc(sizeof(bool *) * num_scripts);
                               3071              59 :         for (int i = 0; i < num_scripts; i++)
                               3072                 :         {
   47 alvherre                 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])
   47 alvherre                 3083 ECB             :     {
                               3084                 :         PGresult   *res;
                               3085                 : 
   47 alvherre                 3086 CBC          99 :         pg_log_debug("client %d preparing %s", st->id, command->prepname);
   47 alvherre                 3087 GIC          99 :         res = PQprepare(st->con, command->prepname,
   47 alvherre                 3088 CBC          99 :                         command->argv[0], command->argc - 1, NULL);
   47 alvherre                 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                 : 
   47 alvherre                 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
   47 alvherre                 3104 CBC          41 : prepareCommandsInPipeline(CState *st)
                               3105                 : {
   47 alvherre                 3106 ECB             :     int         j;
   47 alvherre                 3107 GIC          41 :     Command   **commands = sql_script[st->use_file].commands;
                               3108                 : 
   47 alvherre                 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
   47 alvherre                 3114 ECB             :      * don't need to do this next time without calling prepareCommand(), even
                               3115                 :      * though we don't actually prepare this command.
                               3116                 :      */
   47 alvherre                 3117 GIC          41 :     if (st->prepared &&
   47 alvherre                 3118 CBC          36 :         st->prepared[st->use_file][st->command])
   47 alvherre                 3119 GIC          36 :         return;
                               3120                 : 
                               3121              63 :     for (j = st->command + 1; commands[j] != NULL; j++)
   47 alvherre                 3122 ECB             :     {
   47 alvherre                 3123 CBC          63 :         if (commands[j]->type == META_COMMAND &&
   47 alvherre                 3124 GIC           5 :             commands[j]->meta == META_ENDPIPELINE)
   47 alvherre                 3125 CBC           5 :             break;
   47 alvherre                 3126 ECB             : 
   47 alvherre                 3127 CBC          58 :         prepareCommand(st, j);
                               3128                 :     }
   47 alvherre                 3129 ECB             : 
   47 alvherre                 3130 GIC           5 :     st->prepared[st->use_file][st->command] = true;
   47 alvherre                 3131 ECB             : }
                               3132                 : 
                               3133                 : /* Send a SQL command, using the chosen querymode */
 4997 ishii                    3134                 : static bool
 2386 heikki.linnakangas       3135 GIC        5605 : sendCommand(CState *st, Command *command)
 6401 ishii                    3136 ECB             : {
 2386 heikki.linnakangas       3137                 :     int         r;
                               3138                 : 
 2386 heikki.linnakangas       3139 GIC        5605 :     if (querymode == QUERY_SIMPLE)
 2386 heikki.linnakangas       3140 ECB             :     {
                               3141                 :         char       *sql;
                               3142                 : 
 2386 heikki.linnakangas       3143 GIC        3333 :         sql = pg_strdup(command->argv[0]);
  382 ishii                    3144 CBC        3333 :         sql = assignVariables(&st->variables, sql);
 6401 ishii                    3145 ECB             : 
 1187 peter                    3146 GIC        3333 :         pg_log_debug("client %d sending %s", st->id, sql);
 2386 heikki.linnakangas       3147 CBC        3333 :         r = PQsendQuery(st->con, sql);
                               3148            3333 :         free(sql);
                               3149                 :     }
 2386 heikki.linnakangas       3150 GIC        2272 :     else if (querymode == QUERY_EXTENDED)
                               3151                 :     {
 2386 heikki.linnakangas       3152 GBC         570 :         const char *sql = command->argv[0];
                               3153                 :         const char *params[MAX_ARGS];
 3547 ishii                    3154 ECB             : 
  382 ishii                    3155 GIC         570 :         getQueryParams(&st->variables, command, params);
 3100 heikki.linnakangas       3156 EUB             : 
 1187 peter                    3157 GBC         570 :         pg_log_debug("client %d sending %s", st->id, sql);
 2386 heikki.linnakangas       3158 GIC         570 :         r = PQsendQueryParams(st->con, sql, command->argc - 1,
                               3159                 :                               NULL, params, NULL, NULL, 0);
 2386 heikki.linnakangas       3160 ECB             :     }
 2386 heikki.linnakangas       3161 GIC        1702 :     else if (querymode == QUERY_PREPARED)
                               3162                 :     {
                               3163                 :         const char *params[MAX_ARGS];
                               3164                 : 
   47 alvherre                 3165            1702 :         prepareCommand(st, st->command);
  382 ishii                    3166            1702 :         getQueryParams(&st->variables, command, params);
 2386 heikki.linnakangas       3167 ECB             : 
   47 alvherre                 3168 GIC        1702 :         pg_log_debug("client %d sending %s", st->id, command->prepname);
   47 alvherre                 3169 CBC        1702 :         r = PQsendQueryPrepared(st->con, command->prepname, command->argc - 1,
                               3170                 :                                 params, NULL, NULL, 0);
 3547 ishii                    3171 ECB             :     }
 2118 tgl                      3172                 :     else                        /* unknown sql mode */
 2386 heikki.linnakangas       3173 LBC           0 :         r = 0;
 3547 ishii                    3174 ECB             : 
 2386 heikki.linnakangas       3175 GIC        5605 :     if (r == 0)
                               3176                 :     {
 1187 peter                    3177 LBC           0 :         pg_log_debug("client %d could not send %s", st->id, command->argv[0]);
 2386 heikki.linnakangas       3178 UIC           0 :         return false;
                               3179                 :     }
                               3180                 :     else
 2386 heikki.linnakangas       3181 GIC        5605 :         return true;
                               3182                 : }
                               3183                 : 
  382 ishii                    3184 ECB             : /*
                               3185                 :  * Get the error status from the error code.
                               3186                 :  */
                               3187                 : static EStatus
  382 ishii                    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                 : }
  382 ishii                    3200 ECB             : 
                               3201                 : /*
                               3202                 :  * Returns true if this type of error can be retried.
                               3203                 :  */
                               3204                 : static bool
  382 ishii                    3205 GIC          25 : canRetryError(EStatus estatus)
                               3206                 : {
                               3207              25 :     return (estatus == ESTATUS_SERIALIZATION_ERROR ||
                               3208                 :             estatus == ESTATUS_DEADLOCK_ERROR);
                               3209                 : }
  382 ishii                    3210 ECB             : 
                               3211                 : /*
                               3212                 :  * Process query response from the backend.
                               3213                 :  *
 1476 alvherre                 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
 1101 michael                  3216                 :  * (META_ASET).
                               3217                 :  *
                               3218                 :  * Returns true if everything is A-OK, false if any error occurs.
                               3219                 :  */
                               3220                 : static bool
 1101 michael                  3221 CBC        5647 : readCommandResponse(CState *st, MetaCommand meta, char *varprefix)
 1550 alvherre                 3222 ECB             : {
                               3223                 :     PGresult   *res;
 1461                          3224                 :     PGresult   *next_res;
 1550 alvherre                 3225 GIC        5647 :     int         qrynum = 0;
 1550 alvherre                 3226 ECB             : 
                               3227                 :     /*
  755                          3228                 :      * varprefix should be set only with \gset or \aset, and \endpipeline and
                               3229                 :      * SQL commands do not need it.
 1101 michael                  3230                 :      */
 1101 michael                  3231 GIC        5647 :     Assert((meta == META_NONE && varprefix == NULL) ||
  755 alvherre                 3232 ECB             :            ((meta == META_ENDPIPELINE) && varprefix == NULL) ||
 1101 michael                  3233                 :            ((meta == META_GSET || meta == META_ASET) && varprefix != NULL));
                               3234                 : 
 1476 alvherre                 3235 CBC        5647 :     res = PQgetResult(st->con);
                               3236                 : 
                               3237           11282 :     while (res != NULL)
 1550 alvherre                 3238 ECB             :     {
                               3239                 :         bool        is_last;
 1460                          3240                 : 
                               3241                 :         /* peek at the next result to know whether the current is last */
 1461 alvherre                 3242 CBC        5649 :         next_res = PQgetResult(st->con);
 1460 alvherre                 3243 GIC        5649 :         is_last = (next_res == NULL);
                               3244                 : 
 1550 alvherre                 3245 CBC        5649 :         switch (PQresultStatus(res))
                               3246                 :         {
                               3247            3400 :             case PGRES_COMMAND_OK:  /* non-SELECT commands */
 1550 alvherre                 3248 ECB             :             case PGRES_EMPTY_QUERY: /* may be used for testing no-op overhead */
 1101 michael                  3249 GIC        3400 :                 if (is_last && meta == META_GSET)
 1550 alvherre                 3250 ECB             :                 {
 1187 peter                    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);
  382 ishii                    3253 CBC           1 :                     st->estatus = ESTATUS_META_COMMAND_ERROR;
 1461 alvherre                 3254 GIC           1 :                     goto error;
                               3255                 :                 }
 1550                          3256            3399 :                 break;
 1550 alvherre                 3257 ECB             : 
 1550 alvherre                 3258 GIC        2198 :             case PGRES_TUPLES_OK:
 1101 michael                  3259 CBC        2198 :                 if ((is_last && meta == META_GSET) || meta == META_ASET)
                               3260                 :                 {
 1101 michael                  3261 GIC         431 :                     int         ntuples = PQntuples(res);
 1101 michael                  3262 ECB             : 
 1101 michael                  3263 CBC         431 :                     if (meta == META_GSET && ntuples != 1)
                               3264                 :                     {
                               3265                 :                         /* under \gset, report the error */
 1187 peter                    3266               2 :                         pg_log_error("client %d script %d command %d query %d: expected one row, got %d",
 1187 peter                    3267 ECB             :                                      st->id, st->use_file, st->command, qrynum, PQntuples(res));
  382 ishii                    3268 GIC           2 :                         st->estatus = ESTATUS_META_COMMAND_ERROR;
 1461 alvherre                 3269               2 :                         goto error;
 1550 alvherre                 3270 ECB             :                     }
 1101 michael                  3271 GIC         429 :                     else if (meta == META_ASET && ntuples <= 0)
 1101 michael                  3272 ECB             :                     {
                               3273                 :                         /* coldly skip empty result under \aset */
 1101 michael                  3274 GIC           1 :                         break;
                               3275                 :                     }
 1550 alvherre                 3276 ECB             : 
                               3277                 :                     /* store results into variables */
 1550 alvherre                 3278 GIC         856 :                     for (int fld = 0; fld < PQnfields(res); fld++)
                               3279                 :                     {
                               3280             430 :                         char       *varname = PQfname(res, fld);
 1550 alvherre                 3281 ECB             : 
                               3282                 :                         /* allocate varname only if necessary, freed below */
 1476 alvherre                 3283 CBC         430 :                         if (*varprefix != '\0')
                               3284               1 :                             varname = psprintf("%s%s", varprefix, varname);
 1550 alvherre                 3285 ECB             : 
 1101 michael                  3286 EUB             :                         /* store last row result as a string */
  382 ishii                    3287 GIC         430 :                         if (!putVariable(&st->variables, meta == META_ASET ? "aset" : "gset", varname,
 1101 michael                  3288 CBC         430 :                                          PQgetvalue(res, ntuples - 1, fld)))
                               3289                 :                         {
 1550 alvherre                 3290 ECB             :                             /* internal error */
 1187 peter                    3291 GIC           2 :                             pg_log_error("client %d script %d command %d query %d: error storing into variable %s",
 1187 peter                    3292 ECB             :                                          st->id, st->use_file, st->command, qrynum, varname);
  382 ishii                    3293 GIC           2 :                             st->estatus = ESTATUS_META_COMMAND_ERROR;
 1461 alvherre                 3294 CBC           2 :                             goto error;
                               3295                 :                         }
 1550 alvherre                 3296 ECB             : 
 1476 alvherre                 3297 CBC         428 :                         if (*varprefix != '\0')
 1550                          3298               1 :                             pg_free(varname);
                               3299                 :                     }
                               3300                 :                 }
                               3301                 :                 /* otherwise the result is simply thrown away by PQclear below */
 1550 alvherre                 3302 GIC        2193 :                 break;
                               3303                 : 
  755 alvherre                 3304 CBC          42 :             case PGRES_PIPELINE_SYNC:
  755 alvherre                 3305 GIC          42 :                 pg_log_debug("client %d pipeline ending", st->id);
                               3306              42 :                 if (PQexitPipelineMode(st->con) != 1)
  755 alvherre                 3307 LBC           0 :                     pg_log_error("client %d failed to exit pipeline mode: %s", st->id,
                               3308                 :                                  PQerrorMessage(st->con));
  755 alvherre                 3309 GIC          42 :                 break;
  755 alvherre                 3310 ECB             : 
  382 ishii                    3311 CBC           9 :             case PGRES_NONFATAL_ERROR:
  382 ishii                    3312 ECB             :             case PGRES_FATAL_ERROR:
  332 tgl                      3313 GIC           9 :                 st->estatus = getSQLErrorStatus(PQresultErrorField(res,
                               3314                 :                                                                    PG_DIAG_SQLSTATE));
  382 ishii                    3315 CBC           9 :                 if (canRetryError(st->estatus))
                               3316                 :                 {
  382 ishii                    3317 GBC           2 :                     if (verbose_errors)
                               3318               2 :                         commandError(st, PQerrorMessage(st->con));
  382 ishii                    3319 GIC           2 :                     goto error;
                               3320                 :                 }
  382 ishii                    3321 ECB             :                 /* fall through */
                               3322                 : 
 1550 alvherre                 3323                 :             default:
                               3324                 :                 /* anything else is unexpected */
 1187 peter                    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));
 1461 alvherre                 3328               7 :                 goto error;
 1550 alvherre                 3329 ECB             :         }
                               3330                 : 
 1550 alvherre                 3331 GIC        5635 :         PQclear(res);
 1550 alvherre                 3332 CBC        5635 :         qrynum++;
 1476 alvherre                 3333 GIC        5635 :         res = next_res;
                               3334                 :     }
                               3335                 : 
 1550                          3336            5633 :     if (qrynum == 0)
                               3337                 :     {
 1187 peter                    3338 UIC           0 :         pg_log_error("client %d command %d: no results", st->id, st->command);
 1550 alvherre                 3339               0 :         return false;
 1550 alvherre                 3340 ECB             :     }
                               3341                 : 
 1550 alvherre                 3342 GIC        5633 :     return true;
                               3343                 : 
 1461                          3344              14 : error:
 1461 alvherre                 3345 CBC          14 :     PQclear(res);
 1461 alvherre                 3346 GIC          14 :     PQclear(next_res);
 1461 alvherre                 3347 ECB             :     do
                               3348                 :     {
 1461 alvherre                 3349 CBC          14 :         res = PQgetResult(st->con);
                               3350              14 :         PQclear(res);
 1461 alvherre                 3351 GIC          14 :     } while (res);
                               3352                 : 
 1461 alvherre                 3353 CBC          14 :     return false;
                               3354                 : }
                               3355                 : 
 2386 heikki.linnakangas       3356 ECB             : /*
                               3357                 :  * Parse the argument to a \sleep command, and return the requested amount
 2386 heikki.linnakangas       3358 EUB             :  * of delay, in microseconds.  Returns true on success, false on error.
                               3359                 :  */
                               3360                 : static bool
  382 ishii                    3361 GIC           6 : evaluateSleep(Variables *variables, int argc, char **argv, int *usecs)
                               3362                 : {
                               3363                 :     char       *var;
 2386 heikki.linnakangas       3364 ECB             :     int         usec;
                               3365                 : 
 2386 heikki.linnakangas       3366 CBC           6 :     if (*argv[1] == ':')
                               3367                 :     {
  382 ishii                    3368               3 :         if ((var = getVariable(variables, argv[1] + 1)) == NULL)
 6401 ishii                    3369 ECB             :         {
 1187 peter                    3370 CBC           1 :             pg_log_error("%s: undefined variable \"%s\"", argv[0], argv[1] + 1);
 2386 heikki.linnakangas       3371               1 :             return false;
                               3372                 :         }
                               3373                 : 
                               3374               2 :         usec = atoi(var);
                               3375                 : 
  748 fujii                    3376 ECB             :         /* Raise an error if the value of a variable is not a number */
  748 fujii                    3377 CBC           2 :         if (usec == 0 && !isdigit((unsigned char) *var))
                               3378                 :         {
  748 fujii                    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
 2386 heikki.linnakangas       3385 CBC           3 :         usec = atoi(argv[1]);
                               3386                 : 
                               3387               5 :     if (argc > 2)
                               3388                 :     {
 2386 heikki.linnakangas       3389 GIC           4 :         if (pg_strcasecmp(argv[2], "ms") == 0)
 2386 heikki.linnakangas       3390 CBC           2 :             usec *= 1000;
 2386 heikki.linnakangas       3391 GBC           2 :         else if (pg_strcasecmp(argv[2], "s") == 0)
 2386 heikki.linnakangas       3392 GIC           1 :             usec *= 1000000;
                               3393                 :     }
                               3394                 :     else
                               3395               1 :         usec *= 1000000;
                               3396                 : 
 2386 heikki.linnakangas       3397 CBC           5 :     *usecs = usec;
 2386 heikki.linnakangas       3398 GIC           5 :     return true;
                               3399                 : }
                               3400                 : 
                               3401                 : 
                               3402                 : /*
  382 ishii                    3403 ECB             :  * Returns true if the error can be retried.
  382 ishii                    3404 EUB             :  */
                               3405                 : static bool
  382 ishii                    3406 GIC           2 : doRetry(CState *st, pg_time_usec_t *now)
                               3407                 : {
                               3408               2 :     Assert(st->estatus != ESTATUS_NO_ERROR);
                               3409                 : 
  382 ishii                    3410 ECB             :     /* We can only retry serialization or deadlock errors. */
  382 ishii                    3411 GIC           2 :     if (!canRetryError(st->estatus))
  382 ishii                    3412 UBC           0 :         return false;
  382 ishii                    3413 EUB             : 
                               3414                 :     /*
                               3415                 :      * We must have at least one option to limit the retrying of transactions
                               3416                 :      * that got an error.
                               3417                 :      */
  382 ishii                    3418 GIC           2 :     Assert(max_tries || latency_limit || duration > 0);
                               3419                 : 
  382 ishii                    3420 ECB             :     /*
  332 tgl                      3421 EUB             :      * We cannot retry the error if we have reached the maximum number of
                               3422                 :      * tries.
                               3423                 :      */
  382 ishii                    3424 CBC           2 :     if (max_tries && st->tries >= max_tries)
  382 ishii                    3425 UIC           0 :         return false;
                               3426                 : 
                               3427                 :     /*
                               3428                 :      * We cannot retry the error if we spent too much time on this
                               3429                 :      * transaction.
                               3430                 :      */
  382 ishii                    3431 GBC           2 :     if (latency_limit)
                               3432                 :     {
  382 ishii                    3433 UIC           0 :         pg_time_now_lazy(now);
  382 ishii                    3434 UBC           0 :         if (*now - st->txn_scheduled > latency_limit)
  382 ishii                    3435 UIC           0 :             return false;
  382 ishii                    3436 EUB             :     }
                               3437                 : 
                               3438                 :     /*
                               3439                 :      * We cannot retry the error if the benchmark duration is over.
                               3440                 :      */
  382 ishii                    3441 GIC           2 :     if (timer_exceeded)
  382 ishii                    3442 UIC           0 :         return false;
  382 ishii                    3443 EUB             : 
                               3444                 :     /* OK */
  382 ishii                    3445 GIC           2 :     return true;
  382 ishii                    3446 EUB             : }
                               3447                 : 
                               3448                 : /*
                               3449                 :  * Read results and discard it until a sync point.
                               3450                 :  */
                               3451                 : static int
  382 ishii                    3452 UIC           0 : discardUntilSync(CState *st)
  382 ishii                    3453 EUB             : {
                               3454                 :     /* send a sync */
  382 ishii                    3455 UIC           0 :     if (!PQpipelineSync(st->con))
                               3456                 :     {
  382 ishii                    3457 UBC           0 :         pg_log_error("client %d aborted: failed to send a pipeline sync",
                               3458                 :                      st->id);
                               3459               0 :         return 0;
                               3460                 :     }
  382 ishii                    3461 EUB             : 
                               3462                 :     /* receive PGRES_PIPELINE_SYNC and null following it */
  332 tgl                      3463                 :     for (;;)
  382 ishii                    3464 UIC           0 :     {
  332 tgl                      3465               0 :         PGresult   *res = PQgetResult(st->con);
                               3466                 : 
  382 ishii                    3467               0 :         if (PQresultStatus(res) == PGRES_PIPELINE_SYNC)
                               3468                 :         {
                               3469               0 :             PQclear(res);
                               3470               0 :             res = PQgetResult(st->con);
  382 ishii                    3471 LBC           0 :             Assert(res == NULL);
  382 ishii                    3472 UIC           0 :             break;
                               3473                 :         }
                               3474               0 :         PQclear(res);
  382 ishii                    3475 ECB             :     }
                               3476                 : 
                               3477                 :     /* exit pipeline */
  382 ishii                    3478 LBC           0 :     if (PQexitPipelineMode(st->con) != 1)
  382 ishii                    3479 ECB             :     {
  382 ishii                    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;
  382 ishii                    3483 EUB             :     }
  382 ishii                    3484 UIC           0 :     return 1;
  382 ishii                    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
  382 ishii                    3492 GIC        2431 : getTransactionStatus(PGconn *con)
                               3493                 : {
                               3494                 :     PGTransactionStatusType tx_status;
  382 ishii                    3495 EUB             : 
  382 ishii                    3496 GBC        2431 :     tx_status = PQtransactionStatus(con);
  382 ishii                    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;
  382 ishii                    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;
  382 ishii                    3508 ECB             :             /* fall through */
                               3509                 :         case PQTRANS_ACTIVE:
                               3510                 :         default:
                               3511                 : 
                               3512                 :             /*
  332 tgl                      3513                 :              * We cannot find out whether we are in a transaction block or
                               3514                 :              * not. Internal error which should never occur.
  382 ishii                    3515 EUB             :              */
  382 ishii                    3516 UIC           0 :             pg_log_error("unexpected transaction status %d", tx_status);
  382 ishii                    3517 LBC           0 :             return TSTATUS_OTHER_ERROR;
  382 ishii                    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
  382 ishii                    3529 GIC           2 : printVerboseErrorMessages(CState *st, pg_time_usec_t *now, bool is_retry)
                               3530                 : {
  382 ishii                    3531 ECB             :     static PQExpBuffer buf = NULL;
                               3532                 : 
  382 ishii                    3533 GBC           2 :     if (buf == NULL)
                               3534               2 :         buf = createPQExpBuffer();
  382 ishii                    3535 EUB             :     else
  382 ishii                    3536 UIC           0 :         resetPQExpBuffer(buf);
  382 ishii                    3537 ECB             : 
  382 ishii                    3538 GIC           2 :     printfPQExpBuffer(buf, "client %d ", st->id);
  215 drowley                  3539 GNC           2 :     appendPQExpBufferStr(buf, (is_retry ?
                               3540                 :                                "repeats the transaction after the error" :
                               3541                 :                                "ends the failed transaction"));
  354 peter                    3542 GIC           2 :     appendPQExpBuffer(buf, " (try %u", st->tries);
                               3543                 : 
                               3544                 :     /* Print max_tries if it is not unlimitted. */
  382 ishii                    3545 CBC           2 :     if (max_tries)
  354 peter                    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                 :      */
  382 ishii                    3552               2 :     if (latency_limit)
                               3553                 :     {
  382 ishii                    3554 UIC           0 :         pg_time_now_lazy(now);
                               3555               0 :         appendPQExpBuffer(buf, ", %.3f%% of the maximum time of tries was used",
  382 ishii                    3556 LBC           0 :                           (100.0 * (*now - st->txn_scheduled) / latency_limit));
                               3557                 :     }
  215 drowley                  3558 GNC           2 :     appendPQExpBufferStr(buf, ")\n");
                               3559                 : 
  382 ishii                    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
 1600 alvherre                 3567            7624 : advanceConnectionState(TState *thread, CState *st, StatsData *agg)
 2386 heikki.linnakangas       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                 :      */
  760 tmunro                   3578 GIC        7624 :     pg_time_usec_t now = 0;
 6401 ishii                    3579 ECB             : 
 2386 heikki.linnakangas       3580                 :     /*
                               3581                 :      * Loop in the state machine, until we have to wait for a result from the
 1600 alvherre                 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                 :      */
 2386 heikki.linnakangas       3589                 :     for (;;)
 2386 heikki.linnakangas       3590 CBC       29581 :     {
 1474 alvherre                 3591 ECB             :         Command    *command;
                               3592                 : 
 2386 heikki.linnakangas       3593 GIC       37205 :         switch (st->state)
 6401 ishii                    3594 ECB             :         {
 1600 alvherre                 3595                 :                 /* Select transaction (script) to run.  */
 2386 heikki.linnakangas       3596 GIC        2473 :             case CSTATE_CHOOSE_SCRIPT:
                               3597            2473 :                 st->use_file = chooseScript(thread);
 1600 alvherre                 3598 CBC        2473 :                 Assert(conditional_stack_empty(st->cstack));
                               3599                 : 
  382 ishii                    3600 ECB             :                 /* reset transaction variables to default values */
  382 ishii                    3601 GIC        2473 :                 st->estatus = ESTATUS_NO_ERROR;
  382 ishii                    3602 CBC        2473 :                 st->tries = 1;
                               3603                 : 
 1187 peter                    3604 GIC        2473 :                 pg_log_debug("client %d executing script \"%s\"",
                               3605                 :                              st->id, sql_script[st->use_file].desc);
                               3606                 : 
                               3607                 :                 /*
 1600 alvherre                 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                 :                  */
 1600 alvherre                 3611 GIC        4946 :                 st->state = timer_exceeded ? CSTATE_FINISHED :
                               3612            2473 :                     throttle_delay > 0 ? CSTATE_PREPARE_THROTTLE : CSTATE_START_TX;
                               3613            2473 :                 break;
 1600 alvherre                 3614 ECB             : 
                               3615                 :                 /* Start new transaction (script) */
 1600 alvherre                 3616 CBC        2472 :             case CSTATE_START_TX:
  760 tmunro                   3617 GIC        2472 :                 pg_time_now_lazy(&now);
                               3618                 : 
 1600 alvherre                 3619 ECB             :                 /* establish connection if needed, i.e. under --connect */
 1600 alvherre                 3620 CBC        2472 :                 if (st->con == NULL)
                               3621                 :                 {
  760 tmunro                   3622 GIC         110 :                     pg_time_usec_t start = now;
                               3623                 : 
 1600 alvherre                 3624             110 :                     if ((st->con = doConnect()) == NULL)
                               3625                 :                     {
                               3626                 :                         /*
                               3627                 :                          * as the bench is already running, we do not abort
  523 fujii                    3628 ECB             :                          * the process
                               3629                 :                          */
 1187 peter                    3630 UIC           0 :                         pg_log_error("client %d aborted while establishing connection", st->id);
 1600 alvherre                 3631 LBC           0 :                         st->state = CSTATE_ABORTED;
 1600 alvherre                 3632 UIC           0 :                         break;
                               3633                 :                     }
                               3634                 : 
                               3635                 :                     /* reset now after connection */
  760 tmunro                   3636 GIC         110 :                     now = pg_time_now();
  760 tmunro                   3637 ECB             : 
  760 tmunro                   3638 CBC         110 :                     thread->conn_duration += now - start;
                               3639                 : 
                               3640                 :                     /* Reset session-local state */
   47 alvherre                 3641             110 :                     pg_free(st->prepared);
                               3642             110 :                     st->prepared = NULL;
 1600 alvherre                 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
  332 tgl                      3648                 :                  * to run it again.
                               3649                 :                  */
  382 ishii                    3650 GIC        2472 :                 st->random_state = st->cs_func_rs;
                               3651                 : 
                               3652                 :                 /* record transaction start time */
 1600 alvherre                 3653            2472 :                 st->txn_begin = now;
                               3654                 : 
                               3655                 :                 /*
                               3656                 :                  * When not throttling, this is also the transaction's
                               3657                 :                  * scheduled start time.
                               3658                 :                  */
 1600 alvherre                 3659 CBC        2472 :                 if (!throttle_delay)
  760 tmunro                   3660 GIC        2271 :                     st->txn_scheduled = now;
 1600 alvherre                 3661 ECB             : 
                               3662                 :                 /* Begin with the first command */
 1600 alvherre                 3663 CBC        2472 :                 st->state = CSTATE_START_COMMAND;
 1600 alvherre                 3664 GIC        2472 :                 st->command = 0;
 2386 heikki.linnakangas       3665            2472 :                 break;
                               3666                 : 
                               3667                 :                 /*
                               3668                 :                  * Handle throttling once per transaction by sleeping.
                               3669                 :                  */
 1600 alvherre                 3670             210 :             case CSTATE_PREPARE_THROTTLE:
 6401 ishii                    3671 ECB             : 
                               3672                 :                 /*
 2386 heikki.linnakangas       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                 :                  */
 2386 heikki.linnakangas       3681 GIC         210 :                 Assert(throttle_delay > 0);
                               3682                 : 
 1600 alvherre                 3683             210 :                 thread->throttle_trigger +=
                               3684             210 :                     getPoissonRand(&thread->ts_throttle_rs, throttle_delay);
 2386 heikki.linnakangas       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)
 2386 heikki.linnakangas       3694 ECB             :                 {
  760 tmunro                   3695 CBC         210 :                     pg_time_now_lazy(&now);
                               3696                 : 
  576 fujii                    3697 GIC         210 :                     if (thread->throttle_trigger < now - latency_limit)
 2386 heikki.linnakangas       3698 ECB             :                     {
 2386 heikki.linnakangas       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
  576 fujii                    3706 EUB             :                          * take a very long time to count all of them
  576 fujii                    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                 :                          */
  576 fujii                    3716 CBC           9 :                         if (timer_exceeded || (nxacts > 0 && st->cnt >= nxacts))
  576 fujii                    3717 GBC           1 :                             st->state = CSTATE_FINISHED;
                               3718                 : 
                               3719                 :                         /* Go back to top of loop with CSTATE_PREPARE_THROTTLE */
 2043 tgl                      3720 CBC           9 :                         break;
 2043 tgl                      3721 ECB             :                     }
                               3722                 :                 }
                               3723                 : 
                               3724                 :                 /*
                               3725                 :                  * stop client if next transaction is beyond pgbench end of
 1600 alvherre                 3726                 :                  * execution; otherwise, throttle it.
 2386 heikki.linnakangas       3727                 :                  */
 1600 alvherre                 3728 UIC           0 :                 st->state = end_time > 0 && st->txn_scheduled > end_time ?
 1600 alvherre                 3729 GIC         201 :                     CSTATE_FINISHED : CSTATE_THROTTLE;
 2386 heikki.linnakangas       3730 CBC         201 :                 break;
                               3731                 : 
 2386 heikki.linnakangas       3732 ECB             :                 /*
 1600 alvherre                 3733                 :                  * Wait until it's time to start next transaction.
                               3734                 :                  */
 1600 alvherre                 3735 GIC         201 :             case CSTATE_THROTTLE:
  760 tmunro                   3736             201 :                 pg_time_now_lazy(&now);
 2386 heikki.linnakangas       3737 ECB             : 
  760 tmunro                   3738 GIC         201 :                 if (now < st->txn_scheduled)
 1600 alvherre                 3739 LBC           0 :                     return;     /* still sleeping, nothing to do here */
 5499 ishii                    3740 ECB             : 
                               3741                 :                 /* done sleeping, but don't start transaction if we're done */
 1600 alvherre                 3742 GIC         201 :                 st->state = timer_exceeded ? CSTATE_FINISHED : CSTATE_START_TX;
 2386 heikki.linnakangas       3743             201 :                 break;
 2386 heikki.linnakangas       3744 ECB             : 
                               3745                 :                 /*
                               3746                 :                  * Send a command to server (or execute a meta-command)
                               3747                 :                  */
 2386 heikki.linnakangas       3748 GIC       10305 :             case CSTATE_START_COMMAND:
 1474 alvherre                 3749 CBC       10305 :                 command = sql_script[st->use_file].commands[st->command];
                               3750                 : 
 1600 alvherre                 3751 ECB             :                 /* Transition to script end processing if done */
 1474 alvherre                 3752 CBC       10305 :                 if (command == NULL)
 2386 heikki.linnakangas       3753 ECB             :                 {
 2386 heikki.linnakangas       3754 GIC        2429 :                     st->state = CSTATE_END_TX;
 2386 heikki.linnakangas       3755 CBC        2429 :                     break;
                               3756                 :                 }
 5499 ishii                    3757 EUB             : 
 1600 alvherre                 3758                 :                 /* record begin time of next command, and initiate it */
 1600 alvherre                 3759 GBC        7876 :                 if (report_per_command)
                               3760                 :                 {
  760 tmunro                   3761 GIC         401 :                     pg_time_now_lazy(&now);
 2386 heikki.linnakangas       3762             401 :                     st->stmt_begin = now;
 2386 heikki.linnakangas       3763 ECB             :                 }
                               3764                 : 
 1474 alvherre                 3765 EUB             :                 /* Execute the command */
 1474 alvherre                 3766 GBC        7876 :                 if (command->type == SQL_COMMAND)
                               3767                 :                 {
                               3768                 :                     /* disallow \aset and \gset in pipeline mode */
  755 alvherre                 3769 GIC        5606 :                     if (PQpipelineStatus(st->con) != PQ_PIPELINE_OFF)
                               3770                 :                     {
  755 alvherre                 3771 CBC         501 :                         if (command->meta == META_GSET)
  755 alvherre                 3772 ECB             :                         {
  755 alvherre                 3773 GIC           1 :                             commandFailed(st, "gset", "\\gset is not allowed in pipeline mode");
  755 alvherre                 3774 CBC           1 :                             st->state = CSTATE_ABORTED;
  755 alvherre                 3775 GIC           1 :                             break;
                               3776                 :                         }
  755 alvherre                 3777 CBC         500 :                         else if (command->meta == META_ASET)
                               3778                 :                         {
  755 alvherre                 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                 : 
 1474 alvherre                 3785 CBC        5605 :                     if (!sendCommand(st, command))
 1474 alvherre                 3786 ECB             :                     {
 1474 alvherre                 3787 LBC           0 :                         commandFailed(st, "SQL", "SQL command send failed");
 1474 alvherre                 3788 UIC           0 :                         st->state = CSTATE_ABORTED;
                               3789                 :                     }
                               3790                 :                     else
                               3791                 :                     {
                               3792                 :                         /* Wait for results, unless in pipeline mode */
  755 alvherre                 3793 GIC        5605 :                         if (PQpipelineStatus(st->con) == PQ_PIPELINE_OFF)
                               3794            5105 :                             st->state = CSTATE_WAIT_RESULT;
  755 alvherre                 3795 ECB             :                         else
  755 alvherre                 3796 GIC         500 :                             st->state = CSTATE_END_COMMAND;
                               3797                 :                     }
                               3798                 :                 }
 1474 alvherre                 3799 CBC        2270 :                 else if (command->type == META_COMMAND)
                               3800                 :                 {
                               3801                 :                     /*-----
                               3802                 :                      * Possible state changes when executing meta commands:
                               3803                 :                      * - on errors CSTATE_ABORTED
 1474 alvherre                 3804 ECB             :                      * - on sleep CSTATE_SLEEP
                               3805                 :                      * - else CSTATE_END_COMMAND
                               3806                 :                      */
 1467 tgl                      3807 GIC        2270 :                     st->state = executeMetaCommand(st, &now);
  382 ishii                    3808            2270 :                     if (st->state == CSTATE_ABORTED)
  382 ishii                    3809 CBC          30 :                         st->estatus = ESTATUS_META_COMMAND_ERROR;
                               3810                 :                 }
                               3811                 : 
 1600 alvherre                 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                 :                  */
 1600 alvherre                 3817 GIC        7875 :                 Assert(st->state == CSTATE_WAIT_RESULT ||
 1600 alvherre                 3818 ECB             :                        st->state == CSTATE_END_COMMAND ||
                               3819                 :                        st->state == CSTATE_SLEEP ||
                               3820                 :                        st->state == CSTATE_ABORTED);
 1844 teodor                   3821 CBC        7875 :                 break;
 1844 teodor                   3822 ECB             : 
                               3823                 :                 /*
                               3824                 :                  * non executed conditional branch
                               3825                 :                  */
 1844 teodor                   3826 CBC         377 :             case CSTATE_SKIP_COMMAND:
                               3827             377 :                 Assert(!conditional_active(st->cstack));
 1844 teodor                   3828 ECB             :                 /* quickly skip commands until something to do... */
                               3829                 :                 while (true)
                               3830                 :                 {
 1844 teodor                   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                 : 
 1809 tgl                      3836 ECB             :                     /*
                               3837                 :                      * if this is conditional related, update conditional
                               3838                 :                      * state
                               3839                 :                      */
 1844 teodor                   3840 GIC        1743 :                     if (command->type == META_COMMAND &&
 1844 teodor                   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                 :                     {
 1844 teodor                   3846 GIC         756 :                         switch (conditional_stack_peek(st->cstack))
                               3847                 :                         {
 1809 tgl                      3848             374 :                             case IFSTATE_FALSE:
 1600 alvherre                 3849             374 :                                 if (command->meta == META_IF ||
 1600 alvherre                 3850 CBC         374 :                                     command->meta == META_ELIF)
                               3851                 :                                 {
 1809 tgl                      3852 ECB             :                                     /* we must evaluate the condition */
 1809 tgl                      3853 GIC           3 :                                     st->state = CSTATE_START_COMMAND;
 1809 tgl                      3854 ECB             :                                 }
 1809 tgl                      3855 GIC         371 :                                 else if (command->meta == META_ELSE)
 1809 tgl                      3856 ECB             :                                 {
 1809 tgl                      3857 EUB             :                                     /* we must execute next command */
 1600 alvherre                 3858 GIC           1 :                                     conditional_stack_poke(st->cstack,
 1600 alvherre                 3859 ECB             :                                                            IFSTATE_ELSE_TRUE);
 1844 teodor                   3860 GIC           1 :                                     st->state = CSTATE_START_COMMAND;
 1809 tgl                      3861 CBC           1 :                                     st->command++;
 1809 tgl                      3862 ECB             :                                 }
 1809 tgl                      3863 CBC         370 :                                 else if (command->meta == META_ENDIF)
 1809 tgl                      3864 ECB             :                                 {
 1809 tgl                      3865 GIC         370 :                                     Assert(!conditional_stack_empty(st->cstack));
                               3866             370 :                                     conditional_stack_pop(st->cstack);
 1809 tgl                      3867 CBC         370 :                                     if (conditional_active(st->cstack))
                               3868             370 :                                         st->state = CSTATE_START_COMMAND;
                               3869                 : 
 1809 tgl                      3870 EUB             :                                     /*
                               3871                 :                                      * else state remains in
                               3872                 :                                      * CSTATE_SKIP_COMMAND
                               3873                 :                                      */
 1809 tgl                      3874 GIC         370 :                                     st->command++;
                               3875                 :                                 }
                               3876             374 :                                 break;
                               3877                 : 
                               3878               4 :                             case IFSTATE_IGNORED:
 1809 tgl                      3879 EUB             :                             case IFSTATE_ELSE_FALSE:
 1809 tgl                      3880 GIC           4 :                                 if (command->meta == META_IF)
 1474 alvherre                 3881 UIC           0 :                                     conditional_stack_push(st->cstack,
                               3882                 :                                                            IFSTATE_IGNORED);
 1809 tgl                      3883 GIC           4 :                                 else if (command->meta == META_ENDIF)
                               3884                 :                                 {
 1809 tgl                      3885 CBC           3 :                                     Assert(!conditional_stack_empty(st->cstack));
 1809 tgl                      3886 GIC           3 :                                     conditional_stack_pop(st->cstack);
                               3887               3 :                                     if (conditional_active(st->cstack))
 1809 tgl                      3888 CBC           3 :                                         st->state = CSTATE_START_COMMAND;
                               3889                 :                                 }
 1809 tgl                      3890 ECB             :                                 /* could detect "else" & "elif" after "else" */
 1844 teodor                   3891 GIC           4 :                                 st->command++;
 1809 tgl                      3892 CBC           4 :                                 break;
                               3893                 : 
 1809 tgl                      3894 UIC           0 :                             case IFSTATE_NONE:
                               3895                 :                             case IFSTATE_TRUE:
                               3896                 :                             case IFSTATE_ELSE_TRUE:
 1809 tgl                      3897 ECB             :                             default:
 2386 heikki.linnakangas       3898                 : 
                               3899                 :                                 /*
                               3900                 :                                  * inconsistent if inactive, unreachable dead
                               3901                 :                                  * code
                               3902                 :                                  */
 1809 tgl                      3903 UIC           0 :                                 Assert(false);
                               3904                 :                         }
                               3905                 :                     }
 1844 teodor                   3906 ECB             :                     else
                               3907                 :                     {
                               3908                 :                         /* skip and consider next */
 1844 teodor                   3909 GBC        1365 :                         st->command++;
 1844 teodor                   3910 EUB             :                     }
                               3911                 : 
 1844 teodor                   3912 GIC        1743 :                     if (st->state != CSTATE_SKIP_COMMAND)
 1600 alvherre                 3913 ECB             :                         /* out of quick skip command loop */
 1844 teodor                   3914 CBC         377 :                         break;
                               3915                 :                 }
 2386 heikki.linnakangas       3916 GIC         377 :                 break;
 2386 heikki.linnakangas       3917 ECB             : 
                               3918                 :                 /*
                               3919                 :                  * Wait for the current SQL command to complete
                               3920                 :                  */
 2386 heikki.linnakangas       3921 GIC       10794 :             case CSTATE_WAIT_RESULT:
 1187 peter                    3922           10794 :                 pg_log_debug("client %d receiving", st->id);
                               3923                 : 
                               3924                 :                 /*
                               3925                 :                  * Only check for new network data if we processed all data
  613 andres                   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                 :                  */
  613 andres                   3930 CBC       10794 :                 if (PQisBusy(st->con) && !PQconsumeInput(st->con))
                               3931                 :                 {
 1600 alvherre                 3932 ECB             :                     /* there's something wrong */
 1844 teodor                   3933 LBC           0 :                     commandFailed(st, "SQL", "perhaps the backend died while processing");
 2386 heikki.linnakangas       3934 UIC           0 :                     st->state = CSTATE_ABORTED;
                               3935               0 :                     break;
                               3936                 :                 }
 2386 heikki.linnakangas       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 */
 1101 michael                  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))
  755 alvherre                 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                 :                      */
  755 alvherre                 3950 GIC        5633 :                     if (PQpipelineStatus(st->con) != PQ_PIPELINE_ON)
                               3951            5133 :                         st->state = CSTATE_END_COMMAND;
  755 alvherre                 3952 ECB             :                 }
  382 ishii                    3953 GIC          14 :                 else if (canRetryError(st->estatus))
                               3954               2 :                     st->state = CSTATE_ERROR;
                               3955                 :                 else
 1550 alvherre                 3956              12 :                     st->state = CSTATE_ABORTED;
 2386 heikki.linnakangas       3957            5647 :                 break;
                               3958                 : 
 2386 heikki.linnakangas       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                 :                  */
 2386 heikki.linnakangas       3965 CBC           8 :             case CSTATE_SLEEP:
  760 tmunro                   3966               8 :                 pg_time_now_lazy(&now);
  760 tmunro                   3967 GIC           8 :                 if (now < st->sleep_until)
 1600 alvherre                 3968               3 :                     return;     /* still sleeping, nothing to do here */
                               3969                 :                 /* Else done sleeping. */
 2386 heikki.linnakangas       3970 CBC           5 :                 st->state = CSTATE_END_COMMAND;
                               3971               5 :                 break;
 5756 JanWieck                 3972 ECB             : 
 2386 heikki.linnakangas       3973                 :                 /*
                               3974                 :                  * End of command: record stats and proceed to next command.
                               3975                 :                  */
 2386 heikki.linnakangas       3976 GIC        7831 :             case CSTATE_END_COMMAND:
                               3977                 : 
 2386 heikki.linnakangas       3978 ECB             :                 /*
                               3979                 :                  * command completed: accumulate per-command execution times
                               3980                 :                  * in thread-local data structure, if per-command latencies
                               3981                 :                  * are requested.
                               3982                 :                  */
 1600 alvherre                 3983 GIC        7831 :                 if (report_per_command)
                               3984                 :                 {
  760 tmunro                   3985             401 :                     pg_time_now_lazy(&now);
 4863 itagaki.takahiro         3986 ECB             : 
 1550 alvherre                 3987 GIC         401 :                     command = sql_script[st->use_file].commands[st->command];
 2386 heikki.linnakangas       3988 EUB             :                     /* XXX could use a mutex here, but we choose not to */
 2386 heikki.linnakangas       3989 GIC         401 :                     addToSimpleStats(&command->stats,
  760 tmunro                   3990 GBC         401 :                                      PG_TIME_GET_DOUBLE(now - st->stmt_begin));
 2386 heikki.linnakangas       3991 EUB             :                 }
                               3992                 : 
                               3993                 :                 /* Go ahead with next command, to be executed or skipped */
 2386 heikki.linnakangas       3994 GIC        7831 :                 st->command++;
 1844 teodor                   3995            7831 :                 st->state = conditional_active(st->cstack) ?
                               3996            7831 :                     CSTATE_START_COMMAND : CSTATE_SKIP_COMMAND;
 2386 heikki.linnakangas       3997            7831 :                 break;
                               3998                 : 
 2386 heikki.linnakangas       3999 ECB             :                 /*
  382 ishii                    4000                 :                  * Clean up after an error.
                               4001                 :                  */
  382 ishii                    4002 GIC           2 :             case CSTATE_ERROR:
  382 ishii                    4003 ECB             :                 {
                               4004                 :                     TStatus     tstatus;
 4997 ishii                    4005 EUB             : 
  382 ishii                    4006 GIC           2 :                     Assert(st->estatus != ESTATUS_NO_ERROR);
 2386 heikki.linnakangas       4007 EUB             : 
                               4008                 :                     /* Clear the conditional stack */
  382 ishii                    4009 GIC           2 :                     conditional_stack_reset(st->cstack);
 1844 teodor                   4010 ECB             : 
                               4011                 :                     /* Read and discard until a sync point in pipeline mode */
  382 ishii                    4012 CBC           2 :                     if (PQpipelineStatus(st->con) != PQ_PIPELINE_OFF)
                               4013                 :                     {
  382 ishii                    4014 UIC           0 :                         if (!discardUntilSync(st))
                               4015                 :                         {
                               4016               0 :                             st->state = CSTATE_ABORTED;
                               4017               0 :                             break;
  382 ishii                    4018 ECB             :                         }
                               4019                 :                     }
                               4020                 : 
                               4021                 :                     /*
                               4022                 :                      * Check if we have a (failed) transaction block or not,
  332 tgl                      4023 EUB             :                      * and roll it back if any.
  382 ishii                    4024                 :                      */
  382 ishii                    4025 GIC           2 :                     tstatus = getTransactionStatus(st->con);
  382 ishii                    4026 GBC           2 :                     if (tstatus == TSTATUS_IN_BLOCK)
  382 ishii                    4027 EUB             :                     {
                               4028                 :                         /* Try to rollback a (failed) transaction block. */
  382 ishii                    4029 CBC           1 :                         if (!PQsendQuery(st->con, "ROLLBACK"))
                               4030                 :                         {
  382 ishii                    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                 :                         }
  382 ishii                    4035 ECB             :                         else
  382 ishii                    4036 GIC           1 :                             st->state = CSTATE_WAIT_ROLLBACK_RESULT;
                               4037                 :                     }
                               4038               1 :                     else if (tstatus == TSTATUS_IDLE)
  382 ishii                    4039 ECB             :                     {
                               4040                 :                         /*
                               4041                 :                          * If time is over, we're done; otherwise, check if we
  332 tgl                      4042 EUB             :                          * can retry the error.
                               4043                 :                          */
  382 ishii                    4044 GBC           2 :                         st->state = timer_exceeded ? CSTATE_FINISHED :
                               4045               1 :                             doRetry(st, &now) ? CSTATE_RETRY : CSTATE_FAILURE;
                               4046                 :                     }
  382 ishii                    4047 ECB             :                     else
                               4048                 :                     {
  382 ishii                    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);
  382 ishii                    4053 LBC           0 :                         st->state = CSTATE_ABORTED;
  382 ishii                    4054 ECB             :                     }
  382 ishii                    4055 GIC           2 :                     break;
 2386 heikki.linnakangas       4056 ECB             :                 }
                               4057                 : 
  382 ishii                    4058                 :                 /*
                               4059                 :                  * Wait for the rollback command to complete
                               4060                 :                  */
  382 ishii                    4061 CBC           2 :             case CSTATE_WAIT_ROLLBACK_RESULT:
                               4062                 :                 {
                               4063                 :                     PGresult   *res;
                               4064                 : 
  382 ishii                    4065 GIC           2 :                     pg_log_debug("client %d receiving", st->id);
                               4066               2 :                     if (!PQconsumeInput(st->con))
  382 ishii                    4067 ECB             :                     {
  382 ishii                    4068 LBC           0 :                         pg_log_error("client %d aborted while rolling back the transaction after an error; perhaps the backend died while processing",
  382 ishii                    4069 ECB             :                                      st->id);
  382 ishii                    4070 UBC           0 :                         st->state = CSTATE_ABORTED;
                               4071               0 :                         break;
                               4072                 :                     }
  382 ishii                    4073 GBC           2 :                     if (PQisBusy(st->con))
  332 tgl                      4074               1 :                         return; /* don't have the whole result yet */
  382 ishii                    4075 EUB             : 
                               4076                 :                     /*
  382 ishii                    4077 ECB             :                      * Read and discard the query result;
                               4078                 :                      */
  382 ishii                    4079 GIC           1 :                     res = PQgetResult(st->con);
                               4080               1 :                     switch (PQresultStatus(res))
                               4081                 :                     {
                               4082               1 :                         case PGRES_COMMAND_OK:
  382 ishii                    4083 ECB             :                             /* OK */
  382 ishii                    4084 CBC           1 :                             PQclear(res);
                               4085                 :                             /* null must be returned */
  382 ishii                    4086 GIC           1 :                             res = PQgetResult(st->con);
                               4087               1 :                             Assert(res == NULL);
                               4088                 : 
                               4089                 :                             /*
  332 tgl                      4090 ECB             :                              * If time is over, we're done; otherwise, check
                               4091                 :                              * if we can retry the error.
                               4092                 :                              */
  382 ishii                    4093 GIC           2 :                             st->state = timer_exceeded ? CSTATE_FINISHED :
  382 ishii                    4094 CBC           1 :                                 doRetry(st, &now) ? CSTATE_RETRY : CSTATE_FAILURE;
                               4095               1 :                             break;
  382 ishii                    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;
  382 ishii                    4101 LBC           0 :                             break;
                               4102                 :                     }
 2386 heikki.linnakangas       4103 GIC           1 :                     break;
 2386 heikki.linnakangas       4104 ECB             :                 }
                               4105                 : 
  382 ishii                    4106                 :                 /*
                               4107                 :                  * Retry the transaction after an error.
                               4108                 :                  */
  382 ishii                    4109 GIC           2 :             case CSTATE_RETRY:
                               4110               2 :                 command = sql_script[st->use_file].commands[st->command];
                               4111                 : 
 2386 heikki.linnakangas       4112 EUB             :                 /*
  332 tgl                      4113                 :                  * Inform that the transaction will be retried after the
                               4114                 :                  * error.
                               4115                 :                  */
  382 ishii                    4116 GBC           2 :                 if (verbose_errors)
  382 ishii                    4117 GIC           2 :                     printVerboseErrorMessages(st, &now, true);
                               4118                 : 
                               4119                 :                 /* Count tries and retries */
                               4120               2 :                 st->tries++;
  382 ishii                    4121 GBC           2 :                 command->retries++;
  382 ishii                    4122 EUB             : 
                               4123                 :                 /*
                               4124                 :                  * Reset the random state as they were at the beginning of the
  332 tgl                      4125                 :                  * transaction.
  382 ishii                    4126                 :                  */
  382 ishii                    4127 GIC           2 :                 st->cs_func_rs = st->random_state;
                               4128                 : 
                               4129                 :                 /* Process the first transaction command. */
                               4130               2 :                 st->command = 0;
  382 ishii                    4131 CBC           2 :                 st->estatus = ESTATUS_NO_ERROR;
  382 ishii                    4132 GIC           2 :                 st->state = CSTATE_START_COMMAND;
                               4133               2 :                 break;
                               4134                 : 
                               4135                 :                 /*
  382 ishii                    4136 ECB             :                  * Record a failed transaction.
                               4137                 :                  */
  382 ishii                    4138 UIC           0 :             case CSTATE_FAILURE:
                               4139               0 :                 command = sql_script[st->use_file].commands[st->command];
                               4140                 : 
                               4141                 :                 /* Accumulate the failure. */
  382 ishii                    4142 LBC           0 :                 command->failures++;
                               4143                 : 
                               4144                 :                 /*
                               4145                 :                  * Inform that the failed transaction will not be retried.
                               4146                 :                  */
  382 ishii                    4147 UIC           0 :                 if (verbose_errors)
  382 ishii                    4148 LBC           0 :                     printVerboseErrorMessages(st, &now, false);
  382 ishii                    4149 ECB             : 
                               4150                 :                 /* End the failed transaction. */
  382 ishii                    4151 LBC           0 :                 st->state = CSTATE_END_TX;
  382 ishii                    4152 UIC           0 :                 break;
  382 ishii                    4153 ECB             : 
                               4154                 :                 /*
                               4155                 :                  * End of transaction (end of script, really).
                               4156                 :                  */
  382 ishii                    4157 GIC        2429 :             case CSTATE_END_TX:
  382 ishii                    4158 EUB             :                 {
                               4159                 :                     TStatus     tstatus;
                               4160                 : 
                               4161                 :                     /* transaction finished: calculate latency and do log */
  382 ishii                    4162 GBC        2429 :                     processXactStats(thread, st, &now, false, agg);
  382 ishii                    4163 EUB             : 
                               4164                 :                     /*
                               4165                 :                      * missing \endif... cannot happen if CheckConditional was
  382 ishii                    4166 ECB             :                      * okay
                               4167                 :                      */
  382 ishii                    4168 CBC        2429 :                     Assert(conditional_stack_empty(st->cstack));
                               4169                 : 
  382 ishii                    4170 ECB             :                     /*
                               4171                 :                      * We must complete all the transaction blocks that were
                               4172                 :                      * started in this script.
                               4173                 :                      */
  382 ishii                    4174 GIC        2429 :                     tstatus = getTransactionStatus(st->con);
                               4175            2429 :                     if (tstatus == TSTATUS_IN_BLOCK)
  382 ishii                    4176 ECB             :                     {
  382 ishii                    4177 GIC           1 :                         pg_log_error("client %d aborted: end of script reached without completing the last transaction",
                               4178                 :                                      st->id);
  382 ishii                    4179 CBC           1 :                         st->state = CSTATE_ABORTED;
                               4180               1 :                         break;
                               4181                 :                     }
  382 ishii                    4182 GIC        2428 :                     else if (tstatus != TSTATUS_IDLE)
                               4183                 :                     {
  382 ishii                    4184 LBC           0 :                         if (tstatus == TSTATUS_CONN_ERROR)
  382 ishii                    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                 :                     }
  382 ishii                    4191 ECB             : 
  382 ishii                    4192 GIC        2428 :                     if (is_connect)
                               4193                 :                     {
                               4194             110 :                         pg_time_usec_t start = now;
                               4195                 : 
                               4196             110 :                         pg_time_now_lazy(&start);
  382 ishii                    4197 CBC         110 :                         finishCon(st);
  382 ishii                    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                 : 
  382 ishii                    4212 ECB             :                     /*
  332 tgl                      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                 :                      */
  382 ishii                    4217 GIC        2374 :                     return;
                               4218                 :                 }
                               4219                 : 
                               4220                 :                 /*
                               4221                 :                  * Final states.  Close the connection if it's still open.
                               4222                 :                  */
 2386 heikki.linnakangas       4223              99 :             case CSTATE_ABORTED:
                               4224                 :             case CSTATE_FINISHED:
                               4225                 : 
  585 fujii                    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                 :                  */
 1865 andres                   4238 GIC          99 :                 finishCon(st);
 2386 heikki.linnakangas       4239              99 :                 return;
                               4240                 :         }
 2386 heikki.linnakangas       4241 ECB             :     }
                               4242                 : }
 6401 ishii                    4243                 : 
 1600 alvherre                 4244                 : /*
 1474                          4245                 :  * Subroutine for advanceConnectionState -- initiate or execute the current
                               4246                 :  * meta command, and return the next state to set.
 1600                          4247                 :  *
                               4248                 :  * *now is updated to the current time, unless the command is expected to
 1474                          4249                 :  * take no time to execute.
                               4250                 :  */
                               4251                 : static ConnectionStateEnum
  760 tmunro                   4252 CBC        2270 : executeMetaCommand(CState *st, pg_time_usec_t *now)
                               4253                 : {
 1600 alvherre                 4254 GIC        2270 :     Command    *command = sql_script[st->use_file].commands[st->command];
                               4255                 :     int         argc;
                               4256                 :     char      **argv;
                               4257                 : 
 1474                          4258            2270 :     Assert(command != NULL && command->type == META_COMMAND);
                               4259                 : 
                               4260            2270 :     argc = command->argc;
                               4261            2270 :     argv = command->argv;
 1474 alvherre                 4262 ECB             : 
 1187 peter                    4263 GIC        2270 :     if (unlikely(__pg_log_level <= PG_LOG_DEBUG))
 1474 alvherre                 4264 ECB             :     {
 1060 tgl                      4265                 :         PQExpBufferData buf;
                               4266                 : 
 1185 michael                  4267 GIC         703 :         initPQExpBuffer(&buf);
 1185 michael                  4268 ECB             : 
 1185 michael                  4269 CBC         703 :         printfPQExpBuffer(&buf, "client %d executing \\%s", st->id, argv[0]);
 1474 alvherre                 4270            1406 :         for (int i = 1; i < argc; i++)
 1185 michael                  4271 GIC         703 :             appendPQExpBuffer(&buf, " %s", argv[i]);
 1185 michael                  4272 ECB             : 
 1185 michael                  4273 GIC         703 :         pg_log_debug("%s", buf.data);
 1185 michael                  4274 ECB             : 
 1185 michael                  4275 GIC         703 :         termPQExpBuffer(&buf);
                               4276                 :     }
 1600 alvherre                 4277 ECB             : 
 1474 alvherre                 4278 GIC        2270 :     if (command->meta == META_SLEEP)
 1600 alvherre                 4279 ECB             :     {
 1474                          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                 :          */
  382 ishii                    4288 GIC           6 :         if (!evaluateSleep(&st->variables, argc, argv, &usec))
 1600 alvherre                 4289 ECB             :         {
 1474 alvherre                 4290 GIC           1 :             commandFailed(st, "sleep", "execution of meta-command failed");
                               4291               1 :             return CSTATE_ABORTED;
 1600 alvherre                 4292 ECB             :         }
                               4293                 : 
  760 tmunro                   4294 GIC           5 :         pg_time_now_lazy(now);
                               4295               5 :         st->sleep_until = (*now) + usec;
 1474 alvherre                 4296 CBC           5 :         return CSTATE_SLEEP;
                               4297                 :     }
 1474 alvherre                 4298 GBC        2264 :     else if (command->meta == META_SET)
 1600 alvherre                 4299 EUB             :     {
 1474 alvherre                 4300 GIC        1711 :         PgBenchExpr *expr = command->expr;
                               4301                 :         PgBenchValue result;
 1600 alvherre                 4302 ECB             : 
 1467 tgl                      4303 CBC        1711 :         if (!evaluateExpr(st, expr, &result))
                               4304                 :         {
 1474 alvherre                 4305              22 :             commandFailed(st, argv[0], "evaluation of meta-command failed");
 1474 alvherre                 4306 GIC          23 :             return CSTATE_ABORTED;
                               4307                 :         }
 1600 alvherre                 4308 ECB             : 
  382 ishii                    4309 GIC        1689 :         if (!putVariableValue(&st->variables, argv[0], argv[1], &result))
                               4310                 :         {
 1474 alvherre                 4311               1 :             commandFailed(st, "set", "assignment of meta-command failed");
 1474 alvherre                 4312 CBC           1 :             return CSTATE_ABORTED;
                               4313                 :         }
                               4314                 :     }
                               4315             553 :     else if (command->meta == META_IF)
 1474 alvherre                 4316 ECB             :     {
                               4317                 :         /* backslash commands with an expression to evaluate */
 1474 alvherre                 4318 GIC         413 :         PgBenchExpr *expr = command->expr;
 1474 alvherre                 4319 ECB             :         PgBenchValue result;
                               4320                 :         bool        cond;
 1600 alvherre                 4321 EUB             : 
 1467 tgl                      4322 GBC         413 :         if (!evaluateExpr(st, expr, &result))
                               4323                 :         {
 1474 alvherre                 4324 UIC           0 :             commandFailed(st, argv[0], "evaluation of meta-command failed");
 1474 alvherre                 4325 LBC           0 :             return CSTATE_ABORTED;
 1600 alvherre                 4326 ECB             :         }
                               4327                 : 
 1474 alvherre                 4328 GIC         413 :         cond = valueTruth(&result);
 1474 alvherre                 4329 CBC         413 :         conditional_stack_push(st->cstack, cond ? IFSTATE_TRUE : IFSTATE_FALSE);
                               4330                 :     }
                               4331             140 :     else if (command->meta == META_ELIF)
                               4332                 :     {
 1474 alvherre                 4333 ECB             :         /* backslash commands with an expression to evaluate */
 1474 alvherre                 4334 CBC           5 :         PgBenchExpr *expr = command->expr;
 1474 alvherre                 4335 ECB             :         PgBenchValue result;
 1474 alvherre                 4336 EUB             :         bool        cond;
                               4337                 : 
 1474 alvherre                 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;
 1600 alvherre                 4343 EUB             :         }
                               4344                 : 
 1467 tgl                      4345 GIC           3 :         if (!evaluateExpr(st, expr, &result))
 1600 alvherre                 4346 ECB             :         {
 1474 alvherre                 4347 UIC           0 :             commandFailed(st, argv[0], "evaluation of meta-command failed");
 1474 alvherre                 4348 LBC           0 :             return CSTATE_ABORTED;
 1600 alvherre                 4349 ECB             :         }
                               4350                 : 
 1474 alvherre                 4351 CBC           3 :         cond = valueTruth(&result);
 1474 alvherre                 4352 GIC           3 :         Assert(conditional_stack_peek(st->cstack) == IFSTATE_FALSE);
 1474 alvherre                 4353 CBC           3 :         conditional_stack_poke(st->cstack, cond ? IFSTATE_TRUE : IFSTATE_FALSE);
                               4354                 :     }
                               4355             135 :     else if (command->meta == META_ELSE)
 1474 alvherre                 4356 ECB             :     {
 1474 alvherre                 4357 GIC           1 :         switch (conditional_stack_peek(st->cstack))
                               4358                 :         {
 1474 alvherre                 4359 CBC           1 :             case IFSTATE_TRUE:
 1474 alvherre                 4360 GIC           1 :                 conditional_stack_poke(st->cstack, IFSTATE_ELSE_FALSE);
 1474 alvherre                 4361 CBC           1 :                 break;
 1474 alvherre                 4362 UIC           0 :             case IFSTATE_FALSE: /* inconsistent if active */
 1474 alvherre                 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 */
 1474 alvherre                 4369 UIC           0 :                 Assert(false);
                               4370                 :         }
                               4371                 :     }
 1474 alvherre                 4372 GIC         134 :     else if (command->meta == META_ENDIF)
 1474 alvherre                 4373 ECB             :     {
 1474 alvherre                 4374 GIC          40 :         Assert(!conditional_stack_empty(st->cstack));
 1474 alvherre                 4375 GBC          40 :         conditional_stack_pop(st->cstack);
 1474 alvherre                 4376 EUB             :     }
 1474 alvherre                 4377 GIC          94 :     else if (command->meta == META_SETSHELL)
                               4378                 :     {
  382 ishii                    4379               3 :         if (!runShellCommand(&st->variables, argv[1], argv + 2, argc - 2))
                               4380                 :         {
 1474 alvherre                 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)
 1474 alvherre                 4386 ECB             :     {
  382 ishii                    4387 CBC           3 :         if (!runShellCommand(&st->variables, NULL, argv + 1, argc - 1))
                               4388                 :         {
 1474 alvherre                 4389               2 :             commandFailed(st, "shell", "execution of meta-command failed");
 1474 alvherre                 4390 GIC           2 :             return CSTATE_ABORTED;
 1600 alvherre                 4391 ECB             :         }
                               4392                 :     }
  755 alvherre                 4393 GIC          88 :     else if (command->meta == META_STARTPIPELINE)
  755 alvherre                 4394 ECB             :     {
                               4395                 :         /*
  755 alvherre                 4396 EUB             :          * In pipeline mode, we use a workflow based on libpq pipeline
                               4397                 :          * functions.
                               4398                 :          */
  755 alvherre                 4399 GIC          45 :         if (querymode == QUERY_SIMPLE)
  755 alvherre                 4400 ECB             :         {
  755 alvherre                 4401 UIC           0 :             commandFailed(st, "startpipeline", "cannot use pipeline mode with the simple query protocol");
  755 alvherre                 4402 LBC           0 :             return CSTATE_ABORTED;
                               4403                 :         }
  755 alvherre                 4404 ECB             : 
   47                          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
   47 alvherre                 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                 :          */
   47 alvherre                 4412 GIC          45 :         if (querymode == QUERY_PREPARED)
                               4413              41 :             prepareCommandsInPipeline(st);
   47 alvherre                 4414 ECB             : 
  755 alvherre                 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)
  755 alvherre                 4421 ECB             :         {
  755 alvherre                 4422 UIC           0 :             commandFailed(st, "startpipeline", "failed to enter pipeline mode");
  755 alvherre                 4423 LBC           0 :             return CSTATE_ABORTED;
                               4424                 :         }
                               4425                 :     }
  755 alvherre                 4426 GIC          43 :     else if (command->meta == META_ENDPIPELINE)
                               4427                 :     {
                               4428              43 :         if (PQpipelineStatus(st->con) != PQ_PIPELINE_ON)
                               4429                 :         {
  755 alvherre                 4430 CBC           1 :             commandFailed(st, "endpipeline", "not in pipeline mode");
  755 alvherre                 4431 GIC           1 :             return CSTATE_ABORTED;
  755 alvherre                 4432 ECB             :         }
  755 alvherre                 4433 CBC          42 :         if (!PQpipelineSync(st->con))
                               4434                 :         {
  755 alvherre                 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 */
  755 alvherre                 4440 GIC          42 :         return CSTATE_WAIT_RESULT;
  755 alvherre                 4441 EUB             :     }
                               4442                 : 
 1474                          4443                 :     /*
                               4444                 :      * executing the expression or shell command might have taken a
                               4445                 :      * non-negligible amount of time, so reset 'now'
                               4446                 :      */
  760 tmunro                   4447 GBC        2191 :     *now = 0;
                               4448                 : 
 1474 alvherre                 4449            2191 :     return CSTATE_END_COMMAND;
 1600 alvherre                 4450 EUB             : }
                               4451                 : 
  382 ishii                    4452                 : /*
                               4453                 :  * Return the number of failed transactions.
                               4454                 :  */
                               4455                 : static int64
  382 ishii                    4456 GIC          77 : getFailures(const StatsData *stats)
                               4457                 : {
                               4458             154 :     return (stats->serialization_failures +
  382 ishii                    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 *
  382 ishii                    4467 UIC           0 : getResultString(bool skipped, EStatus estatus)
                               4468                 : {
                               4469               0 :     if (skipped)
                               4470               0 :         return "skipped";
                               4471               0 :     else if (failures_detailed)
  382 ishii                    4472 ECB             :     {
  382 ishii                    4473 UIC           0 :         switch (estatus)
                               4474                 :         {
  382 ishii                    4475 LBC           0 :             case ESTATUS_SERIALIZATION_ERROR:
                               4476               0 :                 return "serialization";
  382 ishii                    4477 UIC           0 :             case ESTATUS_DEADLOCK_ERROR:
  382 ishii                    4478 LBC           0 :                 return "deadlock";
  382 ishii                    4479 UIC           0 :             default:
                               4480                 :                 /* internal error which should never occur */
  366 tgl                      4481               0 :                 pg_fatal("unexpected error status: %d", estatus);
                               4482                 :         }
                               4483                 :     }
  382 ishii                    4484 ECB             :     else
  382 ishii                    4485 LBC           0 :         return "failed";
  382 ishii                    4486 ECB             : }
                               4487                 : 
                               4488                 : /*
 2288 tgl                      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
 2288 tgl                      4498 GIC         110 : doLog(TState *thread, CState *st,
 2627 alvherre                 4499 EUB             :       StatsData *agg, bool skipped, double latency, double lag)
                               4500                 : {
 2495 rhaas                    4501 GBC         110 :     FILE       *logfile = thread->logfile;
  637 tmunro                   4502             110 :     pg_time_usec_t now = pg_time_now() + epoch_shift;
 2613 alvherre                 4503 EUB             : 
 2613 alvherre                 4504 GBC         110 :     Assert(use_log);
 2613 alvherre                 4505 EUB             : 
 3111 heikki.linnakangas       4506                 :     /*
                               4507                 :      * Skip the log entry if sampling is enabled and this row doesn't belong
                               4508                 :      * to the random sample.
                               4509                 :      */
 3111 heikki.linnakangas       4510 GIC         110 :     if (sample_rate != 0.0 &&
  497 tgl                      4511             100 :         pg_prng_double(&thread->ts_sample_rs) > sample_rate)
 3111 heikki.linnakangas       4512 GBC          52 :         return;
 3111 heikki.linnakangas       4513 EUB             : 
                               4514                 :     /* should we aggregate the results or not? */
 3111 heikki.linnakangas       4515 GIC          58 :     if (agg_interval > 0)
                               4516                 :     {
                               4517                 :         pg_time_usec_t next;
                               4518                 : 
                               4519                 :         /*
 2288 tgl                      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).
 3111 heikki.linnakangas       4523                 :          */
 2288 tgl                      4524                 : 
  637 tmunro                   4525 UBC           0 :         while ((next = agg->start_time + agg_interval * INT64CONST(1000000)) <= now)
                               4526                 :         {
  368 ishii                    4527               0 :             double      lag_sum = 0.0;
  368 ishii                    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;
  368 ishii                    4533 UBC           0 :             int64       deadlock_failures = 0;
                               4534               0 :             int64       retried = 0;
                               4535               0 :             int64       retries = 0;
                               4536                 : 
 2627 alvherre                 4537 EUB             :             /* print aggregated report to logfile */
  760 tmunro                   4538 UIC           0 :             fprintf(logfile, INT64_FORMAT " " INT64_FORMAT " %.0f %.0f %.0f %.0f",
  637 tmunro                   4539 UBC           0 :                     agg->start_time / 1000000,   /* seconds since Unix epoch */
 2627 alvherre                 4540 EUB             :                     agg->cnt,
                               4541                 :                     agg->latency.sum,
                               4542                 :                     agg->latency.sum2,
                               4543                 :                     agg->latency.min,
                               4544                 :                     agg->latency.max);
                               4545                 : 
 2627 alvherre                 4546 UBC           0 :             if (throttle_delay)
 3100 heikki.linnakangas       4547 EUB             :             {
  368 ishii                    4548 UIC           0 :                 lag_sum = agg->lag.sum;
  368 ishii                    4549 UBC           0 :                 lag_sum2 = agg->lag.sum2;
  368 ishii                    4550 UIC           0 :                 lag_min = agg->lag.min;
                               4551               0 :                 lag_max = agg->lag.max;
                               4552                 :             }
  368 ishii                    4553 UBC           0 :             fprintf(logfile, " %.0f %.0f %.0f %.0f",
                               4554                 :                     lag_sum,
                               4555                 :                     lag_sum2,
  332 tgl                      4556 EUB             :                     lag_min,
                               4557                 :                     lag_max);
                               4558                 : 
  368 ishii                    4559 UIC           0 :             if (latency_limit)
  368 ishii                    4560 UBC           0 :                 skipped = agg->skipped;
  368 ishii                    4561 UIC           0 :             fprintf(logfile, " " INT64_FORMAT, skipped);
                               4562                 : 
  382                          4563               0 :             if (max_tries != 1)
                               4564                 :             {
  368 ishii                    4565 LBC           0 :                 retried = agg->retried;
                               4566               0 :                 retries = agg->retries;
                               4567                 :             }
  368 ishii                    4568 UIC           0 :             fprintf(logfile, " " INT64_FORMAT " " INT64_FORMAT, retried, retries);
                               4569                 : 
                               4570               0 :             if (failures_detailed)
  368 ishii                    4571 EUB             :             {
  368 ishii                    4572 UIC           0 :                 serialization_failures = agg->serialization_failures;
                               4573               0 :                 deadlock_failures = agg->deadlock_failures;
                               4574                 :             }
  355                          4575               0 :             fprintf(logfile, " " INT64_FORMAT " " INT64_FORMAT,
  368 ishii                    4576 ECB             :                     serialization_failures,
  368 ishii                    4577 EUB             :                     deadlock_failures);
  368 ishii                    4578 ECB             : 
 2627 alvherre                 4579 UBC           0 :             fputc('\n', logfile);
 3111 heikki.linnakangas       4580 ECB             : 
                               4581                 :             /* reset data and move to next interval */
  637 tmunro                   4582 UIC           0 :             initStats(agg, next);
                               4583                 :         }
                               4584                 : 
                               4585                 :         /* accumulate the current transaction */
  382 ishii                    4586               0 :         accumStats(agg, skipped, latency, lag, st->estatus, st->tries);
                               4587                 :     }
                               4588                 :     else
                               4589                 :     {
                               4590                 :         /* no, print raw transactions */
  382 ishii                    4591 GIC          58 :         if (!skipped && st->estatus == ESTATUS_NO_ERROR)
  760 tmunro                   4592 CBC          58 :             fprintf(logfile, "%d " INT64_FORMAT " %.0f %d " INT64_FORMAT " "
                               4593                 :                     INT64_FORMAT,
                               4594                 :                     st->id, st->cnt, latency, st->use_file,
  760 tmunro                   4595 ECB             :                     now / 1000000, now % 1000000);
  382 ishii                    4596                 :         else
  382 ishii                    4597 LBC           0 :             fprintf(logfile, "%d " INT64_FORMAT " %s %d " INT64_FORMAT " "
  382 ishii                    4598 ECB             :                     INT64_FORMAT,
                               4599                 :                     st->id, st->cnt, getResultString(skipped, st->estatus),
                               4600                 :                     st->use_file, now / 1000000, now % 1000000);
                               4601                 : 
 3111 heikki.linnakangas       4602 CBC          58 :         if (throttle_delay)
 3111 heikki.linnakangas       4603 UIC           0 :             fprintf(logfile, " %.0f", lag);
  382 ishii                    4604 GIC          58 :         if (max_tries != 1)
  354 peter                    4605 LBC           0 :             fprintf(logfile, " %u", st->tries - 1);
 3111 heikki.linnakangas       4606 CBC          58 :         fputc('\n', logfile);
                               4607                 :     }
                               4608                 : }
                               4609                 : 
 2627 alvherre                 4610 ECB             : /*
                               4611                 :  * Accumulate and report statistics at end of a transaction.
                               4612                 :  *
 2043 tgl                      4613                 :  * (This is also called when a transaction is late and thus skipped.
  382 ishii                    4614                 :  * Note that even skipped and failed transactions are counted in the CState
                               4615                 :  * "cnt" field.)
                               4616                 :  */
 2627 alvherre                 4617                 : static void
  760 tmunro                   4618 GIC        2438 : processXactStats(TState *thread, CState *st, pg_time_usec_t *now,
 2613 alvherre                 4619 ECB             :                  bool skipped, StatsData *agg)
 2627                          4620                 : {
 2627 alvherre                 4621 GIC        2438 :     double      latency = 0.0,
                               4622            2438 :                 lag = 0.0;
  382 ishii                    4623 CBC        2438 :     bool        detailed = progress || throttle_delay || latency_limit ||
  332 tgl                      4624            4876 :     use_log || per_script_stats;
 2627 alvherre                 4625 ECB             : 
  382 ishii                    4626 CBC        2438 :     if (detailed && !skipped && st->estatus == ESTATUS_NO_ERROR)
                               4627                 :     {
  760 tmunro                   4628 GIC        1411 :         pg_time_now_lazy(now);
                               4629                 : 
                               4630                 :         /* compute latency & lag */
  760 tmunro                   4631 CBC        1411 :         latency = (*now) - st->txn_scheduled;
  760 tmunro                   4632 GIC        1411 :         lag = st->txn_begin - st->txn_scheduled;
                               4633                 :     }
                               4634                 : 
  382 ishii                    4635 ECB             :     /* keep detailed thread stats */
  382 ishii                    4636 CBC        2438 :     accumStats(&thread->stats, skipped, latency, lag, st->estatus, st->tries);
 2627 alvherre                 4637 ECB             : 
                               4638                 :     /* count transactions over the latency limit, if needed */
  382 ishii                    4639 GIC        2438 :     if (latency_limit && latency > latency_limit)
                               4640               1 :         thread->latency_late++;
                               4641                 : 
                               4642                 :     /* client stat is just counting */
 2043 tgl                      4643 CBC        2438 :     st->cnt++;
                               4644                 : 
 2627 alvherre                 4645            2438 :     if (use_log)
 2288 tgl                      4646 GIC         110 :         doLog(thread, st, agg, skipped, latency, lag);
                               4647                 : 
                               4648                 :     /* XXX could use a mutex here, but we choose not to */
 2624 alvherre                 4649            2438 :     if (per_script_stats)
  382 ishii                    4650            1100 :         accumStats(&sql_script[st->use_file].stats, skipped, latency, lag,
  382 ishii                    4651 CBC        1100 :                    st->estatus, st->tries);
 2627 alvherre                 4652 GIC        2438 : }
                               4653                 : 
                               4654                 : 
                               4655                 : /* discard connections */
 8397 bruce                    4656 ECB             : static void
 4997 ishii                    4657 GIC         137 : disconnect_all(CState *state, int length)
                               4658                 : {
                               4659                 :     int         i;
                               4660                 : 
                               4661             335 :     for (i = 0; i < length; i++)
 1865 andres                   4662             198 :         finishCon(&state[i]);
 8485 ishii                    4663             137 : }
                               4664                 : 
 1973 tgl                      4665 ECB             : /*
                               4666                 :  * Remove old pgbench tables, if any exist
                               4667                 :  */
                               4668                 : static void
 1973 tgl                      4669 GIC           3 : initDropTables(PGconn *con)
 8397 bruce                    4670 ECB             : {
 1973 tgl                      4671 GIC           3 :     fprintf(stderr, "dropping old tables...\n");
 1973 tgl                      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                 :      */
 1973 tgl                      4677 GIC           3 :     executeStatement(con, "drop table if exists "
 1973 tgl                      4678 ECB             :                      "pgbench_accounts, "
                               4679                 :                      "pgbench_branches, "
                               4680                 :                      "pgbench_history, "
                               4681                 :                      "pgbench_tellers");
 1973 tgl                      4682 CBC           3 : }
                               4683                 : 
                               4684                 : /*
                               4685                 :  * Create "pgbench_accounts" partitions if needed.
 1286 akapila                  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
 1286 akapila                  4691 GIC           2 : createPartitions(PGconn *con)
                               4692                 : {
                               4693                 :     PQExpBufferData query;
 1286 akapila                  4694 ECB             : 
                               4695                 :     /* we must have to create some partitions */
 1286 akapila                  4696 GIC           2 :     Assert(partitions > 0);
 1286 akapila                  4697 ECB             : 
 1286 akapila                  4698 GIC           2 :     fprintf(stderr, "creating %d partitions...\n", partitions);
 1286 akapila                  4699 ECB             : 
  921 heikki.linnakangas       4700 GIC           2 :     initPQExpBuffer(&query);
  921 heikki.linnakangas       4701 ECB             : 
 1286 akapila                  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                 : 
  921 heikki.linnakangas       4708               3 :             printfPQExpBuffer(&query,
  921 heikki.linnakangas       4709 ECB             :                               "create%s table pgbench_accounts_%d\n"
                               4710                 :                               "  partition of pgbench_accounts\n"
                               4711                 :                               "  for values from (",
  921 heikki.linnakangas       4712 GIC           3 :                               unlogged_tables ? " unlogged" : "", p);
 1286 akapila                  4713 ECB             : 
                               4714                 :             /*
                               4715                 :              * For RANGE, we use open-ended partitions at the beginning and
 1286 akapila                  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                 :              */
 1286 akapila                  4720 GIC           3 :             if (p == 1)
  921 heikki.linnakangas       4721               1 :                 appendPQExpBufferStr(&query, "minvalue");
 1286 akapila                  4722 ECB             :             else
  921 heikki.linnakangas       4723 GIC           2 :                 appendPQExpBuffer(&query, INT64_FORMAT, (p - 1) * part_size + 1);
  921 heikki.linnakangas       4724 ECB             : 
  921 heikki.linnakangas       4725 GIC           3 :             appendPQExpBufferStr(&query, ") to (");
                               4726                 : 
 1286 akapila                  4727 CBC           3 :             if (p < partitions)
  921 heikki.linnakangas       4728               2 :                 appendPQExpBuffer(&query, INT64_FORMAT, p * part_size + 1);
                               4729                 :             else
  921 heikki.linnakangas       4730 GIC           1 :                 appendPQExpBufferStr(&query, "maxvalue");
                               4731                 : 
                               4732               3 :             appendPQExpBufferChar(&query, ')');
                               4733                 :         }
 1286 akapila                  4734 CBC           2 :         else if (partition_method == PART_HASH)
  921 heikki.linnakangas       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 */
 1286 akapila                  4742 UIC           0 :             Assert(0);
                               4743                 : 
                               4744                 :         /*
                               4745                 :          * Per ddlinfo in initCreateTables, fillfactor is needed on table
                               4746                 :          * pgbench_accounts.
                               4747                 :          */
  921 heikki.linnakangas       4748 GIC           5 :         appendPQExpBuffer(&query, " with (fillfactor=%d)", fillfactor);
                               4749                 : 
                               4750               5 :         executeStatement(con, query.data);
                               4751                 :     }
                               4752                 : 
                               4753               2 :     termPQExpBuffer(&query);
 1286 akapila                  4754               2 : }
                               4755                 : 
                               4756                 : /*
                               4757                 :  * Create pgbench's standard tables
                               4758                 :  */
                               4759                 : static void
 1973 tgl                      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",
 3247 tgl                      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)",
 3946                          4785                 :             0
                               4786                 :         },
 4276 rhaas                    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",
 3247 tgl                      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
 4276 rhaas                    4798                 :         },
                               4799                 :         {
                               4800                 :             "pgbench_branches",
 3946 tgl                      4801                 :             "bid int not null,bbalance int,filler char(88)",
                               4802                 :             "bid int not null,bbalance int,filler char(88)",
                               4803                 :             1
 4276 rhaas                    4804                 :         }
                               4805                 :     };
                               4806                 :     int         i;
  921 heikki.linnakangas       4807                 :     PQExpBufferData query;
                               4808                 : 
 1973 tgl                      4809 GIC           3 :     fprintf(stderr, "creating tables...\n");
                               4810                 : 
  921 heikki.linnakangas       4811 CBC           3 :     initPQExpBuffer(&query);
  921 heikki.linnakangas       4812 ECB             : 
 5847 ishii                    4813 CBC          15 :     for (i = 0; i < lengthof(DDLs); i++)
                               4814                 :     {
 3247 tgl                      4815 GIC          12 :         const struct ddlinfo *ddl = &DDLs[i];
 4276 rhaas                    4816 ECB             : 
                               4817                 :         /* Construct new create table statement. */
  921 heikki.linnakangas       4818 GIC          24 :         printfPQExpBuffer(&query, "create%s table %s(%s)",
  921 heikki.linnakangas       4819 CBC          12 :                           unlogged_tables ? " unlogged" : "",
  921 heikki.linnakangas       4820 GIC          12 :                           ddl->table,
  921 heikki.linnakangas       4821 CBC          12 :                           (scale >= SCALE_32BIT_THRESHOLD) ? ddl->bigcols : ddl->smcols);
 1286 akapila                  4822 ECB             : 
                               4823                 :         /* Partition pgbench_accounts table */
 1286 akapila                  4824 GIC          12 :         if (partition_method != PART_NONE && strcmp(ddl->table, "pgbench_accounts") == 0)
  921 heikki.linnakangas       4825               2 :             appendPQExpBuffer(&query,
                               4826                 :                               " partition by %s (aid)", PARTITION_METHOD[partition_method]);
 1286 akapila                  4827              10 :         else if (ddl->declare_fillfactor)
                               4828                 :         {
 1286 akapila                  4829 ECB             :             /* fillfactor is only expected on actual tables */
  921 heikki.linnakangas       4830 GIC           7 :             appendPQExpBuffer(&query, " with (fillfactor=%d)", fillfactor);
  921 heikki.linnakangas       4831 ECB             :         }
                               4832                 : 
 4276 rhaas                    4833 GIC          12 :         if (tablespace != NULL)
                               4834                 :         {
                               4835                 :             char       *escape_tablespace;
 3955 bruce                    4836 ECB             : 
  921 heikki.linnakangas       4837 GIC           4 :             escape_tablespace = PQescapeIdentifier(con, tablespace, strlen(tablespace));
                               4838               4 :             appendPQExpBuffer(&query, " tablespace %s", escape_tablespace);
 4276 rhaas                    4839               4 :             PQfreemem(escape_tablespace);
                               4840                 :         }
                               4841                 : 
  921 heikki.linnakangas       4842 CBC          12 :         executeStatement(con, query.data);
                               4843                 :     }
                               4844                 : 
  921 heikki.linnakangas       4845 GIC           3 :     termPQExpBuffer(&query);
                               4846                 : 
 1286 akapila                  4847               3 :     if (partition_method != PART_NONE)
                               4848               2 :         createPartitions(con);
                               4849               3 : }
                               4850                 : 
                               4851                 : /*
 1250 fujii                    4852 ECB             :  * Truncate away any old data, in one command in case there are foreign keys
                               4853                 :  */
                               4854                 : static void
 1250 fujii                    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");
 1250 fujii                    4862 GIC           3 : }
 1250 fujii                    4863 ECB             : 
                               4864                 : /*
                               4865                 :  * Fill the standard tables with some data generated and sent from the client
                               4866                 :  */
                               4867                 : static void
 1250 fujii                    4868 CBC           2 : initGenerateDataClientSide(PGconn *con)
                               4869                 : {
                               4870                 :     PQExpBufferData sql;
                               4871                 :     PGresult   *res;
                               4872                 :     int         i;
                               4873                 :     int64       k;
  332 tgl                      4874 ECB             :     char       *copy_statement;
                               4875                 : 
                               4876                 :     /* used to track elapsed time and estimate of the remaining time */
  760 tmunro                   4877                 :     pg_time_usec_t start;
 1973 tgl                      4878 GIC           2 :     int         log_interval = 1;
                               4879                 : 
 1222 michael                  4880 ECB             :     /* Stay on the same line if reporting to a terminal */
 1222 michael                  4881 GIC           2 :     char        eol = isatty(fileno(stderr)) ? '\r' : '\n';
                               4882                 : 
 1250 fujii                    4883 CBC           2 :     fprintf(stderr, "generating data (client-side)...\n");
                               4884                 : 
                               4885                 :     /*
 1973 tgl                      4886 ECB             :      * we do all of this in one transaction to enable the backend's
                               4887                 :      * data-loading optimizations
                               4888                 :      */
 5847 ishii                    4889 CBC           2 :     executeStatement(con, "begin");
                               4890                 : 
                               4891                 :     /* truncate away any old data */
 1250 fujii                    4892 GIC           2 :     initTruncateTables(con);
                               4893                 : 
  921 heikki.linnakangas       4894               2 :     initPQExpBuffer(&sql);
                               4895                 : 
                               4896                 :     /*
 1973 tgl                      4897 ECB             :      * fill branches, tellers, accounts in that order in case foreign keys
                               4898                 :      * already exist
                               4899                 :      */
 6052 ishii                    4900 CBC           4 :     for (i = 0; i < nbranches * scale; i++)
                               4901                 :     {
 3478 fujii                    4902 ECB             :         /* "filler" column defaults to NULL */
  921 heikki.linnakangas       4903 GIC           2 :         printfPQExpBuffer(&sql,
  921 heikki.linnakangas       4904 ECB             :                           "insert into pgbench_branches(bid,bbalance) values(%d,0)",
  921 heikki.linnakangas       4905 EUB             :                           i + 1);
  921 heikki.linnakangas       4906 CBC           2 :         executeStatement(con, sql.data);
                               4907                 :     }
 8485 ishii                    4908 ECB             : 
 6052 ishii                    4909 GIC          22 :     for (i = 0; i < ntellers * scale; i++)
 8397 bruce                    4910 ECB             :     {
                               4911                 :         /* "filler" column defaults to NULL */
  921 heikki.linnakangas       4912 CBC          20 :         printfPQExpBuffer(&sql,
                               4913                 :                           "insert into pgbench_tellers(tid,bid,tbalance) values (%d,%d,0)",
  921 heikki.linnakangas       4914 GIC          20 :                           i + 1, i / ntellers + 1);
  921 heikki.linnakangas       4915 CBC          20 :         executeStatement(con, sql.data);
                               4916                 :     }
 8485 ishii                    4917 ECB             : 
 5847                          4918                 :     /*
 1973 tgl                      4919 EUB             :      * accounts is big enough to be worth using COPY and tracking runtime
                               4920                 :      */
  584 ishii                    4921 ECB             : 
  390 michael                  4922 EUB             :     /* use COPY with FREEZE on v14 and later without partitioning */
  584 ishii                    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                 : 
  584 ishii                    4928 CBC           2 :     res = PQexec(con, copy_statement);
  584 ishii                    4929 ECB             : 
 5847 ishii                    4930 CBC           2 :     if (PQresultStatus(res) != PGRES_COPY_IN)
  366 tgl                      4931 LBC           0 :         pg_fatal("unexpected copy in result: %s", PQerrorMessage(con));
 6873 ishii                    4932 GIC           2 :     PQclear(res);
 7921 ishii                    4933 ECB             : 
  760 tmunro                   4934 GIC           2 :     start = pg_time_now();
 3744 ishii                    4935 ECB             : 
 3722 heikki.linnakangas       4936 GIC      200002 :     for (k = 0; k < (int64) naccounts * scale; k++)
                               4937                 :     {
                               4938          200000 :         int64       j = k + 1;
 8397 bruce                    4939 ECB             : 
                               4940                 :         /* "filler" column defaults to blank padded empty string */
  921 heikki.linnakangas       4941 CBC      200000 :         printfPQExpBuffer(&sql,
  921 heikki.linnakangas       4942 ECB             :                           INT64_FORMAT "\t" INT64_FORMAT "\t%d\t\n",
  921 heikki.linnakangas       4943 GIC      200000 :                           j, k / naccounts + 1, 0);
                               4944          200000 :         if (PQputline(con, sql.data))
  366 tgl                      4945 LBC           0 :             pg_fatal("PQputline failed");
                               4946                 : 
 1224 michael                  4947 CBC      200000 :         if (CancelRequested)
 1224 michael                  4948 UIC           0 :             break;
 1224 michael                  4949 ECB             : 
                               4950                 :         /*
                               4951                 :          * If we want to stick with the original logging, print a message each
 3602 bruce                    4952                 :          * 100k inserted rows.
                               4953                 :          */
 3602 bruce                    4954 GIC      200000 :         if ((!use_quiet) && (j % 100000 == 0))
 3744 ishii                    4955               1 :         {
  760 tmunro                   4956               1 :             double      elapsed_sec = PG_TIME_GET_DOUBLE(pg_time_now() - start);
  760 tmunro                   4957 CBC           1 :             double      remaining_sec = ((double) scale * naccounts - j) * elapsed_sec / j;
 3744 ishii                    4958 EUB             : 
 1222 michael                  4959 GIC           1 :             fprintf(stderr, INT64_FORMAT " of " INT64_FORMAT " tuples (%d%%) done (elapsed %.2f s, remaining %.2f s)%c",
 3602 bruce                    4960 ECB             :                     j, (int64) naccounts * scale,
 3405 ishii                    4961 GBC           1 :                     (int) (((int64) j * 100) / (naccounts * (int64) scale)),
 1222 michael                  4962 ECB             :                     elapsed_sec, remaining_sec, eol);
 3744 ishii                    4963 EUB             :         }
                               4964                 :         /* let's not call the timing for each row, but only each 100 rows */
 3744 ishii                    4965 CBC      199999 :         else if (use_quiet && (j % 100 == 0))
                               4966                 :         {
  760 tmunro                   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)? */
 3602 bruce                    4971 GIC        1000 :             if ((j == scale * naccounts) || (elapsed_sec >= log_interval * LOG_STEP_SECONDS))
                               4972                 :             {
 1222 michael                  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 */
 3602 bruce                    4978 CBC           2 :                 log_interval = (int) ceil(elapsed_sec / LOG_STEP_SECONDS);
                               4979                 :             }
                               4980                 :         }
                               4981                 :     }
 1222 michael                  4982 ECB             : 
 1222 michael                  4983 GIC           2 :     if (eol != '\n')
 1222 michael                  4984 UIC           0 :         fputc('\n', stderr);    /* Need to move to next line */
                               4985                 : 
 5847 ishii                    4986 GIC           2 :     if (PQputline(con, "\\.\n"))
  366 tgl                      4987 UIC           0 :         pg_fatal("very last PQputline failed");
 5847 ishii                    4988 CBC           2 :     if (PQendcopy(con))
  366 tgl                      4989 UIC           0 :         pg_fatal("PQendcopy failed");
                               4990                 : 
  921 heikki.linnakangas       4991 CBC           2 :     termPQExpBuffer(&sql);
                               4992                 : 
 5847 ishii                    4993               2 :     executeStatement(con, "commit");
 1973 tgl                      4994 GIC           2 : }
 5847 ishii                    4995 ECB             : 
                               4996                 : /*
                               4997                 :  * Fill the standard tables with some data generated on the server
                               4998                 :  *
 1250 fujii                    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
 1250 fujii                    5004 GIC           1 : initGenerateDataServerSide(PGconn *con)
 1250 fujii                    5005 ECB             : {
                               5006                 :     PQExpBufferData sql;
                               5007                 : 
 1250 fujii                    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
 1250 fujii                    5012 ECB             :      * data-loading optimizations
                               5013                 :      */
 1250 fujii                    5014 CBC           1 :     executeStatement(con, "begin");
                               5015                 : 
 1250 fujii                    5016 ECB             :     /* truncate away any old data */
 1250 fujii                    5017 CBC           1 :     initTruncateTables(con);
                               5018                 : 
  921 heikki.linnakangas       5019 GIC           1 :     initPQExpBuffer(&sql);
                               5020                 : 
                               5021               1 :     printfPQExpBuffer(&sql,
                               5022                 :                       "insert into pgbench_branches(bid,bbalance) "
  921 heikki.linnakangas       5023 ECB             :                       "select bid, 0 "
                               5024                 :                       "from generate_series(1, %d) as bid", nbranches * scale);
  921 heikki.linnakangas       5025 CBC           1 :     executeStatement(con, sql.data);
  921 heikki.linnakangas       5026 ECB             : 
  921 heikki.linnakangas       5027 CBC           1 :     printfPQExpBuffer(&sql,
  921 heikki.linnakangas       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);
  921 heikki.linnakangas       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, '' "
  921 heikki.linnakangas       5036 ECB             :                       "from generate_series(1, " INT64_FORMAT ") as aid",
                               5037                 :                       naccounts, (int64) naccounts * scale);
  921 heikki.linnakangas       5038 GIC           1 :     executeStatement(con, sql.data);
                               5039                 : 
                               5040               1 :     termPQExpBuffer(&sql);
                               5041                 : 
 1250 fujii                    5042               1 :     executeStatement(con, "commit");
                               5043               1 : }
                               5044                 : 
                               5045                 : /*
 1973 tgl                      5046 ECB             :  * Invoke vacuum on the standard tables
                               5047                 :  */
                               5048                 : static void
 1973 tgl                      5049 CBC           2 : initVacuum(PGconn *con)
                               5050                 : {
                               5051               2 :     fprintf(stderr, "vacuuming...\n");
                               5052               2 :     executeStatement(con, "vacuum analyze pgbench_branches");
 1973 tgl                      5053 GIC           2 :     executeStatement(con, "vacuum analyze pgbench_tellers");
 1973 tgl                      5054 CBC           2 :     executeStatement(con, "vacuum analyze pgbench_accounts");
 1973 tgl                      5055 GIC           2 :     executeStatement(con, "vacuum analyze pgbench_history");
                               5056               2 : }
                               5057                 : 
 1973 tgl                      5058 ECB             : /*
                               5059                 :  * Create primary keys on the standard tables
                               5060                 :  */
                               5061                 : static void
 1973 tgl                      5062 GIC           3 : initCreatePKeys(PGconn *con)
                               5063                 : {
 1973 tgl                      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                 : 
 1973 tgl                      5072 GIC           3 :     fprintf(stderr, "creating primary keys...\n");
  921 heikki.linnakangas       5073               3 :     initPQExpBuffer(&query);
  921 heikki.linnakangas       5074 ECB             : 
 3247 tgl                      5075 GIC          12 :     for (i = 0; i < lengthof(DDLINDEXes); i++)
                               5076                 :     {
  921 heikki.linnakangas       5077               9 :         resetPQExpBuffer(&query);
                               5078               9 :         appendPQExpBufferStr(&query, DDLINDEXes[i]);
                               5079                 : 
 4276 rhaas                    5080               9 :         if (index_tablespace != NULL)
                               5081                 :         {
                               5082                 :             char       *escape_tablespace;
                               5083                 : 
                               5084               3 :             escape_tablespace = PQescapeIdentifier(con, index_tablespace,
 4276 rhaas                    5085 ECB             :                                                    strlen(index_tablespace));
  921 heikki.linnakangas       5086 CBC           3 :             appendPQExpBuffer(&query, " using index tablespace %s", escape_tablespace);
 4276 rhaas                    5087 GIC           3 :             PQfreemem(escape_tablespace);
 4276 rhaas                    5088 ECB             :         }
                               5089                 : 
  921 heikki.linnakangas       5090 CBC           9 :         executeStatement(con, query.data);
                               5091                 :     }
                               5092                 : 
  921 heikki.linnakangas       5093 GIC           3 :     termPQExpBuffer(&query);
 1973 tgl                      5094               3 : }
                               5095                 : 
                               5096                 : /*
                               5097                 :  * Create foreign key constraints between the standard tables
                               5098                 :  */
                               5099                 : static void
 1973 tgl                      5100 CBC           2 : initCreateFKeys(PGconn *con)
                               5101                 : {
 1973 tgl                      5102 ECB             :     static const char *const DDLKEYs[] = {
 1973 tgl                      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",
 1973 tgl                      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                 : 
 1973 tgl                      5111 CBC           2 :     fprintf(stderr, "creating foreign keys...\n");
 1973 tgl                      5112 GIC          12 :     for (i = 0; i < lengthof(DDLKEYs); i++)
                               5113                 :     {
 1973 tgl                      5114 CBC          10 :         executeStatement(con, DDLKEYs[i]);
                               5115                 :     }
 1973 tgl                      5116 GIC           2 : }
                               5117                 : 
                               5118                 : /*
                               5119                 :  * Validate an initialization-steps string
 1973 tgl                      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
 1973 tgl                      5126 CBC           4 : checkInitSteps(const char *initialize_steps)
                               5127                 : {
                               5128               4 :     if (initialize_steps[0] == '\0')
  366 tgl                      5129 UIC           0 :         pg_fatal("no initialization steps specified");
 1973 tgl                      5130 ECB             : 
 1250 fujii                    5131 GBC          21 :     for (const char *step = initialize_steps; *step != '\0'; step++)
                               5132                 :     {
 1250 fujii                    5133 CBC          18 :         if (strchr(ALL_INIT_STEPS " ", *step) == NULL)
 1973 tgl                      5134 ECB             :         {
  366 tgl                      5135 GIC           1 :             pg_log_error("unrecognized initialization step \"%c\"", *step);
  366 tgl                      5136 CBC           1 :             pg_log_error_detail("Allowed step characters are: \"" ALL_INIT_STEPS "\".");
 1973 tgl                      5137 GIC           1 :             exit(1);
 1973 tgl                      5138 ECB             :         }
                               5139                 :     }
 1973 tgl                      5140 GIC           3 : }
 1973 tgl                      5141 ECB             : 
                               5142                 : /*
                               5143                 :  * Invoke each initialization step in the given string
                               5144                 :  */
                               5145                 : static void
 1973 tgl                      5146 CBC           3 : runInitSteps(const char *initialize_steps)
 1973 tgl                      5147 ECB             : {
 1363 tmunro                   5148                 :     PQExpBufferData stats;
 1973 tgl                      5149                 :     PGconn     *con;
                               5150                 :     const char *step;
 1363 tmunro                   5151 CBC           3 :     double      run_time = 0.0;
                               5152               3 :     bool        first = true;
 1363 tmunro                   5153 ECB             : 
 1363 tmunro                   5154 CBC           3 :     initPQExpBuffer(&stats);
 1973 tgl                      5155 ECB             : 
 1973 tgl                      5156 CBC           3 :     if ((con = doConnect()) == NULL)
  366 tgl                      5157 LBC           0 :         pg_fatal("could not create connection for initialization");
 1973 tgl                      5158 ECB             : 
 1224 michael                  5159 CBC           3 :     setup_cancel_handler(NULL);
                               5160               3 :     SetCancelConn(con);
 1224 michael                  5161 ECB             : 
 1973 tgl                      5162 CBC          22 :     for (step = initialize_steps; *step != '\0'; step++)
 3946 tgl                      5163 ECB             :     {
 1363 tmunro                   5164 CBC          19 :         char       *op = NULL;
  760                          5165              19 :         pg_time_usec_t start = pg_time_now();
 1363 tmunro                   5166 ECB             : 
 1973 tgl                      5167 CBC          19 :         switch (*step)
 3946 tgl                      5168 ECB             :         {
 1973 tgl                      5169 CBC           3 :             case 'd':
 1363 tmunro                   5170               3 :                 op = "drop tables";
 1973 tgl                      5171               3 :                 initDropTables(con);
                               5172               3 :                 break;
 1973 tgl                      5173 GBC           3 :             case 't':
 1363 tmunro                   5174               3 :                 op = "create tables";
 1973 tgl                      5175               3 :                 initCreateTables(con);
                               5176               3 :                 break;
 1973 tgl                      5177 GIC           2 :             case 'g':
 1250 fujii                    5178               2 :                 op = "client-side generate";
 1250 fujii                    5179 CBC           2 :                 initGenerateDataClientSide(con);
 1250 fujii                    5180 GIC           2 :                 break;
 1250 fujii                    5181 CBC           1 :             case 'G':
 1250 fujii                    5182 GIC           1 :                 op = "server-side generate";
 1250 fujii                    5183 CBC           1 :                 initGenerateDataServerSide(con);
 1973 tgl                      5184               1 :                 break;
 1973 tgl                      5185 GIC           2 :             case 'v':
 1363 tmunro                   5186 CBC           2 :                 op = "vacuum";
 1973 tgl                      5187 GIC           2 :                 initVacuum(con);
 1973 tgl                      5188 CBC           2 :                 break;
 1973 tgl                      5189 GIC           3 :             case 'p':
 1363 tmunro                   5190 CBC           3 :                 op = "primary keys";
 1973 tgl                      5191 GIC           3 :                 initCreatePKeys(con);
                               5192               3 :                 break;
                               5193               2 :             case 'f':
 1363 tmunro                   5194 CBC           2 :                 op = "foreign keys";
 1973 tgl                      5195               2 :                 initCreateFKeys(con);
                               5196               2 :                 break;
                               5197               3 :             case ' ':
                               5198               3 :                 break;          /* ignore */
 1973 tgl                      5199 UIC           0 :             default:
  366                          5200               0 :                 pg_log_error("unrecognized initialization step \"%c\"", *step);
 1973                          5201               0 :                 PQfinish(con);
                               5202               0 :                 exit(1);
                               5203                 :         }
                               5204                 : 
 1363 tmunro                   5205 CBC          19 :         if (op != NULL)
                               5206                 :         {
  760 tmunro                   5207 GIC          16 :             double      elapsed_sec = PG_TIME_GET_DOUBLE(pg_time_now() - start);
                               5208                 : 
 1363                          5209              16 :             if (!first)
                               5210              13 :                 appendPQExpBufferStr(&stats, ", ");
                               5211                 :             else
                               5212               3 :                 first = false;
 1363 tmunro                   5213 ECB             : 
 1363 tmunro                   5214 CBC          16 :             appendPQExpBuffer(&stats, "%s %.2f s", op, elapsed_sec);
                               5215                 : 
                               5216              16 :             run_time += elapsed_sec;
                               5217                 :         }
 3946 tgl                      5218 ECB             :     }
                               5219                 : 
 1363 tmunro                   5220 CBC           3 :     fprintf(stderr, "done in %.2f s (%s).\n", run_time, stats.data);
 1224 michael                  5221               3 :     ResetCancelConn();
 8397 bruce                    5222 GIC           3 :     PQfinish(con);
 1363 tmunro                   5223               3 :     termPQExpBuffer(&stats);
 8397 bruce                    5224 CBC           3 : }
                               5225                 : 
 1286 akapila                  5226 ECB             : /*
  888 michael                  5227                 :  * Extract pgbench table information into global variables scale,
 1286 akapila                  5228 EUB             :  * partition_method and partitions.
                               5229                 :  */
 1286 akapila                  5230 ECB             : static void
 1286 akapila                  5231 GIC           7 : GetTableInfo(PGconn *con, bool scale_given)
                               5232                 : {
 1286 akapila                  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                 :      */
 1286 akapila                  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                 : 
  366 tgl                      5244               1 :         pg_log_error("could not count number of branches: %s", PQerrorMessage(con));
                               5245                 : 
 1286 akapila                  5246               1 :         if (sqlState && strcmp(sqlState, ERRCODE_UNDEFINED_TABLE) == 0)
  366 tgl                      5247               1 :             pg_log_error_hint("Perhaps you need to do initialization (\"pgbench -i\") in database \"%s\".",
                               5248                 :                               PQdb(con));
                               5249                 : 
 1286 akapila                  5250               1 :         exit(1);
                               5251                 :     }
 1286 akapila                  5252 CBC           6 :     scale = atoi(PQgetvalue(res, 0, 0));
 1286 akapila                  5253 GIC           6 :     if (scale < 0)
  366 tgl                      5254 UIC           0 :         pg_fatal("invalid count(*) from pgbench_branches: \"%s\"",
                               5255                 :                  PQgetvalue(res, 0, 0));
 1286 akapila                  5256 GIC           6 :     PQclear(res);
                               5257                 : 
                               5258                 :     /* warn if we override user-given -s switch */
                               5259               6 :     if (scale_given)
 1187 peter                    5260               1 :         pg_log_warning("scale option ignored, using count from pgbench_branches table (%d)",
                               5261                 :                        scale);
                               5262                 : 
                               5263                 :     /*
 1286 akapila                  5264 ECB             :      * Get the partition information for the first "pgbench_accounts" table
                               5265                 :      * found in search_path.
                               5266                 :      *
 1286 akapila                  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
 1286 akapila                  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
 1286 akapila                  5276 EUB             :      * old version without "pg_partitioned_table".
                               5277                 :      */
 1286 akapila                  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) "
 1286 akapila                  5283 ECB             :                  "left join pg_catalog.pg_partitioned_table as p on (p.partrelid = c.oid) "
 1286 akapila                  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 "
 1286 akapila                  5287 ECB             :                  "order by 1 asc "
                               5288                 :                  "limit 1");
                               5289                 : 
 1286 akapila                  5290 CBC           6 :     if (PQresultStatus(res) != PGRES_TUPLES_OK)
                               5291                 :     {
 1286 akapila                  5292 ECB             :         /* probably an older version, coldly assume no partitioning */
 1286 akapila                  5293 LBC           0 :         partition_method = PART_NONE;
 1286 akapila                  5294 UBC           0 :         partitions = 0;
 1286 akapila                  5295 EUB             :     }
 1286 akapila                  5296 GIC           6 :     else if (PQntuples(res) == 0)
                               5297                 :     {
                               5298                 :         /*
 1286 akapila                  5299 EUB             :          * This case is unlikely as pgbench already found "pgbench_branches"
                               5300                 :          * above to compute the scale.
                               5301                 :          */
  366 tgl                      5302 UIC           0 :         pg_log_error("no pgbench_accounts table found in search_path");
  366 tgl                      5303 LBC           0 :         pg_log_error_hint("Perhaps you need to do initialization (\"pgbench -i\") in database \"%s\".", PQdb(con));
 1286 akapila                  5304 UIC           0 :         exit(1);
                               5305                 :     }
 1286 akapila                  5306 ECB             :     else                        /* PQntupes(res) == 1 */
                               5307                 :     {
                               5308                 :         /* normal case, extract partition information */
 1286 akapila                  5309 GIC           6 :         if (PQgetisnull(res, 0, 1))
 1286 akapila                  5310 UIC           0 :             partition_method = PART_NONE;
                               5311                 :         else
                               5312                 :         {
 1286 akapila                  5313 GIC           6 :             char       *ps = PQgetvalue(res, 0, 1);
 1286 akapila                  5314 ECB             : 
                               5315                 :             /* column must be there */
 1286 akapila                  5316 GIC           6 :             Assert(ps != NULL);
                               5317                 : 
                               5318               6 :             if (strcmp(ps, "r") == 0)
 1286 akapila                  5319 CBC           6 :                 partition_method = PART_RANGE;
 1286 akapila                  5320 UIC           0 :             else if (strcmp(ps, "h") == 0)
 1286 akapila                  5321 LBC           0 :                 partition_method = PART_HASH;
 1286 akapila                  5322 ECB             :             else
                               5323                 :             {
                               5324                 :                 /* possibly a newer version with new partition method */
  366 tgl                      5325 UIC           0 :                 pg_fatal("unexpected partition method: \"%s\"", ps);
                               5326                 :             }
                               5327                 :         }
 1286 akapila                  5328 ECB             : 
 1286 akapila                  5329 CBC           6 :         partitions = atoi(PQgetvalue(res, 0, 2));
                               5330                 :     }
 1286 akapila                  5331 ECB             : 
 1286 akapila                  5332 GIC           6 :     PQclear(res);
 1286 akapila                  5333 CBC           6 : }
                               5334                 : 
 5499 ishii                    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
 2067 tgl                      5340 GIC          69 : parseQuery(Command *cmd)
                               5341                 : {
 5499 ishii                    5342 ECB             :     char       *sql,
                               5343                 :                *p;
                               5344                 : 
 5499 ishii                    5345 GIC          69 :     cmd->argc = 1;
 5499 ishii                    5346 ECB             : 
 1550 alvherre                 5347 CBC          69 :     p = sql = pg_strdup(cmd->lines.data);
 5499 ishii                    5348 GIC         365 :     while ((p = strchr(p, ':')) != NULL)
                               5349                 :     {
 1851 peter_e                  5350 ECB             :         char        var[13];
 5050 bruce                    5351                 :         char       *name;
                               5352                 :         int         eaten;
 5499 ishii                    5353                 : 
 5499 ishii                    5354 CBC         297 :         name = parseVariable(p, &eaten);
 5499 ishii                    5355 GIC         297 :         if (name == NULL)
                               5356                 :         {
 5050 bruce                    5357 CBC          48 :             while (*p == ':')
 5050 bruce                    5358 ECB             :             {
 5050 bruce                    5359 CBC          32 :                 p++;
                               5360                 :             }
 5499 ishii                    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                 :         {
 1187 peter                    5370               1 :             pg_log_error("statement has too many arguments (maximum is %d): %s",
                               5371                 :                          MAX_ARGS - 1, cmd->lines.data);
 3022 ishii                    5372               1 :             pg_free(name);
 5499                          5373               1 :             return false;
                               5374                 :         }
 5499 ishii                    5375 ECB             : 
 5499 ishii                    5376 GIC         280 :         sprintf(var, "$%d", cmd->argc);
 4623 tgl                      5377             280 :         p = replaceVariable(&sql, p, eaten, var);
                               5378                 : 
 5499 ishii                    5379             280 :         cmd->argv[cmd->argc] = name;
                               5380             280 :         cmd->argc++;
 5499 ishii                    5381 ECB             :     }
                               5382                 : 
 1550 alvherre                 5383 CBC          68 :     Assert(cmd->argv[0] == NULL);
 5499 ishii                    5384              68 :     cmd->argv[0] = sql;
                               5385              68 :     return true;
 5499 ishii                    5386 ECB             : }
 5499 ishii                    5387 EUB             : 
 2576 tgl                      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
 2576 tgl                      5401 GIC          33 : syntax_error(const char *source, int lineno,
 2929 rhaas                    5402 ECB             :              const char *line, const char *command,
                               5403                 :              const char *msg, const char *more, int column)
                               5404                 : {
                               5405                 :     PQExpBufferData buf;
                               5406                 : 
 1187 peter                    5407 GIC          33 :     initPQExpBuffer(&buf);
                               5408                 : 
                               5409              33 :     printfPQExpBuffer(&buf, "%s:%d: %s", source, lineno, msg);
 2929 rhaas                    5410              33 :     if (more != NULL)
 1187 peter                    5411 CBC          15 :         appendPQExpBuffer(&buf, " (%s)", more);
 2576 tgl                      5412 GIC          33 :     if (column >= 0 && line == NULL)
 1187 peter                    5413 LBC           0 :         appendPQExpBuffer(&buf, " at column %d", column + 1);
 2576 tgl                      5414 GIC          33 :     if (command != NULL)
 1187 peter                    5415              30 :         appendPQExpBuffer(&buf, " in command \"%s\"", command);
                               5416                 : 
  366 tgl                      5417              33 :     pg_log_error("%s", buf.data);
 1187 peter                    5418 ECB             : 
 1187 peter                    5419 GBC          33 :     termPQExpBuffer(&buf);
 1187 peter                    5420 ECB             : 
 2929 rhaas                    5421 GIC          33 :     if (line != NULL)
 2929 rhaas                    5422 EUB             :     {
 2929 rhaas                    5423 GBC          28 :         fprintf(stderr, "%s\n", line);
 2576 tgl                      5424              28 :         if (column >= 0)
 1060                          5425              21 :             fprintf(stderr, "%*c error found here\n", column + 1, '^');
                               5426                 :     }
                               5427                 : 
 2929 rhaas                    5428 CBC          33 :     exit(1);
                               5429                 : }
                               5430                 : 
                               5431                 : /*
 1550 alvherre                 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.
 2576 tgl                      5435                 :  */
                               5436                 : static char *
 1550 alvherre                 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                 :     {
 2576 tgl                      5444            1035 :         if (isspace((unsigned char) *p))
 2576 tgl                      5445 UIC           0 :             p++;
 2576 tgl                      5446 CBC        1035 :         else if (strncmp(p, "--", 2) == 0)
                               5447                 :         {
 2576 tgl                      5448 UIC           0 :             p = strchr(p, '\n');
 2576 tgl                      5449 LBC           0 :             if (p == NULL)
 2576 tgl                      5450 UIC           0 :                 return NULL;
 2576 tgl                      5451 LBC           0 :             p++;
 2576 tgl                      5452 ECB             :         }
                               5453                 :         else
 2576 tgl                      5454 GIC        1035 :             break;
 2576 tgl                      5455 ECB             :     }
                               5456                 : 
 1550 alvherre                 5457                 :     /* NULL if there's nothing but whitespace and comments */
 2576 tgl                      5458 CBC        1035 :     if (*p == '\0')
                               5459             666 :         return NULL;
 2576 tgl                      5460 ECB             : 
 1550 alvherre                 5461 CBC         369 :     return p;
 1550 alvherre                 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 *
 1476 alvherre                 5472 GIC        1035 : create_sql_command(PQExpBuffer buf, const char *source)
                               5473                 : {
                               5474                 :     Command    *my_command;
 1550 alvherre                 5475 CBC        1035 :     char       *p = skip_sql_comments(buf->data);
                               5476                 : 
                               5477            1035 :     if (p == NULL)
                               5478             666 :         return NULL;
 1550 alvherre                 5479 ECB             : 
 2576 tgl                      5480                 :     /* Allocate and initialize Command structure */
 1550 alvherre                 5481 CBC         369 :     my_command = (Command *) pg_malloc(sizeof(Command));
 1550 alvherre                 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 */
 2576 tgl                      5485             369 :     my_command->type = SQL_COMMAND;
 1984                          5486             369 :     my_command->meta = META_NONE;
 1550 alvherre                 5487 CBC         369 :     my_command->argc = 0;
  382 ishii                    5488             369 :     my_command->retries = 0;
  382 ishii                    5489 GIC         369 :     my_command->failures = 0;
 1550 alvherre                 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;
 2576 tgl                      5493             369 :     initSimpleStats(&my_command->stats);
   47 alvherre                 5494             369 :     my_command->prepname = NULL; /* set later, if needed */
 2576 tgl                      5495 ECB             : 
 1550 alvherre                 5496 GIC         369 :     return my_command;
                               5497                 : }
                               5498                 : 
                               5499                 : /* Free a Command structure and associated data */
 1550 alvherre                 5500 ECB             : static void
 1550 alvherre                 5501 GIC          28 : free_command(Command *command)
                               5502                 : {
 1550 alvherre                 5503 CBC          28 :     termPQExpBuffer(&command->lines);
  296 peter                    5504 GNC          28 :     pg_free(command->first_line);
 1550 alvherre                 5505 GIC          58 :     for (int i = 0; i < command->argc; i++)
                               5506              30 :         pg_free(command->argv[i]);
  296 peter                    5507 GNC          28 :     pg_free(command->varprefix);
 1474 alvherre                 5508 ECB             : 
 2576 tgl                      5509                 :     /*
 1550 alvherre                 5510                 :      * It should also free expr recursively, but this is currently not needed
 1476                          5511                 :      * as only gset commands (which do not have an expression) are freed.
 2576 tgl                      5512                 :      */
 1550 alvherre                 5513 CBC          28 :     pg_free(command);
 1550 alvherre                 5514 GIC          28 : }
 1550 alvherre                 5515 ECB             : 
                               5516                 : /*
                               5517                 :  * Once an SQL command is fully parsed, possibly by accumulating several
                               5518                 :  * parts, complete other fields of the Command structure.
 1550 alvherre                 5519 EUB             :  */
                               5520                 : static void
 1550 alvherre                 5521 GIC         238 : postprocess_sql_command(Command *my_command)
 1550 alvherre                 5522 ECB             : {
                               5523                 :     char        buffer[128];
                               5524                 :     static int  prepnum = 0;
                               5525                 : 
 1550 alvherre                 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));
 1550 alvherre                 5530 CBC         238 :     buffer[strcspn(buffer, "\n\r")] = '\0';
 1550 alvherre                 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;
 1550 alvherre                 5540 CBC          50 :         case QUERY_PREPARED:
   47 alvherre                 5541 GIC          50 :             my_command->prepname = psprintf("P_%d", prepnum++);
                               5542                 :             /* fall through */
   47 alvherre                 5543 CBC          69 :         case QUERY_EXTENDED:
 1550                          5544              69 :             if (!parseQuery(my_command))
 1550 alvherre                 5545 GIC           1 :                 exit(1);
                               5546              68 :             break;
 1550 alvherre                 5547 LBC           0 :         default:
 1550 alvherre                 5548 UIC           0 :             exit(1);
 2576 tgl                      5549 EUB             :     }
 1550 alvherre                 5550 GBC         237 : }
                               5551                 : 
                               5552                 : /*
                               5553                 :  * Parse a backslash command; return a Command struct, or NULL if comment
 2576 tgl                      5554 ECB             :  *
                               5555                 :  * At call, we have scanned only the initial backslash.
                               5556                 :  */
                               5557                 : static Command *
 2576 tgl                      5558 GIC         467 : process_backslash_command(PsqlScanState sstate, const char *source)
                               5559                 : {
 2576 tgl                      5560 ECB             :     Command    *my_command;
                               5561                 :     PQExpBufferData word_buf;
                               5562                 :     int         word_offset;
 2118                          5563                 :     int         offsets[MAX_ARGS];  /* offsets of argument words */
                               5564                 :     int         start_offset;
                               5565                 :     int         lineno;
 6396 ishii                    5566                 :     int         j;
                               5567                 : 
 2576 tgl                      5568 CBC         467 :     initPQExpBuffer(&word_buf);
 6396 ishii                    5569 ECB             : 
 2576 tgl                      5570                 :     /* Remember location of the backslash */
 2576 tgl                      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 */
 2576 tgl                      5575 CBC         467 :     if (!expr_lex_one_word(sstate, &word_buf, &word_offset))
                               5576                 :     {
 2576 tgl                      5577 LBC           0 :         termPQExpBuffer(&word_buf);
 6396 ishii                    5578               0 :         return NULL;
                               5579                 :     }
                               5580                 : 
 4623 tgl                      5581 ECB             :     /* Allocate and initialize Command structure */
 2576 tgl                      5582 CBC         467 :     my_command = (Command *) pg_malloc0(sizeof(Command));
                               5583             467 :     my_command->type = META_COMMAND;
 2576 tgl                      5584 GIC         467 :     my_command->argc = 0;
                               5585             467 :     initSimpleStats(&my_command->stats);
                               5586                 : 
 2576 tgl                      5587 ECB             :     /* Save first word (command name) */
 2576 tgl                      5588 CBC         467 :     j = 0;
 2576 tgl                      5589 GIC         467 :     offsets[j] = word_offset;
 2576 tgl                      5590 CBC         467 :     my_command->argv[j++] = pg_strdup(word_buf.data);
 2576 tgl                      5591 GIC         467 :     my_command->argc++;
                               5592                 : 
 1984 tgl                      5593 EUB             :     /* ... and convert it to enum form */
 1984 tgl                      5594 GIC         467 :     my_command->meta = getMetaCommand(my_command->argv[0]);
                               5595                 : 
 1844 teodor                   5596 CBC         467 :     if (my_command->meta == META_SET ||
 1844 teodor                   5597 GIC         105 :         my_command->meta == META_IF ||
                               5598              90 :         my_command->meta == META_ELIF)
 6396 ishii                    5599 ECB             :     {
 2576 tgl                      5600                 :         yyscan_t    yyscanner;
                               5601                 : 
                               5602                 :         /* For \set, collect var name */
 1844 teodor                   5603 GIC         385 :         if (my_command->meta == META_SET)
                               5604                 :         {
 1844 teodor                   5605 CBC         362 :             if (!expr_lex_one_word(sstate, &word_buf, &word_offset))
 1550 alvherre                 5606 GIC           1 :                 syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
 1844 teodor                   5607 ECB             :                              "missing argument", NULL, -1);
                               5608                 : 
 1844 teodor                   5609 CBC         361 :             offsets[j] = word_offset;
 1844 teodor                   5610 GIC         361 :             my_command->argv[j++] = pg_strdup(word_buf.data);
                               5611             361 :             my_command->argc++;
                               5612                 :         }
 6401 ishii                    5613 ECB             : 
                               5614                 :         /* then for all parse the expression */
 2576 tgl                      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)
 6401 ishii                    5619 ECB             :         {
 2576 tgl                      5620                 :             /* dead code: exit done from syntax_error called by yyerror */
 2576 tgl                      5621 UIC           0 :             exit(1);
                               5622                 :         }
 6385 bruce                    5623 ECB             : 
 2576 tgl                      5624 CBC         365 :         my_command->expr = expr_parse_result;
 3175 rhaas                    5625 ECB             : 
                               5626                 :         /* Save line, trimming any trailing newline */
 1550 alvherre                 5627 GIC         365 :         my_command->first_line =
                               5628             365 :             expr_scanner_get_substring(sstate,
 1550 alvherre                 5629 ECB             :                                        start_offset,
                               5630                 :                                        expr_scanner_offset(sstate),
                               5631                 :                                        true);
                               5632                 : 
 2576 tgl                      5633 GIC         365 :         expr_scanner_finish(yyscanner);
                               5634                 : 
 2576 tgl                      5635 CBC         365 :         termPQExpBuffer(&word_buf);
                               5636                 : 
                               5637             365 :         return my_command;
 2576 tgl                      5638 ECB             :     }
                               5639                 : 
                               5640                 :     /* For all other commands, collect remaining words. */
 2576 tgl                      5641 CBC         373 :     while (expr_lex_one_word(sstate, &word_buf, &word_offset))
 2576 tgl                      5642 ECB             :     {
                               5643                 :         /*
 1490 andrew                   5644                 :          * my_command->argv[0] is the command itself, so the max number of
                               5645                 :          * arguments is one less than MAX_ARGS
                               5646                 :          */
 2576 tgl                      5647 GIC         292 :         if (j >= MAX_ARGS)
 1550 alvherre                 5648               1 :             syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
                               5649                 :                          "too many arguments", NULL, -1);
                               5650                 : 
 2576 tgl                      5651             291 :         offsets[j] = word_offset;
 2576 tgl                      5652 CBC         291 :         my_command->argv[j++] = pg_strdup(word_buf.data);
 2576 tgl                      5653 GIC         291 :         my_command->argc++;
 2576 tgl                      5654 ECB             :     }
 2960 rhaas                    5655                 : 
                               5656                 :     /* Save line, trimming any trailing newline */
 1550 alvherre                 5657 GIC          81 :     my_command->first_line =
 1550 alvherre                 5658 CBC          81 :         expr_scanner_get_substring(sstate,
 1550 alvherre                 5659 EUB             :                                    start_offset,
                               5660                 :                                    expr_scanner_offset(sstate),
                               5661                 :                                    true);
 4997 tgl                      5662 ECB             : 
 1984 tgl                      5663 CBC          81 :     if (my_command->meta == META_SLEEP)
                               5664                 :     {
 2576 tgl                      5665 GIC           9 :         if (my_command->argc < 2)
 1550 alvherre                 5666 CBC           1 :             syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
 2576 tgl                      5667 ECB             :                          "missing argument", NULL, -1);
                               5668                 : 
 2576 tgl                      5669 CBC           8 :         if (my_command->argc > 3)
 1550 alvherre                 5670 GIC           1 :             syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
 2576 tgl                      5671 ECB             :                          "too many arguments", NULL,
 2576 tgl                      5672 GIC           1 :                          offsets[3] - start_offset);
 2576 tgl                      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                 :          */
  748 fujii                    5680 GIC           7 :         if (my_command->argv[1][0] != ':')
                               5681                 :         {
 2576 tgl                      5682               4 :             char       *c = my_command->argv[1];
  748 fujii                    5683 GBC           4 :             bool        have_digit = false;
                               5684                 : 
  748 fujii                    5685 EUB             :             /* Skip sign */
  748 fujii                    5686 GIC           4 :             if (*c == '+' || *c == '-')
  748 fujii                    5687 UIC           0 :                 c++;
                               5688                 : 
                               5689                 :             /* Require at least one digit */
  748 fujii                    5690 CBC           4 :             if (*c && isdigit((unsigned char) *c))
  748 fujii                    5691 GIC           4 :                 have_digit = true;
 2576 tgl                      5692 ECB             : 
  748 fujii                    5693                 :             /* Eat all digits */
  748 fujii                    5694 CBC          10 :             while (*c && isdigit((unsigned char) *c))
 2576 tgl                      5695               6 :                 c++;
                               5696                 : 
                               5697               4 :             if (*c)
                               5698                 :             {
  748 fujii                    5699 GIC           1 :                 if (my_command->argc == 2 && have_digit)
  748 fujii                    5700 ECB             :                 {
  748 fujii                    5701 GIC           1 :                     my_command->argv[2] = c;
  748 fujii                    5702 CBC           1 :                     offsets[2] = offsets[1] + (c - my_command->argv[1]);
                               5703               1 :                     my_command->argc = 3;
                               5704                 :                 }
                               5705                 :                 else
  748 fujii                    5706 ECB             :                 {
                               5707                 :                     /*
                               5708                 :                      * Raise an error if argument starts with non-digit
                               5709                 :                      * character (after sign).
                               5710                 :                      */
  748 fujii                    5711 UIC           0 :                     syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
  748 fujii                    5712 ECB             :                                  "invalid sleep time, must be an integer",
  748 fujii                    5713 LBC           0 :                                  my_command->argv[1], offsets[1] - start_offset);
  748 fujii                    5714 ECB             :                 }
                               5715                 :             }
 4863 itagaki.takahiro         5716                 :         }
 2576 tgl                      5717                 : 
 2576 tgl                      5718 GIC           7 :         if (my_command->argc == 3)
                               5719                 :         {
 2576 tgl                      5720 CBC           9 :             if (pg_strcasecmp(my_command->argv[2], "us") != 0 &&
 2576 tgl                      5721 GIC           6 :                 pg_strcasecmp(my_command->argv[2], "ms") != 0 &&
 2576 tgl                      5722 CBC           2 :                 pg_strcasecmp(my_command->argv[2], "s") != 0)
 1550 alvherre                 5723               1 :                 syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
                               5724                 :                              "unrecognized time unit, must be us, ms or s",
 2576 tgl                      5725 GIC           1 :                              my_command->argv[2], offsets[2] - start_offset);
                               5726                 :         }
                               5727                 :     }
 1984                          5728              72 :     else if (my_command->meta == META_SETSHELL)
 2576 tgl                      5729 ECB             :     {
 2576 tgl                      5730 GIC           4 :         if (my_command->argc < 3)
 1550 alvherre                 5731               1 :             syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
                               5732                 :                          "missing argument", NULL, -1);
 2576 tgl                      5733 ECB             :     }
 1984 tgl                      5734 GIC          68 :     else if (my_command->meta == META_SHELL)
 2576 tgl                      5735 ECB             :     {
 2576 tgl                      5736 GIC           4 :         if (my_command->argc < 2)
 1550 alvherre                 5737               1 :             syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
                               5738                 :                          "missing command", NULL, -1);
 2576 tgl                      5739 ECB             :     }
  755 alvherre                 5740 GIC          64 :     else if (my_command->meta == META_ELSE || my_command->meta == META_ENDIF ||
  755 alvherre                 5741 CBC          44 :              my_command->meta == META_STARTPIPELINE ||
  755 alvherre                 5742 GIC          38 :              my_command->meta == META_ENDPIPELINE)
                               5743                 :     {
 1844 teodor                   5744              31 :         if (my_command->argc != 1)
 1550 alvherre                 5745               2 :             syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
                               5746                 :                          "unexpected argument", NULL, -1);
                               5747                 :     }
 1101 michael                  5748              33 :     else if (my_command->meta == META_GSET || my_command->meta == META_ASET)
 1550 alvherre                 5749 ECB             :     {
 1550 alvherre                 5750 GIC          32 :         if (my_command->argc > 2)
                               5751               1 :             syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
 1550 alvherre                 5752 ECB             :                          "too many arguments", NULL, -1);
                               5753                 :     }
                               5754                 :     else
 6396 ishii                    5755                 :     {
                               5756                 :         /* my_command->meta == META_NONE */
 1550 alvherre                 5757 CBC           1 :         syntax_error(source, lineno, my_command->first_line, my_command->argv[0],
                               5758                 :                      "invalid command", NULL, -1);
 2576 tgl                      5759 ECB             :     }
                               5760                 : 
 2576 tgl                      5761 CBC          72 :     termPQExpBuffer(&word_buf);
                               5762                 : 
                               5763              72 :     return my_command;
 2576 tgl                      5764 ECB             : }
                               5765                 : 
 1844 teodor                   5766                 : static void
 1844 teodor                   5767 CBC           6 : ConditionError(const char *desc, int cmdn, const char *msg)
 1844 teodor                   5768 ECB             : {
  366 tgl                      5769 CBC           6 :     pg_fatal("condition error in script \"%s\" command %d: %s",
  366 tgl                      5770 ECB             :              desc, cmdn, msg);
 1844 teodor                   5771                 : }
                               5772                 : 
                               5773                 : /*
                               5774                 :  * Partial evaluation of conditionals before recording and running the script.
                               5775                 :  */
                               5776                 : static void
  378 tgl                      5777 CBC         227 : CheckConditional(const ParsedScript *ps)
 1844 teodor                   5778 ECB             : {
                               5779                 :     /* statically check conditional structure */
 1844 teodor                   5780 CBC         227 :     ConditionalStack cs = conditional_stack_create();
 1809 tgl                      5781 ECB             :     int         i;
                               5782                 : 
  378 tgl                      5783 CBC         987 :     for (i = 0; ps->commands[i] != NULL; i++)
                               5784                 :     {
                               5785             765 :         Command    *cmd = ps->commands[i];
                               5786                 : 
 1844 teodor                   5787 GIC         765 :         if (cmd->type == META_COMMAND)
                               5788                 :         {
 1844 teodor                   5789 CBC         399 :             switch (cmd->meta)
 1844 teodor                   5790 ECB             :             {
 1809 tgl                      5791 CBC          11 :                 case META_IF:
                               5792              11 :                     conditional_stack_push(cs, IFSTATE_FALSE);
 1809 tgl                      5793 GIC          11 :                     break;
                               5794               7 :                 case META_ELIF:
                               5795               7 :                     if (conditional_stack_empty(cs))
  378                          5796               1 :                         ConditionError(ps->desc, i + 1, "\\elif without matching \\if");
 1809                          5797               6 :                     if (conditional_stack_peek(cs) == IFSTATE_ELSE_FALSE)
  378                          5798               1 :                         ConditionError(ps->desc, i + 1, "\\elif after \\else");
 1809 tgl                      5799 CBC           5 :                     break;
 1809 tgl                      5800 GIC           7 :                 case META_ELSE:
                               5801               7 :                     if (conditional_stack_empty(cs))
  378                          5802               1 :                         ConditionError(ps->desc, i + 1, "\\else without matching \\if");
 1809                          5803               6 :                     if (conditional_stack_peek(cs) == IFSTATE_ELSE_FALSE)
  378                          5804               1 :                         ConditionError(ps->desc, i + 1, "\\else after \\else");
 1809                          5805               5 :                     conditional_stack_poke(cs, IFSTATE_ELSE_FALSE);
                               5806               5 :                     break;
                               5807               9 :                 case META_ENDIF:
                               5808               9 :                     if (!conditional_stack_pop(cs))
  378                          5809               1 :                         ConditionError(ps->desc, i + 1, "\\endif without matching \\if");
 1809 tgl                      5810 CBC           8 :                     break;
 1809 tgl                      5811 GIC         365 :                 default:
                               5812                 :                     /* ignore anything else... */
 1809 tgl                      5813 CBC         365 :                     break;
 1844 teodor                   5814 ECB             :             }
                               5815                 :         }
                               5816                 :     }
 1844 teodor                   5817 GIC         222 :     if (!conditional_stack_empty(cs))
  378 tgl                      5818               1 :         ConditionError(ps->desc, i + 1, "\\if without matching \\endif");
 1844 teodor                   5819 CBC         221 :     conditional_stack_destroy(cs);
 1844 teodor                   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
 2576 tgl                      5827             262 : ParseScript(const char *script, const char *desc, int weight)
                               5828                 : {
                               5829                 :     ParsedScript ps;
 2576 tgl                      5830 ECB             :     PsqlScanState sstate;
                               5831                 :     PQExpBufferData line_buf;
                               5832                 :     int         alloc_num;
                               5833                 :     int         index;
                               5834                 :     int         lineno;
 1550 alvherre                 5835                 :     int         start_offset;
                               5836                 : 
                               5837                 : #define COMMANDS_ALLOC_NUM 128
 2576 tgl                      5838 CBC         262 :     alloc_num = COMMANDS_ALLOC_NUM;
                               5839                 : 
                               5840                 :     /* Initialize all fields of ps */
                               5841             262 :     ps.desc = desc;
 2576 tgl                      5842 GIC         262 :     ps.weight = weight;
 2576 tgl                      5843 CBC         262 :     ps.commands = (Command **) pg_malloc(sizeof(Command *) * alloc_num);
 2288                          5844             262 :     initStats(&ps.stats, 0);
                               5845                 : 
 2576 tgl                      5846 ECB             :     /* Prepare to parse script */
 2576 tgl                      5847 GIC         262 :     sstate = psql_scan_create(&pgbench_callbacks);
                               5848                 : 
 2576 tgl                      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                 :      */
 2576 tgl                      5858 CBC         262 :     psql_scan_setup(sstate, script, strlen(script), 0, true);
 1550 alvherre                 5859 GIC         262 :     start_offset = expr_scanner_offset(sstate) - 1;
 2576 tgl                      5860 ECB             : 
 2576 tgl                      5861 GIC         262 :     initPQExpBuffer(&line_buf);
                               5862                 : 
                               5863             262 :     index = 0;
                               5864                 : 
                               5865                 :     for (;;)
 2576 tgl                      5866 CBC         773 :     {
 2576 tgl                      5867 ECB             :         PsqlScanResult sr;
                               5868                 :         promptStatus_t prompt;
 1550 alvherre                 5869 GIC        1035 :         Command    *command = NULL;
 2576 tgl                      5870 ECB             : 
 2576 tgl                      5871 CBC        1035 :         resetPQExpBuffer(&line_buf);
 1550 alvherre                 5872 GIC        1035 :         lineno = expr_scanner_get_lineno(sstate, start_offset);
                               5873                 : 
 2576 tgl                      5874            1035 :         sr = psql_scan(sstate, &line_buf, &prompt);
 6396 ishii                    5875 ECB             : 
                               5876                 :         /* If we collected a new SQL command, process that */
 1476 alvherre                 5877 CBC        1035 :         command = create_sql_command(&line_buf, desc);
 2576 tgl                      5878 ECB             : 
 1476 alvherre                 5879                 :         /* store new command */
 1476 alvherre                 5880 GIC        1035 :         if (command)
 1476 alvherre                 5881 CBC         369 :             ps.commands[index++] = command;
                               5882                 : 
                               5883                 :         /* If we reached a backslash, process that */
 2576 tgl                      5884            1035 :         if (sr == PSCAN_BACKSLASH)
 2576 tgl                      5885 ECB             :         {
 2576 tgl                      5886 GIC         467 :             command = process_backslash_command(sstate, desc);
 1550 alvherre                 5887 ECB             : 
 2576 tgl                      5888 GIC         437 :             if (command)
                               5889                 :             {
 1550 alvherre                 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                 :                  */
 1101 michael                  5894 GIC         437 :                 if (command->meta == META_GSET || command->meta == META_ASET)
 2576 tgl                      5895 CBC          28 :                 {
                               5896                 :                     Command    *cmd;
                               5897                 : 
 1550 alvherre                 5898 GIC          31 :                     if (index == 0)
 1550 alvherre                 5899 CBC           1 :                         syntax_error(desc, lineno, NULL, NULL,
                               5900                 :                                      "\\gset must follow an SQL command",
                               5901                 :                                      NULL, -1);
                               5902                 : 
 1550 alvherre                 5903 GIC          30 :                     cmd = ps.commands[index - 1];
                               5904                 : 
 1476                          5905              30 :                     if (cmd->type != SQL_COMMAND ||
                               5906              29 :                         cmd->varprefix != NULL)
 1550                          5907               2 :                         syntax_error(desc, lineno, NULL, NULL,
  667 drowley                  5908 ECB             :                                      "\\gset must follow an SQL command",
 1550 alvherre                 5909 GIC           2 :                                      cmd->first_line, -1);
 1550 alvherre                 5910 EUB             : 
                               5911                 :                     /* get variable prefix */
 1550 alvherre                 5912 GBC          28 :                     if (command->argc <= 1 || command->argv[1][0] == '\0')
 1476 alvherre                 5913 GIC          26 :                         cmd->varprefix = pg_strdup("");
                               5914                 :                     else
                               5915               2 :                         cmd->varprefix = pg_strdup(command->argv[1]);
 1550 alvherre                 5916 ECB             : 
                               5917                 :                     /* update the sql command meta */
 1101 michael                  5918 GIC          28 :                     cmd->meta = command->meta;
                               5919                 : 
 1550 alvherre                 5920 ECB             :                     /* cleanup unused command */
 1550 alvherre                 5921 GIC          28 :                     free_command(command);
 1550 alvherre                 5922 ECB             : 
 1550 alvherre                 5923 GIC          28 :                     continue;
 2576 tgl                      5924 ECB             :                 }
 1550 alvherre                 5925                 : 
                               5926                 :                 /* Attach any other backslash command as a new command */
 1550 alvherre                 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                 :         {
 1550 alvherre                 5938 UIC           0 :             alloc_num += COMMANDS_ALLOC_NUM;
 1550 alvherre                 5939 LBC           0 :             ps.commands = (Command **)
                               5940               0 :                 pg_realloc(ps.commands, sizeof(Command *) * alloc_num);
                               5941                 :         }
 1550 alvherre                 5942 ECB             : 
                               5943                 :         /* Done if we reached EOF */
 2576 tgl                      5944 GIC         974 :         if (sr == PSCAN_INCOMPLETE || sr == PSCAN_EOL)
 2576 tgl                      5945 EUB             :             break;
                               5946                 :     }
                               5947                 : 
 2576 tgl                      5948 CBC         229 :     ps.commands[index] = NULL;
 2576 tgl                      5949 ECB             : 
  378 tgl                      5950 GIC         229 :     addScript(&ps);
 2576 tgl                      5951 ECB             : 
 2576 tgl                      5952 CBC         221 :     termPQExpBuffer(&line_buf);
 2576 tgl                      5953 GIC         221 :     psql_scan_finish(sstate);
 2576 tgl                      5954 GBC         221 :     psql_scan_destroy(sstate);
 6396 ishii                    5955             221 : }
                               5956                 : 
                               5957                 : /*
 2576 tgl                      5958 ECB             :  * Read the entire contents of file fd, and return it in a malloc'd buffer.
                               5959                 :  *
 3432                          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 *
 2576 tgl                      5964 GIC         109 : read_file_contents(FILE *fd)
                               5965                 : {
                               5966                 :     char       *buf;
 3432                          5967             109 :     size_t      buflen = BUFSIZ;
                               5968             109 :     size_t      used = 0;
 3432 tgl                      5969 ECB             : 
 2576 tgl                      5970 GIC         109 :     buf = (char *) pg_malloc(buflen);
                               5971                 : 
                               5972                 :     for (;;)
 3432 tgl                      5973 UIC           0 :     {
                               5974                 :         size_t      nread;
 3432 tgl                      5975 ECB             : 
 2576 tgl                      5976 GBC         109 :         nread = fread(buf + used, 1, BUFSIZ, fd);
 2576 tgl                      5977 CBC         109 :         used += nread;
 2576 tgl                      5978 ECB             :         /* If fread() read less than requested, must be EOF or error */
 2576 tgl                      5979 GIC         109 :         if (nread < BUFSIZ)
 3432 tgl                      5980 CBC         109 :             break;
                               5981                 :         /* Enlarge buf so we can read some more */
 3432 tgl                      5982 LBC           0 :         buflen += BUFSIZ;
 3432 tgl                      5983 UBC           0 :         buf = (char *) pg_realloc(buf, buflen);
                               5984                 :     }
 2576 tgl                      5985 ECB             :     /* There is surely room for a terminator */
 2576 tgl                      5986 CBC         109 :     buf[used] = '\0';
                               5987                 : 
                               5988             109 :     return buf;
                               5989                 : }
 3432 tgl                      5990 ECB             : 
 2577 alvherre                 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
 2576 tgl                      5997 CBC         110 : process_file(const char *filename, int weight)
 2577 alvherre                 5998 ECB             : {
                               5999                 :     FILE       *fd;
                               6000                 :     char       *buf;
                               6001                 : 
 2576 tgl                      6002                 :     /* Slurp the file contents into "buf" */
 6396 ishii                    6003 GIC         110 :     if (strcmp(filename, "-") == 0)
 6396 ishii                    6004 UIC           0 :         fd = stdin;
 6396 ishii                    6005 GIC         110 :     else if ((fd = fopen(filename, "r")) == NULL)
  366 tgl                      6006 CBC           1 :         pg_fatal("could not open file \"%s\": %m", filename);
 6401 ishii                    6007 ECB             : 
 2576 tgl                      6008 CBC         109 :     buf = read_file_contents(fd);
 2577 alvherre                 6009 ECB             : 
 2576 tgl                      6010 CBC         109 :     if (ferror(fd))
  366 tgl                      6011 UIC           0 :         pg_fatal("could not read file \"%s\": %m", filename);
                               6012                 : 
 2576 tgl                      6013 GIC         109 :     if (fd != stdin)
 2576 tgl                      6014 CBC         109 :         fclose(fd);
                               6015                 : 
 2576 tgl                      6016 GIC         109 :     ParseScript(buf, filename, weight);
 2576 tgl                      6017 ECB             : 
 2576 tgl                      6018 CBC          69 :     free(buf);
 6396 ishii                    6019              69 : }
                               6020                 : 
 2576 tgl                      6021 ECB             : /* Parse the given builtin script and add it to the list. */
                               6022                 : static void
 2576 tgl                      6023 CBC         153 : process_builtin(const BuiltinScript *bi, int weight)
                               6024                 : {
                               6025             153 :     ParseScript(bi->script, bi->desc, weight);
 6401 ishii                    6026             152 : }
                               6027                 : 
                               6028                 : /* show available builtin scripts */
                               6029                 : static void
 2629 alvherre                 6030 GIC           3 : listAvailableScripts(void)
 2629 alvherre                 6031 ECB             : {
 2627                          6032                 :     int         i;
                               6033                 : 
 2629 alvherre                 6034 GIC           3 :     fprintf(stderr, "Available builtin scripts:\n");
 2577 alvherre                 6035 CBC          12 :     for (i = 0; i < lengthof(builtin_script); i++)
 1363 tmunro                   6036               9 :         fprintf(stderr, "  %13s: %s\n", builtin_script[i].name, builtin_script[i].desc);
 2629 alvherre                 6037 GIC           3 :     fprintf(stderr, "\n");
 2629 alvherre                 6038 CBC           3 : }
                               6039                 : 
 2576 tgl                      6040 ECB             : /* return builtin script "name" if unambiguous, fails if not found */
                               6041                 : static const BuiltinScript *
 2577 alvherre                 6042 GIC         156 : findBuiltin(const char *name)
                               6043                 : {
                               6044                 :     int         i,
 2593                          6045             156 :                 found = 0,
                               6046             156 :                 len = strlen(name);
 2576 tgl                      6047             156 :     const BuiltinScript *result = NULL;
                               6048                 : 
 2577 alvherre                 6049             624 :     for (i = 0; i < lengthof(builtin_script); i++)
 2629 alvherre                 6050 ECB             :     {
 2593 alvherre                 6051 GIC         468 :         if (strncmp(builtin_script[i].name, name, len) == 0)
                               6052                 :         {
 2577                          6053             156 :             result = &builtin_script[i];
 2593                          6054             156 :             found++;
 2629 alvherre                 6055 ECB             :         }
                               6056                 :     }
                               6057                 : 
                               6058                 :     /* ok, unambiguous result */
 2593 alvherre                 6059 GIC         156 :     if (found == 1)
 2577                          6060             154 :         return result;
                               6061                 : 
 2593 alvherre                 6062 ECB             :     /* error cases */
 2593 alvherre                 6063 CBC           2 :     if (found == 0)
  366 tgl                      6064               1 :         pg_log_error("no builtin script found for name \"%s\"", name);
                               6065                 :     else                        /* found > 1 */
  366 tgl                      6066 GIC           1 :         pg_log_error("ambiguous builtin name: %d builtin scripts found for prefix \"%s\"", found, name);
 2593 alvherre                 6067 ECB             : 
 2629 alvherre                 6068 CBC           2 :     listAvailableScripts();
                               6069               2 :     exit(1);
 2629 alvherre                 6070 ECB             : }
                               6071                 : 
 2577                          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
 2577 alvherre                 6078 CBC         121 : parseScriptWeight(const char *option, char **script)
 2577 alvherre                 6079 ECB             : {
                               6080                 :     char       *sep;
                               6081                 :     int         weight;
                               6082                 : 
 2577 alvherre                 6083 GIC         121 :     if ((sep = strrchr(option, WSEP)))
                               6084                 :     {
                               6085               7 :         int         namelen = sep - option;
                               6086                 :         long        wtmp;
 2577 alvherre                 6087 ECB             :         char       *badp;
                               6088                 : 
                               6089                 :         /* generate the script name */
 2577 alvherre                 6090 CBC           7 :         *script = pg_malloc(namelen + 1);
 2577 alvherre                 6091 GIC           7 :         strncpy(*script, option, namelen);
 2577 alvherre                 6092 CBC           7 :         (*script)[namelen] = '\0';
 2577 alvherre                 6093 ECB             : 
                               6094                 :         /* process digits of the weight spec */
 2577 alvherre                 6095 CBC           7 :         errno = 0;
 2577 alvherre                 6096 GIC           7 :         wtmp = strtol(sep + 1, &badp, 10);
 2577 alvherre                 6097 CBC           7 :         if (errno != 0 || badp == sep + 1 || *badp != '\0')
  366 tgl                      6098               1 :             pg_fatal("invalid weight specification: %s", sep);
 2567 alvherre                 6099               6 :         if (wtmp > INT_MAX || wtmp < 0)
  366 tgl                      6100 GIC           1 :             pg_fatal("weight specification out of range (0 .. %d): %lld",
                               6101                 :                      INT_MAX, (long long) wtmp);
 2577 alvherre                 6102               5 :         weight = wtmp;
                               6103                 :     }
                               6104                 :     else
                               6105                 :     {
                               6106             114 :         *script = pg_strdup(option);
                               6107             114 :         weight = 1;
 2577 alvherre                 6108 EUB             :     }
                               6109                 : 
 2577 alvherre                 6110 GIC         119 :     return weight;
                               6111                 : }
 2577 alvherre                 6112 EUB             : 
                               6113                 : /* append a script to the list of scripts to process */
                               6114                 : static void
  378 tgl                      6115 GIC         229 : addScript(const ParsedScript *script)
                               6116                 : {
                               6117             229 :     if (script->commands == NULL || script->commands[0] == NULL)
  366                          6118               1 :         pg_fatal("empty command list for script \"%s\"", script->desc);
                               6119                 : 
 2629 alvherre                 6120             228 :     if (num_scripts >= MAX_SCRIPTS)
  366 tgl                      6121               1 :         pg_fatal("at most %d SQL scripts are allowed", MAX_SCRIPTS);
                               6122                 : 
 1844 teodor                   6123             227 :     CheckConditional(script);
                               6124                 : 
  378 tgl                      6125             221 :     sql_script[num_scripts] = *script;
 2629 alvherre                 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                 :  */
 1476 heikki.linnakangas       6135 EUB             : static void
  760 tmunro                   6136 UBC           0 : printProgressReport(TState *threads, int64 test_start, pg_time_usec_t now,
                               6137                 :                     StatsData *last, int64 *last_report)
 1476 heikki.linnakangas       6138 EUB             : {
                               6139                 :     /* generate and show report */
  760 tmunro                   6140 UBC           0 :     pg_time_usec_t run = now - *last_report;
  382 ishii                    6141 EUB             :     int64       cnt,
                               6142                 :                 failures,
                               6143                 :                 retried;
 1476 heikki.linnakangas       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                 :      */
 1476 heikki.linnakangas       6163 UIC           0 :     initStats(&cur, 0);
 1476 heikki.linnakangas       6164 UBC           0 :     for (int i = 0; i < nthreads; i++)
 1476 heikki.linnakangas       6165 EUB             :     {
 1467 tgl                      6166 UIC           0 :         mergeSimpleStats(&cur.latency, &threads[i].stats.latency);
 1467 tgl                      6167 UBC           0 :         mergeSimpleStats(&cur.lag, &threads[i].stats.lag);
 1467 tgl                      6168 UIC           0 :         cur.cnt += threads[i].stats.cnt;
 1467 tgl                      6169 UBC           0 :         cur.skipped += threads[i].stats.skipped;
  382 ishii                    6170               0 :         cur.retries += threads[i].stats.retries;
  382 ishii                    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;
 1476 heikki.linnakangas       6175 EUB             :     }
                               6176                 : 
                               6177                 :     /* we count only actually executed transactions */
  382 ishii                    6178 UBC           0 :     cnt = cur.cnt - last->cnt;
 1476 heikki.linnakangas       6179 UIC           0 :     total_run = (now - test_start) / 1000000.0;
  382 ishii                    6180               0 :     tps = 1000000.0 * cnt / run;
                               6181               0 :     if (cnt > 0)
 1476 heikki.linnakangas       6182 EUB             :     {
  382 ishii                    6183 UIC           0 :         latency = 0.001 * (cur.latency.sum - last->latency.sum) / cnt;
  382 ishii                    6184 UBC           0 :         sqlat = 1.0 * (cur.latency.sum2 - last->latency.sum2) / cnt;
 1476 heikki.linnakangas       6185               0 :         stdev = 0.001 * sqrt(sqlat - 1000000.0 * latency * latency);
  382 ishii                    6186               0 :         lag = 0.001 * (cur.lag.sum - last->lag.sum) / cnt;
 1476 heikki.linnakangas       6187 EUB             :     }
                               6188                 :     else
                               6189                 :     {
 1476 heikki.linnakangas       6190 UIC           0 :         latency = sqlat = stdev = lag = 0;
 1476 heikki.linnakangas       6191 EUB             :     }
  382 ishii                    6192 UBC           0 :     failures = getFailures(&cur) - getFailures(last);
  382 ishii                    6193 UIC           0 :     retried = cur.retried - last->retried;
 1476 heikki.linnakangas       6194 EUB             : 
 1476 heikki.linnakangas       6195 UBC           0 :     if (progress_timestamp)
                               6196                 :     {
  637 tmunro                   6197               0 :         snprintf(tbuf, sizeof(tbuf), "%.3f s",
                               6198               0 :                  PG_TIME_GET_DOUBLE(now + epoch_shift));
 1476 heikki.linnakangas       6199 EUB             :     }
                               6200                 :     else
                               6201                 :     {
 1476 heikki.linnakangas       6202 ECB             :         /* round seconds are expected, but the thread may be late */
 1476 heikki.linnakangas       6203 UIC           0 :         snprintf(tbuf, sizeof(tbuf), "%.1f s", total_run);
 1476 heikki.linnakangas       6204 ECB             :     }
                               6205                 : 
 1476 heikki.linnakangas       6206 LBC           0 :     fprintf(stderr,
  382 ishii                    6207 ECB             :             "progress: %s, %.1f tps, lat %.3f ms stddev %.3f, " INT64_FORMAT " failed",
                               6208                 :             tbuf, tps, latency, stdev, failures);
 1476 heikki.linnakangas       6209                 : 
 1476 heikki.linnakangas       6210 LBC           0 :     if (throttle_delay)
                               6211                 :     {
                               6212               0 :         fprintf(stderr, ", lag %.3f ms", lag);
 1476 heikki.linnakangas       6213 UIC           0 :         if (latency_limit)
                               6214               0 :             fprintf(stderr, ", " INT64_FORMAT " skipped",
                               6215               0 :                     cur.skipped - last->skipped);
 1476 heikki.linnakangas       6216 ECB             :     }
                               6217                 : 
  382 ishii                    6218                 :     /* it can be non-zero only if max_tries is not equal to one */
  382 ishii                    6219 LBC           0 :     if (max_tries != 1)
  382 ishii                    6220 UIC           0 :         fprintf(stderr,
  382 ishii                    6221 ECB             :                 ", " INT64_FORMAT " retried, " INT64_FORMAT " retries",
  382 ishii                    6222 UIC           0 :                 retried, cur.retries - last->retries);
 1476 heikki.linnakangas       6223               0 :     fprintf(stderr, "\n");
                               6224                 : 
                               6225               0 :     *last = cur;
                               6226               0 :     *last_report = now;
 1476 heikki.linnakangas       6227 UBC           0 : }
                               6228                 : 
 2627 alvherre                 6229 EUB             : static void
 1986 peter_e                  6230 GIC          11 : printSimpleStats(const char *prefix, SimpleStats *ss)
 2627 alvherre                 6231 EUB             : {
 1965 tgl                      6232 GIC          11 :     if (ss->count > 0)
 1965 tgl                      6233 EUB             :     {
 1965 tgl                      6234 GIC          11 :         double      latency = ss->sum / ss->count;
                               6235              11 :         double      stddev = sqrt(ss->sum2 / ss->count - latency * latency);
 2627 alvherre                 6236 EUB             : 
 1965 tgl                      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                 :     }
 2627 alvherre                 6240              11 : }
 2627 alvherre                 6241 ECB             : 
  660 tgl                      6242                 : /* print version banner */
                               6243                 : static void
  660 tgl                      6244 GIC          69 : printVersion(PGconn *con)
                               6245                 : {
                               6246              69 :     int         server_ver = PQserverVersion(con);
  660 tgl                      6247 CBC          69 :     int         client_ver = PG_VERSION_NUM;
                               6248                 : 
  660 tgl                      6249 GIC          69 :     if (server_ver != client_ver)
                               6250                 :     {
                               6251                 :         const char *server_version;
                               6252                 :         char        sverbuf[32];
                               6253                 : 
  660 tgl                      6254 ECB             :         /* Try to get full text form, might include "devel" etc */
  660 tgl                      6255 LBC           0 :         server_version = PQparameterStatus(con, "server_version");
  660 tgl                      6256 ECB             :         /* Otherwise fall back on server_ver */
  660 tgl                      6257 LBC           0 :         if (!server_version)
                               6258                 :         {
  660 tgl                      6259 UIC           0 :             formatPGVersionNumber(server_ver, true,
  660 tgl                      6260 ECB             :                                   sverbuf, sizeof(sverbuf));
  660 tgl                      6261 UIC           0 :             server_version = sverbuf;
  660 tgl                      6262 ECB             :         }
                               6263                 : 
  660 tgl                      6264 LBC           0 :         printf(_("%s (%s, server %s)\n"),
  660 tgl                      6265 ECB             :                "pgbench", PG_VERSION, server_version);
                               6266                 :     }
                               6267                 :     /* For version match, only print pgbench version */
                               6268                 :     else
  660 tgl                      6269 CBC          69 :         printf("%s (%s)\n", "pgbench", PG_VERSION);
  660 tgl                      6270 GIC          69 :     fflush(stdout);
  660 tgl                      6271 CBC          69 : }
  660 tgl                      6272 ECB             : 
                               6273                 : /* print out results */
 8397 bruce                    6274                 : static void
  760 tmunro                   6275 GIC          68 : printResults(StatsData *total,
  760 tmunro                   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 */
  382 ishii                    6282 GBC          68 :     int64       failures = getFailures(total);
                               6283              68 :     int64       total_cnt = total->cnt + total->skipped + failures;
  760 tmunro                   6284 GIC          68 :     double      bench_duration = PG_TIME_GET_DOUBLE(total_duration);
  382 ishii                    6285              68 :     double      tps = total->cnt / bench_duration;
                               6286                 : 
 2391 heikki.linnakangas       6287 ECB             :     /* Report test parameters. */
 2629 alvherre                 6288 GIC          68 :     printf("transaction type: %s\n",
                               6289                 :            num_scripts == 1 ? sql_script[0].desc : "multiple scripts");
 6052 ishii                    6290 CBC          68 :     printf("scaling factor: %d\n", scale);
                               6291                 :     /* only print partitioning information if some partitioning was detected */
 1286 akapila                  6292 GBC          68 :     if (partition_method != PART_NONE)
 1286 akapila                  6293 GIC           6 :         printf("partition method: %s\npartitions: %d\n",
                               6294                 :                PARTITION_METHOD[partition_method], partitions);
 5499 ishii                    6295 GBC          68 :     printf("query mode: %s\n", QUERYMODE[querymode]);
 8397 bruce                    6296 GIC          68 :     printf("number of clients: %d\n", nclients);
 4997 ishii                    6297              68 :     printf("number of threads: %d\n", nthreads);
                               6298                 : 
  382                          6299              68 :     if (max_tries)
  354 peter                    6300              68 :         printf("maximum number of tries: %u\n", max_tries);
  382 ishii                    6301 ECB             : 
 5323 tgl                      6302 GIC          68 :     if (duration <= 0)
 5323 tgl                      6303 ECB             :     {
 5323 tgl                      6304 GIC          68 :         printf("number of transactions per client: %d\n", nxacts);
 2627 alvherre                 6305 CBC          68 :         printf("number of transactions actually processed: " INT64_FORMAT "/%d\n",
                               6306                 :                total->cnt, nxacts * nclients);
                               6307                 :     }
                               6308                 :     else
 5323 tgl                      6309 ECB             :     {
 5323 tgl                      6310 LBC           0 :         printf("duration: %d s\n", duration);
 3241 tgl                      6311 UIC           0 :         printf("number of transactions actually processed: " INT64_FORMAT "\n",
  382 ishii                    6312 ECB             :                total->cnt);
                               6313                 :     }
                               6314                 : 
  382 ishii                    6315 GIC          68 :     printf("number of failed transactions: " INT64_FORMAT " (%.3f%%)\n",
  382 ishii                    6316 ECB             :            failures, 100.0 * failures / total_cnt);
                               6317                 : 
  382 ishii                    6318 GIC          68 :     if (failures_detailed)
                               6319                 :     {
  382 ishii                    6320 UIC           0 :         printf("number of serialization failures: " INT64_FORMAT " (%.3f%%)\n",
  382 ishii                    6321 ECB             :                total->serialization_failures,
                               6322                 :                100.0 * total->serialization_failures / total_cnt);
  382 ishii                    6323 UIC           0 :         printf("number of deadlock failures: " INT64_FORMAT " (%.3f%%)\n",
                               6324                 :                total->deadlock_failures,
                               6325                 :                100.0 * total->deadlock_failures / total_cnt);
  382 ishii                    6326 ECB             :     }
                               6327                 : 
                               6328                 :     /* it can be non-zero only if max_tries is not equal to one */
  382 ishii                    6329 GIC          68 :     if (max_tries != 1)
                               6330                 :     {
  382 ishii                    6331 CBC           2 :         printf("number of transactions retried: " INT64_FORMAT " (%.3f%%)\n",
                               6332                 :                total->retried, 100.0 * total->retried / total_cnt);
  382 ishii                    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)
 3036 tgl                      6338              43 :         return;
 3036 tgl                      6339 ECB             : 
 3100 heikki.linnakangas       6340 GIC          25 :     if (throttle_delay && latency_limit)
  403 ishii                    6341               2 :         printf("number of transactions skipped: " INT64_FORMAT " (%.3f%%)\n",
                               6342                 :                total->skipped, 100.0 * total->skipped / total_cnt);
                               6343                 : 
 3100 heikki.linnakangas       6344              25 :     if (latency_limit)
  403 ishii                    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                 : 
 3100 heikki.linnakangas       6349              25 :     if (throttle_delay || progress || latency_limit)
 2627 alvherre                 6350               2 :         printSimpleStats("latency", &total->latency);
                               6351                 :     else
 2391 heikki.linnakangas       6352 ECB             :     {
                               6353                 :         /* no measurement, show average latency computed from run time */
  382 ishii                    6354 CBC          23 :         printf("latency average = %.3f ms%s\n",
  382 ishii                    6355 ECB             :                0.001 * total_duration * nclients / total_cnt,
                               6356                 :                failures > 0 ? " (including failures)" : "");
                               6357                 :     }
                               6358                 : 
 3547 ishii                    6359 CBC          25 :     if (throttle_delay)
 3547 ishii                    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                 :          */
 3473 noah                     6367 GIC           2 :         printf("rate limit schedule lag: avg %.3f (max %.3f) ms\n",
 2627 alvherre                 6368 ECB             :                0.001 * total->lag.sum / total->cnt, 0.001 * total->lag.max);
                               6369                 :     }
 3547 ishii                    6370                 : 
                               6371                 :     /*
  760 tmunro                   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                 :      */
  760 tmunro                   6380 GIC          25 :     if (is_connect)
                               6381                 :     {
  382 ishii                    6382               2 :         printf("average connection time = %.3f ms\n", 0.001 * conn_total_duration / (total->cnt + failures));
  760 tmunro                   6383               2 :         printf("tps = %f (including reconnection times)\n", tps);
                               6384                 :     }
                               6385                 :     else
                               6386                 :     {
  760 tmunro                   6387 CBC          23 :         printf("initial connection time = %.3f ms\n", 0.001 * conn_elapsed_duration);
  760 tmunro                   6388 GIC          23 :         printf("tps = %f (without initial connection time)\n", tps);
                               6389                 :     }
                               6390                 : 
 2577 alvherre                 6391 ECB             :     /* Report per-script/command statistics */
 1600 alvherre                 6392 GIC          25 :     if (per_script_stats || report_per_command)
 4623 tgl                      6393 EUB             :     {
                               6394                 :         int         i;
                               6395                 : 
 2629 alvherre                 6396 GIC          16 :         for (i = 0; i < num_scripts; i++)
 4623 tgl                      6397 EUB             :         {
 1965 tgl                      6398 GIC          11 :             if (per_script_stats)
                               6399                 :             {
                               6400               9 :                 StatsData  *sstats = &sql_script[i].stats;
  382 ishii                    6401               9 :                 int64       script_failures = getFailures(sstats);
                               6402               9 :                 int64       script_total_cnt =
  332 tgl                      6403               9 :                 sstats->cnt + sstats->skipped + script_failures;
 1965 tgl                      6404 ECB             : 
 2577 alvherre                 6405 GIC           9 :                 printf("SQL script %d: %s\n"
 2391 heikki.linnakangas       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,
 2577 alvherre                 6409                 :                        sql_script[i].weight,
                               6410                 :                        100.0 * sql_script[i].weight / total_weight,
                               6411                 :                        sstats->cnt,
                               6412                 :                        100.0 * sstats->cnt / total->cnt,
  382 ishii                    6413 ECB             :                        sstats->cnt / bench_duration);
  382 ishii                    6414 EUB             : 
  382 ishii                    6415 GIC           9 :                 printf(" - number of failed transactions: " INT64_FORMAT " (%.3f%%)\n",
                               6416                 :                        script_failures,
                               6417                 :                        100.0 * script_failures / script_total_cnt);
  382 ishii                    6418 ECB             : 
  382 ishii                    6419 GIC           9 :                 if (failures_detailed)
                               6420                 :                 {
  382 ishii                    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));
  382 ishii                    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));
  382 ishii                    6429 ECB             :                 }
                               6430                 : 
                               6431                 :                 /* it can be non-zero only if max_tries is not equal to one */
  382 ishii                    6432 GIC           9 :                 if (max_tries != 1)
                               6433                 :                 {
  382 ishii                    6434 UIC           0 :                     printf(" - number of transactions retried: " INT64_FORMAT " (%.3f%%)\n",
  382 ishii                    6435 ECB             :                            sstats->retried,
                               6436                 :                            100.0 * sstats->retried / script_total_cnt);
  382 ishii                    6437 LBC           0 :                     printf(" - total number of retries: " INT64_FORMAT "\n",
                               6438                 :                            sstats->retries);
  382 ishii                    6439 ECB             :                 }
                               6440                 : 
  382 ishii                    6441 CBC           9 :                 if (throttle_delay && latency_limit && script_total_cnt > 0)
 1965 tgl                      6442 LBC           0 :                     printf(" - number of transactions skipped: " INT64_FORMAT " (%.3f%%)\n",
                               6443                 :                            sstats->skipped,
                               6444                 :                            100.0 * sstats->skipped / script_total_cnt);
                               6445                 : 
 1965 tgl                      6446 GIC           9 :                 printSimpleStats(" - latency", &sstats->latency);
                               6447                 :             }
 2624 alvherre                 6448 EUB             : 
                               6449                 :             /*
                               6450                 :              * Report per-command statistics: latencies, retries after errors,
                               6451                 :              * failures (errors without retrying).
                               6452                 :              */
 1600 alvherre                 6453 GIC          11 :             if (report_per_command)
                               6454                 :             {
                               6455                 :                 Command   **commands;
                               6456                 : 
  382 ishii                    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                 : 
 2624 alvherre                 6463               2 :                 for (commands = sql_script[i].commands;
                               6464               5 :                      *commands != NULL;
 2624 alvherre                 6465 CBC           3 :                      commands++)
                               6466                 :                 {
 1965 tgl                      6467 GIC           3 :                     SimpleStats *cstats = &(*commands)->stats;
                               6468                 : 
  382 ishii                    6469 CBC           3 :                     if (max_tries == 1)
  382 ishii                    6470 GIC           3 :                         printf("   %11.3f  %10" INT64_MODIFIER "d  %s\n",
                               6471                 :                                (cstats->count > 0) ?
  382 ishii                    6472 ECB             :                                1000.0 * cstats->sum / cstats->count : 0.0,
                               6473                 :                                (*commands)->failures,
                               6474                 :                                (*commands)->first_line);
                               6475                 :                     else
  382 ishii                    6476 UIC           0 :                         printf("   %11.3f  %10" INT64_MODIFIER "d  %10" INT64_MODIFIER "d  %s\n",
  382 ishii                    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),
 1536 tgl                      6490 ECB             :  * and initialize base_random_sequence for use in initializing other sequences.
                               6491                 :  */
 1835                          6492                 : static bool
 1835 tgl                      6493 CBC         161 : set_random_seed(const char *seed)
 1840 teodor                   6494 ECB             : {
                               6495                 :     uint64      iseed;
                               6496                 : 
 1840 teodor                   6497 GIC         161 :     if (seed == NULL || strcmp(seed, "time") == 0)
                               6498                 :     {
 1840 teodor                   6499 ECB             :         /* rely on current time */
  760 tmunro                   6500 CBC         157 :         iseed = pg_time_now();
                               6501                 :     }
 1840 teodor                   6502               4 :     else if (strcmp(seed, "rand") == 0)
                               6503                 :     {
                               6504                 :         /* use some "strong" random source */
 1840 teodor                   6505 LBC           0 :         if (!pg_strong_random(&iseed, sizeof(iseed)))
                               6506                 :         {
 1187 peter                    6507               0 :             pg_log_error("could not generate random seed");
 1835 tgl                      6508 UIC           0 :             return false;
                               6509                 :         }
                               6510                 :     }
 1840 teodor                   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 */
 1453 tgl                      6518 GIC           4 :         if (sscanf(seed, "%lu%c", &ulseed, &garbage) != 1)
                               6519                 :         {
 1187 peter                    6520               1 :             pg_log_error("unrecognized random seed option \"%s\"", seed);
  366 tgl                      6521               1 :             pg_log_error_detail("Expecting an unsigned integer, \"time\" or \"rand\".");
 1835                          6522               1 :             return false;
                               6523                 :         }
 1453                          6524               3 :         iseed = (uint64) ulseed;
                               6525                 :     }
                               6526                 : 
 1840 teodor                   6527             160 :     if (seed != NULL)
  716 michael                  6528               3 :         pg_log_info("setting random seed to %llu", (unsigned long long) iseed);
                               6529                 : 
 1840 teodor                   6530             160 :     random_seed = iseed;
                               6531                 : 
                               6532                 :     /* Initialize base_random_sequence using seed */
  497 tgl                      6533             160 :     pg_prng_seed(&base_random_sequence, (uint64) iseed);
                               6534                 : 
 1835                          6535             160 :     return true;
                               6536                 : }
                               6537                 : 
                               6538                 : int
 8397 bruce                    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'},
 2629 alvherre                 6562 ECB             :         {"rate", required_argument, NULL, 'R'},
 3573 rhaas                    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 */
 1973 tgl                      6571                 :         {"unlogged-tables", no_argument, NULL, 1},
 3782 bruce                    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},
 1840 teodor                   6579                 :         {"random-seed", required_argument, NULL, 9},
                               6580                 :         {"show-script", required_argument, NULL, 10},
                               6581                 :         {"partitions", required_argument, NULL, 11},
 1286 akapila                  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;
 1973 tgl                      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;
 5448 tgl                      6596 CBC         159 :     bool        scale_given = false;
                               6597                 : 
 3162 ishii                    6598 GIC         159 :     bool        benchmarking_option_set = false;
                               6599             159 :     bool        initialization_option_set = false;
 2629 alvherre                 6600             159 :     bool        internal_script_used = false;
                               6601                 : 
                               6602                 :     CState     *state;          /* status of clients */
 4997 ishii                    6603 ECB             :     TState     *threads;        /* array of thread */
 8397 bruce                    6604                 : 
                               6605                 :     pg_time_usec_t
  760 tmunro                   6606                 :                 start_time,     /* start up time */
  760 tmunro                   6607 CBC         159 :                 bench_start = 0,    /* first recorded benchmarking time */
                               6608                 :                 conn_total_duration;    /* cumulated connection time in
  760 tmunro                   6609 ECB             :                                          * threads */
 3100 heikki.linnakangas       6610 GIC         159 :     int64       latency_late = 0;
 2627 alvherre                 6611 ECB             :     StatsData   stats;
                               6612                 :     int         weight;
 8397 bruce                    6613                 : 
                               6614                 :     int         i;
                               6615                 :     int         nclients_dealt;
                               6616                 : 
                               6617                 : #ifdef HAVE_GETRLIMIT
                               6618                 :     struct rlimit rlim;
 8485 ishii                    6619                 : #endif
                               6620                 : 
                               6621                 :     PGconn     *con;
                               6622                 :     char       *env;
 7243                          6623                 : 
 1643 peter_e                  6624 GIC         159 :     int         exit_code = 0;
                               6625                 :     struct timeval tv;
  637 tmunro                   6626 ECB             : 
  637 tmunro                   6627 EUB             :     /*
                               6628                 :      * Record difference between Unix time and instr_time time.  We'll use
  637 tmunro                   6629 ECB             :      * this for logging and aggregation.
                               6630                 :      */
  637 tmunro                   6631 GIC         159 :     gettimeofday(&tv, NULL);
                               6632             159 :     epoch_shift = tv.tv_sec * INT64CONST(1000000) + tv.tv_usec - pg_time_now();
 1643 peter_e                  6633 ECB             : 
 1469 peter                    6634 GIC         159 :     pg_logging_init(argv[0]);
 5154 peter_e                  6635 CBC         159 :     progname = get_progname(argv[0]);
 5154 peter_e                  6636 ECB             : 
 5154 peter_e                  6637 GIC         159 :     if (argc > 1)
 5154 peter_e                  6638 ECB             :     {
 5154 peter_e                  6639 CBC         159 :         if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
                               6640                 :         {
 3931 rhaas                    6641               1 :             usage();
 5154 peter_e                  6642               1 :             exit(0);
 5154 peter_e                  6643 ECB             :         }
 5154 peter_e                  6644 CBC         158 :         if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
 5154 peter_e                  6645 ECB             :         {
 5154 peter_e                  6646 CBC           1 :             puts("pgbench (PostgreSQL) " PG_VERSION);
                               6647               1 :             exit(0);
 5154 peter_e                  6648 ECB             :         }
                               6649                 :     }
                               6650                 : 
 1474 michael                  6651 CBC         157 :     state = (CState *) pg_malloc0(sizeof(CState));
                               6652                 : 
                               6653                 :     /* set random seed early, because it may be used while parsing scripts. */
 1835 tgl                      6654             157 :     if (!set_random_seed(getenv("PGBENCH_RANDOM_SEED")))
  366 tgl                      6655 UBC           0 :         pg_fatal("error while setting random seed from PGBENCH_RANDOM_SEED environment variable");
 1840 teodor                   6656 ECB             : 
  118 peter                    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)
 8397 bruce                    6658 EUB             :     {
                               6659                 :         char       *script;
 2577 alvherre                 6660                 : 
 8397 bruce                    6661 GBC        1055 :         switch (c)
                               6662                 :         {
  118 peter                    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);
 1973 tgl                      6671 GIC           7 :                 benchmarking_option_set = true;
  118 peter                    6672 GNC           7 :                 internal_script_used = true;
 8397 bruce                    6673 CBC           7 :                 break;
                               6674              21 :             case 'c':
 3162 ishii                    6675              21 :                 benchmarking_option_set = true;
  624 michael                  6676              21 :                 if (!option_parse_int(optarg, "-c/--clients", 1, INT_MAX,
  624 michael                  6677 ECB             :                                       &nclients))
 8397 bruce                    6678                 :                 {
 8397 bruce                    6679 GIC           1 :                     exit(1);
 8397 bruce                    6680 ECB             :                 }
 6028 tgl                      6681                 : #ifdef HAVE_GETRLIMIT
 8397 bruce                    6682 CBC          20 :                 if (getrlimit(RLIMIT_NOFILE, &rlim) == -1)
  366 tgl                      6683 LBC           0 :                     pg_fatal("getrlimit failed: %m");
 2835 tgl                      6684 CBC          20 :                 if (rlim.rlim_cur < nclients + 3)
 8397 bruce                    6685 ECB             :                 {
  366 tgl                      6686 LBC           0 :                     pg_log_error("need at least %d open files, but system limit is %ld",
 1187 peter                    6687 ECB             :                                  nclients + 3, (long) rlim.rlim_cur);
  366 tgl                      6688 LBC           0 :                     pg_log_error_hint("Reduce number of clients, or use limit/ulimit to increase the system limit.");
 8397 bruce                    6689               0 :                     exit(1);
 8397 bruce                    6690 ECB             :                 }
 2118 tgl                      6691                 : #endif                          /* HAVE_GETRLIMIT */
 8397 bruce                    6692 CBC          20 :                 break;
 7836 bruce                    6693 GNC           2 :             case 'C':
 3162 ishii                    6694               2 :                 benchmarking_option_set = true;
 4765 itagaki.takahiro         6695               2 :                 is_connect = true;
 7836 bruce                    6696               2 :                 break;
  118 peter                    6697               3 :             case 'd':
                               6698               3 :                 pg_logging_increase_verbosity();
 6401 ishii                    6699               3 :                 break;
 6101                          6700             433 :             case 'D':
                               6701                 :                 {
                               6702                 :                     char       *p;
                               6703                 : 
 3162                          6704             433 :                     benchmarking_option_set = true;
                               6705                 : 
 6101                          6706             433 :                     if ((p = strchr(optarg, '=')) == NULL || p == optarg || *(p + 1) == '\0')
  366 tgl                      6707               1 :                         pg_fatal("invalid variable definition: \"%s\"", optarg);
                               6708                 : 
 6101 ishii                    6709             432 :                     *p++ = '\0';
  382                          6710             432 :                     if (!putVariable(&state[0].variables, "option", optarg, p))
 6101 ishii                    6711 UNC           0 :                         exit(1);
                               6712                 :                 }
 6101 ishii                    6713 GNC         432 :                 break;
  118 peter                    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;
 5845 ishii                    6719               3 :             case 'F':
 3162                          6720               3 :                 initialization_option_set = true;
  624 michael                  6721               3 :                 if (!option_parse_int(optarg, "-F/--fillfactor", 10, 100,
                               6722                 :                                       &fillfactor))
 5845 ishii                    6723               1 :                     exit(1);
                               6724               2 :                 break;
  118 peter                    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;
  118 peter                    6737 GIC           4 :             case 'j':           /* jobs */
                               6738               4 :                 benchmarking_option_set = true;
  118 peter                    6739 CBC           4 :                 if (!option_parse_int(optarg, "-j/--jobs", 1, INT_MAX,
                               6740                 :                                       &nthreads))
                               6741                 :                 {
  118 peter                    6742 GIC           1 :                     exit(1);
                               6743                 :                 }
                               6744                 : #ifndef ENABLE_THREAD_SAFETY
  118 peter                    6745 ECB             :                 if (nthreads != 1)
                               6746                 :                     pg_fatal("threads are not supported on this platform; use -j1");
                               6747                 : #endif                          /* !ENABLE_THREAD_SAFETY */
  118 peter                    6748 CBC           3 :                 break;
  118 peter                    6749 GNC           7 :             case 'l':
  118 peter                    6750 CBC           7 :                 benchmarking_option_set = true;
  118 peter                    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;
 5499 ishii                    6763              73 :             case 'M':
 3162                          6764              73 :                 benchmarking_option_set = true;
 5499                          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)
  366 tgl                      6769               1 :                     pg_fatal("invalid query mode (-M): \"%s\"", optarg);
 5499 ishii                    6770              72 :                 break;
  118 peter                    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;
 3553 ishii                    6782               2 :             case 'P':
 3162                          6783               2 :                 benchmarking_option_set = true;
  624 michael                  6784               2 :                 if (!option_parse_int(optarg, "-P/--progress", 1, INT_MAX,
                               6785                 :                                       &progress))
 3553 ishii                    6786               1 :                     exit(1);
                               6787               1 :                 break;
  118 peter                    6788               1 :             case 'q':
                               6789               1 :                 initialization_option_set = true;
                               6790               1 :                 use_quiet = true;
  118 peter                    6791 CBC           1 :                 break;
  118 peter                    6792 GIC           2 :             case 'r':
  118 peter                    6793 CBC           2 :                 benchmarking_option_set = true;
                               6794               2 :                 report_per_command = true;
                               6795               2 :                 break;
 3547 ishii                    6796 GNC           3 :             case 'R':
                               6797                 :                 {
                               6798                 :                     /* get a double from the beginning of option value */
 3260 bruce                    6799               3 :                     double      throttle_value = atof(optarg);
                               6800                 : 
 3162 ishii                    6801               3 :                     benchmarking_option_set = true;
                               6802                 : 
 3260 bruce                    6803               3 :                     if (throttle_value <= 0.0)
  366 tgl                      6804               1 :                         pg_fatal("invalid rate limit: \"%s\"", optarg);
                               6805                 :                     /* Invert rate limit into per-transaction delay in usec */
 1657                          6806               2 :                     throttle_delay = 1000000.0 / throttle_value;
                               6807                 :                 }
 3547 ishii                    6808               2 :                 break;
  118 peter                    6809 CBC           3 :             case 's':
  118 peter                    6810 GIC           3 :                 scale_given = true;
  118 peter                    6811 CBC           3 :                 if (!option_parse_int(optarg, "-s/--scale", 1, INT_MAX,
  118 peter                    6812 ECB             :                                       &scale))
  118 peter                    6813 CBC           1 :                     exit(1);
                               6814               2 :                 break;
  118 peter                    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;
  118 peter                    6820 CBC          92 :             case 't':
                               6821              92 :                 benchmarking_option_set = true;
                               6822              92 :                 if (!option_parse_int(optarg, "-t/--transactions", 1, INT_MAX,
  118 peter                    6823 ECB             :                                       &nxacts))
  118 peter                    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,
  118 peter                    6829 ECB             :                                       &duration))
  118 peter                    6830 CBC           1 :                     exit(1);
                               6831               4 :                 break;
                               6832               1 :             case 'U':
                               6833               1 :                 username = pg_strdup(optarg);
                               6834               1 :                 break;
  118 peter                    6835 GNC           1 :             case 'v':
  118 peter                    6836 CBC           1 :                 benchmarking_option_set = true;
  118 peter                    6837 GNC           1 :                 do_vacuum_accounts = true;
 3100 heikki.linnakangas       6838 CBC           1 :                 break;
 1973 tgl                      6839               2 :             case 1:             /* unlogged-tables */
                               6840               2 :                 initialization_option_set = true;
                               6841               2 :                 unlogged_tables = true;
 4276 rhaas                    6842               2 :                 break;
 3955 bruce                    6843               1 :             case 2:             /* tablespace */
 3162 ishii                    6844               1 :                 initialization_option_set = true;
 3831 bruce                    6845               1 :                 tablespace = pg_strdup(optarg);
 4276 rhaas                    6846               1 :                 break;
 3955 bruce                    6847               1 :             case 3:             /* index-tablespace */
 3162 ishii                    6848 GIC           1 :                 initialization_option_set = true;
 3831 bruce                    6849 CBC           1 :                 index_tablespace = pg_strdup(optarg);
 4276 rhaas                    6850 GIC           1 :                 break;
 1973 tgl                      6851 CBC           5 :             case 4:             /* sampling-rate */
 3162 ishii                    6852               5 :                 benchmarking_option_set = true;
 3840 heikki.linnakangas       6853 GIC           5 :                 sample_rate = atof(optarg);
                               6854               5 :                 if (sample_rate <= 0.0 || sample_rate > 1.0)
  366 tgl                      6855 CBC           1 :                     pg_fatal("invalid sampling rate: \"%s\"", optarg);
 3840 heikki.linnakangas       6856               4 :                 break;
 1973 tgl                      6857               6 :             case 5:             /* aggregate-interval */
 3162 ishii                    6858 GIC           6 :                 benchmarking_option_set = true;
  624 michael                  6859 CBC           6 :                 if (!option_parse_int(optarg, "--aggregate-interval", 1, INT_MAX,
  624 michael                  6860 ECB             :                                       &agg_interval))
 3720 ishii                    6861 CBC           1 :                     exit(1);
                               6862               5 :                 break;
 1973 tgl                      6863               2 :             case 6:             /* progress-timestamp */
 2762 teodor                   6864 GBC           2 :                 progress_timestamp = true;
 2762 teodor                   6865 CBC           2 :                 benchmarking_option_set = true;
                               6866               2 :                 break;
 1973 tgl                      6867 GIC           4 :             case 7:             /* log-prefix */
 2342 rhaas                    6868 CBC           4 :                 benchmarking_option_set = true;
 2342 rhaas                    6869 GIC           4 :                 logfile_prefix = pg_strdup(optarg);
 2342 rhaas                    6870 CBC           4 :                 break;
 1973 tgl                      6871 GBC           2 :             case 8:             /* foreign-keys */
                               6872               2 :                 initialization_option_set = true;
                               6873               2 :                 foreign_keys = true;
                               6874               2 :                 break;
 1840 teodor                   6875 CBC           4 :             case 9:             /* random-seed */
 1840 teodor                   6876 GIC           4 :                 benchmarking_option_set = true;
 1835 tgl                      6877 CBC           4 :                 if (!set_random_seed(optarg))
  366 tgl                      6878 GIC           1 :                     pg_fatal("error while setting random seed from --random-seed option");
 1840 teodor                   6879 CBC           3 :                 break;
 1363 tmunro                   6880               1 :             case 10:            /* list */
                               6881                 :                 {
                               6882               1 :                     const BuiltinScript *s = findBuiltin(optarg);
 1363 tmunro                   6883 ECB             : 
 1363 tmunro                   6884 GIC           1 :                     fprintf(stderr, "-- %s: %s\n%s\n", s->name, s->desc, s->script);
 1363 tmunro                   6885 CBC           1 :                     exit(0);
 1363 tmunro                   6886 ECB             :                 }
                               6887                 :                 break;
 1286 akapila                  6888 CBC           3 :             case 11:            /* partitions */
                               6889               3 :                 initialization_option_set = true;
  326 michael                  6890               3 :                 if (!option_parse_int(optarg, "--partitions", 0, INT_MAX,
                               6891                 :                                       &partitions))
 1286 akapila                  6892               1 :                     exit(1);
                               6893               2 :                 break;
 1286 akapila                  6894 GIC           3 :             case 12:            /* partition-method */
                               6895               3 :                 initialization_option_set = true;
                               6896               3 :                 if (pg_strcasecmp(optarg, "range") == 0)
 1286 akapila                  6897 UIC           0 :                     partition_method = PART_RANGE;
 1286 akapila                  6898 CBC           3 :                 else if (pg_strcasecmp(optarg, "hash") == 0)
 1286 akapila                  6899 GIC           2 :                     partition_method = PART_HASH;
 1286 akapila                  6900 ECB             :                 else
  366 tgl                      6901 CBC           1 :                     pg_fatal("invalid partition method, expecting \"range\" or \"hash\", got: \"%s\"",
  366 tgl                      6902 ECB             :                              optarg);
 1286 akapila                  6903 GIC           2 :                 break;
  382 ishii                    6904 UIC           0 :             case 13:            /* failures-detailed */
                               6905               0 :                 benchmarking_option_set = true;
  382 ishii                    6906 LBC           0 :                 failures_detailed = true;
  382 ishii                    6907 UIC           0 :                 break;
  382 ishii                    6908 CBC           4 :             case 14:            /* max-tries */
                               6909                 :                 {
                               6910               4 :                     int32       max_tries_arg = atoi(optarg);
  382 ishii                    6911 ECB             : 
  382 ishii                    6912 CBC           4 :                     if (max_tries_arg < 0)
  366 tgl                      6913 GIC           1 :                         pg_fatal("invalid number of maximum tries: \"%s\"", optarg);
                               6914                 : 
  382 ishii                    6915 CBC           3 :                     benchmarking_option_set = true;
  382 ishii                    6916 GIC           3 :                     max_tries = (uint32) max_tries_arg;
                               6917                 :                 }
  382 ishii                    6918 CBC           3 :                 break;
                               6919               2 :             case 15:            /* verbose-errors */
  382 ishii                    6920 GIC           2 :                 benchmarking_option_set = true;
                               6921               2 :                 verbose_errors = true;
  382 ishii                    6922 CBC           2 :                 break;
 8397 bruce                    6923               2 :             default:
                               6924                 :                 /* getopt_long already emitted a complaint */
  366 tgl                      6925 GIC           2 :                 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
 8397 bruce                    6926               2 :                 exit(1);
                               6927                 :         }
                               6928                 :     }
                               6929                 : 
 2629 alvherre                 6930 ECB             :     /* set default script if none */
 2629 alvherre                 6931 CBC          89 :     if (num_scripts == 0 && !is_init_mode)
                               6932                 :     {
 2576 tgl                      6933 GIC          11 :         process_builtin(findBuiltin("tpcb-like"), 1);
 2629 alvherre                 6934              11 :         benchmarking_option_set = true;
                               6935              11 :         internal_script_used = true;
                               6936                 :     }
                               6937                 : 
 1550 alvherre                 6938 ECB             :     /* complete SQL command initialization and compute total weight */
 1550 alvherre                 6939 GIC         181 :     for (i = 0; i < num_scripts; i++)
 2067 tgl                      6940 ECB             :     {
 1550 alvherre                 6941 CBC          93 :         Command   **commands = sql_script[i].commands;
                               6942                 : 
 1550 alvherre                 6943 GIC         591 :         for (int j = 0; commands[j] != NULL; j++)
 1550 alvherre                 6944 CBC         499 :             if (commands[j]->type == SQL_COMMAND)
                               6945             238 :                 postprocess_sql_command(commands[j]);
 2067 tgl                      6946 ECB             : 
 2577 alvherre                 6947 EUB             :         /* cannot overflow: weight is 32b, total_weight 64b */
 2577 alvherre                 6948 GIC          92 :         total_weight += sql_script[i].weight;
 1550 alvherre                 6949 ECB             :     }
                               6950                 : 
 2567 alvherre                 6951 GIC          88 :     if (total_weight == 0 && !is_init_mode)
  366 tgl                      6952 CBC           1 :         pg_fatal("total script weight must not be zero");
                               6953                 : 
 2624 alvherre                 6954 EUB             :     /* show per script stats if several scripts are used */
 2624 alvherre                 6955 GIC          87 :     if (num_scripts > 1)
 2624 alvherre                 6956 GBC           3 :         per_script_stats = true;
 2624 alvherre                 6957 EUB             : 
                               6958                 :     /*
                               6959                 :      * Don't need more threads than there are clients.  (This is not merely an
 2837 heikki.linnakangas       6960 ECB             :      * optimization; throttle_delay is calculated incorrectly below if some
                               6961                 :      * threads have no clients assigned to them.)
                               6962                 :      */
 2837 heikki.linnakangas       6963 CBC          87 :     if (nthreads > nclients)
 2837 heikki.linnakangas       6964 GIC           1 :         nthreads = nclients;
 2837 heikki.linnakangas       6965 ECB             : 
 1657 tgl                      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                 :      */
 3547 ishii                    6971 GIC          87 :     throttle_delay *= nthreads;
 3547 ishii                    6972 ECB             : 
 8397 bruce                    6973 CBC          87 :     if (argc > optind)
 1319 peter                    6974 GIC           1 :         dbName = argv[optind++];
 8397 bruce                    6975 ECB             :     else
                               6976                 :     {
 7243 ishii                    6977 GIC          86 :         if ((env = getenv("PGDATABASE")) != NULL && *env != '\0')
                               6978              72 :             dbName = env;
  764 michael                  6979              14 :         else if ((env = getenv("PGUSER")) != NULL && *env != '\0')
  764 michael                  6980 LBC           0 :             dbName = env;
 7243 ishii                    6981 ECB             :         else
  764 michael                  6982 GIC          14 :             dbName = get_user_name_or_exit(progname);
                               6983                 :     }
 8397 bruce                    6984 ECB             : 
 1319 peter                    6985 GIC          87 :     if (optind < argc)
                               6986                 :     {
  366 tgl                      6987 LBC           0 :         pg_log_error("too many command-line arguments (first is \"%s\")",
                               6988                 :                      argv[optind]);
  366 tgl                      6989 UIC           0 :         pg_log_error_hint("Try \"%s --help\" for more information.", progname);
 1319 peter                    6990 LBC           0 :         exit(1);
 1319 peter                    6991 ECB             :     }
                               6992                 : 
 8397 bruce                    6993 GIC          87 :     if (is_init_mode)
                               6994                 :     {
 3162 ishii                    6995               5 :         if (benchmarking_option_set)
  366 tgl                      6996 CBC           1 :             pg_fatal("some of the specified options cannot be used in initialization (-i) mode");
 3162 ishii                    6997 ECB             : 
 1286 akapila                  6998 GIC           4 :         if (partitions == 0 && partition_method != PART_NONE)
  366 tgl                      6999               1 :             pg_fatal("--partition-method requires greater than zero --partitions");
                               7000                 : 
 1286 akapila                  7001 ECB             :         /* set default method */
 1286 akapila                  7002 CBC           3 :         if (partitions > 0 && partition_method == PART_NONE)
 1286 akapila                  7003 GIC           1 :             partition_method = PART_RANGE;
                               7004                 : 
 1973 tgl                      7005 CBC           3 :         if (initialize_steps == NULL)
                               7006               1 :             initialize_steps = pg_strdup(DEFAULT_INIT_STEPS);
                               7007                 : 
 1973 tgl                      7008 GIC           3 :         if (is_no_vacuum)
 1973 tgl                      7009 ECB             :         {
                               7010                 :             /* Remove any vacuum step in initialize_steps */
                               7011                 :             char       *p;
                               7012                 : 
 1973 tgl                      7013 CBC           4 :             while ((p = strchr(initialize_steps, 'v')) != NULL)
                               7014               3 :                 *p = ' ';
                               7015                 :         }
                               7016                 : 
                               7017               3 :         if (foreign_keys)
 1973 tgl                      7018 ECB             :         {
                               7019                 :             /* Add 'f' to end of initialize_steps, if not already there */
 1973 tgl                      7020 CBC           2 :             if (strchr(initialize_steps, 'f') == NULL)
 1973 tgl                      7021 ECB             :             {
                               7022                 :                 initialize_steps = (char *)
 1973 tgl                      7023 CBC           2 :                     pg_realloc(initialize_steps,
                               7024               2 :                                strlen(initialize_steps) + 2);
 1973 tgl                      7025 GIC           2 :                 strcat(initialize_steps, "f");
 1973 tgl                      7026 ECB             :             }
                               7027                 :         }
                               7028                 : 
 1973 tgl                      7029 CBC           3 :         runInitSteps(initialize_steps);
 8397 bruce                    7030               3 :         exit(0);
                               7031                 :     }
 3162 ishii                    7032 ECB             :     else
                               7033                 :     {
 3162 ishii                    7034 GIC          82 :         if (initialization_option_set)
  366 tgl                      7035 CBC           2 :             pg_fatal("some of the specified options cannot be used in benchmarking mode");
                               7036                 :     }
 8397 bruce                    7037 ECB             : 
 1973 tgl                      7038 CBC          80 :     if (nxacts > 0 && duration > 0)
  366 tgl                      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. */
 5323                          7042              78 :     if (nxacts <= 0 && duration <= 0)
                               7043               8 :         nxacts = DEFAULT_NXACTS;
                               7044                 : 
 3840 heikki.linnakangas       7045 ECB             :     /* --sampling-rate may be used only with -l */
 3840 heikki.linnakangas       7046 GIC          78 :     if (sample_rate > 0.0 && !use_log)
  366 tgl                      7047 CBC           1 :         pg_fatal("log sampling (--sampling-rate) is allowed only when logging transactions (-l)");
                               7048                 : 
 2613 alvherre                 7049 ECB             :     /* --sampling-rate may not be used with --aggregate-interval */
 3720 ishii                    7050 CBC          77 :     if (sample_rate > 0.0 && agg_interval > 0)
  366 tgl                      7051 GIC           1 :         pg_fatal("log sampling (--sampling-rate) and aggregation (--aggregate-interval) cannot be used at the same time");
                               7052                 : 
 2835 tgl                      7053 CBC          76 :     if (agg_interval > 0 && !use_log)
  366 tgl                      7054 GIC           1 :         pg_fatal("log aggregation is allowed only when actually logging transactions");
                               7055                 : 
 2342 rhaas                    7056              75 :     if (!use_log && logfile_prefix)
  366 tgl                      7057 CBC           1 :         pg_fatal("log file prefix (--log-prefix) is allowed only when logging transactions (-l)");
 2342 rhaas                    7058 ECB             : 
 2835 tgl                      7059 GIC          74 :     if (duration > 0 && agg_interval > duration)
  366 tgl                      7060 CBC           1 :         pg_fatal("number of seconds for aggregation (%d) must not be higher than test duration (%d)", agg_interval, duration);
                               7061                 : 
 2835                          7062              73 :     if (duration > 0 && agg_interval > 0 && duration % agg_interval != 0)
  366 tgl                      7063 GIC           1 :         pg_fatal("duration (%d) must be a multiple of aggregation interval (%d)", duration, agg_interval);
 3720 ishii                    7064 EUB             : 
 2043 tgl                      7065 GBC          72 :     if (progress_timestamp && progress == 0)
  366                          7066               1 :         pg_fatal("--progress-timestamp is allowed only under --progress");
                               7067                 : 
  382 ishii                    7068 GIC          71 :     if (!max_tries)
                               7069                 :     {
  382 ishii                    7070 CBC           1 :         if (!latency_limit && duration <= 0)
  366 tgl                      7071               1 :             pg_fatal("an unlimited number of transaction tries can only be used with --latency-limit or a duration (-T)");
  382 ishii                    7072 EUB             :     }
                               7073                 : 
                               7074                 :     /*
                               7075                 :      * save main process id in the global variable because process id will be
                               7076                 :      * changed after fork.
                               7077                 :      */
 4765 itagaki.takahiro         7078 GIC          70 :     main_pid = (int) getpid();
 4765 itagaki.takahiro         7079 ECB             : 
 6101 ishii                    7080 GIC          70 :     if (nclients > 1)
 6101 ishii                    7081 ECB             :     {
 3841 tgl                      7082 CBC          12 :         state = (CState *) pg_realloc(state, sizeof(CState) * nclients);
 4623 tgl                      7083 GIC          12 :         memset(state + 1, 0, sizeof(CState) * (nclients - 1));
                               7084                 : 
                               7085                 :         /* copy any -D switch values to all clients */
 6101 ishii                    7086 CBC          43 :         for (i = 1; i < nclients; i++)
 6101 ishii                    7087 ECB             :         {
                               7088                 :             int         j;
                               7089                 : 
 4997 ishii                    7090 GIC          31 :             state[i].id = i;
  382 ishii                    7091 CBC          32 :             for (j = 0; j < state[0].variables.nvars; j++)
                               7092                 :             {
                               7093               1 :                 Variable   *var = &state[0].variables.vars[j];
                               7094                 : 
 1916 teodor                   7095 GIC           1 :                 if (var->value.type != PGBT_NO_VALUE)
                               7096                 :                 {
  382 ishii                    7097 UIC           0 :                     if (!putVariableValue(&state[i].variables, "startup",
 1809 tgl                      7098 LBC           0 :                                           var->name, &var->value))
 2529                          7099               0 :                         exit(1);
                               7100                 :                 }
                               7101                 :                 else
                               7102                 :                 {
  382 ishii                    7103 GIC           1 :                     if (!putVariable(&state[i].variables, "startup",
 1916 teodor                   7104               1 :                                      var->name, var->svalue))
 2529 tgl                      7105 LBC           0 :                         exit(1);
                               7106                 :                 }
 6101 ishii                    7107 ECB             :             }
                               7108                 :         }
                               7109                 :     }
 7568 ishii                    7110 EUB             : 
                               7111                 :     /* other CState initializations */
 1844 teodor                   7112 GIC         171 :     for (i = 0; i < nclients; i++)
                               7113                 :     {
                               7114             101 :         state[i].cstack = conditional_stack_create();
 1605 alvherre                 7115             101 :         initRandomState(&state[i].cs_func_rs);
                               7116                 :     }
                               7117                 : 
 8397 bruce                    7118 ECB             :     /* opening connection... */
 7882 ishii                    7119 GIC          70 :     con = doConnect();
 7882 ishii                    7120 CBC          70 :     if (con == NULL)
  366 tgl                      7121               1 :         pg_fatal("could not create connection for setup");
 7882 ishii                    7122 EUB             : 
                               7123                 :     /* report pgbench and server versions */
  660 tgl                      7124 GIC          69 :     printVersion(con);
                               7125                 : 
  764 michael                  7126 CBC          69 :     pg_log_debug("pghost: %s pgport: %s nclients: %d %s: %d dbName: %s",
                               7127                 :                  PQhost(con), PQport(con), nclients,
  764 michael                  7128 ECB             :                  duration <= 0 ? "nxacts" : "duration",
                               7129                 :                  duration <= 0 ? nxacts : duration, PQdb(con));
                               7130                 : 
 2629 alvherre                 7131 CBC          69 :     if (internal_script_used)
 1286 akapila                  7132 GIC           7 :         GetTableInfo(con, scale_given);
 6014 ishii                    7133 EUB             : 
                               7134                 :     /*
                               7135                 :      * :scale variables normally get -s or database scale, but don't override
                               7136                 :      * an explicit -D switch
 5448 tgl                      7137 ECB             :      */
  382 ishii                    7138 GIC          68 :     if (lookupVariable(&state[0].variables, "scale") == NULL)
 5448 tgl                      7139 ECB             :     {
 5448 tgl                      7140 CBC         167 :         for (i = 0; i < nclients; i++)
                               7141                 :         {
  382 ishii                    7142 GBC          99 :             if (!putVariableInt(&state[i].variables, "startup", "scale", scale))
 5448 tgl                      7143 UIC           0 :                 exit(1);
                               7144                 :         }
 6396 ishii                    7145 ECB             :     }
                               7146                 : 
 3586 heikki.linnakangas       7147                 :     /*
                               7148                 :      * Define a :client_id variable that is unique per connection. But don't
                               7149                 :      * override an explicit -D switch.
                               7150                 :      */
  382 ishii                    7151 CBC          68 :     if (lookupVariable(&state[0].variables, "client_id") == NULL)
                               7152                 :     {
 3586 heikki.linnakangas       7153             167 :         for (i = 0; i < nclients; i++)
  382 ishii                    7154 GIC          99 :             if (!putVariableInt(&state[i].variables, "startup", "client_id", i))
 3586 heikki.linnakangas       7155 UBC           0 :                 exit(1);
 3586 heikki.linnakangas       7156 EUB             :     }
                               7157                 : 
                               7158                 :     /* set default seed for hash functions */
  382 ishii                    7159 GIC          68 :     if (lookupVariable(&state[0].variables, "default_seed") == NULL)
 1845 teodor                   7160 ECB             :     {
  497 tgl                      7161 GIC          68 :         uint64      seed = pg_prng_uint64(&base_random_sequence);
                               7162                 : 
 1845 teodor                   7163 CBC         167 :         for (i = 0; i < nclients; i++)
  382 ishii                    7164              99 :             if (!putVariableInt(&state[i].variables, "startup", "default_seed",
                               7165                 :                                 (int64) seed))
 1845 teodor                   7166 LBC           0 :                 exit(1);
                               7167                 :     }
 1845 teodor                   7168 ECB             : 
                               7169                 :     /* set random seed unless overwritten */
  382 ishii                    7170 CBC          68 :     if (lookupVariable(&state[0].variables, "random_seed") == NULL)
 1840 teodor                   7171 ECB             :     {
 1840 teodor                   7172 CBC         167 :         for (i = 0; i < nclients; i++)
  382 ishii                    7173              99 :             if (!putVariableInt(&state[i].variables, "startup", "random_seed",
  382 ishii                    7174 ECB             :                                 random_seed))
 1840 teodor                   7175 LBC           0 :                 exit(1);
 1840 teodor                   7176 ECB             :     }
                               7177                 : 
 6396 ishii                    7178 CBC          68 :     if (!is_no_vacuum)
 6396 ishii                    7179 ECB             :     {
 6396 ishii                    7180 GIC           9 :         fprintf(stderr, "starting vacuum...");
 2889 sfrost                   7181 CBC           9 :         tryExecuteStatement(con, "vacuum pgbench_branches");
 2889 sfrost                   7182 GIC           9 :         tryExecuteStatement(con, "vacuum pgbench_tellers");
                               7183               9 :         tryExecuteStatement(con, "truncate pgbench_history");
 6396 ishii                    7184               9 :         fprintf(stderr, "end.\n");
 6396 ishii                    7185 ECB             : 
 5847 ishii                    7186 GIC           9 :         if (do_vacuum_accounts)
                               7187                 :         {
 5085 tgl                      7188 LBC           0 :             fprintf(stderr, "starting vacuum pgbench_accounts...");
 2889 sfrost                   7189 UIC           0 :             tryExecuteStatement(con, "vacuum analyze pgbench_accounts");
 8397 bruce                    7190               0 :             fprintf(stderr, "end.\n");
 8397 bruce                    7191 ECB             :         }
 8397 bruce                    7192 EUB             :     }
 6396 ishii                    7193 GIC          68 :     PQfinish(con);
 8397 bruce                    7194 ECB             : 
 4623 tgl                      7195                 :     /* set up thread data structures */
 3841 tgl                      7196 GBC          68 :     threads = (TState *) pg_malloc(sizeof(TState) * nthreads);
 2837 heikki.linnakangas       7197 GIC          68 :     nclients_dealt = 0;
                               7198                 : 
 4623 tgl                      7199             137 :     for (i = 0; i < nthreads; i++)
 4623 tgl                      7200 ECB             :     {
 4382 bruce                    7201 GIC          69 :         TState     *thread = &threads[i];
 4623 tgl                      7202 ECB             : 
 4623 tgl                      7203 GIC          69 :         thread->tid = i;
 2837 heikki.linnakangas       7204 CBC          69 :         thread->state = &state[nclients_dealt];
                               7205              69 :         thread->nstate =
 2837 heikki.linnakangas       7206 GIC          69 :             (nclients - nclients_dealt + nthreads - i - 1) / (nthreads - i);
 1605 alvherre                 7207 CBC          69 :         initRandomState(&thread->ts_choose_rs);
 1605 alvherre                 7208 GBC          69 :         initRandomState(&thread->ts_throttle_rs);
 1605 alvherre                 7209 GIC          69 :         initRandomState(&thread->ts_sample_rs);
 2495 rhaas                    7210              69 :         thread->logfile = NULL; /* filled in later */
 3100 heikki.linnakangas       7211              69 :         thread->latency_late = 0;
 2288 tgl                      7212              69 :         initStats(&thread->stats, 0);
                               7213                 : 
 2837 heikki.linnakangas       7214              69 :         nclients_dealt += thread->nstate;
 4623 tgl                      7215 ECB             :     }
                               7216                 : 
 2837 heikki.linnakangas       7217 EUB             :     /* all clients must be assigned to a thread */
 2837 heikki.linnakangas       7218 GIC          68 :     Assert(nclients_dealt == nclients);
                               7219                 : 
  760 tmunro                   7220 ECB             :     /* get start up time for the whole computation */
  760 tmunro                   7221 GIC          68 :     start_time = pg_time_now();
                               7222                 : 
 4997 ishii                    7223 ECB             :     /* set alarm if duration is specified. */
 4997 ishii                    7224 CBC          68 :     if (duration > 0)
 4997 ishii                    7225 UIC           0 :         setalarm(duration);
 4997 ishii                    7226 ECB             : 
  760 tmunro                   7227 GIC          68 :     errno = THREAD_BARRIER_INIT(&barrier, nthreads);
  760 tmunro                   7228 CBC          68 :     if (errno != 0)
  366 tgl                      7229 UIC           0 :         pg_fatal("could not initialize barrier: %m");
                               7230                 : 
 2837 heikki.linnakangas       7231 ECB             : #ifdef ENABLE_THREAD_SAFETY
  760 tmunro                   7232                 :     /* start all threads but thread 0 which is executed directly later */
  760 tmunro                   7233 GIC          69 :     for (i = 1; i < nthreads; i++)
                               7234                 :     {
 4382 bruce                    7235 CBC           1 :         TState     *thread = &threads[i];
 4623 tgl                      7236 ECB             : 
  760 tmunro                   7237 CBC           1 :         thread->create_time = pg_time_now();
  760 tmunro                   7238 GIC           1 :         errno = THREAD_CREATE(&thread->thread, threadRun, thread);
                               7239                 : 
  760 tmunro                   7240 CBC           1 :         if (errno != 0)
  366 tgl                      7241 LBC           0 :             pg_fatal("could not create thread: %m");
 4997 ishii                    7242 ECB             :     }
 2837 heikki.linnakangas       7243                 : #else
  760 tmunro                   7244                 :     Assert(nthreads == 1);
                               7245                 : #endif                          /* ENABLE_THREAD_SAFETY */
                               7246                 : 
 2587 rhaas                    7247                 :     /* compute when to stop */
  760 tmunro                   7248 CBC          68 :     threads[0].create_time = pg_time_now();
 2587 rhaas                    7249              68 :     if (duration > 0)
  760 tmunro                   7250 UIC           0 :         end_time = threads[0].create_time + (int64) 1000000 * duration;
                               7251                 : 
  760 tmunro                   7252 ECB             :     /* run thread 0 directly */
  760 tmunro                   7253 CBC          68 :     (void) threadRun(&threads[0]);
                               7254                 : 
                               7255                 :     /* wait for other threads and accumulate results */
 2288 tgl                      7256 GIC          68 :     initStats(&stats, 0);
  760 tmunro                   7257              68 :     conn_total_duration = 0;
                               7258                 : 
 4997 ishii                    7259             137 :     for (i = 0; i < nthreads; i++)
                               7260                 :     {
 2837 heikki.linnakangas       7261 CBC          69 :         TState     *thread = &threads[i];
                               7262                 : 
                               7263                 : #ifdef ENABLE_THREAD_SAFETY
  760 tmunro                   7264 GIC          69 :         if (i > 0)
                               7265               1 :             THREAD_JOIN(thread->thread);
                               7266                 : #endif                          /* ENABLE_THREAD_SAFETY */
                               7267                 : 
 1643 peter_e                  7268             168 :         for (int j = 0; j < thread->nstate; j++)
  557 fujii                    7269              99 :             if (thread->state[j].state != CSTATE_FINISHED)
 1643 peter_e                  7270 CBC          44 :                 exit_code = 2;
                               7271                 : 
                               7272                 :         /* aggregate thread level stats */
 2627 alvherre                 7273              69 :         mergeSimpleStats(&stats.latency, &thread->stats.latency);
 2627 alvherre                 7274 GIC          69 :         mergeSimpleStats(&stats.lag, &thread->stats.lag);
 2627 alvherre                 7275 CBC          69 :         stats.cnt += thread->stats.cnt;
                               7276              69 :         stats.skipped += thread->stats.skipped;
  382 ishii                    7277 GIC          69 :         stats.retries += thread->stats.retries;
  382 ishii                    7278 CBC          69 :         stats.retried += thread->stats.retried;
  382 ishii                    7279 GIC          69 :         stats.serialization_failures += thread->stats.serialization_failures;
                               7280              69 :         stats.deadlock_failures += thread->stats.deadlock_failures;
 2792 heikki.linnakangas       7281              69 :         latency_late += thread->latency_late;
  760 tmunro                   7282 CBC          69 :         conn_total_duration += thread->conn_duration;
                               7283                 : 
  760 tmunro                   7284 ECB             :         /* first recorded benchmarking start time */
  760 tmunro                   7285 CBC          69 :         if (bench_start == 0 || thread->bench_start < bench_start)
  760 tmunro                   7286 GIC          68 :             bench_start = thread->bench_start;
 4997 ishii                    7287 ECB             :     }
  760 tmunro                   7288                 : 
  585 fujii                    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                 :      */
 4997 ishii                    7294 GIC          68 :     disconnect_all(state, nclients);
                               7295                 : 
                               7296                 :     /*
  760 tmunro                   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.
 3472 noah                     7302                 :      */
  760 tmunro                   7303 CBC          68 :     printResults(&stats, pg_time_now() - bench_start, conn_total_duration,
                               7304                 :                  bench_start - start_time, latency_late);
 4997 ishii                    7305 EUB             : 
  760 tmunro                   7306 GIC          68 :     THREAD_BARRIER_DESTROY(&barrier);
  760 tmunro                   7307 ECB             : 
 1643 peter_e                  7308 GIC          68 :     if (exit_code != 0)
  366 tgl                      7309 CBC          44 :         pg_log_error("Run was aborted; the above results are incomplete.");
 1643 peter_e                  7310 EUB             : 
 1643 peter_e                  7311 GIC          68 :     return exit_code;
                               7312                 : }
                               7313                 : 
  760 tmunro                   7314 ECB             : static THREAD_FUNC_RETURN_TYPE THREAD_FUNC_CC
 4997 ishii                    7315 CBC          69 : threadRun(void *arg)
                               7316                 : {
 4997 ishii                    7317 GIC          69 :     TState     *thread = (TState *) arg;
 4997 ishii                    7318 CBC          69 :     CState     *state = thread->state;
                               7319                 :     pg_time_usec_t start;
                               7320              69 :     int         nstate = thread->nstate;
 2118 tgl                      7321              69 :     int         remains = nstate;   /* number of remaining clients */
 1658                          7322              69 :     socket_set *sockets = alloc_socket_set(nstate);
  760 tmunro                   7323 ECB             :     int64       thread_start,
                               7324                 :                 last_report,
                               7325                 :                 next_report;
                               7326                 :     StatsData   last,
 2627 alvherre                 7327                 :                 aggs;
                               7328                 : 
                               7329                 :     /* open log file if requested */
 4765 itagaki.takahiro         7330 CBC          69 :     if (use_log)
                               7331                 :     {
 2336 rhaas                    7332 ECB             :         char        logpath[MAXPGPATH];
 2289 tgl                      7333 GIC           2 :         char       *prefix = logfile_prefix ? logfile_prefix : "pgbench_log";
                               7334                 : 
 4765 itagaki.takahiro         7335 GBC           2 :         if (thread->tid == 0)
 2342 rhaas                    7336 GIC           2 :             snprintf(logpath, sizeof(logpath), "%s.%d", prefix, main_pid);
                               7337                 :         else
 2342 rhaas                    7338 UIC           0 :             snprintf(logpath, sizeof(logpath), "%s.%d.%d", prefix, main_pid, thread->tid);
                               7339                 : 
 2613 alvherre                 7340 GIC           2 :         thread->logfile = fopen(logpath, "w");
                               7341                 : 
 2613 alvherre                 7342 CBC           2 :         if (thread->logfile == NULL)
  366 tgl                      7343 UIC           0 :             pg_fatal("could not open logfile \"%s\": %m", logpath);
 4765 itagaki.takahiro         7344 ECB             :     }
                               7345                 : 
  760 tmunro                   7346                 :     /* explicitly initialize the state machines */
  760 tmunro                   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;
  587 fujii                    7355 CBC          69 :     thread->conn_duration = 0;
  760 tmunro                   7356              69 :     last_report = thread_start;
  760 tmunro                   7357 GIC          69 :     next_report = last_report + (int64) 1000000 * progress;
                               7358                 : 
  760 tmunro                   7359 ECB             :     /* STEADY */
 4765 itagaki.takahiro         7360 GIC          69 :     if (!is_connect)
                               7361                 :     {
                               7362                 :         /* make connections to the database before starting */
  760 tmunro                   7363 CBC         159 :         for (int i = 0; i < nstate; i++)
                               7364                 :         {
 4997 ishii                    7365 GIC          92 :             if ((state[i].con = doConnect()) == NULL)
                               7366                 :             {
                               7367                 :                 /* coldly abort on initial connection failure */
  366 tgl                      7368 UIC           0 :                 pg_fatal("could not create connection for client %d",
  366 tgl                      7369 ECB             :                          state[i].id);
  760 tmunro                   7370                 :             }
 4997 ishii                    7371                 :         }
 8397 bruce                    7372                 :     }
                               7373                 : 
  760 tmunro                   7374                 :     /* GO */
  760 tmunro                   7375 GIC          69 :     THREAD_BARRIER_WAIT(&barrier);
  760 tmunro                   7376 ECB             : 
  760 tmunro                   7377 CBC          69 :     start = pg_time_now();
  760 tmunro                   7378 GIC          69 :     thread->bench_start = start;
                               7379              69 :     thread->throttle_trigger = start;
                               7380                 : 
                               7381                 :     /*
  637 tmunro                   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                 :      */
  637 tmunro                   7388 CBC          69 :     initStats(&aggs, (start + epoch_shift) / 1000000 * 1000000);
  760 tmunro                   7389 GIC          69 :     last = aggs;
  760 tmunro                   7390 ECB             : 
 2386 tgl                      7391                 :     /* loop till all clients have terminated */
 4997 ishii                    7392 CBC        7236 :     while (remains > 0)
                               7393                 :     {
                               7394                 :         int         nsocks;     /* number of sockets to be waited for */
                               7395                 :         pg_time_usec_t min_usec;
  760 tmunro                   7396 GIC        7167 :         pg_time_usec_t now = 0; /* set this only if needed */
 8397 bruce                    7397 ECB             : 
                               7398                 :         /*
 1658 tgl                      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.
 1658 tgl                      7401 EUB             :          */
 1658 tgl                      7402 GBC        7167 :         clear_socket_set(sockets);
 1658 tgl                      7403 GIC        7167 :         nsocks = 0;
 2929 andres                   7404            7167 :         min_usec = PG_INT64_MAX;
  760 tmunro                   7405 CBC       34078 :         for (int i = 0; i < nstate; i++)
                               7406                 :         {
 4997 ishii                    7407           29307 :             CState     *st = &state[i];
 6396 ishii                    7408 ECB             : 
 1600 alvherre                 7409 GIC       29307 :             if (st->state == CSTATE_SLEEP || st->state == CSTATE_THROTTLE)
 3547 ishii                    7410               3 :             {
                               7411                 :                 /* a nap from the script, or under throttling */
                               7412                 :                 pg_time_usec_t this_usec;
                               7413                 : 
 2386 tgl                      7414 ECB             :                 /* get current time if needed */
  760 tmunro                   7415 CBC           3 :                 pg_time_now_lazy(&now);
                               7416                 : 
                               7417                 :                 /* min_usec should be the minimum delay across all clients */
 2386 heikki.linnakangas       7418 GIC           6 :                 this_usec = (st->state == CSTATE_SLEEP ?
  760 tmunro                   7419               3 :                              st->sleep_until : st->txn_scheduled) - now;
 2386 heikki.linnakangas       7420 CBC           3 :                 if (min_usec > this_usec)
 2386 heikki.linnakangas       7421 GIC           3 :                     min_usec = this_usec;
 4997 ishii                    7422 EUB             :             }
  382 ishii                    7423 GIC       29304 :             else if (st->state == CSTATE_WAIT_RESULT ||
  382 ishii                    7424 GBC        4650 :                      st->state == CSTATE_WAIT_ROLLBACK_RESULT)
 4997                          7425           24655 :             {
 2386 heikki.linnakangas       7426 EUB             :                 /*
                               7427                 :                  * waiting for result from server - nothing to do unless the
                               7428                 :                  * socket is readable
                               7429                 :                  */
 2386 tgl                      7430 GIC       24655 :                 int         sock = PQsocket(st->con);
                               7431                 : 
      heikki.linnakangas       7432           24655 :                 if (sock < 0)
                               7433                 :                 {
 1187 peter                    7434 LBC           0 :                     pg_log_error("invalid socket: %s", PQerrorMessage(st->con));
 2386 heikki.linnakangas       7435 UIC           0 :                     goto done;
 2386 heikki.linnakangas       7436 ECB             :                 }
                               7437                 : 
 1658 tgl                      7438 CBC       24655 :                 add_socket_to_set(sockets, sock, nsocks++);
                               7439                 :             }
 2386                          7440            4649 :             else if (st->state != CSTATE_ABORTED &&
 2386 tgl                      7441 GIC        4649 :                      st->state != CSTATE_FINISHED)
 4997 ishii                    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.
 2386 tgl                      7446 ECB             :                  */
 2386 heikki.linnakangas       7447 GIC        2396 :                 min_usec = 0;
                               7448            2396 :                 break;
                               7449                 :             }
                               7450                 :         }
 8397 bruce                    7451 ECB             : 
                               7452                 :         /* also wake up to print the next progress report on time */
 2801 andres                   7453 GIC        7167 :         if (progress && min_usec > 0 && thread->tid == 0)
 2837 heikki.linnakangas       7454 ECB             :         {
  760 tmunro                   7455 UIC           0 :             pg_time_now_lazy(&now);
 2837 heikki.linnakangas       7456 EUB             : 
  760 tmunro                   7457 UIC           0 :             if (now >= next_report)
 2837 heikki.linnakangas       7458               0 :                 min_usec = 0;
  760 tmunro                   7459 UBC           0 :             else if ((next_report - now) < min_usec)
  760 tmunro                   7460 UIC           0 :                 min_usec = next_report - now;
                               7461                 :         }
 2837 heikki.linnakangas       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                 :          */
 2016 heikki.linnakangas       7467 GIC        7167 :         if (min_usec > 0)
                               7468                 :         {
 1658 tgl                      7469            4771 :             int         rc = 0;
                               7470                 : 
 2929 andres                   7471 CBC        4771 :             if (min_usec != PG_INT64_MAX)
                               7472                 :             {
 1658 tgl                      7473 GIC           3 :                 if (nsocks > 0)
                               7474                 :                 {
 1658 tgl                      7475 LBC           0 :                     rc = wait_on_socket_set(sockets, min_usec);
 2016 heikki.linnakangas       7476 ECB             :                 }
                               7477                 :                 else            /* nothing active, simple sleep */
                               7478                 :                 {
 2016 heikki.linnakangas       7479 GIC           3 :                     pg_usleep(min_usec);
 2016 heikki.linnakangas       7480 ECB             :                 }
 5756 JanWieck                 7481                 :             }
 1658 tgl                      7482                 :             else                /* no explicit delay, wait without timeout */
                               7483                 :             {
 1658 tgl                      7484 CBC        4768 :                 rc = wait_on_socket_set(sockets, 0);
                               7485                 :             }
 2016 heikki.linnakangas       7486 ECB             : 
 1658 tgl                      7487 GIC        4771 :             if (rc < 0)
 8397 bruce                    7488 EUB             :             {
 6401 ishii                    7489 UBC           0 :                 if (errno == EINTR)
                               7490                 :                 {
                               7491                 :                     /* On EINTR, go back to top of loop */
 6401 ishii                    7492 LBC           0 :                     continue;
 2386 tgl                      7493 ECB             :                 }
                               7494                 :                 /* must be something wrong */
  557 fujii                    7495 LBC           0 :                 pg_log_error("%s() failed: %m", SOCKET_WAIT_METHOD);
 4997 ishii                    7496               0 :                 goto done;
                               7497                 :             }
                               7498                 :         }
 1984 tgl                      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 */
 1658 tgl                      7504 GIC        2396 :             clear_socket_set(sockets);
                               7505                 :         }
                               7506                 : 
                               7507                 :         /* ok, advance the state machine of each connection */
 1658 tgl                      7508 CBC        7167 :         nsocks = 0;
  760 tmunro                   7509           41079 :         for (int i = 0; i < nstate; i++)
                               7510                 :         {
 4997 ishii                    7511 GIC       33912 :             CState     *st = &state[i];
                               7512                 : 
  382 ishii                    7513 CBC       33912 :             if (st->state == CSTATE_WAIT_RESULT ||
  382 ishii                    7514 GIC        4944 :                 st->state == CSTATE_WAIT_ROLLBACK_RESULT)
 8397 bruce                    7515 GBC        5148 :             {
                               7516                 :                 /* don't call advanceConnectionState unless data is available */
 2610 alvherre                 7517           28969 :                 int         sock = PQsocket(st->con);
                               7518                 : 
 2610 alvherre                 7519 GIC       28969 :                 if (sock < 0)
                               7520                 :                 {
 1187 peter                    7521 UIC           0 :                     pg_log_error("invalid socket: %s", PQerrorMessage(st->con));
 2610 alvherre                 7522               0 :                     goto done;
                               7523                 :                 }
                               7524                 : 
 1658 tgl                      7525 GBC       28969 :                 if (!socket_has_input(sockets, sock, nsocks++))
 2386 tgl                      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                 :             }
 2386 tgl                      7534 EUB             : 
 1600 alvherre                 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.
 1600 alvherre                 7540 ECB             :              */
 2386 tgl                      7541 CBC        7624 :             if (st->state == CSTATE_FINISHED || st->state == CSTATE_ABORTED)
 2386 tgl                      7542 GIC          99 :                 remains--;
 8397 bruce                    7543 ECB             :         }
                               7544                 : 
 2386 tgl                      7545                 :         /* progress report is made by thread 0 for all threads */
 3553 ishii                    7546 GIC        7167 :         if (progress && thread->tid == 0)
                               7547                 :         {
  185 drowley                  7548 UNC           0 :             pg_time_usec_t now2 = pg_time_now();
                               7549                 : 
                               7550               0 :             if (now2 >= next_report)
 3553 ishii                    7551 ECB             :             {
                               7552                 :                 /*
 1467 tgl                      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                 :                  */
  185 drowley                  7558 UNC           0 :                 printProgressReport(thread, thread_start, now2,
                               7559                 :                                     &last, &last_report);
 2837 heikki.linnakangas       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                 :                 {
  760 tmunro                   7567 UIC           0 :                     next_report += (int64) 1000000 * progress;
  185 drowley                  7568 UNC           0 :                 } while (now2 >= next_report);
                               7569                 :             }
                               7570                 :         }
                               7571                 :     }
                               7572                 : 
 4997 ishii                    7573 GIC          69 : done:
 4997 ishii                    7574 GBC          69 :     disconnect_all(state, nstate);
                               7575                 : 
 2613 alvherre                 7576              69 :     if (thread->logfile)
 2627 alvherre                 7577 EUB             :     {
 2288 tgl                      7578 GIC           2 :         if (agg_interval > 0)
                               7579                 :         {
 2627 alvherre                 7580 EUB             :             /* log aggregated but not yet reported transactions */
 2288 tgl                      7581 UIC           0 :             doLog(thread, state, &aggs, false, 0, 0);
 2627 alvherre                 7582 EUB             :         }
 2613 alvherre                 7583 GBC           2 :         fclose(thread->logfile);
 2288 tgl                      7584               2 :         thread->logfile = NULL;
                               7585                 :     }
 1658 tgl                      7586 GIC          69 :     free_socket_set(sockets);
  760 tmunro                   7587              69 :     THREAD_FUNC_RETURN;
                               7588                 : }
                               7589                 : 
                               7590                 : static void
 1865 andres                   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
 5323 tgl                      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).
 1658 tgl                      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 *
 1658 tgl                      7683 GIC          69 : alloc_socket_set(int count)
 1658 tgl                      7684 ECB             : {
                               7685                 :     socket_set *sa;
                               7686                 : 
 1658 tgl                      7687 GIC          69 :     sa = (socket_set *) pg_malloc0(offsetof(socket_set, pollfds) +
                               7688                 :                                    sizeof(struct pollfd) * count);
                               7689              69 :     sa->maxfds = count;
 1658 tgl                      7690 GBC          69 :     sa->curfds = 0;
                               7691              69 :     return sa;
 1658 tgl                      7692 EUB             : }
                               7693                 : 
                               7694                 : static void
 1658 tgl                      7695 GIC          69 : free_socket_set(socket_set *sa)
 1658 tgl                      7696 ECB             : {
 1658 tgl                      7697 GIC          69 :     pg_free(sa);
                               7698              69 : }
                               7699                 : 
                               7700                 : static void
 1658 tgl                      7701 CBC        9563 : clear_socket_set(socket_set *sa)
                               7702                 : {
 1658 tgl                      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;
 1658 tgl                      7711 CBC       24655 :     sa->pollfds[idx].events = POLLIN;
                               7712           24655 :     sa->pollfds[idx].revents = 0;
 1658 tgl                      7713 GIC       24655 :     sa->curfds++;
 1658 tgl                      7714 CBC       24655 : }
 1658 tgl                      7715 ECB             : 
                               7716                 : static int
 1658 tgl                      7717 GIC        4768 : wait_on_socket_set(socket_set *sa, int64 usecs)
                               7718                 : {
                               7719            4768 :     if (usecs > 0)
                               7720                 :     {
                               7721                 :         struct timespec timeout;
                               7722                 : 
 1658 tgl                      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                 :     {
 1658 tgl                      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