summaryrefslogtreecommitdiff
path: root/src/backend/rewrite/rewriteManip.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/rewrite/rewriteManip.c')
-rw-r--r--src/backend/rewrite/rewriteManip.c179
1 files changed, 66 insertions, 113 deletions
diff --git a/src/backend/rewrite/rewriteManip.c b/src/backend/rewrite/rewriteManip.c
index e83ac05485..0b07b5e9c4 100644
--- a/src/backend/rewrite/rewriteManip.c
+++ b/src/backend/rewrite/rewriteManip.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.48 2000/09/12 21:07:04 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.49 2000/09/29 18:21:24 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -473,8 +473,7 @@ attribute_used(Node *node, int rt_index, int attno, int sublevels_up)
void
AddQual(Query *parsetree, Node *qual)
{
- Node *copy,
- *old;
+ Node *copy;
if (qual == NULL)
return;
@@ -482,11 +481,8 @@ AddQual(Query *parsetree, Node *qual)
/* INTERSECT want's the original, but we need to copy - Jan */
copy = copyObject(qual);
- old = parsetree->qual;
- if (old == NULL)
- parsetree->qual = copy;
- else
- parsetree->qual = (Node *) make_andclause(makeList(old, copy, -1));
+ parsetree->jointree->quals = make_and_qual(parsetree->jointree->quals,
+ copy);
/*
* Make sure query is marked correctly if added qual has sublinks or
@@ -504,8 +500,7 @@ AddQual(Query *parsetree, Node *qual)
void
AddHavingQual(Query *parsetree, Node *havingQual)
{
- Node *copy,
- *old;
+ Node *copy;
if (havingQual == NULL)
return;
@@ -513,11 +508,8 @@ AddHavingQual(Query *parsetree, Node *havingQual)
/* INTERSECT want's the original, but we need to copy - Jan */
copy = copyObject(havingQual);
- old = parsetree->havingQual;
- if (old == NULL)
- parsetree->havingQual = copy;
- else
- parsetree->havingQual = (Node *) make_andclause(makeList(old, copy, -1));
+ parsetree->havingQual = make_and_qual(parsetree->havingQual,
+ copy);
/*
* Make sure query is marked correctly if added qual has sublinks or
@@ -560,45 +552,7 @@ AddNotQual(Query *parsetree, Node *qual)
}
-/*
- * Add all expressions used by the given GroupClause list to the
- * parsetree's targetlist and groupclause list.
- *
- * tlist is the old targetlist associated with the input groupclauses.
- *
- * XXX shouldn't we be checking to see if there are already matching
- * entries in parsetree->targetlist?
- */
-void
-AddGroupClause(Query *parsetree, List *group_by, List *tlist)
-{
- List *l;
-
- foreach(l, group_by)
- {
- GroupClause *groupclause = (GroupClause *) copyObject(lfirst(l));
- TargetEntry *tle = get_sortgroupclause_tle(groupclause, tlist);
-
- /* copy the groupclause's TLE from the old tlist */
- tle = (TargetEntry *) copyObject(tle);
-
- /*
- * The ressortgroupref number in the old tlist might be already
- * taken in the new tlist, so force assignment of a new number.
- */
- tle->resdom->ressortgroupref = 0;
- groupclause->tleSortGroupRef =
- assignSortGroupRef(tle, parsetree->targetList);
-
- /* Also need to set the resno and mark it resjunk. */
- tle->resdom->resno = length(parsetree->targetList) + 1;
- tle->resdom->resjunk = true;
-
- parsetree->targetList = lappend(parsetree->targetList, tle);
- parsetree->groupClause = lappend(parsetree->groupClause, groupclause);
- }
-}
-
+/* Build a NULL constant expression of the given type */
static Node *
make_null(Oid type)
{
@@ -612,28 +566,6 @@ make_null(Oid type)
return (Node *) c;
}
-#ifdef NOT_USED
-void
-FixResdomTypes(List *tlist)
-{
- List *i;
-
- foreach(i, tlist)
- {
- TargetEntry *tle = lfirst(i);
-
- if (nodeTag(tle->expr) == T_Var)
- {
- Var *var = (Var *) tle->expr;
-
- tle->resdom->restype = var->vartype;
- tle->resdom->restypmod = var->vartypmod;
- }
- }
-}
-
-#endif
-
/* Find a targetlist entry by resno */
static Node *
FindMatchingNew(List *tlist, int attno)
@@ -650,6 +582,8 @@ FindMatchingNew(List *tlist, int attno)
return NULL;
}
+#ifdef NOT_USED
+
/* Find a targetlist entry by resname */
static Node *
FindMatchingTLEntry(List *tlist, char *e_attname)
@@ -662,25 +596,31 @@ FindMatchingTLEntry(List *tlist, char *e_attname)
char *resname;
resname = tle->resdom->resname;
- if (!strcmp(e_attname, resname))
+ if (strcmp(e_attname, resname) == 0)
return tle->expr;
}
return NULL;
}
+#endif
+
/*
* ResolveNew - replace Vars with corresponding items from a targetlist
*
- * Vars matching info->new_varno and sublevels_up are replaced by the
+ * Vars matching target_varno and sublevels_up are replaced by the
* entry with matching resno from targetlist, if there is one.
+ * If not, we either change the unmatched Var's varno to update_varno
+ * (when event == CMD_UPDATE) or replace it with a constant NULL.
*/
typedef struct
{
- RewriteInfo *info;
- List *targetlist;
+ int target_varno;
int sublevels_up;
+ List *targetlist;
+ int event;
+ int update_varno;
} ResolveNew_context;
static Node *
@@ -694,7 +634,7 @@ ResolveNew_mutator(Node *node, ResolveNew_context *context)
int this_varno = (int) var->varno;
int this_varlevelsup = (int) var->varlevelsup;
- if (this_varno == context->info->new_varno &&
+ if (this_varno == context->target_varno &&
this_varlevelsup == context->sublevels_up)
{
Node *n = FindMatchingNew(context->targetlist,
@@ -702,13 +642,13 @@ ResolveNew_mutator(Node *node, ResolveNew_context *context)
if (n == NULL)
{
- if (context->info->event == CMD_UPDATE)
+ if (context->event == CMD_UPDATE)
{
/* For update, just change unmatched var's varno */
- n = copyObject(node);
- ((Var *) n)->varno = context->info->current_varno;
- ((Var *) n)->varnoold = context->info->current_varno;
- return n;
+ var = (Var *) copyObject(node);
+ var->varno = context->update_varno;
+ var->varnoold = context->update_varno;
+ return (Node *) var;
}
else
{
@@ -755,54 +695,68 @@ ResolveNew_mutator(Node *node, ResolveNew_context *context)
FLATCOPY(newnode, query, Query);
MUTATE(newnode->targetList, query->targetList, List *,
ResolveNew_mutator, context);
- MUTATE(newnode->qual, query->qual, Node *,
+ MUTATE(newnode->jointree, query->jointree, FromExpr *,
ResolveNew_mutator, context);
MUTATE(newnode->havingQual, query->havingQual, Node *,
ResolveNew_mutator, context);
- MUTATE(newnode->jointree, query->jointree, List *,
- ResolveNew_mutator, context);
return (Node *) newnode;
}
return expression_tree_mutator(node, ResolveNew_mutator,
(void *) context);
}
-static Node *
-ResolveNew(Node *node, RewriteInfo *info, List *targetlist,
- int sublevels_up)
+Node *
+ResolveNew(Node *node, int target_varno, int sublevels_up,
+ List *targetlist, int event, int update_varno)
{
ResolveNew_context context;
- context.info = info;
- context.targetlist = targetlist;
+ context.target_varno = target_varno;
context.sublevels_up = sublevels_up;
+ context.targetlist = targetlist;
+ context.event = event;
+ context.update_varno = update_varno;
+ /*
+ * Note: if an entire Query is passed, the right things will happen,
+ * because ResolveNew_mutator increments sublevels_up when it sees
+ * a SubLink, not a Query.
+ */
return ResolveNew_mutator(node, &context);
}
+/*
+ * Alternate interface to ResolveNew: substitute Vars in info->rule_action
+ * with targetlist items from the parsetree's targetlist.
+ */
void
FixNew(RewriteInfo *info, Query *parsetree)
{
+ ResolveNew_context context;
+
+ context.target_varno = info->new_varno;
+ context.sublevels_up = 0;
+ context.targetlist = parsetree->targetList;
+ context.event = info->event;
+ context.update_varno = info->current_varno;
+
info->rule_action->targetList = (List *)
- ResolveNew((Node *) info->rule_action->targetList,
- info, parsetree->targetList, 0);
- info->rule_action->qual = ResolveNew(info->rule_action->qual,
- info, parsetree->targetList, 0);
- info->rule_action->havingQual = ResolveNew(info->rule_action->havingQual,
- info, parsetree->targetList, 0);
- info->rule_action->jointree = (List *)
- ResolveNew((Node *) info->rule_action->jointree,
- info, parsetree->targetList, 0);
+ ResolveNew_mutator((Node *) info->rule_action->targetList, &context);
+ info->rule_action->jointree = (FromExpr *)
+ ResolveNew_mutator((Node *) info->rule_action->jointree, &context);
+ info->rule_action->havingQual =
+ ResolveNew_mutator(info->rule_action->havingQual, &context);
}
+
+#ifdef NOT_USED
+
/*
* HandleRIRAttributeRule
* Replace Vars matching a given RT index with copies of TL expressions.
*
* Handles 'on retrieve to relation.attribute
* do instead retrieve (attribute = expression) w/qual'
- *
- * XXX Why is this not unified with apply_RIR_view()?
*/
typedef struct
@@ -897,12 +851,12 @@ HandleRIRAttributeRule_mutator(Node *node,
FLATCOPY(newnode, query, Query);
MUTATE(newnode->targetList, query->targetList, List *,
HandleRIRAttributeRule_mutator, context);
- MUTATE(newnode->qual, query->qual, Node *,
+ MUTATE(newnode->jointree, query->jointree, FromExpr *,
HandleRIRAttributeRule_mutator, context);
MUTATE(newnode->havingQual, query->havingQual, Node *,
HandleRIRAttributeRule_mutator, context);
- MUTATE(newnode->jointree, query->jointree, List *,
- HandleRIRAttributeRule_mutator, context);
+
+
return (Node *) newnode;
}
return expression_tree_mutator(node, HandleRIRAttributeRule_mutator,
@@ -931,13 +885,12 @@ HandleRIRAttributeRule(Query *parsetree,
parsetree->targetList = (List *)
HandleRIRAttributeRule_mutator((Node *) parsetree->targetList,
&context);
- parsetree->qual =
- HandleRIRAttributeRule_mutator(parsetree->qual,
+ parsetree->jointree = (FromExpr *)
+ HandleRIRAttributeRule_mutator((Node *) parsetree->jointree,
&context);
parsetree->havingQual =
HandleRIRAttributeRule_mutator(parsetree->havingQual,
&context);
- parsetree->jointree = (List *)
- HandleRIRAttributeRule_mutator((Node *) parsetree->jointree,
- &context);
}
+
+#endif /* NOT_USED */