diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2004-11-28 22:16:49 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2004-11-28 22:16:49 +0000 |
commit | 0b9f48daf2601a1be20f8a85ad151bdc05dd1907 (patch) | |
tree | da40dc98dfa232338f103bdf6b3804279c6dab3f | |
parent | f5778c63e546d7990f6422d9acdae09347133b81 (diff) | |
download | postgresql-0b9f48daf2601a1be20f8a85ad151bdc05dd1907.tar.gz postgresql-0b9f48daf2601a1be20f8a85ad151bdc05dd1907.zip |
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.
-rw-r--r-- | src/backend/commands/portalcmds.c | 13 |
1 files 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 $ * *------------------------------------------------------------------------- */ @@ -62,12 +62,21 @@ PerformCursorOpen(DeclareCursorStmt *stmt) 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); |