@@ -113,7 +113,7 @@ static char *generate_relation_name(Relation rel);
113113static void dblink_connstr_check (const char * connstr );
114114static void dblink_security_check (PGconn * conn ,remoteConn * rconn );
115115static void dblink_res_error (PGconn * conn ,const char * conname ,PGresult * res ,
116- const char * dblink_context_msg , bool fail );
116+ bool fail , const char * fmt ,...) pg_attribute_printf ( 5 , 6 );
117117static char * get_connect_string (const char * servername );
118118static char * escape_param_str (const char * from );
119119static void validate_pkattnums (Relation rel ,
@@ -441,7 +441,8 @@ dblink_open(PG_FUNCTION_ARGS)
441441res = PQexec (conn ,buf .data );
442442if (!res || PQresultStatus (res )!= PGRES_COMMAND_OK )
443443{
444- dblink_res_error (conn ,conname ,res ,"could not open cursor" ,fail );
444+ dblink_res_error (conn ,conname ,res ,fail ,
445+ "while opening cursor \"%s\"" ,curname );
445446PG_RETURN_TEXT_P (cstring_to_text ("ERROR" ));
446447}
447448
@@ -509,7 +510,8 @@ dblink_close(PG_FUNCTION_ARGS)
509510res = PQexec (conn ,buf .data );
510511if (!res || PQresultStatus (res )!= PGRES_COMMAND_OK )
511512{
512- dblink_res_error (conn ,conname ,res ,"could not close cursor" ,fail );
513+ dblink_res_error (conn ,conname ,res ,fail ,
514+ "while closing cursor \"%s\"" ,curname );
513515PG_RETURN_TEXT_P (cstring_to_text ("ERROR" ));
514516}
515517
@@ -612,8 +614,8 @@ dblink_fetch(PG_FUNCTION_ARGS)
612614(PQresultStatus (res )!= PGRES_COMMAND_OK &&
613615PQresultStatus (res )!= PGRES_TUPLES_OK ))
614616{
615- dblink_res_error (conn ,conname ,res ,
616- "could not fetch from cursor" , fail );
617+ dblink_res_error (conn ,conname ,res ,fail ,
618+ "while fetching from cursor \"%s\"" , curname );
617619return (Datum )0 ;
618620}
619621else if (PQresultStatus (res )== PGRES_COMMAND_OK )
@@ -763,8 +765,8 @@ dblink_record_internal(FunctionCallInfo fcinfo, bool is_async)
763765if (PQresultStatus (res )!= PGRES_COMMAND_OK &&
764766PQresultStatus (res )!= PGRES_TUPLES_OK )
765767{
766- dblink_res_error (conn ,conname ,res ,
767- "could not execute query" , fail );
768+ dblink_res_error (conn ,conname ,res ,fail ,
769+ "while executing query" );
768770/* if fail isn't set, we'll return an empty query result */
769771}
770772else
@@ -1009,8 +1011,8 @@ materializeQueryResult(FunctionCallInfo fcinfo,
10091011PGresult * res1 = res ;
10101012
10111013res = NULL ;
1012- dblink_res_error (conn ,conname ,res1 ,
1013- "could not execute query" , fail );
1014+ dblink_res_error (conn ,conname ,res1 ,fail ,
1015+ "while executing query" );
10141016/* if fail isn't set, we'll return an empty query result */
10151017}
10161018else if (PQresultStatus (res )== PGRES_COMMAND_OK )
@@ -1438,8 +1440,8 @@ dblink_exec(PG_FUNCTION_ARGS)
14381440(PQresultStatus (res )!= PGRES_COMMAND_OK &&
14391441PQresultStatus (res )!= PGRES_TUPLES_OK ))
14401442{
1441- dblink_res_error (conn ,conname ,res ,
1442- "could not execute command" , fail );
1443+ dblink_res_error (conn ,conname ,res ,fail ,
1444+ "while executing command" );
14431445
14441446/*
14451447 * and save a copy of the command status string to return as our
@@ -1980,7 +1982,7 @@ dblink_fdw_validator(PG_FUNCTION_ARGS)
19801982ereport (ERROR ,
19811983(errcode (ERRCODE_FDW_OUT_OF_MEMORY ),
19821984errmsg ("out of memory" ),
1983- errdetail ("could not get libpq's default connection options" )));
1985+ errdetail ("Could not get libpq's default connection options. " )));
19841986}
19851987
19861988/* Validate each supplied option. */
@@ -2676,9 +2678,17 @@ dblink_connstr_check(const char *connstr)
26762678}
26772679}
26782680
2681+ /*
2682+ * Report an error received from the remote server
2683+ *
2684+ * res: the received error result (will be freed)
2685+ * fail: true for ERROR ereport, false for NOTICE
2686+ * fmt and following args: sprintf-style format and values for errcontext;
2687+ * the resulting string should be worded like "while <some action>"
2688+ */
26792689static void
26802690dblink_res_error (PGconn * conn ,const char * conname ,PGresult * res ,
2681- const char * dblink_context_msg , bool fail )
2691+ bool fail , const char * fmt ,... )
26822692{
26832693int level ;
26842694char * pg_diag_sqlstate = PQresultErrorField (res ,PG_DIAG_SQLSTATE );
@@ -2691,7 +2701,8 @@ dblink_res_error(PGconn *conn, const char *conname, PGresult *res,
26912701char * message_detail ;
26922702char * message_hint ;
26932703char * message_context ;
2694- const char * dblink_context_conname = "unnamed" ;
2704+ va_list ap ;
2705+ char dblink_context_msg [512 ];
26952706
26962707if (fail )
26972708level = ERROR ;
@@ -2720,21 +2731,38 @@ dblink_res_error(PGconn *conn, const char *conname, PGresult *res,
27202731if (message_primary == NULL )
27212732message_primary = pchomp (PQerrorMessage (conn ));
27222733
2734+ /*
2735+ * Now that we've copied all the data we need out of the PGresult, it's
2736+ * safe to free it. We must do this to avoid PGresult leakage. We're
2737+ * leaking all the strings too, but those are in palloc'd memory that will
2738+ * get cleaned up eventually.
2739+ */
27232740if (res )
27242741PQclear (res );
27252742
2726- if (conname )
2727- dblink_context_conname = conname ;
2743+ /*
2744+ * Format the basic errcontext string. Below, we'll add on something
2745+ * about the connection name. That's a violation of the translatability
2746+ * guidelines about constructing error messages out of parts, but since
2747+ * there's no translation support for dblink, there's no need to worry
2748+ * about that (yet).
2749+ */
2750+ va_start (ap ,fmt );
2751+ vsnprintf (dblink_context_msg ,sizeof (dblink_context_msg ),fmt ,ap );
2752+ va_end (ap );
27282753
27292754ereport (level ,
27302755(errcode (sqlstate ),
27312756message_primary ?errmsg_internal ("%s" ,message_primary ) :
27322757errmsg ("could not obtain message string for remote error" ),
27332758message_detail ?errdetail_internal ("%s" ,message_detail ) :0 ,
27342759message_hint ?errhint ("%s" ,message_hint ) :0 ,
2735- message_context ?errcontext ("%s" ,message_context ) :0 ,
2736- errcontext ("Error occurred on dblink connection named \"%s\": %s." ,
2737- dblink_context_conname ,dblink_context_msg )));
2760+ message_context ? (errcontext ("%s" ,message_context )) :0 ,
2761+ conname ?
2762+ (errcontext ("%s on dblink connection named \"%s\"" ,
2763+ dblink_context_msg ,conname )) :
2764+ (errcontext ("%s on unnamed dblink connection" ,
2765+ dblink_context_msg ))));
27382766}
27392767
27402768/*
@@ -2769,7 +2797,7 @@ get_connect_string(const char *servername)
27692797ereport (ERROR ,
27702798(errcode (ERRCODE_FDW_OUT_OF_MEMORY ),
27712799errmsg ("out of memory" ),
2772- errdetail ("could not get libpq's default connection options" )));
2800+ errdetail ("Could not get libpq's default connection options. " )));
27732801}
27742802
27752803/* first gather the server connstr options */