|
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;
|
|