Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 352871a

Browse files
committed
Repair bug reported by Huxton, 1/24/01. We need to include a rule's
original table ('OLD' table) in its join tree if OLD is referenced by either the rule action, the rule qual, or the original query qual that will be added to the rule action. However, we only want one instance of the original table to be included; so beware of the possibility that the rule action already has a jointree entry for OLD.
1 parent a605372 commit 352871a

File tree

1 file changed

+33
-25
lines changed

1 file changed

+33
-25
lines changed

src/backend/rewrite/rewriteHandler.c

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.88 2001/01/24 19:43:05 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.89 2001/01/27 04:40:59 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -37,7 +37,7 @@ static RewriteInfo *gatherRewriteMeta(Query *parsetree,
3737
int rt_index,
3838
CmdType event,
3939
bool instead_flag);
40-
static List *adjustJoinTreeList(Query *parsetree, int rt_index, bool *found);
40+
static List *adjustJoinTreeList(Query *parsetree, bool removert, int rt_index);
4141
static void markQueryForUpdate(Query *qry, bool skipOldNew);
4242
static List *matchLocks(CmdType event, RuleLock *rulelocks,
4343
int varno, Query *parsetree);
@@ -119,18 +119,25 @@ gatherRewriteMeta(Query *parsetree,
119119

120120
/*
121121
* Each rule action's jointree should be the main parsetree's jointree
122-
* plus that rule's jointree, but *without* the original rtindex
122+
* plus that rule's jointree, but usually *without* the original rtindex
123123
* that we're replacing (if present, which it won't be for INSERT).
124-
* Note that if the rule refers to OLD, its jointree will add back
125-
* a reference to rt_index.
124+
* Note that if the rule action refers to OLD, its jointree will add
125+
* a reference to rt_index. If the rule action doesn't refer to OLD,
126+
* but either the rule_qual or the user query quals do, then we need to
127+
* keep the original rtindex in the jointree to provide data for the
128+
* quals. We don't want the original rtindex to be joined twice,
129+
* however, so avoid keeping it if the rule action mentions it.
126130
*/
127131
if (sub_action->jointree != NULL)
128132
{
129-
bool found;
130-
List *newjointree = adjustJoinTreeList(parsetree,
131-
rt_index,
132-
&found);
133-
133+
bool keeporig;
134+
List *newjointree;
135+
136+
keeporig = (! rangeTableEntry_used((Node *) sub_action->jointree,
137+
rt_index, 0)) &&
138+
(rangeTableEntry_used(info->rule_qual, rt_index, 0) ||
139+
rangeTableEntry_used(parsetree->jointree->quals, rt_index, 0));
140+
newjointree = adjustJoinTreeList(parsetree, !keeporig, rt_index);
134141
sub_action->jointree->fromlist =
135142
nconc(newjointree, sub_action->jointree->fromlist);
136143
}
@@ -181,29 +188,30 @@ gatherRewriteMeta(Query *parsetree,
181188
}
182189

183190
/*
184-
* Copy the query's jointree list, and attempt to remove any occurrence
185-
* of the given rt_index as a top-level join item (we do not look for it
186-
* within join items; this is OK because we are only expecting to find it
187-
* as an UPDATE or DELETE target relation, which will be at the top level
188-
* of the join). Returns modified jointree list --- original list
189-
* is not changed. *found is set to indicate if we found the rt_index.
191+
* Copy the query's jointree list, and optionally attempt to remove any
192+
* occurrence of the given rt_index as a top-level join item (we do not look
193+
* for it within join items; this is OK because we are only expecting to find
194+
* it as an UPDATE or DELETE target relation, which will be at the top level
195+
* of the join). Returns modified jointree list --- original list is not
196+
* changed.
190197
*/
191198
static List *
192-
adjustJoinTreeList(Query *parsetree, int rt_index, bool *found)
199+
adjustJoinTreeList(Query *parsetree, bool removert, int rt_index)
193200
{
194201
List *newjointree = listCopy(parsetree->jointree->fromlist);
195202
List *jjt;
196203

197-
*found = false;
198-
foreach(jjt, newjointree)
204+
if (removert)
199205
{
200-
RangeTblRef *rtr = lfirst(jjt);
201-
202-
if (IsA(rtr, RangeTblRef) && rtr->rtindex == rt_index)
206+
foreach(jjt, newjointree)
203207
{
204-
newjointree = lremove(rtr, newjointree);
205-
*found = true;
206-
break;
208+
RangeTblRef *rtr = lfirst(jjt);
209+
210+
if (IsA(rtr, RangeTblRef) && rtr->rtindex == rt_index)
211+
{
212+
newjointree = lremove(rtr, newjointree);
213+
break;
214+
}
207215
}
208216
}
209217
return newjointree;

0 commit comments

Comments
 (0)