提交 2a06b3bd 编写于 作者: T Tom Lane

Repair problem with multi-action rules in combination with any nontrivial

manipulation of rtable/jointree by planner.  Rewriter was generating
actions that shared rtable/jointree substructure, which caused havoc
when planner got to the later actions that it'd already mucked up.
上级 c1db506a
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.93 2001/05/03 17:47:49 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.94 2001/06/12 18:54:22 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -82,7 +82,7 @@ gatherRewriteMeta(Query *parsetree,
/*
* Adjust rule action and qual to offset its varnos, so that we can
* merge its rtable into the main parsetree's rtable.
* merge its rtable with the main parsetree's rtable.
*
* If the rule action is an INSERT...SELECT, the OLD/NEW rtable entries
* will be in the SELECT part, and we have to modify that rather than
......@@ -99,23 +99,19 @@ gatherRewriteMeta(Query *parsetree,
PRS2_OLD_VARNO + rt_length, rt_index, 0);
/*
* We want the main parsetree's rtable to end up as the concatenation
* of its original contents plus those of all the relevant rule
* actions. Also store same into all the rule_action rtables. Some of
* the entries may be unused after we finish rewriting, but if we
* tried to clean those out we'd have a much harder job to adjust RT
* indexes in the query's Vars. It's OK to have unused RT entries,
* since planner will ignore them.
* Generate expanded rtable consisting of main parsetree's rtable
* plus rule action's rtable; this becomes the complete rtable for the
* rule action. Some of the entries may be unused after we finish
* rewriting, but if we tried to clean those out we'd have a much harder
* job to adjust RT indexes in the query's Vars. It's OK to have unused
* RT entries, since planner will ignore them.
*
* NOTE KLUGY HACK: we assume the parsetree rtable had at least one entry
* to begin with (OK enough, else where'd the rule come from?).
* Because of this, if multiple rules nconc() their rtable additions
* onto parsetree->rtable, they'll all see the same rtable because
* they all have the same list head pointer.
* NOTE: because planner will destructively alter rtable, we must ensure
* that rule action's rtable is separate and shares no substructure with
* the main rtable. Hence do a deep copy here.
*/
parsetree->rtable = nconc(parsetree->rtable,
sub_action->rtable);
sub_action->rtable = parsetree->rtable;
sub_action->rtable = nconc((List *) copyObject(parsetree->rtable),
sub_action->rtable);
/*
* Each rule action's jointree should be the main parsetree's jointree
......@@ -128,6 +124,9 @@ gatherRewriteMeta(Query *parsetree,
* data for the quals. We don't want the original rtindex to be
* joined twice, however, so avoid keeping it if the rule action
* mentions it.
*
* As above, the action's jointree must not share substructure with
* the main parsetree's.
*/
if (sub_action->jointree != NULL)
{
......@@ -193,13 +192,13 @@ gatherRewriteMeta(Query *parsetree,
* occurrence of the given rt_index as a top-level join item (we do not look
* for it within join items; this is OK because we are only expecting to find
* it as an UPDATE or DELETE target relation, which will be at the top level
* of the join). Returns modified jointree list --- original list is not
* changed.
* of the join). Returns modified jointree list --- this is a separate copy
* sharing no nodes with the original.
*/
static List *
adjustJoinTreeList(Query *parsetree, bool removert, int rt_index)
{
List *newjointree = listCopy(parsetree->jointree->fromlist);
List *newjointree = copyObject(parsetree->jointree->fromlist);
List *jjt;
if (removert)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册