]> granicus.if.org Git - postgresql/commitdiff
chomp PQerrorMessage() in backend uses
authorPeter Eisentraut <peter_e@gmx.net>
Mon, 27 Feb 2017 13:30:06 +0000 (08:30 -0500)
committerPeter Eisentraut <peter_e@gmx.net>
Mon, 27 Feb 2017 13:54:51 +0000 (08:54 -0500)
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.

contrib/dblink/dblink.c
contrib/dblink/expected/dblink.out
contrib/postgres_fdw/connection.c
src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
src/backend/utils/mmgr/mcxt.c
src/include/utils/palloc.h

index ac43c458cb646e17f43285442e4fcec22cc3dcdc..e0d6778a0840fe22059bc3a53fd4d51dfe467df3 100644 (file)
@@ -166,7 +166,7 @@ typedef struct remoteConnHashEnt
 
 #define DBLINK_RES_INTERNALERROR(p2) \
        do { \
-                       msg = pstrdup(PQerrorMessage(conn)); \
+                       msg = pchomp(PQerrorMessage(conn)); \
                        if (res) \
                                PQclear(res); \
                        elog(ERROR, "%s: %s", p2, msg); \
@@ -204,7 +204,7 @@ typedef struct remoteConnHashEnt
                                conn = PQconnectdb(connstr); \
                                if (PQstatus(conn) == CONNECTION_BAD) \
                                { \
-                                       msg = pstrdup(PQerrorMessage(conn)); \
+                                       msg = pchomp(PQerrorMessage(conn)); \
                                        PQfinish(conn); \
                                        ereport(ERROR, \
                                                        (errcode(ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION), \
@@ -278,7 +278,7 @@ dblink_connect(PG_FUNCTION_ARGS)
 
        if (PQstatus(conn) == CONNECTION_BAD)
        {
-               msg = pstrdup(PQerrorMessage(conn));
+               msg = pchomp(PQerrorMessage(conn));
                PQfinish(conn);
                if (rconn)
                        pfree(rconn);
@@ -651,7 +651,7 @@ dblink_send_query(PG_FUNCTION_ARGS)
        /* async query send */
        retval = PQsendQuery(conn, sql);
        if (retval != 1)
-               elog(NOTICE, "could not send query: %s", PQerrorMessage(conn));
+               elog(NOTICE, "could not send query: %s", pchomp(PQerrorMessage(conn)));
 
        PG_RETURN_INT32(retval);
 }
@@ -1087,7 +1087,7 @@ storeQueryResult(volatile storeInfo *sinfo, PGconn *conn, const char *sql)
        PGresult   *res;
 
        if (!PQsendQuery(conn, sql))
-               elog(ERROR, "could not send query: %s", PQerrorMessage(conn));
+               elog(ERROR, "could not send query: %s", pchomp(PQerrorMessage(conn)));
 
        if (!PQsetSingleRowMode(conn))          /* shouldn't fail */
                elog(ERROR, "failed to set single-row mode for dblink query");
@@ -1370,7 +1370,7 @@ dblink_error_message(PG_FUNCTION_ARGS)
        if (msg == NULL || msg[0] == '\0')
                PG_RETURN_TEXT_P(cstring_to_text("OK"));
        else
-               PG_RETURN_TEXT_P(cstring_to_text(msg));
+               PG_RETURN_TEXT_P(cstring_to_text(pchomp(msg)));
 }
 
 /*
@@ -2709,7 +2709,7 @@ dblink_res_error(PGconn *conn, const char *conname, PGresult *res,
         * return NULL, not a PGresult at all.
         */
        if (message_primary == NULL)
-               message_primary = PQerrorMessage(conn);
+               message_primary = pchomp(PQerrorMessage(conn));
 
        if (res)
                PQclear(res);
index 5acaaf225a9d5ea73e58f3b4be9836a905d505c7..4b6d26e5743b5711054483eab04e8eefc4e1f071 100644 (file)
@@ -377,7 +377,6 @@ FROM dblink('myconn','SELECT * FROM foo') AS t(a int, b text, c text[])
 WHERE t.a > 7;
 ERROR:  could not establish connection
 DETAIL:  missing "=" after "myconn" in connection info string
-
 -- create a named persistent connection
 SELECT dblink_connect('myconn',connection_parameters());
  dblink_connect 
@@ -604,7 +603,6 @@ FROM dblink('myconn','SELECT * FROM foo') AS t(a int, b text, c text[])
 WHERE t.a > 7;
 ERROR:  could not establish connection
 DETAIL:  missing "=" after "myconn" in connection info string
-
 -- create a named persistent connection
 SELECT dblink_connect('myconn',connection_parameters());
  dblink_connect 
index 7f7a744ac0a07dcb93ca7dcdaff0e6addb1f203c..c6e3d44515534d460cb8592ab47be3e80169429d 100644 (file)
@@ -226,21 +226,11 @@ connect_pg_server(ForeignServer *server, UserMapping *user)
 
                conn = PQconnectdbParams(keywords, values, false);
                if (!conn || PQstatus(conn) != CONNECTION_OK)
-               {
-                       char       *connmessage;
-                       int                     msglen;
-
-                       /* libpq typically appends a newline, strip that */
-                       connmessage = pstrdup(PQerrorMessage(conn));
-                       msglen = strlen(connmessage);
-                       if (msglen > 0 && connmessage[msglen - 1] == '\n')
-                               connmessage[msglen - 1] = '\0';
                        ereport(ERROR,
                           (errcode(ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION),
                                errmsg("could not connect to server \"%s\"",
                                           server->servername),
-                               errdetail_internal("%s", connmessage)));
-               }
+                               errdetail_internal("%s", pchomp(PQerrorMessage(conn)))));
 
                /*
                 * Check that non-superuser has used password to establish connection;
@@ -563,7 +553,7 @@ pgfdw_report_error(int elevel, PGresult *res, PGconn *conn,
                 * return NULL, not a PGresult at all.
                 */
                if (message_primary == NULL)
-                       message_primary = PQerrorMessage(conn);
+                       message_primary = pchomp(PQerrorMessage(conn));
 
                ereport(elevel,
                                (errcode(sqlstate),
index 44ded74f51980d30e44ca8eb8fbbdc356c67766a..daae3f70e73baa6ddad65c8fcd9698b87d4292e5 100644 (file)
@@ -149,7 +149,7 @@ libpqrcv_connect(const char *conninfo, bool logical, const char *appname,
        conn->streamConn = PQconnectdbParams(keys, vals, /* expand_dbname = */ true);
        if (PQstatus(conn->streamConn) != CONNECTION_OK)
        {
-               *err = pstrdup(PQerrorMessage(conn->streamConn));
+               *err = pchomp(PQerrorMessage(conn->streamConn));
                return NULL;
        }
 
@@ -247,7 +247,7 @@ libpqrcv_identify_system(WalReceiverConn *conn, TimeLineID *primary_tli,
                ereport(ERROR,
                                (errmsg("could not receive database system identifier and timeline ID from "
                                                "the primary server: %s",
-                                               PQerrorMessage(conn->streamConn))));
+                                               pchomp(PQerrorMessage(conn->streamConn)))));
        }
        if (PQnfields(res) < 3 || PQntuples(res) != 1)
        {
@@ -324,13 +324,13 @@ libpqrcv_startstreaming(WalReceiverConn *conn,
                if (!pubnames_str)
                        ereport(ERROR,
                                        (errmsg("could not start WAL streaming: %s",
-                                                       PQerrorMessage(conn->streamConn))));
+                                                       pchomp(PQerrorMessage(conn->streamConn)))));
                pubnames_literal = PQescapeLiteral(conn->streamConn, pubnames_str,
                                                                                   strlen(pubnames_str));
                if (!pubnames_literal)
                        ereport(ERROR,
                                        (errmsg("could not start WAL streaming: %s",
-                                                       PQerrorMessage(conn->streamConn))));
+                                                       pchomp(PQerrorMessage(conn->streamConn)))));
                appendStringInfo(&cmd, ", publication_names %s", pubnames_literal);
                PQfreemem(pubnames_literal);
                pfree(pubnames_str);
