aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2004-11-28 22:16:49 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2004-11-28 22:16:49 +0000
commit0b9f48daf2601a1be20f8a85ad151bdc05dd1907 (patch)
treeda40dc98dfa232338f103bdf6b3804279c6dab3f
parentf5778c63e546d7990f6422d9acdae09347133b81 (diff)
downloadpostgresql-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.c13
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);