Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit914611e

Browse files
committed
Fix missed cases in libpq's error handling.
Commit618c167 invented an "error_result" flag in PGconn, whichintends to represent the state that we have an error condition andneed to build a PGRES_FATAL_ERROR PGresult from the message text inconn->errorMessage, but have not yet done so. (Postponing constructionof the error object simplifies dealing with out-of-memory conditionsand with concatenation of messages for multiple errors.) For nearly allpurposes, this "virtual" PGresult object should act the same as if itwere already materialized. But a couple of places in fe-protocol3.cdidn't get that memo, and were only testing conn->result as they usedto, without also checking conn->error_result.In hopes of reducing the probability of similar mistakes in future,I invented a pgHavePendingResult() macro that includes both tests.Per report from Peter Eisentraut.Discussion:https://postgr.es/m/b52277b9-fa66-b027-4a37-fb8989c73ff8@enterprisedb.com
1 parent2cb1272 commit914611e

File tree

3 files changed

+16
-7
lines changed

3 files changed

+16
-7
lines changed

‎src/interfaces/libpq/fe-exec.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1196,6 +1196,7 @@ pqSaveParameterStatus(PGconn *conn, const char *name, const char *value)
11961196
* Returns 1 if OK, 0 if error occurred.
11971197
*
11981198
* On error, *errmsgp can be set to an error string to be returned.
1199+
* (Such a string should already be translated via libpq_gettext().)
11991200
* If it is left NULL, the error is presumed to be "out of memory".
12001201
*
12011202
* In single-row mode, we create a new result holding just the current row,
@@ -1986,7 +1987,7 @@ PQsetSingleRowMode(PGconn *conn)
19861987
(conn->cmd_queue_head->queryclass!=PGQUERY_SIMPLE&&
19871988
conn->cmd_queue_head->queryclass!=PGQUERY_EXTENDED))
19881989
return0;
1989-
if (conn->result||conn->error_result)
1990+
if (pgHavePendingResult(conn))
19901991
return0;
19911992

19921993
/* OK, set flag */
@@ -2941,7 +2942,7 @@ PQfn(PGconn *conn,
29412942
}
29422943

29432944
if (conn->sock==PGINVALID_SOCKET||conn->asyncStatus!=PGASYNC_IDLE||
2944-
conn->result||conn->error_result)
2945+
pgHavePendingResult(conn))
29452946
{
29462947
appendPQExpBufferStr(&conn->errorMessage,
29472948
libpq_gettext("connection in wrong state\n"));

‎src/interfaces/libpq/fe-protocol3.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ pqParseInput3(PGconn *conn)
209209
case'C':/* command complete */
210210
if (pqGets(&conn->workBuffer,conn))
211211
return;
212-
if (conn->result==NULL)
212+
if (!pgHavePendingResult(conn))
213213
{
214214
conn->result=PQmakeEmptyPGresult(conn,
215215
PGRES_COMMAND_OK);
@@ -263,7 +263,7 @@ pqParseInput3(PGconn *conn)
263263
}
264264
break;
265265
case'I':/* empty query */
266-
if (conn->result==NULL)
266+
if (!pgHavePendingResult(conn))
267267
{
268268
conn->result=PQmakeEmptyPGresult(conn,
269269
PGRES_EMPTY_QUERY);
@@ -281,7 +281,7 @@ pqParseInput3(PGconn *conn)
281281
if (conn->cmd_queue_head&&
282282
conn->cmd_queue_head->queryclass==PGQUERY_PREPARE)
283283
{
284-
if (conn->result==NULL)
284+
if (!pgHavePendingResult(conn))
285285
{
286286
conn->result=PQmakeEmptyPGresult(conn,
287287
PGRES_COMMAND_OK);
@@ -362,7 +362,7 @@ pqParseInput3(PGconn *conn)
362362
if (conn->cmd_queue_head&&
363363
conn->cmd_queue_head->queryclass==PGQUERY_DESCRIBE)
364364
{
365-
if (conn->result==NULL)
365+
if (!pgHavePendingResult(conn))
366366
{
367367
conn->result=PQmakeEmptyPGresult(conn,
368368
PGRES_COMMAND_OK);
@@ -2133,7 +2133,7 @@ pqFunctionCall3(PGconn *conn, Oid fnid,
21332133
* report COMMAND_OK. Otherwise, the backend violated the
21342134
* protocol, so complain.
21352135
*/
2136-
if (!(conn->result||conn->error_result))
2136+
if (!pgHavePendingResult(conn))
21372137
{
21382138
if (status==PGRES_COMMAND_OK)
21392139
{

‎src/interfaces/libpq/libpq-int.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,14 @@ extern void pqTraceOutputNoTypeByteMessage(PGconn *conn, const char *message);
852852
(resetPQExpBuffer(&(conn)->errorMessage), \
853853
(conn)->errorReported = 0)
854854

855+
/*
856+
* Check whether we have a PGresult pending to be returned --- either a
857+
* constructed one in conn->result, or a "virtual" error result that we
858+
* don't intend to materialize until the end of the query cycle.
859+
*/
860+
#definepgHavePendingResult(conn) \
861+
((conn)->result != NULL || (conn)->error_result)
862+
855863
/*
856864
* this is so that we can check if a connection is non-blocking internally
857865
* without the overhead of a function call

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp