Fix pgbench in prepared mode with an empty pipeline

It crashes because it references memory that's not allocated in that
particular case.  Fix by allocating it.

Reported-by: Alexander Lakhin <exclusion@gmail.com>
Discussion: https://postgr.es/m/bcf802a6-afc1-95b9-7bf4-c5dd868ec144@gmail.com
This commit is contained in:
Alvaro Herrera 2023-05-25 12:36:18 +02:00
parent ecb968e7e3
commit 8f5e42d334
No known key found for this signature in database
GPG Key ID: 1C20ACB9D5C564AE
2 changed files with 28 additions and 18 deletions

View File

@ -3050,23 +3050,14 @@ chooseScript(TState *thread)
}
/*
* Prepare the SQL command from st->use_file at command_num.
* Allocate space for CState->prepared: we need one boolean for each command
* of each script.
*/
static void
prepareCommand(CState *st, int command_num)
allocCStatePrepared(CState *st)
{
Command *command = sql_script[st->use_file].commands[command_num];
Assert(st->prepared == NULL);
/* No prepare for non-SQL commands */
if (command->type != SQL_COMMAND)
return;
/*
* If not already done, allocate space for 'prepared' flags: one boolean
* for each command of each script.
*/
if (!st->prepared)
{
st->prepared = pg_malloc(sizeof(bool *) * num_scripts);
for (int i = 0; i < num_scripts; i++)
{
@ -3079,6 +3070,21 @@ prepareCommand(CState *st, int command_num)
}
}
/*
* Prepare the SQL command from st->use_file at command_num.
*/
static void
prepareCommand(CState *st, int command_num)
{
Command *command = sql_script[st->use_file].commands[command_num];
/* No prepare for non-SQL commands */
if (command->type != SQL_COMMAND)
return;
if (!st->prepared)
allocCStatePrepared(st);
if (!st->prepared[st->use_file][command_num])
{
PGresult *res;
@ -3109,13 +3115,15 @@ prepareCommandsInPipeline(CState *st)
Assert(commands[st->command]->type == META_COMMAND &&
commands[st->command]->meta == META_STARTPIPELINE);
if (!st->prepared)
allocCStatePrepared(st);
/*
* We set the 'prepared' flag on the \startpipeline itself to flag that we
* don't need to do this next time without calling prepareCommand(), even
* though we don't actually prepare this command.
*/
if (st->prepared &&
st->prepared[st->use_file][st->command])
if (st->prepared[st->use_file][st->command])
return;
for (j = st->command + 1; commands[j] != NULL; j++)

View File

@ -790,6 +790,8 @@ $node->pgbench(
'001_pgbench_pipeline_prep' => q{
-- test startpipeline
\startpipeline
\endpipeline
\startpipeline
} . "select 1;\n" x 10 . q{
\endpipeline
}