Skip to content

Commit 9938d11

Browse files
committed
pgbench: doExecuteCommand -> executeMetaCommand
The new function is only in charge of meta commands, not SQL commands. This change makes the code a little clearer: now all the state changes are effected by advanceConnectionState. It also removes one indent level, which makes the diff look bulkier than it really is. Author: Fabien Coelho Reviewed-by: Kirk Jamison Discussion: https://postgr.es/m/alpine.DEB.2.21.1811240904500.12627@lancre
1 parent a51cc7e commit 9938d11

File tree

1 file changed

+151
-148
lines changed

1 file changed

+151
-148
lines changed

src/bin/pgbench/pgbench.c

Lines changed: 151 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -607,8 +607,8 @@ static void setIntValue(PgBenchValue *pv, int64 ival);
607607
static void setDoubleValue(PgBenchValue *pv, double dval);
608608
static bool evaluateExpr(TState *thread, CState *st, PgBenchExpr *expr,
609609
PgBenchValue *retval);
610-
static instr_time doExecuteCommand(TState *thread, CState *st,
611-
instr_time now);
610+
static ConnectionStateEnum executeMetaCommand(TState *thread, CState *st,
611+
instr_time *now);
612612
static void doLog(TState *thread, CState *st,
613613
StatsData *agg, bool skipped, double latency, double lag);
614614
static void processXactStats(TState *thread, CState *st, instr_time *now,
@@ -802,7 +802,7 @@ strtoint64(const char *str, bool errorOK, int64 *result)
802802
invalid_syntax:
803803
if (!errorOK)
804804
fprintf(stderr,
805-
"invalid input syntax for type bigint: \"%s\"\n",str);
805+
"invalid input syntax for type bigint: \"%s\"\n", str);
806806
return false;
807807
}
808808

