From 0b9f48daf2601a1be20f8a85ad151bdc05dd1907 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 28 Nov 2004 22:16:49 +0000 Subject: [PATCH] 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. --- src/backend/commands/portalcmds.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/backend/commands/portalcmds.c b/src/backend/commands/portalcmds.c index 27cd7503c30..8c4c9fe282d 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);