aboutsummaryrefslogtreecommitdiff
path: root/contrib/dblink/dblink.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/dblink/dblink.c')
-rw-r--r--contrib/dblink/dblink.c129
1 files changed, 71 insertions, 58 deletions
diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index 4e29ee94072..226e737e2d9 100644
--- a/contrib/dblink/dblink.c
+++ b/contrib/dblink/dblink.c
@@ -8,7 +8,7 @@
* Darko Prenosil <Darko.Prenosil@finteh.hr>
* Shridhar Daithankar <shridhar_daithankar@persistent.co.in>
*
- * $PostgreSQL: pgsql/contrib/dblink/dblink.c,v 1.73 2008/04/04 17:02:56 momjian Exp $
+ * $PostgreSQL: pgsql/contrib/dblink/dblink.c,v 1.74 2008/07/03 03:56:57 joe Exp $
* Copyright (c) 2001-2008, PostgreSQL Global Development Group
* ALL RIGHTS RESERVED;
*
@@ -94,6 +94,7 @@ static HeapTuple get_tuple_of_interest(Oid relid, int2vector *pkattnums, int16 p
static Oid get_relid_from_relname(text *relname_text);
static char *generate_relation_name(Oid relid);
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);
/* Global */
static remoteConn *pconn = NULL;
@@ -125,34 +126,20 @@ typedef struct remoteConnHashEnt
} \
} while (0)
-#define DBLINK_RES_INTERNALERROR(p2) \
- do { \
- msg = pstrdup(PQerrorMessage(conn)); \
- if (res) \
- PQclear(res); \
- elog(ERROR, "%s: %s", p2, msg); \
- } while (0)
-
-#define DBLINK_RES_ERROR(p2) \
+#define xpstrdup(var_c, var_) \
do { \
- msg = pstrdup(PQerrorMessage(conn)); \
- if (res) \
- PQclear(res); \
- ereport(ERROR, \
- (errcode(ERRCODE_SYNTAX_ERROR), \
- errmsg("%s", p2), \
- errdetail("%s", msg))); \
+ if (var_ != NULL) \
+ var_c = pstrdup(var_); \
+ else \
+ var_c = NULL; \
} while (0)
-#define DBLINK_RES_ERROR_AS_NOTICE(p2) \
+#define DBLINK_RES_INTERNALERROR(p2) \
do { \
msg = pstrdup(PQerrorMessage(conn)); \
if (res) \
PQclear(res); \
- ereport(NOTICE, \
- (errcode(ERRCODE_SYNTAX_ERROR), \
- errmsg("%s", p2), \
- errdetail("%s", msg))); \
+ elog(ERROR, "%s: %s", p2, msg); \
} while (0)
#define DBLINK_CONN_NOT_AVAIL \
@@ -396,13 +383,8 @@ dblink_open(PG_FUNCTION_ARGS)
res = PQexec(conn, buf.data);
if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
{
- if (fail)
- DBLINK_RES_ERROR("sql error");
- else
- {
- DBLINK_RES_ERROR_AS_NOTICE("sql error");
- PG_RETURN_TEXT_P(cstring_to_text("ERROR"));
- }
+ dblink_res_error(conname, res, "could not open cursor", fail);
+ PG_RETURN_TEXT_P(cstring_to_text("ERROR"));
}
PQclear(res);
@@ -470,13 +452,8 @@ dblink_close(PG_FUNCTION_ARGS)
res = PQexec(conn, buf.data);
if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
{
- if (fail)
- DBLINK_RES_ERROR("sql error");
- else
- {
- DBLINK_RES_ERROR_AS_NOTICE("sql error");
- PG_RETURN_TEXT_P(cstring_to_text("ERROR"));
- }
+ dblink_res_error(conname, res, "could not close cursor", fail);
+ PG_RETURN_TEXT_P(cstring_to_text("ERROR"));
}
PQclear(res);
@@ -513,7 +490,6 @@ dblink_fetch(PG_FUNCTION_ARGS)
int call_cntr;
int max_calls;
AttInMetadata *attinmeta;
- char *msg;
PGresult *res = NULL;
MemoryContext oldcontext;
char *conname = NULL;
@@ -590,13 +566,8 @@ dblink_fetch(PG_FUNCTION_ARGS)
(PQresultStatus(res) != PGRES_COMMAND_OK &&
PQresultStatus(res) != PGRES_TUPLES_OK))
{
- if (fail)
- DBLINK_RES_ERROR("sql error");
- else
- {
- DBLINK_RES_ERROR_AS_NOTICE("sql error");
- SRF_RETURN_DONE(funcctx);
- }
+ dblink_res_error(conname, res, "could not fetch from cursor", fail);
+ SRF_RETURN_DONE(funcctx);
}
else if (PQresultStatus(res) == PGRES_COMMAND_OK)
{
@@ -846,15 +817,10 @@ dblink_record_internal(FunctionCallInfo fcinfo, bool is_async, bool do_get)
(PQresultStatus(res) != PGRES_COMMAND_OK &&
PQresultStatus(res) != PGRES_TUPLES_OK))
{
- if (fail)
- DBLINK_RES_ERROR("sql error");
- else
- {
- DBLINK_RES_ERROR_AS_NOTICE("sql error");
- if (freeconn)
- PQfinish(conn);
- SRF_RETURN_DONE(funcctx);
- }
+ dblink_res_error(conname, res, "could not execute query", fail);
+ if (freeconn)
+ PQfinish(conn);
+ SRF_RETURN_DONE(funcctx);
}
if (PQresultStatus(res) == PGRES_COMMAND_OK)
@@ -1180,10 +1146,7 @@ dblink_exec(PG_FUNCTION_ARGS)
(PQresultStatus(res) != PGRES_COMMAND_OK &&
PQresultStatus(res) != PGRES_TUPLES_OK))
{
- if (fail)
- DBLINK_RES_ERROR("sql error");
- else
- DBLINK_RES_ERROR_AS_NOTICE("sql error");
+ dblink_res_error(conname, res, "could not execute command", fail);
/* need a tuple descriptor representing one TEXT column */
tupdesc = CreateTemplateTupleDesc(1, false);
@@ -1195,7 +1158,6 @@ dblink_exec(PG_FUNCTION_ARGS)
* result tuple
*/
sql_cmd_status = cstring_to_text("ERROR");
-
}
else if (PQresultStatus(res) == PGRES_COMMAND_OK)
{
@@ -2288,3 +2250,54 @@ dblink_security_check(PGconn *conn, remoteConn *rconn)
}
}
}
+
+static void
+dblink_res_error(const char *conname, PGresult *res, const char *dblink_context_msg, bool fail)
+{
+ int level;
+ char *pg_diag_sqlstate = PQresultErrorField(res, PG_DIAG_SQLSTATE);
+ char *pg_diag_message_primary = PQresultErrorField(res, PG_DIAG_MESSAGE_PRIMARY);
+ char *pg_diag_message_detail = PQresultErrorField(res, PG_DIAG_MESSAGE_DETAIL);
+ char *pg_diag_message_hint = PQresultErrorField(res, PG_DIAG_MESSAGE_HINT);
+ char *pg_diag_context = PQresultErrorField(res, PG_DIAG_CONTEXT);
+ int sqlstate;
+ char *message_primary;
+ char *message_detail;
+ char *message_hint;
+ char *message_context;
+ const char *dblink_context_conname = "unnamed";
+
+ if (fail)
+ level = ERROR;
+ else
+ level = NOTICE;
+
+ if (pg_diag_sqlstate)
+ sqlstate = MAKE_SQLSTATE(pg_diag_sqlstate[0],
+ pg_diag_sqlstate[1],
+ pg_diag_sqlstate[2],
+ pg_diag_sqlstate[3],
+ pg_diag_sqlstate[4]);
+ else
+ sqlstate = ERRCODE_CONNECTION_FAILURE;
+
+ xpstrdup(message_primary, pg_diag_message_primary);
+ xpstrdup(message_detail, pg_diag_message_detail);
+ xpstrdup(message_hint, pg_diag_message_hint);
+ xpstrdup(message_context, pg_diag_context);
+
+ if (res)
+ PQclear(res);
+
+ if (conname)
+ dblink_context_conname = conname;
+
+ ereport(level,
+ (errcode(sqlstate),
+ message_primary ? errmsg("%s", message_primary) : errmsg("unknown error"),
+ message_detail ? errdetail("%s", message_detail) : 0,
+ message_hint ? errhint("%s", message_hint) : 0,
+ message_context ? errcontext("%s", message_context) : 0,
+ errcontext("Error occurred on dblink connection named \"%s\": %s.",
+ dblink_context_conname, dblink_context_msg)));
+}