@@ -113,7 +113,7 @@ static char *generate_relation_name(Relation rel);
113
113
static void dblink_connstr_check (const char * connstr );
114
114
static void dblink_security_check (PGconn * conn ,remoteConn * rconn );
115
115
static 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 );
117
117
static char * get_connect_string (const char * servername );
118
118
static char * escape_param_str (const char * from );
119
119
static void validate_pkattnums (Relation rel ,
@@ -441,7 +441,8 @@ dblink_open(PG_FUNCTION_ARGS)
441
441
res = PQexec (conn ,buf .data );
442
442
if (!res || PQresultStatus (res )!= PGRES_COMMAND_OK )
443
443
{
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 );
445
446
PG_RETURN_TEXT_P (cstring_to_text ("ERROR" ));
446
447
}
447
448
@@ -509,7 +510,8 @@ dblink_close(PG_FUNCTION_ARGS)
509
510
res = PQexec (conn ,buf .data );
510
511
if (!res || PQresultStatus (res )!= PGRES_COMMAND_OK )
511
512
{
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 );
513
515
PG_RETURN_TEXT_P (cstring_to_text ("ERROR" ));
514
516
}
515
517
@@ -612,8 +614,8 @@ dblink_fetch(PG_FUNCTION_ARGS)
612
614
(PQresultStatus (res )!= PGRES_COMMAND_OK &&
613
615
PQresultStatus (res )!= PGRES_TUPLES_OK ))
614
616
{
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 );
617
619
return (Datum )0 ;
618
620
}
619
621
else if (PQresultStatus (res )== PGRES_COMMAND_OK )
@@ -763,8 +765,8 @@ dblink_record_internal(FunctionCallInfo fcinfo, bool is_async)
763
765
if (PQresultStatus (res )!= PGRES_COMMAND_OK &&
764
766
PQresultStatus (res )!= PGRES_TUPLES_OK )
765
767
{
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" );
768
770
/* if fail isn't set, we'll return an empty query result */
769
771
}
770
772
else
@@ -1009,8 +1011,8 @@ materializeQueryResult(FunctionCallInfo fcinfo,
1009
1011
PGresult * res1 = res ;
1010
1012
1011
1013
res = 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" );
1014
1016
/* if fail isn't set, we'll return an empty query result */
1015
1017
}
1016
1018
else if (PQresultStatus (res )== PGRES_COMMAND_OK )
@@ -1438,8 +1440,8 @@ dblink_exec(PG_FUNCTION_ARGS)
1438
1440
(PQresultStatus (res )!= PGRES_COMMAND_OK &&
1439
1441
PQresultStatus (res )!= PGRES_TUPLES_OK ))
1440
1442
{
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" );
1443
1445
1444
1446
/*
1445
1447
* and save a copy of the command status string to return as our
@@ -1980,7 +1982,7 @@ dblink_fdw_validator(PG_FUNCTION_ARGS)
1980
1982
ereport (ERROR ,
1981
1983
(errcode (ERRCODE_FDW_OUT_OF_MEMORY ),
1982
1984
errmsg ("out of memory" ),
1983
- errdetail ("could not get libpq's default connection options" )));
1985
+ errdetail ("Could not get libpq's default connection options. " )));
1984
1986
}
1985
1987
1986
1988
/* Validate each supplied option. */
@@ -2676,9 +2678,17 @@ dblink_connstr_check(const char *connstr)
2676
2678
}
2677
2679
}
2678
2680
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
+ */
2679
2689
static void
2680
2690
dblink_res_error (PGconn * conn ,const char * conname ,PGresult * res ,
2681
- const char * dblink_context_msg , bool fail )
2691
+ bool fail , const char * fmt ,... )
2682
2692
{
2683
2693
int level ;
2684
2694
char * pg_diag_sqlstate = PQresultErrorField (res ,PG_DIAG_SQLSTATE );
@@ -2691,7 +2701,8 @@ dblink_res_error(PGconn *conn, const char *conname, PGresult *res,
2691
2701
char * message_detail ;
2692
2702
char * message_hint ;
2693
2703
char * message_context ;
2694
- const char * dblink_context_conname = "unnamed" ;
2704
+ va_list ap ;
2705
+ char dblink_context_msg [512 ];
2695
2706
2696
2707
if (fail )
2697
2708
level = ERROR ;
@@ -2720,21 +2731,38 @@ dblink_res_error(PGconn *conn, const char *conname, PGresult *res,
2720
2731
if (message_primary == NULL )
2721
2732
message_primary = pchomp (PQerrorMessage (conn ));
2722
2733
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
+ */
2723
2740
if (res )
2724
2741
PQclear (res );
2725
2742
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 );
2728
2753
2729
2754
ereport (level ,
2730
2755
(errcode (sqlstate ),
2731
2756
message_primary ?errmsg_internal ("%s" ,message_primary ) :
2732
2757
errmsg ("could not obtain message string for remote error" ),
2733
2758
message_detail ?errdetail_internal ("%s" ,message_detail ) :0 ,
2734
2759
message_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 ))));
2738
2766
}
2739
2767
2740
2768
/*
@@ -2769,7 +2797,7 @@ get_connect_string(const char *servername)
2769
2797
ereport (ERROR ,
2770
2798
(errcode (ERRCODE_FDW_OUT_OF_MEMORY ),
2771
2799
errmsg ("out of memory" ),
2772
- errdetail ("could not get libpq's default connection options" )));
2800
+ errdetail ("Could not get libpq's default connection options. " )));
2773
2801
}
2774
2802
2775
2803
/* first gather the server connstr options */