summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2012-04-04 00:43:30 +0000
committerTom Lane2012-04-04 00:43:30 +0000
commit230e779f58e937834902501b28704a13f47f2d57 (patch)
tree441aefc9a297d3eb906eb9658f6bdab59d3c6957
parenta584bc5cb05cb9c5a2e98e3416107bb38bc5b9a0 (diff)
Fix a couple of contrib/dblink bugs.
dblink_exec leaked temporary database connections if any error occurred after connection setup, for example SELECT dblink_exec('...connect string...', 'select 1/0'); Add a PG_TRY block to ensure PQfinish gets done when it is needed. (dblink_record_internal is on the hairy edge of needing similar treatment, but seems not to be actively broken at the moment.) Also, in 9.0 and up, only one of the three functions using tuplestore return mode was properly checking that the query context would allow a tuplestore result. Noted while reviewing dblink patch. Back-patch to all supported branches.
-rw-r--r--contrib/dblink/dblink.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index c8f91a72fb3..cc8714dae62 100644
--- a/contrib/dblink/dblink.c
+++ b/contrib/dblink/dblink.c
@@ -1127,20 +1127,23 @@ PG_FUNCTION_INFO_V1(dblink_exec);
Datum
dblink_exec(PG_FUNCTION_ARGS)
{
+ text *volatile sql_cmd_status = NULL;
+ PGconn *volatile conn = NULL;
+ volatile bool freeconn = false;
+
+ DBLINK_INIT;
+
+ PG_TRY();
+ {
char *msg;
PGresult *res = NULL;
- text *sql_cmd_status = NULL;
TupleDesc tupdesc = NULL;
- PGconn *conn = NULL;
char *connstr = NULL;
char *sql = NULL;
char *conname = NULL;
remoteConn *rconn = NULL;
- bool freeconn = false;
bool fail = true; /* default to backward compatible behavior */
- DBLINK_INIT;
-
if (PG_NARGS() == 3)
{
/* must be text,text,bool */
@@ -1215,8 +1218,17 @@ dblink_exec(PG_FUNCTION_ARGS)
(errcode(ERRCODE_S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED),
errmsg("statement returning results not allowed")));
}
+ }
+ PG_CATCH();
+ {
+ /* if needed, close the connection to the database */
+ if (freeconn)
+ PQfinish(conn);
+ PG_RE_THROW();
+ }
+ PG_END_TRY();
- /* if needed, close the connection to the database and cleanup */
+ /* if needed, close the connection to the database */
if (freeconn)
PQfinish(conn);