aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/rewrite/rewriteHandler.c58
1 files changed, 33 insertions, 25 deletions
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index e23d7005c94..505d5f4350b 100644
--- a/src/backend/rewrite/rewriteHandler.c
+++ b/src/backend/rewrite/rewriteHandler.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.88 2001/01/24 19:43:05 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.89 2001/01/27 04:40:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -37,7 +37,7 @@ static RewriteInfo *gatherRewriteMeta(Query *parsetree,
int rt_index,
CmdType event,
bool instead_flag);
-static List *adjustJoinTreeList(Query *parsetree, int rt_index, bool *found);
+static List *adjustJoinTreeList(Query *parsetree, bool removert, int rt_index);
static void markQueryForUpdate(Query *qry, bool skipOldNew);
static List *matchLocks(CmdType event, RuleLock *rulelocks,
int varno, Query *parsetree);
@@ -119,18 +119,25 @@ gatherRewriteMeta(Query *parsetree,
/*
* Each rule action's jointree should be the main parsetree's jointree
- * plus that rule's jointree, but *without* the original rtindex
+ * plus that rule's jointree, but usually *without* the original rtindex
* that we're replacing (if present, which it won't be for INSERT).
- * Note that if the rule refers to OLD, its jointree will add back
- * a reference to rt_index.
+ * Note that if the rule action refers to OLD, its jointree will add
+ * a reference to rt_index. If the rule action doesn't refer to OLD,
+ * but either the rule_qual or the user query quals do, then we need to
+ * keep the original rtindex in the jointree to provide 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.
*/
if (sub_action->jointree != NULL)
{
- bool found;
- List *newjointree = adjustJoinTreeList(parsetree,
- rt_index,
- &found);
-
+ bool keeporig;
+ List *newjointree;
+
+ keeporig = (! rangeTableEntry_used((Node *) sub_action->jointree,
+ rt_index, 0)) &&
+ (rangeTableEntry_used(info->rule_qual, rt_index, 0) ||
+ rangeTableEntry_used(parsetree->jointree->quals, rt_index, 0));
+ newjointree = adjustJoinTreeList(parsetree, !keeporig, rt_index);
sub_action->jointree->fromlist =
nconc(newjointree, sub_action->jointree->fromlist);
}
@@ -181,29 +188,30 @@ gatherRewriteMeta(Query *parsetree,
}
/*
- * Copy the query's jointree list, and attempt to remove any 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. *found is set to indicate if we found the rt_index.
+ * Copy the query's jointree list, and optionally attempt to remove any
+ * 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.
*/
static List *
-adjustJoinTreeList(Query *parsetree, int rt_index, bool *found)
+adjustJoinTreeList(Query *parsetree, bool removert, int rt_index)
{
List *newjointree = listCopy(parsetree->jointree->fromlist);
List *jjt;
- *found = false;
- foreach(jjt, newjointree)
+ if (removert)
{
- RangeTblRef *rtr = lfirst(jjt);
-
- if (IsA(rtr, RangeTblRef) && rtr->rtindex == rt_index)
+ foreach(jjt, newjointree)
{
- newjointree = lremove(rtr, newjointree);
- *found = true;
- break;
+ RangeTblRef *rtr = lfirst(jjt);
+
+ if (IsA(rtr, RangeTblRef) && rtr->rtindex == rt_index)
+ {
+ newjointree = lremove(rtr, newjointree);
+ break;
+ }
}
}
return newjointree;