]> granicus.if.org Git - postgresql/commitdiff
Avoid scribbling on original parsetree during DECLARE CURSOR. This
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 28 Nov 2004 22:16:49 +0000 (22:16 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 28 Nov 2004 22:16:49 +0000 (22:16 +0000)
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

index 27cd7503c30ce4ba1f92454fd269e43e7e43b821..8c4c9fe282d8d37fdcb9f650ae3ff0b6ef2de36c 100644 (file)
@@ -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);