Commit fe0e0b4f authored by Alvaro Herrera's avatar Alvaro Herrera

Fix memory leak in pgbench

Commit 25ee7051 introduced a memory leak in pgbench: some PGresult
structs were not being freed during error bailout, because we're now
doing more PQgetResult() calls than previously.  Since there's more
cleanup code outside the discard_response() routine than in it, refactor
the cleanup code, removing the routine.

This has little effect currently, since we abandon processing after
hitting errors, but if we ever get further pgbench features (such as
testing for serializable transactions), it'll matter.

Per Coverity.

Reviewed-by: Michaël Paquier
parent a2418f9e
...@@ -1214,20 +1214,6 @@ doConnect(void) ...@@ -1214,20 +1214,6 @@ doConnect(void)
return conn; return conn;
} }
/* throw away response from backend */
static void
discard_response(CState *state)
{
PGresult *res;
do
{
res = PQgetResult(state->con);
if (res)
PQclear(res);
} while (res);
}
/* qsort comparator for Variable array */ /* qsort comparator for Variable array */
static int static int
compareVariableNames(const void *v1, const void *v2) compareVariableNames(const void *v1, const void *v2)
...@@ -2732,6 +2718,7 @@ static bool ...@@ -2732,6 +2718,7 @@ static bool
readCommandResponse(CState *st, char *varprefix) readCommandResponse(CState *st, char *varprefix)
{ {
PGresult *res; PGresult *res;
PGresult *next_res;
int qrynum = 0; int qrynum = 0;
res = PQgetResult(st->con); res = PQgetResult(st->con);
...@@ -2739,7 +2726,7 @@ readCommandResponse(CState *st, char *varprefix) ...@@ -2739,7 +2726,7 @@ readCommandResponse(CState *st, char *varprefix)
while (res != NULL) while (res != NULL)
{ {
/* look now at the next result to know whether it is the last */ /* look now at the next result to know whether it is the last */
PGresult *next_res = PQgetResult(st->con); next_res = PQgetResult(st->con);
bool is_last = (next_res == NULL); bool is_last = (next_res == NULL);
switch (PQresultStatus(res)) switch (PQresultStatus(res))
...@@ -2751,8 +2738,7 @@ readCommandResponse(CState *st, char *varprefix) ...@@ -2751,8 +2738,7 @@ readCommandResponse(CState *st, char *varprefix)
fprintf(stderr, fprintf(stderr,
"client %d script %d command %d query %d: expected one row, got %d\n", "client %d script %d command %d query %d: expected one row, got %d\n",
st->id, st->use_file, st->command, qrynum, 0); st->id, st->use_file, st->command, qrynum, 0);
st->ecnt++; goto error;
return false;
} }
break; break;
...@@ -2764,10 +2750,7 @@ readCommandResponse(CState *st, char *varprefix) ...@@ -2764,10 +2750,7 @@ readCommandResponse(CState *st, char *varprefix)
fprintf(stderr, fprintf(stderr,
"client %d script %d command %d query %d: expected one row, got %d\n", "client %d script %d command %d query %d: expected one row, got %d\n",
st->id, st->use_file, st->command, qrynum, PQntuples(res)); st->id, st->use_file, st->command, qrynum, PQntuples(res));
st->ecnt++; goto error;
PQclear(res);
discard_response(st);
return false;
} }
/* store results into variables */ /* store results into variables */
...@@ -2788,10 +2771,7 @@ readCommandResponse(CState *st, char *varprefix) ...@@ -2788,10 +2771,7 @@ readCommandResponse(CState *st, char *varprefix)
"client %d script %d command %d query %d: error storing into variable %s\n", "client %d script %d command %d query %d: error storing into variable %s\n",
st->id, st->use_file, st->command, qrynum, st->id, st->use_file, st->command, qrynum,
varname); varname);
st->ecnt++; goto error;
PQclear(res);
discard_response(st);
return false;
} }
if (*varprefix != '\0') if (*varprefix != '\0')
...@@ -2807,10 +2787,7 @@ readCommandResponse(CState *st, char *varprefix) ...@@ -2807,10 +2787,7 @@ readCommandResponse(CState *st, char *varprefix)
"client %d script %d aborted in command %d query %d: %s", "client %d script %d aborted in command %d query %d: %s",
st->id, st->use_file, st->command, qrynum, st->id, st->use_file, st->command, qrynum,
PQerrorMessage(st->con)); PQerrorMessage(st->con));
st->ecnt++; goto error;
PQclear(res);
discard_response(st);
return false;
} }
PQclear(res); PQclear(res);
...@@ -2826,8 +2803,19 @@ readCommandResponse(CState *st, char *varprefix) ...@@ -2826,8 +2803,19 @@ readCommandResponse(CState *st, char *varprefix)
} }
return true; return true;
}
error:
st->ecnt++;
PQclear(res);
PQclear(next_res);
do
{
res = PQgetResult(st->con);
PQclear(res);
} while (res);
return false;
}
/* /*
* Parse the argument to a \sleep command, and return the requested amount * Parse the argument to a \sleep command, and return the requested amount
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment