diff options
Diffstat (limited to 'contrib/dblink/dblink.c')
-rw-r--r-- | contrib/dblink/dblink.c | 129 |
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))); +} |