|
7 | 7 | * |
8 | 8 | * |
9 | 9 | * 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 $ |
11 | 11 | * |
12 | 12 | *------------------------------------------------------------------------- |
13 | 13 | */ |
@@ -37,7 +37,7 @@ static RewriteInfo *gatherRewriteMeta(Query *parsetree, |
37 | 37 | intrt_index, |
38 | 38 | CmdTypeevent, |
39 | 39 | boolinstead_flag); |
40 | | -staticList*adjustJoinTreeList(Query*parsetree,intrt_index,bool*found); |
| 40 | +staticList*adjustJoinTreeList(Query*parsetree,boolremovert,intrt_index); |
41 | 41 | staticvoidmarkQueryForUpdate(Query*qry,boolskipOldNew); |
42 | 42 | staticList*matchLocks(CmdTypeevent,RuleLock*rulelocks, |
43 | 43 | intvarno,Query*parsetree); |
@@ -119,18 +119,25 @@ gatherRewriteMeta(Query *parsetree, |
119 | 119 |
|
120 | 120 | /* |
121 | 121 | * 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, butusually*without* the original rtindex |
123 | 123 | * 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. |
126 | 130 | */ |
127 | 131 | if (sub_action->jointree!=NULL) |
128 | 132 | { |
129 | | -boolfound; |
130 | | -List*newjointree=adjustJoinTreeList(parsetree, |
131 | | -rt_index, |
132 | | -&found); |
133 | | - |
| 133 | +boolkeeporig; |
| 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); |
134 | 141 | sub_action->jointree->fromlist= |
135 | 142 | nconc(newjointree,sub_action->jointree->fromlist); |
136 | 143 | } |
@@ -181,29 +188,30 @@ gatherRewriteMeta(Query *parsetree, |
181 | 188 | } |
182 | 189 |
|
183 | 190 | /* |
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 notchanged. *found is set to indicate if we found the rt_index. |
| 191 | + * Copy the query's jointree list, andoptionallyattempt to remove any |
| 192 | + *occurrenceof the given rt_index as a top-level join item (we do not look |
| 193 | + *for itwithin join items; this is OK because we are only expecting to find |
| 194 | + *itas 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. |
190 | 197 | */ |
191 | 198 | staticList* |
192 | | -adjustJoinTreeList(Query*parsetree,intrt_index,bool*found) |
| 199 | +adjustJoinTreeList(Query*parsetree,boolremovert,intrt_index) |
193 | 200 | { |
194 | 201 | List*newjointree=listCopy(parsetree->jointree->fromlist); |
195 | 202 | List*jjt; |
196 | 203 |
|
197 | | -*found= false; |
198 | | -foreach(jjt,newjointree) |
| 204 | +if (removert) |
199 | 205 | { |
200 | | -RangeTblRef*rtr=lfirst(jjt); |
201 | | - |
202 | | -if (IsA(rtr,RangeTblRef)&&rtr->rtindex==rt_index) |
| 206 | +foreach(jjt,newjointree) |
203 | 207 | { |
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 | +} |
207 | 215 | } |
208 | 216 | } |
209 | 217 | returnnewjointree; |
|