summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2004-12-12 20:17:06 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2004-12-12 20:17:06 +0000
commitc604ed56e3f9d4c236e06b717a18d1a5baa27c88 (patch)
tree6c4d533182e268ea010618071e47f9df38733bc7
parentf9a6ba184a2b8db78919eac89dc56c68ad475587 (diff)
downloadpostgresql-c604ed56e3f9d4c236e06b717a18d1a5baa27c88.tar.gz
PREPARE and EXPLAIN need to copy the source query just like we recently
had to do in DECLARE CURSOR. AFAICS these are all the places affected. PREPARE case per example from Michael Fuhr, EXPLAIN case located by grepping for planner calls ...
-rw-r--r--src/backend/commands/explain.c12
-rw-r--r--src/backend/commands/prepare.c15
2 files changed, 24 insertions, 3 deletions
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index 34f6aa51f7..66e795d422 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994-5, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.127 2004/09/30 17:42:42 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.128 2004/12/12 20:17:06 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -75,6 +75,16 @@ ExplainQuery(ExplainStmt *stmt, DestReceiver *dest)
List *rewritten;
ListCell *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));
diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c
index ae9366c5ee..66fa15c37a 100644
--- a/src/backend/commands/prepare.c
+++ b/src/backend/commands/prepare.c
@@ -10,7 +10,7 @@
* Copyright (c) 2002-2004, PostgreSQL Global Development Group
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.34 2004/12/03 21:26:31 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.35 2004/12/12 20:17:06 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -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, NULL, false);