Back-patch copyOject fix for EXPLAIN/PREPARE.
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 13 Dec 2004 00:17:52 +0000 (00:17 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 13 Dec 2004 00:17:52 +0000 (00:17 +0000)
src/backend/commands/explain.c
src/backend/commands/prepare.c

index 0b2707573b711d9b97026bf9db2a90e4bf9603d1..c3837e854f5abefa6c3c6373e13cdb719cf13375 100644 (file)
@@ -74,6 +74,16 @@ ExplainQuery(ExplainStmt *stmt, DestReceiver *dest)
        List       *rewritten;
        List       *l;
 
+       /*
+        * 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 EXPLAIN is in a portal or plpgsql
+        * function and is executed repeatedly.  (See also the same hack in
+        * DECLARE CURSOR and PREPARE.)  XXX the planner really shouldn't
+        * modify its input ... FIXME someday.
+        */
+       query = copyObject(query);
+
        /* prepare for projection of tuples */
        tstate = begin_tup_output_tupdesc(dest, ExplainResultDesc(stmt));
 
index 70239aa79a0f9c3be76aa37da44a1b3d83e454cd..c4e90001bc8090587abb0876ffd306d8761c6d5e 100644 (file)
@@ -48,6 +48,7 @@ void
 PrepareQuery(PrepareStmt *stmt)
 {
        const char *commandTag;
+       Query      *query;
        List       *query_list,
                           *plan_list;
 
@@ -87,8 +88,18 @@ PrepareQuery(PrepareStmt *stmt)
         * the query.
         */
 
+       /*
+        * 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 PREPARE is in a portal or plpgsql
+        * function and is executed repeatedly.  (See also the same hack in
+        * DECLARE CURSOR and EXPLAIN.)  XXX the planner really shouldn't
+        * modify its input ... FIXME someday.
+        */
+       query = copyObject(stmt->query);
+
        /* Rewrite the query. The result could be 0, 1, or many queries. */
-       query_list = QueryRewrite(stmt->query);
+       query_list = QueryRewrite(query);
 
        /* Generate plans for queries.  Snapshot is already set. */
        plan_list = pg_plan_queries(query_list, false);