From: Tom Lane Date: Mon, 13 Dec 2004 00:17:52 +0000 (+0000) Subject: Back-patch copyOject fix for EXPLAIN/PREPARE. X-Git-Url: http://waps.l3s.uni-hannover.de/gitweb/?a=commitdiff_plain;h=80119250ad2bc739318e07d098aa96096fe19e5e;p=users%2Fbernd%2Fpostgres.git Back-patch copyOject fix for EXPLAIN/PREPARE. --- diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index 0b2707573b..c3837e854f 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -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)); diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c index 70239aa79a..c4e90001bc 100644 --- a/src/backend/commands/prepare.c +++ b/src/backend/commands/prepare.c @@ -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);