mirror of
https://github.com/postgres/postgres.git
synced 2025-05-11 05:41:32 +03:00
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
This commit is contained in:
parent
a51cc7e9e6
commit
9938d11633
@ -607,8 +607,8 @@ static void setIntValue(PgBenchValue *pv, int64 ival);
|
|||||||
static void setDoubleValue(PgBenchValue *pv, double dval);
|
static void setDoubleValue(PgBenchValue *pv, double dval);
|
||||||
static bool evaluateExpr(TState *thread, CState *st, PgBenchExpr *expr,
|
static bool evaluateExpr(TState *thread, CState *st, PgBenchExpr *expr,
|
||||||
PgBenchValue *retval);
|
PgBenchValue *retval);
|
||||||
static instr_time doExecuteCommand(TState *thread, CState *st,
|
static ConnectionStateEnum executeMetaCommand(TState *thread, CState *st,
|
||||||
instr_time now);
|
instr_time *now);
|
||||||
static void doLog(TState *thread, CState *st,
|
static void doLog(TState *thread, CState *st,
|
||||||
StatsData *agg, bool skipped, double latency, double lag);
|
StatsData *agg, bool skipped, double latency, double lag);
|
||||||
static void processXactStats(TState *thread, CState *st, instr_time *now,
|
static void processXactStats(TState *thread, CState *st, instr_time *now,
|
||||||
@ -3012,6 +3012,8 @@ advanceConnectionState(TState *thread, CState *st, StatsData *agg)
|
|||||||
*/
|
*/
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
Command *command;
|
||||||
|
|
||||||
switch (st->state)
|
switch (st->state)
|
||||||
{
|
{
|
||||||
/* Select transaction (script) to run. */
|
/* Select transaction (script) to run. */
|
||||||
@ -3151,8 +3153,10 @@ advanceConnectionState(TState *thread, CState *st, StatsData *agg)
|
|||||||
* Send a command to server (or execute a meta-command)
|
* Send a command to server (or execute a meta-command)
|
||||||
*/
|
*/
|
||||||
case CSTATE_START_COMMAND:
|
case CSTATE_START_COMMAND:
|
||||||
|
command = sql_script[st->use_file].commands[st->command];
|
||||||
|
|
||||||
/* Transition to script end processing if done */
|
/* Transition to script end processing if done */
|
||||||
if (sql_script[st->use_file].commands[st->command] == NULL)
|
if (command == NULL)
|
||||||
{
|
{
|
||||||
st->state = CSTATE_END_TX;
|
st->state = CSTATE_END_TX;
|
||||||
break;
|
break;
|
||||||
@ -3164,7 +3168,28 @@ advanceConnectionState(TState *thread, CState *st, StatsData *agg)
|
|||||||
INSTR_TIME_SET_CURRENT_LAZY(now);
|
INSTR_TIME_SET_CURRENT_LAZY(now);
|
||||||
st->stmt_begin = now;
|
st->stmt_begin = now;
|
||||||
}
|
}
|
||||||
now = doExecuteCommand(thread, st, now);
|
|
||||||
|
/* Execute the command */
|
||||||
|
if (command->type == SQL_COMMAND)
|
||||||
|
{
|
||||||
|
if (!sendCommand(st, command))
|
||||||
|
{
|
||||||
|
commandFailed(st, "SQL", "SQL command send failed");
|
||||||
|
st->state = CSTATE_ABORTED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
st->state = CSTATE_WAIT_RESULT;
|
||||||
|
}
|
||||||
|
else if (command->type == META_COMMAND)
|
||||||
|
{
|
||||||
|
/*-----
|
||||||
|
* Possible state changes when executing meta commands:
|
||||||
|
* - on errors CSTATE_ABORTED
|
||||||
|
* - on sleep CSTATE_SLEEP
|
||||||
|
* - else CSTATE_END_COMMAND
|
||||||
|
*/
|
||||||
|
st->state = executeMetaCommand(thread, st, &now);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We're now waiting for an SQL command to complete, or
|
* We're now waiting for an SQL command to complete, or
|
||||||
@ -3237,7 +3262,8 @@ advanceConnectionState(TState *thread, CState *st, StatsData *agg)
|
|||||||
case IFSTATE_IGNORED:
|
case IFSTATE_IGNORED:
|
||||||
case IFSTATE_ELSE_FALSE:
|
case IFSTATE_ELSE_FALSE:
|
||||||
if (command->meta == META_IF)
|
if (command->meta == META_IF)
|
||||||
conditional_stack_push(st->cstack, IFSTATE_IGNORED);
|
conditional_stack_push(st->cstack,
|
||||||
|
IFSTATE_IGNORED);
|
||||||
else if (command->meta == META_ENDIF)
|
else if (command->meta == META_ENDIF)
|
||||||
{
|
{
|
||||||
Assert(!conditional_stack_empty(st->cstack));
|
Assert(!conditional_stack_empty(st->cstack));
|
||||||
@ -3387,36 +3413,27 @@ advanceConnectionState(TState *thread, CState *st, StatsData *agg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Subroutine for advanceConnectionState -- execute or initiate the current
|
* Subroutine for advanceConnectionState -- initiate or execute the current
|
||||||
* command, and transition to next state appropriately.
|
* meta command, and return the next state to set.
|
||||||
*
|
*
|
||||||
* Returns an updated timestamp from 'now', used to update 'now' at callsite.
|
* *now is updated to the current time, unless the command is expected to
|
||||||
|
* take no time to execute.
|
||||||
*/
|
*/
|
||||||
static instr_time
|
static ConnectionStateEnum
|
||||||
doExecuteCommand(TState *thread, CState *st, instr_time now)
|
executeMetaCommand(TState *thread, CState *st, instr_time *now)
|
||||||
{
|
{
|
||||||
Command *command = sql_script[st->use_file].commands[st->command];
|
Command *command = sql_script[st->use_file].commands[st->command];
|
||||||
|
int argc;
|
||||||
|
char **argv;
|
||||||
|
|
||||||
/* execute the command */
|
Assert(command != NULL && command->type == META_COMMAND);
|
||||||
if (command->type == SQL_COMMAND)
|
|
||||||
{
|
argc = command->argc;
|
||||||
if (!sendCommand(st, command))
|
argv = command->argv;
|
||||||
{
|
|
||||||
commandFailed(st, "SQL", "SQL command send failed");
|
|
||||||
st->state = CSTATE_ABORTED;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
st->state = CSTATE_WAIT_RESULT;
|
|
||||||
}
|
|
||||||
else if (command->type == META_COMMAND)
|
|
||||||
{
|
|
||||||
int argc = command->argc;
|
|
||||||
char **argv = command->argv;
|
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "client %d executing \\%s",
|
fprintf(stderr, "client %d executing \\%s", st->id, argv[0]);
|
||||||
st->id, argv[0]);
|
|
||||||
for (int i = 1; i < argc; i++)
|
for (int i = 1; i < argc; i++)
|
||||||
fprintf(stderr, " %s", argv[i]);
|
fprintf(stderr, " %s", argv[i]);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
@ -3427,23 +3444,20 @@ doExecuteCommand(TState *thread, CState *st, instr_time now)
|
|||||||
int usec;
|
int usec;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A \sleep doesn't execute anything, we just get the delay from
|
* A \sleep doesn't execute anything, we just get the delay from the
|
||||||
* the argument, and enter the CSTATE_SLEEP state. (The
|
* argument, and enter the CSTATE_SLEEP state. (The per-command
|
||||||
* per-command latency will be recorded in CSTATE_SLEEP state, not
|
* latency will be recorded in CSTATE_SLEEP state, not here, after the
|
||||||
* here, after the delay has elapsed.)
|
* delay has elapsed.)
|
||||||
*/
|
*/
|
||||||
if (!evaluateSleep(st, argc, argv, &usec))
|
if (!evaluateSleep(st, argc, argv, &usec))
|
||||||
{
|
{
|
||||||
commandFailed(st, "sleep", "execution of meta-command failed");
|
commandFailed(st, "sleep", "execution of meta-command failed");
|
||||||
st->state = CSTATE_ABORTED;
|
return CSTATE_ABORTED;
|
||||||
return now;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
INSTR_TIME_SET_CURRENT_LAZY(now);
|
INSTR_TIME_SET_CURRENT_LAZY(*now);
|
||||||
|
st->sleep_until = INSTR_TIME_GET_MICROSEC(*now) + usec;
|
||||||
st->sleep_until = INSTR_TIME_GET_MICROSEC(now) + usec;
|
return CSTATE_SLEEP;
|
||||||
st->state = CSTATE_SLEEP;
|
|
||||||
return now;
|
|
||||||
}
|
}
|
||||||
else if (command->meta == META_SET)
|
else if (command->meta == META_SET)
|
||||||
{
|
{
|
||||||
@ -3453,15 +3467,13 @@ doExecuteCommand(TState *thread, CState *st, instr_time now)
|
|||||||
if (!evaluateExpr(thread, st, expr, &result))
|
if (!evaluateExpr(thread, st, expr, &result))
|
||||||
{
|
{
|
||||||
commandFailed(st, argv[0], "evaluation of meta-command failed");
|
commandFailed(st, argv[0], "evaluation of meta-command failed");
|
||||||
st->state = CSTATE_ABORTED;
|
return CSTATE_ABORTED;
|
||||||
return now;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!putVariableValue(st, argv[0], argv[1], &result))
|
if (!putVariableValue(st, argv[0], argv[1], &result))
|
||||||
{
|
{
|
||||||
commandFailed(st, "set", "assignment of meta-command failed");
|
commandFailed(st, "set", "assignment of meta-command failed");
|
||||||
st->state = CSTATE_ABORTED;
|
return CSTATE_ABORTED;
|
||||||
return now;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (command->meta == META_IF)
|
else if (command->meta == META_IF)
|
||||||
@ -3474,8 +3486,7 @@ doExecuteCommand(TState *thread, CState *st, instr_time now)
|
|||||||
if (!evaluateExpr(thread, st, expr, &result))
|
if (!evaluateExpr(thread, st, expr, &result))
|
||||||
{
|
{
|
||||||
commandFailed(st, argv[0], "evaluation of meta-command failed");
|
commandFailed(st, argv[0], "evaluation of meta-command failed");
|
||||||
st->state = CSTATE_ABORTED;
|
return CSTATE_ABORTED;
|
||||||
return now;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cond = valueTruth(&result);
|
cond = valueTruth(&result);
|
||||||
@ -3490,19 +3501,15 @@ doExecuteCommand(TState *thread, CState *st, instr_time now)
|
|||||||
|
|
||||||
if (conditional_stack_peek(st->cstack) == IFSTATE_TRUE)
|
if (conditional_stack_peek(st->cstack) == IFSTATE_TRUE)
|
||||||
{
|
{
|
||||||
/*
|
/* elif after executed block, skip eval and wait for endif. */
|
||||||
* elif after executed block, skip eval and wait for endif.
|
|
||||||
*/
|
|
||||||
conditional_stack_poke(st->cstack, IFSTATE_IGNORED);
|
conditional_stack_poke(st->cstack, IFSTATE_IGNORED);
|
||||||
st->state = CSTATE_END_COMMAND;
|
return CSTATE_END_COMMAND;
|
||||||
return now;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!evaluateExpr(thread, st, expr, &result))
|
if (!evaluateExpr(thread, st, expr, &result))
|
||||||
{
|
{
|
||||||
commandFailed(st, argv[0], "evaluation of meta-command failed");
|
commandFailed(st, argv[0], "evaluation of meta-command failed");
|
||||||
st->state = CSTATE_ABORTED;
|
return CSTATE_ABORTED;
|
||||||
return now;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cond = valueTruth(&result);
|
cond = valueTruth(&result);
|
||||||
@ -3536,8 +3543,7 @@ doExecuteCommand(TState *thread, CState *st, instr_time now)
|
|||||||
if (!runShellCommand(st, argv[1], argv + 2, argc - 2))
|
if (!runShellCommand(st, argv[1], argv + 2, argc - 2))
|
||||||
{
|
{
|
||||||
commandFailed(st, "setshell", "execution of meta-command failed");
|
commandFailed(st, "setshell", "execution of meta-command failed");
|
||||||
st->state = CSTATE_ABORTED;
|
return CSTATE_ABORTED;
|
||||||
return now;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (command->meta == META_SHELL)
|
else if (command->meta == META_SHELL)
|
||||||
@ -3545,8 +3551,7 @@ doExecuteCommand(TState *thread, CState *st, instr_time now)
|
|||||||
if (!runShellCommand(st, NULL, argv + 1, argc - 1))
|
if (!runShellCommand(st, NULL, argv + 1, argc - 1))
|
||||||
{
|
{
|
||||||
commandFailed(st, "shell", "execution of meta-command failed");
|
commandFailed(st, "shell", "execution of meta-command failed");
|
||||||
st->state = CSTATE_ABORTED;
|
return CSTATE_ABORTED;
|
||||||
return now;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3554,12 +3559,9 @@ doExecuteCommand(TState *thread, CState *st, instr_time now)
|
|||||||
* executing the expression or shell command might have taken a
|
* executing the expression or shell command might have taken a
|
||||||
* non-negligible amount of time, so reset 'now'
|
* non-negligible amount of time, so reset 'now'
|
||||||
*/
|
*/
|
||||||
INSTR_TIME_SET_ZERO(now);
|
INSTR_TIME_SET_ZERO(*now);
|
||||||
|
|
||||||
st->state = CSTATE_END_COMMAND;
|
return CSTATE_END_COMMAND;
|
||||||
}
|
|
||||||
|
|
||||||
return now;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -4281,6 +4283,7 @@ free_command(Command *command)
|
|||||||
pg_free(command->argv[i]);
|
pg_free(command->argv[i]);
|
||||||
if (command->varprefix)
|
if (command->varprefix)
|
||||||
pg_free(command->varprefix);
|
pg_free(command->varprefix);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* It should also free expr recursively, but this is currently not needed
|
* It should also free expr recursively, but this is currently not needed
|
||||||
* as only gset commands (which do not have an expression) are freed.
|
* as only gset commands (which do not have an expression) are freed.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user