Oliver Jowett wrote:
> Perhaps PerformCursorOpen should copy the query tree before planning, or
> plan in a different memory context?
Patch attached. It moves query planning inside the new portal's memory
context. With this applied I can run Barry's testcase without errors,
and valgrind seems OK with it too.
-O
Index: src/backend/commands/portalcmds.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/portalcmds.c,v
retrieving revision 1.36
diff -c -r1.36 portalcmds.c
*** src/backend/commands/portalcmds.c 16 Sep 2004 16:58:28 -0000 1.36
--- src/backend/commands/portalcmds.c 24 Nov 2004 09:28:34 -0000
***************
*** 67,73 ****
* query, so we are not expecting rule rewriting to do anything
* strange.
*/
! rewritten = QueryRewrite((Query *) stmt->query);
if (list_length(rewritten) != 1 || !IsA(linitial(rewritten), Query))
elog(ERROR, "unexpected rewrite result");
query = (Query *) linitial(rewritten);
--- 67,86 ----
* query, so we are not expecting rule rewriting to do anything
* strange.
*/
!
! /* Create a new portal, and do all query planning on a copy of
! * the query allocated in the new portal's memory context. The
! * planner may modify the query, and it is not safe to have
! * those modifications persist as we are ourselves running in a
! * transient portal context.
! */
! portal = CreatePortal(stmt->portalname, false, false);
!
! oldContext = MemoryContextSwitchTo(PortalGetHeapMemory(portal));
!
! query = copyObject(stmt->query);
!
! rewritten = QueryRewrite(query);
if (list_length(rewritten) != 1 || !IsA(linitial(rewritten), Query))
elog(ERROR, "unexpected rewrite result");
query = (Query *) linitial(rewritten);
***************
*** 86,102 ****
plan = planner(query, true, stmt->options, NULL);
- /*
- * Create a portal and copy the query and plan into its memory
- * context.
- */
- portal = CreatePortal(stmt->portalname, false, false);
-
- oldContext = MemoryContextSwitchTo(PortalGetHeapMemory(portal));
-
- query = copyObject(query);
- plan = copyObject(plan);
-
PortalDefineQuery(portal,
NULL, /* unfortunately don't have sourceText */
"SELECT", /* cursor's query is always a SELECT */
--- 99,104 ----