@@ -827,7 +827,7 @@ strtodouble(const char *str, bool errorOK, double *dv)
827827
{
828828
if (!errorOK)
829829
fprintf(stderr,
830-
"invalid input syntax for type double: \"%s\"\n",str);
830+
"invalid input syntax for type double: \"%s\"\n", str);
831831
return false;
832832
}
833833
return true;
@@ -3012,6 +3012,8 @@ advanceConnectionState(TState *thread, CState *st, StatsData *agg)
30123012
*/
30133013
for (;;)
30143014
{
3015+
Command *command;
3016+
30153017
switch (st->state)
30163018
{
30173019
/* Select transaction (script) to run. */
@@ -3151,8 +3153,10 @@ advanceConnectionState(TState *thread, CState *st, StatsData *agg)
31513153
* Send a command to server (or execute a meta-command)
31523154
*/
31533155
case CSTATE_START_COMMAND:
3156+
command = sql_script[st->use_file].commands[st->command];
3157+
31543158
/* Transition to script end processing if done */
3155-
if (sql_script[st->use_file].commands[st->command] == NULL)
3159+
if (command == NULL)
31563160
{
31573161
st->state = CSTATE_END_TX;
31583162
break;
@@ -3164,7 +3168,28 @@ advanceConnectionState(TState *thread, CState *st, StatsData *agg)
31643168
INSTR_TIME_SET_CURRENT_LAZY(now);
31653169
st->stmt_begin = now;
31663170
}
3167-
now = doExecuteCommand(thread, st, now);
3171+
3172+
/* Execute the command */
3173+
if (command->type == SQL_COMMAND)
3174+
{
3175+
if (!sendCommand(st, command))
3176+
{
3177+
commandFailed(st, "SQL", "SQL command send failed");
3178+
st->state = CSTATE_ABORTED;
3179+
}
3180+
else
3181+
st->state = CSTATE_WAIT_RESULT;
3182+
}
3183+
else if (command->type == META_COMMAND)
3184+
{
3185+
/*-----
3186+
* Possible state changes when executing meta commands:
3187+
* - on errors CSTATE_ABORTED
3188+
* - on sleep CSTATE_SLEEP
3189+
* - else CSTATE_END_COMMAND
3190+
*/
3191+
st->state = executeMetaCommand(thread, st, &now);
3192+
}
31683193

31693194
/*
31703195
* We're now waiting for an SQL command to complete, or
@@ -3237,7 +3262,8 @@ advanceConnectionState(TState *thread, CState *st, StatsData *agg)
32373262
case IFSTATE_IGNORED:
32383263
case IFSTATE_ELSE_FALSE:
32393264
if (command->meta == META_IF)
3240-
conditional_stack_push(st->cstack, IFSTATE_IGNORED);
3265+
conditional_stack_push(st->cstack,
3266+
IFSTATE_IGNORED);
32413267
else if (command->meta == META_ENDIF)
32423268
{
32433269
Assert(!conditional_stack_empty(st->cstack));
@@ -3387,179 +3413,155 @@ advanceConnectionState(TState *thread, CState *st, StatsData *agg)
33873413
}
33883414

33893415
/*
3390-
* Subroutine for advanceConnectionState -- execute or initiate the current
3391-
* command, and transition to next state appropriately.
3416+
* Subroutine for advanceConnectionState -- initiate or execute the current
3417+
* meta command, and return the next state to set.
33923418
*
3393-
* Returns an updated timestamp from 'now', used to update 'now' at callsite.
3419+
* *now is updated to the current time, unless the command is expected to
3420+
* take no time to execute.
33943421
*/
3395-
static instr_time
3396-
doExecuteCommand(TState *thread, CState *st, instr_time now)
3422+
static ConnectionStateEnum
3423+
executeMetaCommand(TState *thread, CState *st, instr_time *now)
33973424
{
33983425
Command *command = sql_script[st->use_file].commands[st->command];
3426+
int argc;
3427+
char **argv;
3428+
3429+
Assert(command != NULL && command->type == META_COMMAND);
33993430

3400-
/* execute the command */
3401-
if (command->type == SQL_COMMAND)
3431+
argc = command->argc;
3432+
argv = command->argv;
3433+
3434+
if (debug)
34023435
{
3403-
if (!sendCommand(st, command))
3436+
fprintf(stderr, "client %d executing \\%s", st->id, argv[0]);
3437+
for (int i = 1; i < argc; i++)
3438+
fprintf(stderr, " %s", argv[i]);
3439+
fprintf(stderr, "\n");
3440+
}
3441+
3442+
if (command->meta == META_SLEEP)
3443+
{
3444+
int usec;
3445+
3446+
/*
3447+
* A \sleep doesn't execute anything, we just get the delay from the
3448+
* argument, and enter the CSTATE_SLEEP state. (The per-command
3449+
* latency will be recorded in CSTATE_SLEEP state, not here, after the
3450+
* delay has elapsed.)
3451+
*/
3452+
if (!evaluateSleep(st, argc, argv, &usec))
34043453
{
3405-
commandFailed(st, "SQL", "SQL command send failed");
3406-
st->state = CSTATE_ABORTED;
3454+
commandFailed(st, "sleep", "execution of meta-command failed");
3455+
return CSTATE_ABORTED;
34073456
}
3408-
else
3409-
st->state = CSTATE_WAIT_RESULT;
3457+
3458+
INSTR_TIME_SET_CURRENT_LAZY(*now);
3459+
st->sleep_until = INSTR_TIME_GET_MICROSEC(*now) + usec;
3460+
return CSTATE_SLEEP;
34103461
}
3411-
else if (command->type == META_COMMAND)
3462+
else if (command->meta == META_SET)
34123463
{
3413-
int argc = command->argc;
3414-
char **argv = command->argv;
3464+
PgBenchExpr *expr = command->expr;
3465+
PgBenchValue result;
34153466

3416-
if (debug)
3467+
if (!evaluateExpr(thread, st, expr, &result))
34173468
{
3418-
fprintf(stderr, "client %d executing \\%s",
3419-
st->id, argv[0]);
3420-
for (int i = 1; i < argc; i++)
3421-
fprintf(stderr, " %s", argv[i]);
3422-
fprintf(stderr, "\n");
3469+
commandFailed(st, argv[0], "evaluation of meta-command failed");
3470+
return CSTATE_ABORTED;
34233471
}
34243472

3425-
if (command->meta == META_SLEEP)
3473+
if (!putVariableValue(st, argv[0], argv[1], &result))
34263474
{
3427-
int usec;
3428-
3429-
/*
3430-
* A \sleep doesn't execute anything, we just get the delay from
3431-
* the argument, and enter the CSTATE_SLEEP state. (The
3432-
* per-command latency will be recorded in CSTATE_SLEEP state, not
3433-
* here, after the delay has elapsed.)
3434-
*/
3435-
if (!evaluateSleep(st, argc, argv, &usec))
3436-
{
3437-
commandFailed(st, "sleep", "execution of meta-command failed");
3438-
st->state = CSTATE_ABORTED;
3439-
return now;
3440-
}
3441-
3442-
INSTR_TIME_SET_CURRENT_LAZY(now);
3443-
3444-
st->sleep_until = INSTR_TIME_GET_MICROSEC(now) + usec;
3445-
st->state = CSTATE_SLEEP;
3446-
return now;
3475+
commandFailed(st, "set", "assignment of meta-command failed");
3476+
return CSTATE_ABORTED;
34473477
}
3448-
else if (command->meta == META_SET)
3449-
{
3450-
PgBenchExpr *expr = command->expr;
3451-
PgBenchValue result;
3452-
3453-
if (!evaluateExpr(thread, st, expr, &result))
3454-
{
3455-
commandFailed(st, argv[0], "evaluation of meta-command failed");
3456-
st->state = CSTATE_ABORTED;
3457-
return now;
3458-
}
3478+
}
3479+
else if (command->meta == META_IF)
3480+
{
3481+
/* backslash commands with an expression to evaluate */
3482+
PgBenchExpr *expr = command->expr;
3483+
PgBenchValue result;
3484+
bool cond;
34593485

3460-
if (!putVariableValue(st, argv[0], argv[1], &result))
3461-
{
3462-
commandFailed(st, "set", "assignment of meta-command failed");
3463-
st->state = CSTATE_ABORTED;
3464-
return now;
3465-
}
3466-
}
3467-
else if (command->meta == META_IF)
3486+
if (!evaluateExpr(thread, st, expr, &result))
34683487
{
3469-
/* backslash commands with an expression to evaluate */
3470-
PgBenchExpr *expr = command->expr;
3471-
PgBenchValue result;
3472-
bool cond;
3473-
3474-
if (!evaluateExpr(thread, st, expr, &result))
3475-
{
3476-
commandFailed(st, argv[0], "evaluation of meta-command failed");
3477-
st->state = CSTATE_ABORTED;
3478-
return now;
3479-
}
3480-
3481-
cond = valueTruth(&result);
3482-
conditional_stack_push(st->cstack, cond ? IFSTATE_TRUE : IFSTATE_FALSE);
3488+
commandFailed(st, argv[0], "evaluation of meta-command failed");
3489+
return CSTATE_ABORTED;
34833490
}
3484-
else if (command->meta == META_ELIF)
3485-
{
3486-
/* backslash commands with an expression to evaluate */
3487-
PgBenchExpr *expr = command->expr;
3488-
PgBenchValue result;
3489-
bool cond;
34903491

3491-
if (conditional_stack_peek(st->cstack) == IFSTATE_TRUE)
3492-
{
3493-
/*
3494-
* elif after executed block, skip eval and wait for endif.
3495-
*/
3496-
conditional_stack_poke(st->cstack, IFSTATE_IGNORED);
3497-
st->state = CSTATE_END_COMMAND;
3498-
return now;
3499-
}
3500-
3501-
if (!evaluateExpr(thread, st, expr, &result))
3502-
{
3503-
commandFailed(st, argv[0], "evaluation of meta-command failed");
3504-
st->state = CSTATE_ABORTED;
3505-
return now;
3506-
}
3492+
cond = valueTruth(&result);
3493+
conditional_stack_push(st->cstack, cond ? IFSTATE_TRUE : IFSTATE_FALSE);
3494+
}
3495+
else if (command->meta == META_ELIF)
3496+
{
3497+
/* backslash commands with an expression to evaluate */
3498+
PgBenchExpr *expr = command->expr;
3499+
PgBenchValue result;
3500+
bool cond;
35073501

3508-
cond = valueTruth(&result);
3509-
Assert(conditional_stack_peek(st->cstack) == IFSTATE_FALSE);
3510-
conditional_stack_poke(st->cstack, cond ? IFSTATE_TRUE : IFSTATE_FALSE);
3502+
if (conditional_stack_peek(st->cstack) == IFSTATE_TRUE)
3503+
{
3504+
/* elif after executed block, skip eval and wait for endif. */
3505+
conditional_stack_poke(st->cstack, IFSTATE_IGNORED);
3506+
return CSTATE_END_COMMAND;
35113507
}
3512-
else if (command->meta == META_ELSE)
3508+
3509+
if (!evaluateExpr(thread, st, expr, &result))
35133510
{
3514-
switch (conditional_stack_peek(st->cstack))
3515-
{
3516-
case IFSTATE_TRUE:
3517-
conditional_stack_poke(st->cstack, IFSTATE_ELSE_FALSE);
3518-
break;
3519-
case IFSTATE_FALSE: /* inconsistent if active */
3520-
case IFSTATE_IGNORED: /* inconsistent if active */
3521-
case IFSTATE_NONE: /* else without if */
3522-
case IFSTATE_ELSE_TRUE: /* else after else */
3523-
case IFSTATE_ELSE_FALSE: /* else after else */
3524-
default:
3525-
/* dead code if conditional check is ok */
3526-
Assert(false);
3527-
}
3511+
commandFailed(st, argv[0], "evaluation of meta-command failed");
3512+
return CSTATE_ABORTED;
35283513
}
3529-
else if (command->meta == META_ENDIF)
3514+
3515+
cond = valueTruth(&result);
3516+
Assert(conditional_stack_peek(st->cstack) == IFSTATE_FALSE);
3517+
conditional_stack_poke(st->cstack, cond ? IFSTATE_TRUE : IFSTATE_FALSE);
3518+
}
3519+
else if (command->meta == META_ELSE)
3520+
{
3521+
switch (conditional_stack_peek(st->cstack))
35303522
{
3531-
Assert(!conditional_stack_empty(st->cstack));
3532-
conditional_stack_pop(st->cstack);
3523+
case IFSTATE_TRUE:
3524+
conditional_stack_poke(st->cstack, IFSTATE_ELSE_FALSE);
3525+
break;
3526+
case IFSTATE_FALSE: /* inconsistent if active */
3527+
case IFSTATE_IGNORED: /* inconsistent if active */
3528+
case IFSTATE_NONE: /* else without if */
3529+
case IFSTATE_ELSE_TRUE: /* else after else */
3530+
case IFSTATE_ELSE_FALSE: /* else after else */
3531+
default:
3532+
/* dead code if conditional check is ok */
3533+
Assert(false);
35333534
}
3534-
else if (command->meta == META_SETSHELL)
3535+
}
3536+
else if (command->meta == META_ENDIF)
3537+
{
3538+
Assert(!conditional_stack_empty(st->cstack));
3539+
conditional_stack_pop(st->cstack);
3540+
}
3541+
else if (command->meta == META_SETSHELL)
3542+
{
3543+
if (!runShellCommand(st, argv[1], argv + 2, argc - 2))
35353544
{
3536-
if (!runShellCommand(st, argv[1], argv + 2, argc - 2))
3537-
{
3538-
commandFailed(st, "setshell", "execution of meta-command failed");
3539-
st->state = CSTATE_ABORTED;
3540-
return now;
3541-
}
3545+
commandFailed(st, "setshell", "execution of meta-command failed");
3546+
return CSTATE_ABORTED;
35423547
}
3543-
else if (command->meta == META_SHELL)
3548+
}
3549+
else if (command->meta == META_SHELL)
3550+
{
3551+
if (!runShellCommand(st, NULL, argv + 1, argc - 1))
35443552
{
3545-
if (!runShellCommand(st, NULL, argv + 1, argc - 1))
3546-
{
3547-
commandFailed(st, "shell", "execution of meta-command failed");
3548-
st->state = CSTATE_ABORTED;
3549-
return now;
3550-
}
3553+
commandFailed(st, "shell", "execution of meta-command failed");
3554+
return CSTATE_ABORTED;
35513555
}
3552-
3553-
/*
3554-
* executing the expression or shell command might have taken a
3555-
* non-negligible amount of time, so reset 'now'
3556-
*/
3557-
INSTR_TIME_SET_ZERO(now);
3558-
3559-
st->state = CSTATE_END_COMMAND;
35603556
}
35613557

3562-
return now;
3558+
/*
3559+
* executing the expression or shell command might have taken a
3560+
* non-negligible amount of time, so reset 'now'
3561+
*/
3562+
INSTR_TIME_SET_ZERO(*now);
3563+
3564+
return CSTATE_END_COMMAND;
35633565
}
35643566

35653567
/*
@@ -4281,6 +4283,7 @@ free_command(Command *command)
42814283
pg_free(command->argv[i]);
42824284
if (command->varprefix)
42834285
pg_free(command->varprefix);
4286+
42844287
/*
42854288
* It should also free expr recursively, but this is currently not needed
42864289
* as only gset commands (which do not have an expression) are freed.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy