Skip to content

Commit 2ed193c

Browse files
committed
chomp PQerrorMessage() in backend uses
PQerrorMessage() returns an error message with a trailing newline, but in backend use (dblink, postgres_fdw, libpqwalreceiver), we want to have the error message without that for emitting via ereport(). To simplify that, add a function pchomp() that returns a pstrdup'ed string with the trailing newline characters removed.
1 parent 9fab40a commit 2ed193c

File tree

6 files changed

+40
-36
lines changed

6 files changed

+40
-36
lines changed

contrib/dblink/dblink.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ typedef struct remoteConnHashEnt
166166

167167
#define DBLINK_RES_INTERNALERROR(p2) \
168168
do { \
169-
msg = pstrdup(PQerrorMessage(conn)); \
169+
msg = pchomp(PQerrorMessage(conn)); \
170170
if (res) \
171171
PQclear(res); \
172172
elog(ERROR, "%s: %s", p2, msg); \
@@ -204,7 +204,7 @@ typedef struct remoteConnHashEnt
204204
conn = PQconnectdb(connstr); \
205205
if (PQstatus(conn) == CONNECTION_BAD) \
206206
{ \
207-
msg = pstrdup(PQerrorMessage(conn)); \
207+
msg = pchomp(PQerrorMessage(conn)); \
208208
PQfinish(conn); \
209209
ereport(ERROR, \
210210
(errcode(ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION), \
@@ -278,7 +278,7 @@ dblink_connect(PG_FUNCTION_ARGS)
278278

279279
if (PQstatus(conn) == CONNECTION_BAD)
280280
{
281-
msg = pstrdup(PQerrorMessage(conn));
281+
msg = pchomp(PQerrorMessage(conn));
282282
PQfinish(conn);
283283
if (rconn)
284284
pfree(rconn);
@@ -651,7 +651,7 @@ dblink_send_query(PG_FUNCTION_ARGS)
651651
/* async query send */
652652
retval = PQsendQuery(conn, sql);
653653
if (retval != 1)
654-
elog(NOTICE, "could not send query: %s", PQerrorMessage(conn));
654+
elog(NOTICE, "could not send query: %s", pchomp(PQerrorMessage(conn)));
655655

656656
PG_RETURN_INT32(retval);
657657
}
@@ -1087,7 +1087,7 @@ storeQueryResult(volatile storeInfo *sinfo, PGconn *conn, const char *sql)
10871087
PGresult *res;
10881088

10891089
if (!PQsendQuery(conn, sql))
1090-
elog(ERROR, "could not send query: %s", PQerrorMessage(conn));
1090+
elog(ERROR, "could not send query: %s", pchomp(PQerrorMessage(conn)));
10911091

10921092
if (!PQsetSingleRowMode(conn)) /* shouldn't fail */
10931093
elog(ERROR, "failed to set single-row mode for dblink query");
@@ -1370,7 +1370,7 @@ dblink_error_message(PG_FUNCTION_ARGS)
13701370
if (msg == NULL || msg[0] == '\0')
13711371
PG_RETURN_TEXT_P(cstring_to_text("OK"));
13721372
else
1373-
PG_RETURN_TEXT_P(cstring_to_text(msg));
1373+
PG_RETURN_TEXT_P(cstring_to_text(pchomp(msg)));
13741374
}
13751375

13761376
/*
@@ -2709,7 +2709,7 @@ dblink_res_error(PGconn *conn, const char *conname, PGresult *res,
27092709
* return NULL, not a PGresult at all.
27102710
*/
27112711
if (message_primary == NULL)
2712-
message_primary = PQerrorMessage(conn);
2712+
message_primary = pchomp(PQerrorMessage(conn));
27132713

27142714
if (res)
27152715
PQclear(res);

contrib/dblink/expected/dblink.out

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,6 @@ FROM dblink('myconn','SELECT * FROM foo') AS t(a int, b text, c text[])
377377
WHERE t.a > 7;
378378
ERROR: could not establish connection
379379
DETAIL: missing "=" after "myconn" in connection info string
380-
381380
-- create a named persistent connection
382381
SELECT dblink_connect('myconn',connection_parameters());
383382
dblink_connect
@@ -604,7 +603,6 @@ FROM dblink('myconn','SELECT * FROM foo') AS t(a int, b text, c text[])
604603
WHERE t.a > 7;
605604
ERROR: could not establish connection
606605
DETAIL: missing "=" after "myconn" in connection info string
607-
608606
-- create a named persistent connection
609607
SELECT dblink_connect('myconn',connection_parameters());
610608
dblink_connect

contrib/postgres_fdw/connection.c

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -226,21 +226,11 @@ connect_pg_server(ForeignServer *server, UserMapping *user)
226226

227227
conn = PQconnectdbParams(keywords, values, false);
228228
if (!conn || PQstatus(conn) != CONNECTION_OK)
229-
{
230-
char *connmessage;
231-
int msglen;
232-
233-
/* libpq typically appends a newline, strip that */
234-
connmessage = pstrdup(PQerrorMessage(conn));
235-
msglen = strlen(connmessage);
236-
if (msglen > 0 && connmessage[msglen - 1] == '\n')
237-
connmessage[msglen - 1] = '\0';
238229
ereport(ERROR,
239230
(errcode(ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION),
240231
errmsg("could not connect to server \"%s\"",
241232
server->servername),
242-
errdetail_internal("%s", connmessage)));
243-
}
233+
errdetail_internal("%s", pchomp(PQerrorMessage(conn)))));
244234

245235
/*
246236
* Check that non-superuser has used password to establish connection;
@@ -563,7 +553,7 @@ pgfdw_report_error(int elevel, PGresult *res, PGconn *conn,
563553
* return NULL, not a PGresult at all.
564554
*/
565555
if (message_primary == NULL)
566-
message_primary = PQerrorMessage(conn);
556+
message_primary = pchomp(PQerrorMessage(conn));
567557

568558
ereport(elevel,
569559
(errcode(sqlstate),

src/backend/replication/libpqwalreceiver/libpqwalreceiver.c

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ libpqrcv_connect(const char *conninfo, bool logical, const char *appname,
149149
conn->streamConn = PQconnectdbParams(keys, vals, /* expand_dbname = */ true);
150150
if (PQstatus(conn->streamConn) != CONNECTION_OK)
151151
{
152-
*err = pstrdup(PQerrorMessage(conn->streamConn));
152+
*err = pchomp(PQerrorMessage(conn->streamConn));
153153
return NULL;
154154
}
155155

@@ -247,7 +247,7 @@ libpqrcv_identify_system(WalReceiverConn *conn, TimeLineID *primary_tli,
247247
ereport(ERROR,
248248
(errmsg("could not receive database system identifier and timeline ID from "
249249
"the primary server: %s",
250-
PQerrorMessage(conn->streamConn))));
250+
pchomp(PQerrorMessage(conn->streamConn)))));
251251
}
252252
if (PQnfields(res) < 3 || PQntuples(res) != 1)
253253
{
@@ -324,13 +324,13 @@ libpqrcv_startstreaming(WalReceiverConn *conn,
324324
if (!pubnames_str)
325325
ereport(ERROR,
326326
(errmsg("could not start WAL streaming: %s",
327-
PQerrorMessage(conn->streamConn))));
327+
pchomp(PQerrorMessage(conn->streamConn)))));
328328
pubnames_literal = PQescapeLiteral(conn->streamConn, pubnames_str,
329329
strlen(pubnames_str));
330330
if (!pubnames_literal)
331331
ereport(ERROR,
332332
(errmsg("could not start WAL streaming: %s",
333-
PQerrorMessage(conn->streamConn))));
333+
pchomp(PQerrorMessage(conn->streamConn)))));
334334
appendStringInfo(&cmd, ", publication_names %s", pubnames_literal);
335335
PQfreemem(pubnames_literal);
336336
pfree(pubnames_str);
@@ -355,7 +355,7 @@ libpqrcv_startstreaming(WalReceiverConn *conn,
355355
PQclear(res);
356356
ereport(ERROR,
357357
(errmsg("could not start WAL streaming: %s",
358-
PQerrorMessage(conn->streamConn))));
358+
pchomp(PQerrorMessage(conn->streamConn)))));
359359
}
360360
PQclear(res);
361361
return true;
@@ -374,7 +374,7 @@ libpqrcv_endstreaming(WalReceiverConn *conn, TimeLineID *next_tli)
374374
PQflush(conn->streamConn))
375375
ereport(ERROR,
376376
(errmsg("could not send end-of-streaming message to primary: %s",
377-
PQerrorMessage(conn->streamConn))));
377+
pchomp(PQerrorMessage(conn->streamConn)))));
378378

379379
*next_tli = 0;
380380

@@ -418,15 +418,15 @@ libpqrcv_endstreaming(WalReceiverConn *conn, TimeLineID *next_tli)
418418
if (PQresultStatus(res) != PGRES_COMMAND_OK)
419419
ereport(ERROR,
420420
(errmsg("error reading result of streaming command: %s",
421-
PQerrorMessage(conn->streamConn))));
421+
pchomp(PQerrorMessage(conn->streamConn)))));
422422
PQclear(res);
423423

424424
/* Verify that there are no more results */
425425
res = PQgetResult(conn->streamConn);
426426
if (res != NULL)
427427
ereport(ERROR,
428428
(errmsg("unexpected result after CommandComplete: %s",
429-
PQerrorMessage(conn->streamConn))));
429+
pchomp(PQerrorMessage(conn->streamConn)))));
430430
}
431431

432432
/*
@@ -453,7 +453,7 @@ libpqrcv_readtimelinehistoryfile(WalReceiverConn *conn,
453453
ereport(ERROR,
454454
(errmsg("could not receive timeline history file from "
455455
"the primary server: %s",
456-
PQerrorMessage(conn->streamConn))));
456+
pchomp(PQerrorMessage(conn->streamConn)))));
457457
}
458458
if (PQnfields(res) != 2 || PQntuples(res) != 1)
459459
{
@@ -611,7 +611,7 @@ libpqrcv_receive(WalReceiverConn *conn, char **buffer,
611611
if (PQconsumeInput(conn->streamConn) == 0)
612612
ereport(ERROR,
613613
(errmsg("could not receive data from WAL stream: %s",
614-
PQerrorMessage(conn->streamConn))));
614+
pchomp(PQerrorMessage(conn->streamConn)))));
615615

616616
/* Now that we've consumed some input, try again */
617617
rawlen = PQgetCopyData(conn->streamConn, &conn->recvBuf, 1);
@@ -638,13 +638,13 @@ libpqrcv_receive(WalReceiverConn *conn, char **buffer,
638638
PQclear(res);
639639
ereport(ERROR,
640640
(errmsg("could not receive data from WAL stream: %s",
641-
PQerrorMessage(conn->streamConn))));
641+
pchomp(PQerrorMessage(conn->streamConn)))));
642642
}
643643
}
644644
if (rawlen < -1)
645645
ereport(ERROR,
646646
(errmsg("could not receive data from WAL stream: %s",
647-
PQerrorMessage(conn->streamConn))));
647+
pchomp(PQerrorMessage(conn->streamConn)))));
648648

649649
/* Return received messages to caller */
650650
*buffer = conn->recvBuf;
@@ -663,7 +663,7 @@ libpqrcv_send(WalReceiverConn *conn, const char *buffer, int nbytes)
663663
PQflush(conn->streamConn))
664664
ereport(ERROR,
665665
(errmsg("could not send data to WAL stream: %s",
666-
PQerrorMessage(conn->streamConn))));
666+
pchomp(PQerrorMessage(conn->streamConn)))));
667667
}
668668

669669
/*
@@ -697,7 +697,7 @@ libpqrcv_create_slot(WalReceiverConn *conn, const char *slotname,
697697
PQclear(res);
698698
ereport(ERROR,
699699
(errmsg("could not create replication slot \"%s\": %s",
700-
slotname, PQerrorMessage(conn->streamConn))));
700+
slotname, pchomp(PQerrorMessage(conn->streamConn)))));
701701
}
702702

703703
*lsn = DatumGetLSN(DirectFunctionCall1Coll(pg_lsn_in, InvalidOid,
@@ -728,7 +728,7 @@ libpqrcv_command(WalReceiverConn *conn, const char *cmd, char **err)
728728
if (PQresultStatus(res) != PGRES_COMMAND_OK)
729729
{
730730
PQclear(res);
731-
*err = pstrdup(PQerrorMessage(conn->streamConn));
731+
*err = pchomp(PQerrorMessage(conn->streamConn));
732732
return false;
733733
}
734734

src/backend/utils/mmgr/mcxt.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,3 +1181,17 @@ pnstrdup(const char *in, Size len)
11811181
out[len] = '\0';
11821182
return out;
11831183
}
1184+
1185+
/*
1186+
* Make copy of string with all trailing newline characters removed.
1187+
*/
1188+
char *
1189+
pchomp(const char *in)
1190+
{
1191+
size_t n;
1192+
1193+
n = strlen(in);
1194+
while (n > 0 && in[n - 1] == '\n')
1195+
n--;
1196+
return pnstrdup(in, n);
1197+
}

src/include/utils/palloc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ extern char *MemoryContextStrdup(MemoryContext context, const char *string);
127127
extern char *pstrdup(const char *in);
128128
extern char *pnstrdup(const char *in, Size len);
129129

130+
extern char *pchomp(const char *in);
131+
130132
/* sprintf into a palloc'd buffer --- these are in psprintf.c */
131133
extern char *psprintf(const char *fmt,...) pg_attribute_printf(1, 2);
132134
extern size_t pvsnprintf(char *buf, size_t len, const char *fmt, va_list args) pg_attribute_printf(3, 0);

0 commit comments

Comments
 (0)