*** pgsql/contrib/dblink/dblink.c 2008/01/14 02:49:47 1.69 --- pgsql/contrib/dblink/dblink.c 2008/11/30 23:24:01 1.69.2.1 *************** *** 8,14 **** * Darko Prenosil * Shridhar Daithankar * ! * $PostgreSQL: pgsql/contrib/dblink/dblink.c,v 1.68 2008/01/03 21:27:59 tgl Exp $ * Copyright (c) 2001-2008, PostgreSQL Global Development Group * ALL RIGHTS RESERVED; * --- 8,14 ---- * Darko Prenosil * Shridhar Daithankar * ! * $PostgreSQL: pgsql/contrib/dblink/dblink.c,v 1.69 2008/01/14 02:49:47 tgl Exp $ * Copyright (c) 2001-2008, PostgreSQL Global Development Group * ALL RIGHTS RESERVED; * *************** dblink_connect(PG_FUNCTION_ARGS) *** 226,232 **** char *connstr = NULL; char *connname = NULL; char *msg; - MemoryContext oldcontext; PGconn *conn = NULL; remoteConn *rconn = NULL; --- 226,231 ---- *************** dblink_connect(PG_FUNCTION_ARGS) *** 240,252 **** else if (PG_NARGS() == 1) connstr = GET_STR(PG_GETARG_TEXT_P(0)); - oldcontext = MemoryContextSwitchTo(TopMemoryContext); - if (connname) ! rconn = (remoteConn *) palloc(sizeof(remoteConn)); ! conn = PQconnectdb(connstr); ! MemoryContextSwitchTo(oldcontext); if (PQstatus(conn) == CONNECTION_BAD) { --- 239,249 ---- else if (PG_NARGS() == 1) connstr = GET_STR(PG_GETARG_TEXT_P(0)); if (connname) ! rconn = (remoteConn *) MemoryContextAlloc(TopMemoryContext, ! sizeof(remoteConn)); ! conn = PQconnectdb(connstr); if (PQstatus(conn) == CONNECTION_BAD) { *************** dblink_fetch(PG_FUNCTION_ARGS) *** 583,592 **** funcctx = SRF_FIRSTCALL_INIT(); /* ! * switch to memory context appropriate for multiple function calls */ - oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); - res = PQexec(conn, buf.data); if (!res || (PQresultStatus(res) != PGRES_COMMAND_OK && --- 580,589 ---- funcctx = SRF_FIRSTCALL_INIT(); /* ! * Try to execute the query. Note that since libpq uses malloc, ! * the PGresult will be long-lived even though we are still in ! * a short-lived memory context. */ res = PQexec(conn, buf.data); if (!res || (PQresultStatus(res) != PGRES_COMMAND_OK && *************** dblink_fetch(PG_FUNCTION_ARGS) *** 633,641 **** break; } - /* make sure we have a persistent copy of the tupdesc */ - tupdesc = CreateTupleDescCopy(tupdesc); - /* check result and tuple descriptor have the same number of columns */ if (PQnfields(res) != tupdesc->natts) ereport(ERROR, --- 630,635 ---- *************** dblink_fetch(PG_FUNCTION_ARGS) *** 643,656 **** errmsg("remote query result rowtype does not match " "the specified FROM clause rowtype"))); ! /* fast track when no results */ if (funcctx->max_calls < 1) { ! if (res) ! PQclear(res); SRF_RETURN_DONE(funcctx); } /* store needed metadata for subsequent calls */ attinmeta = TupleDescGetAttInMetadata(tupdesc); funcctx->attinmeta = attinmeta; --- 637,661 ---- errmsg("remote query result rowtype does not match " "the specified FROM clause rowtype"))); ! /* ! * fast track when no results. We could exit earlier, but then ! * we'd not report error if the result tuple type is wrong. ! */ if (funcctx->max_calls < 1) { ! PQclear(res); SRF_RETURN_DONE(funcctx); } + /* + * switch to memory context appropriate for multiple function calls, + * so we can make long-lived copy of tupdesc etc + */ + oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); + + /* make sure we have a persistent copy of the tupdesc */ + tupdesc = CreateTupleDescCopy(tupdesc); + /* store needed metadata for subsequent calls */ attinmeta = TupleDescGetAttInMetadata(tupdesc); funcctx->attinmeta = attinmeta; *************** dblink_record_internal(FunctionCallInfo *** 841,847 **** --- 846,855 ---- res = PQgetResult(conn); /* NULL means we're all done with the async results */ if (!res) + { + MemoryContextSwitchTo(oldcontext); SRF_RETURN_DONE(funcctx); + } } if (!res || *************** dblink_record_internal(FunctionCallInfo *** 855,860 **** --- 863,869 ---- DBLINK_RES_ERROR_AS_NOTICE("sql error"); if (freeconn) PQfinish(conn); + MemoryContextSwitchTo(oldcontext); SRF_RETURN_DONE(funcctx); } } *************** dblink_record_internal(FunctionCallInfo *** 925,930 **** --- 934,940 ---- { if (res) PQclear(res); + MemoryContextSwitchTo(oldcontext); SRF_RETURN_DONE(funcctx); } *************** dblink_get_pkey(PG_FUNCTION_ARGS) *** 1296,1303 **** --- 1306,1316 ---- funcctx->user_fctx = results; } else + { /* fast track when no results */ + MemoryContextSwitchTo(oldcontext); SRF_RETURN_DONE(funcctx); + } MemoryContextSwitchTo(oldcontext); }