@@ -355,7 +355,7 @@ libpqrcv_startstreaming(WalReceiverConn *conn,
                PQclear(res);
                ereport(ERROR,
                                (errmsg("could not start WAL streaming: %s",
-                                               PQerrorMessage(conn->streamConn))));
+                                               pchomp(PQerrorMessage(conn->streamConn)))));
        }
        PQclear(res);
        return true;
@@ -374,7 +374,7 @@ libpqrcv_endstreaming(WalReceiverConn *conn, TimeLineID *next_tli)
                PQflush(conn->streamConn))
                ereport(ERROR,
                        (errmsg("could not send end-of-streaming message to primary: %s",
-                                       PQerrorMessage(conn->streamConn))));
+                                       pchomp(PQerrorMessage(conn->streamConn)))));
 
        *next_tli = 0;
 
@@ -418,7 +418,7 @@ libpqrcv_endstreaming(WalReceiverConn *conn, TimeLineID *next_tli)
        if (PQresultStatus(res) != PGRES_COMMAND_OK)
                ereport(ERROR,
                                (errmsg("error reading result of streaming command: %s",
-                                               PQerrorMessage(conn->streamConn))));
+                                               pchomp(PQerrorMessage(conn->streamConn)))));
        PQclear(res);
 
        /* Verify that there are no more results */
@@ -426,7 +426,7 @@ libpqrcv_endstreaming(WalReceiverConn *conn, TimeLineID *next_tli)
        if (res != NULL)
                ereport(ERROR,
                                (errmsg("unexpected result after CommandComplete: %s",
-                                               PQerrorMessage(conn->streamConn))));
+                                               pchomp(PQerrorMessage(conn->streamConn)))));
 }
 
 /*
@@ -453,7 +453,7 @@ libpqrcv_readtimelinehistoryfile(WalReceiverConn *conn,
                ereport(ERROR,
                                (errmsg("could not receive timeline history file from "
                                                "the primary server: %s",
-                                               PQerrorMessage(conn->streamConn))));
+                                               pchomp(PQerrorMessage(conn->streamConn)))));
        }
        if (PQnfields(res) != 2 || PQntuples(res) != 1)
        {
@@ -611,7 +611,7 @@ libpqrcv_receive(WalReceiverConn *conn, char **buffer,
                if (PQconsumeInput(conn->streamConn) == 0)
                        ereport(ERROR,
                                        (errmsg("could not receive data from WAL stream: %s",
-                                                       PQerrorMessage(conn->streamConn))));
+                                                       pchomp(PQerrorMessage(conn->streamConn)))));
 
                /* Now that we've consumed some input, try again */
                rawlen = PQgetCopyData(conn->streamConn, &conn->recvBuf, 1);
@@ -638,13 +638,13 @@ libpqrcv_receive(WalReceiverConn *conn, char **buffer,
                        PQclear(res);
                        ereport(ERROR,
                                        (errmsg("could not receive data from WAL stream: %s",
-                                                       PQerrorMessage(conn->streamConn))));
+                                                       pchomp(PQerrorMessage(conn->streamConn)))));
                }
        }
        if (rawlen < -1)
                ereport(ERROR,
                                (errmsg("could not receive data from WAL stream: %s",
-                                               PQerrorMessage(conn->streamConn))));
+                                               pchomp(PQerrorMessage(conn->streamConn)))));
 
        /* Return received messages to caller */
        *buffer = conn->recvBuf;
@@ -663,7 +663,7 @@ libpqrcv_send(WalReceiverConn *conn, const char *buffer, int nbytes)
                PQflush(conn->streamConn))
                ereport(ERROR,
                                (errmsg("could not send data to WAL stream: %s",
-                                               PQerrorMessage(conn->streamConn))));
+                                               pchomp(PQerrorMessage(conn->streamConn)))));
 }
 
 /*
@@ -697,7 +697,7 @@ libpqrcv_create_slot(WalReceiverConn *conn, const char *slotname,
                PQclear(res);
                ereport(ERROR,
                                (errmsg("could not create replication slot \"%s\": %s",
-                                               slotname, PQerrorMessage(conn->streamConn))));
+                                               slotname, pchomp(PQerrorMessage(conn->streamConn)))));
        }
 
        *lsn = DatumGetLSN(DirectFunctionCall1Coll(pg_lsn_in, InvalidOid,
@@ -728,7 +728,7 @@ libpqrcv_command(WalReceiverConn *conn, const char *cmd, char **err)
        if (PQresultStatus(res) != PGRES_COMMAND_OK)
        {
                PQclear(res);
-               *err = pstrdup(PQerrorMessage(conn->streamConn));
+               *err = pchomp(PQerrorMessage(conn->streamConn));
                return false;
        }
 
index 6ad0bb47b60add94d21cf08cfd9685db47e4cd03..c21dfcb96bac70397113fdd0326ac931f2268e15 100644 (file)
@@ -1181,3 +1181,17 @@ pnstrdup(const char *in, Size len)
        out[len] = '\0';
        return out;
 }
+
+/*
+ * Make copy of string with all trailing newline characters removed.
+ */
+char *
+pchomp(const char *in)
+{
+       size_t          n;
+
+       n = strlen(in);
+       while (n > 0 && in[n - 1] == '\n')
+               n--;
+       return pnstrdup(in, n);
+}
index b72fe4aee8c084c4404050eaa832e1b2e69831df..2e07bd57ad41119203a457c02508f10af1caef3e 100644 (file)
@@ -127,6 +127,8 @@ extern char *MemoryContextStrdup(MemoryContext context, const char *string);
 extern char *pstrdup(const char *in);
 extern char *pnstrdup(const char *in, Size len);
 
+extern char *pchomp(const char *in);
+
 /* sprintf into a palloc'd buffer --- these are in psprintf.c */
 extern char *psprintf(const char *fmt,...) pg_attribute_printf(1, 2);
 extern size_t pvsnprintf(char *buf, size_t len, const char *fmt, va_list args) pg_attribute_printf(3, 0);