aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/dblink/dblink.c31
1 files changed, 22 insertions, 9 deletions
diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index 10dc9bd347d..5b041ddc7ce 100644
--- a/contrib/dblink/dblink.c
+++ b/contrib/dblink/dblink.c
@@ -113,7 +113,8 @@ static Relation get_rel_from_relname(text *relname_text, LOCKMODE lockmode, AclM
static char *generate_relation_name(Relation rel);
static void dblink_connstr_check(const char *connstr);
static void dblink_security_check(PGconn *conn, remoteConn *rconn);
-static void dblink_res_error(const char *conname, PGresult *res, const char *dblink_context_msg, bool fail);
+static void dblink_res_error(PGconn *conn, const char *conname, PGresult *res,
+ const char *dblink_context_msg, bool fail);
static char *get_connect_string(const char *servername);
static char *escape_param_str(const char *from);
static void validate_pkattnums(Relation rel,
@@ -428,7 +429,7 @@ dblink_open(PG_FUNCTION_ARGS)
res = PQexec(conn, buf.data);
if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
{
- dblink_res_error(conname, res, "could not open cursor", fail);
+ dblink_res_error(conn, conname, res, "could not open cursor", fail);
PG_RETURN_TEXT_P(cstring_to_text("ERROR"));
}
@@ -497,7 +498,7 @@ dblink_close(PG_FUNCTION_ARGS)
res = PQexec(conn, buf.data);
if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
{
- dblink_res_error(conname, res, "could not close cursor", fail);
+ dblink_res_error(conn, conname, res, "could not close cursor", fail);
PG_RETURN_TEXT_P(cstring_to_text("ERROR"));
}
@@ -600,7 +601,8 @@ dblink_fetch(PG_FUNCTION_ARGS)
(PQresultStatus(res) != PGRES_COMMAND_OK &&
PQresultStatus(res) != PGRES_TUPLES_OK))
{
- dblink_res_error(conname, res, "could not fetch from cursor", fail);
+ dblink_res_error(conn, conname, res,
+ "could not fetch from cursor", fail);
return (Datum) 0;
}
else if (PQresultStatus(res) == PGRES_COMMAND_OK)
@@ -751,8 +753,8 @@ dblink_record_internal(FunctionCallInfo fcinfo, bool is_async)
if (PQresultStatus(res) != PGRES_COMMAND_OK &&
PQresultStatus(res) != PGRES_TUPLES_OK)
{
- dblink_res_error(conname, res, "could not execute query",
- fail);
+ dblink_res_error(conn, conname, res,
+ "could not execute query", fail);
/* if fail isn't set, we'll return an empty query result */
}
else
@@ -997,7 +999,8 @@ materializeQueryResult(FunctionCallInfo fcinfo,
PGresult *res1 = res;
res = NULL;
- dblink_res_error(conname, res1, "could not execute query", fail);
+ dblink_res_error(conn, conname, res1,
+ "could not execute query", fail);
/* if fail isn't set, we'll return an empty query result */
}
else if (PQresultStatus(res) == PGRES_COMMAND_OK)
@@ -1432,7 +1435,8 @@ dblink_exec(PG_FUNCTION_ARGS)
(PQresultStatus(res) != PGRES_COMMAND_OK &&
PQresultStatus(res) != PGRES_TUPLES_OK))
{
- dblink_res_error(conname, res, "could not execute command", fail);
+ dblink_res_error(conn, conname, res,
+ "could not execute command", fail);
/*
* and save a copy of the command status string to return as our
@@ -2663,7 +2667,8 @@ dblink_connstr_check(const char *connstr)
}
static void
-dblink_res_error(const char *conname, PGresult *res, const char *dblink_context_msg, bool fail)
+dblink_res_error(PGconn *conn, const char *conname, PGresult *res,
+ const char *dblink_context_msg, bool fail)
{
int level;
char *pg_diag_sqlstate = PQresultErrorField(res, PG_DIAG_SQLSTATE);
@@ -2697,6 +2702,14 @@ dblink_res_error(const char *conname, PGresult *res, const char *dblink_context_
xpstrdup(message_hint, pg_diag_message_hint);
xpstrdup(message_context, pg_diag_context);
+ /*
+ * If we don't get a message from the PGresult, try the PGconn. This
+ * is needed because for connection-level failures, PQexec may just
+ * return NULL, not a PGresult at all.
+ */
+ if (message_primary == NULL)
+ message_primary = PQerrorMessage(conn);
+
if (res)
PQclear(res);