@@ -362,6 +362,15 @@ typedef struct
362362#define META_COMMAND 2
363363#define MAX_ARGS 10
364364
365+ typedef enum MetaCommand
366+ {
367+ META_NONE ,/* not a known meta-command */
368+ META_SET ,/* \set */
369+ META_SETSHELL ,/* \setshell */
370+ META_SHELL ,/* \shell */
371+ META_SLEEP /* \sleep */
372+ }MetaCommand ;
373+
365374typedef enum QueryMode
366375{
367376QUERY_SIMPLE ,/* simple query */
@@ -378,6 +387,7 @@ typedef struct
378387char * line ;/* text of command line */
379388int command_num ;/* unique index of this Command struct */
380389int type ;/* command type (SQL_COMMAND or META_COMMAND) */
390+ MetaCommand meta ;/* meta command identifier, or META_NONE */
381391int argc ;/* number of command words */
382392char * argv [MAX_ARGS ];/* command word list */
383393PgBenchExpr * expr ;/* parsed expression, if needed */
@@ -1721,6 +1731,29 @@ evaluateExpr(TState *thread, CState *st, PgBenchExpr *expr, PgBenchValue *retval
17211731}
17221732}
17231733
1734+ /*
1735+ * Convert command name to meta-command enum identifier
1736+ */
1737+ static MetaCommand
1738+ getMetaCommand (const char * cmd )
1739+ {
1740+ MetaCommand mc ;
1741+
1742+ if (cmd == NULL )
1743+ mc = META_NONE ;
1744+ else if (pg_strcasecmp (cmd ,"set" )== 0 )
1745+ mc = META_SET ;
1746+ else if (pg_strcasecmp (cmd ,"setshell" )== 0 )
1747+ mc = META_SETSHELL ;
1748+ else if (pg_strcasecmp (cmd ,"shell" )== 0 )
1749+ mc = META_SHELL ;
1750+ else if (pg_strcasecmp (cmd ,"sleep" )== 0 )
1751+ mc = META_SLEEP ;
1752+ else
1753+ mc = META_NONE ;
1754+ return mc ;
1755+ }
1756+
17241757/*
17251758 * Run a shell command. The result is assigned to the variable if not NULL.
17261759 * Return true if succeeded, or false on error.
@@ -2214,7 +2247,7 @@ doCustom(TState *thread, CState *st, StatsData *agg)
22142247fprintf (stderr ,"\n" );
22152248}
22162249
2217- if (pg_strcasecmp ( argv [ 0 ], "sleep" ) == 0 )
2250+ if (command -> meta == META_SLEEP )
22182251{
22192252/*
22202253 * A \sleep doesn't execute anything, we just get the
@@ -2240,7 +2273,7 @@ doCustom(TState *thread, CState *st, StatsData *agg)
22402273}
22412274else
22422275{
2243- if (pg_strcasecmp ( argv [ 0 ], "set" ) == 0 )
2276+ if (command -> meta == META_SET )
22442277{
22452278PgBenchExpr * expr = command -> expr ;
22462279PgBenchValue result ;
@@ -2259,7 +2292,7 @@ doCustom(TState *thread, CState *st, StatsData *agg)
22592292break ;
22602293}
22612294}
2262- else if (pg_strcasecmp ( argv [ 0 ], "setshell" ) == 0 )
2295+ else if (command -> meta == META_SETSHELL )
22632296{
22642297bool ret = runShellCommand (st ,argv [1 ],argv + 2 ,argc - 2 );
22652298
@@ -2279,7 +2312,7 @@ doCustom(TState *thread, CState *st, StatsData *agg)
22792312/* succeeded */
22802313}
22812314}
2282- else if (pg_strcasecmp ( argv [ 0 ], "shell" ) == 0 )
2315+ else if (command -> meta == META_SHELL )
22832316{
22842317bool ret = runShellCommand (st ,NULL ,argv + 1 ,argc - 1 );
22852318
@@ -3023,6 +3056,7 @@ process_sql_command(PQExpBuffer buf, const char *source)
30233056my_command = (Command * )pg_malloc0 (sizeof (Command ));
30243057my_command -> command_num = num_commands ++ ;
30253058my_command -> type = SQL_COMMAND ;
3059+ my_command -> meta = META_NONE ;
30263060initSimpleStats (& my_command -> stats );
30273061
30283062/*
@@ -3091,7 +3125,10 @@ process_backslash_command(PsqlScanState sstate, const char *source)
30913125my_command -> argv [j ++ ]= pg_strdup (word_buf .data );
30923126my_command -> argc ++ ;
30933127
3094- if (pg_strcasecmp (my_command -> argv [0 ],"set" )== 0 )
3128+ /* ... and convert it to enum form */
3129+ my_command -> meta = getMetaCommand (my_command -> argv [0 ]);
3130+
3131+ if (my_command -> meta == META_SET )
30953132{
30963133/* For \set, collect var name, then lex the expression. */
30973134yyscan_t yyscanner ;
@@ -3146,7 +3183,7 @@ process_backslash_command(PsqlScanState sstate, const char *source)
31463183expr_scanner_offset (sstate ),
31473184 true);
31483185
3149- if (pg_strcasecmp ( my_command -> argv [ 0 ], "sleep" ) == 0 )
3186+ if (my_command -> meta == META_SLEEP )
31503187{
31513188if (my_command -> argc < 2 )
31523189syntax_error (source ,lineno ,my_command -> line ,my_command -> argv [0 ],
@@ -3187,20 +3224,21 @@ process_backslash_command(PsqlScanState sstate, const char *source)
31873224my_command -> argv [2 ],offsets [2 ]- start_offset );
31883225}
31893226}
3190- else if (pg_strcasecmp ( my_command -> argv [ 0 ], "setshell" ) == 0 )
3227+ else if (my_command -> meta == META_SETSHELL )
31913228{
31923229if (my_command -> argc < 3 )
31933230syntax_error (source ,lineno ,my_command -> line ,my_command -> argv [0 ],
31943231"missing argument" ,NULL ,-1 );
31953232}
3196- else if (pg_strcasecmp ( my_command -> argv [ 0 ], "shell" ) == 0 )
3233+ else if (my_command -> meta == META_SHELL )
31973234{
31983235if (my_command -> argc < 2 )
31993236syntax_error (source ,lineno ,my_command -> line ,my_command -> argv [0 ],
32003237"missing command" ,NULL ,-1 );
32013238}
32023239else
32033240{
3241+ /* my_command->meta == META_NONE */
32043242syntax_error (source ,lineno ,my_command -> line ,my_command -> argv [0 ],
32053243"invalid command" ,NULL ,-1 );
32063244}
@@ -4592,12 +4630,12 @@ threadRun(void *arg)
45924630timeout .tv_usec = min_usec %1000000 ;
45934631nsocks = select (maxsock + 1 ,& input_mask ,NULL ,NULL ,& timeout );
45944632}
4595- else /* nothing active, simple sleep */
4633+ else /* nothing active, simple sleep */
45964634{
45974635pg_usleep (min_usec );
45984636}
45994637}
4600- else /* no explicit delay, select without timeout */
4638+ else /* no explicit delay, select without timeout */
46014639{
46024640nsocks = select (maxsock + 1 ,& input_mask ,NULL ,NULL ,NULL );
46034641}
@@ -4614,8 +4652,10 @@ threadRun(void *arg)
46144652gotodone ;
46154653}
46164654}
4617- else /* min_usec == 0, i.e. something needs to be executed */
4655+ else
46184656{
4657+ /* min_usec == 0, i.e. something needs to be executed */
4658+
46194659/* If we didn't call select(), don't try to read any data */
46204660FD_ZERO (& input_mask );
46214661}