From: Tom Lane Date: Sun, 28 Nov 2004 22:16:49 +0000 (+0000) Subject: Avoid scribbling on original parsetree during DECLARE CURSOR. This X-Git-Tag: REL7_4_7~26 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0b9f48daf2601a1be20f8a85ad151bdc05dd1907;p=postgresql Avoid scribbling on original parsetree during DECLARE CURSOR. This prevents problems when the DECLARE is in a portal and is executed repeatedly, as is possible in v3 protocol. Per analysis by Oliver Jowett, though I didn't use his patch exactly. --- diff --git a/src/backend/commands/portalcmds.c b/src/backend/commands/portalcmds.c index 27cd7503c3..8c4c9fe282 100644 --- a/src/backend/commands/portalcmds.c +++ b/src/backend/commands/portalcmds.c @@ -14,7 +14,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/portalcmds.c,v 1.24 2003/08/24 21:02:43 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/portalcmds.c,v 1.24.2.1 2004/11/28 22:16:49 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -61,13 +61,22 @@ PerformCursorOpen(DeclareCursorStmt *stmt) if (!(stmt->options & CURSOR_OPT_HOLD)) RequireTransactionChain((void *) stmt, "DECLARE CURSOR"); + /* + * Because the planner is not cool about not scribbling on its input, + * we make a preliminary copy of the source querytree. This prevents + * problems in the case that the DECLARE CURSOR is in a portal and is + * executed repeatedly. XXX the planner really shouldn't modify its + * input ... FIXME someday. + */ + query = copyObject(stmt->query); + /* * The query has been through parse analysis, but not rewriting or * planning as yet. Note that the grammar ensured we have a SELECT * query, so we are not expecting rule rewriting to do anything * strange. */ - rewritten = QueryRewrite((Query *) stmt->query); + rewritten = QueryRewrite(query); if (length(rewritten) != 1 || !IsA(lfirst(rewritten), Query)) elog(ERROR, "unexpected rewrite result"); query = (Query *) lfirst(rewritten);