rewriteManip.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:24k
- /*-------------------------------------------------------------------------
- *
- * rewriteManip.c
- *
- * Copyright (c) 1994, Regents of the University of California
- *
- *
- * IDENTIFICATION
- * $Header: /usr/local/cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.32 1999/05/26 12:55:48 momjian Exp $
- *
- *-------------------------------------------------------------------------
- */
- #include <string.h>
- #include "postgres.h"
- #include "nodes/pg_list.h"
- #include "utils/elog.h"
- #include "nodes/nodes.h"
- #include "nodes/relation.h"
- #include "nodes/primnodes.h"
- #include "parser/parsetree.h" /* for getrelid() */
- #include "utils/lsyscache.h"
- #include "utils/builtins.h"
- #include "rewrite/rewriteHandler.h"
- #include "rewrite/rewriteManip.h"
- #include "rewrite/rewriteSupport.h"
- #include "rewrite/locks.h"
- #include "nodes/plannodes.h"
- #include "optimizer/clauses.h"
- static void ResolveNew(RewriteInfo *info, List *targetlist,
- Node **node, int sublevels_up);
- /*
- * OffsetVarnodes -
- */
- void
- OffsetVarNodes(Node *node, int offset, int sublevels_up)
- {
- if (node == NULL)
- return;
- switch (nodeTag(node))
- {
- case T_TargetEntry:
- {
- TargetEntry *tle = (TargetEntry *) node;
- OffsetVarNodes(
- (Node *) (tle->expr),
- offset,
- sublevels_up);
- }
- break;
- case T_Aggref:
- {
- Aggref *aggref = (Aggref *) node;
- OffsetVarNodes(
- (Node *) (aggref->target),
- offset,
- sublevels_up);
- }
- break;
- case T_GroupClause:
- break;
- case T_Expr:
- {
- Expr *exp = (Expr *) node;
- OffsetVarNodes(
- (Node *) (exp->args),
- offset,
- sublevels_up);
- }
- break;
- case T_Iter:
- {
- Iter *iter = (Iter *) node;
- OffsetVarNodes(
- (Node *) (iter->iterexpr),
- offset,
- sublevels_up);
- }
- break;
- case T_ArrayRef:
- {
- ArrayRef *ref = (ArrayRef *) node;
- OffsetVarNodes(
- (Node *) (ref->refupperindexpr),
- offset,
- sublevels_up);
- OffsetVarNodes(
- (Node *) (ref->reflowerindexpr),
- offset,
- sublevels_up);
- OffsetVarNodes(
- (Node *) (ref->refexpr),
- offset,
- sublevels_up);
- OffsetVarNodes(
- (Node *) (ref->refassgnexpr),
- offset,
- sublevels_up);
- }
- break;
- case T_Var:
- {
- Var *var = (Var *) node;
- if (var->varlevelsup == sublevels_up)
- {
- var->varno += offset;
- var->varnoold += offset;
- }
- }
- break;
- case T_Param:
- break;
- case T_Const:
- break;
- case T_List:
- {
- List *l;
- foreach(l, (List *) node)
- OffsetVarNodes(
- (Node *) lfirst(l),
- offset,
- sublevels_up);
- }
- break;
- case T_SubLink:
- {
- SubLink *sub = (SubLink *) node;
- List *tmp_oper,
- *tmp_lefthand;
- /*
- * We also have to adapt the variables used in
- * sub->lefthand and sub->oper
- */
- OffsetVarNodes(
- (Node *) (sub->lefthand),
- offset,
- sublevels_up);
- OffsetVarNodes(
- (Node *) (sub->subselect),
- offset,
- sublevels_up + 1);
- /***S*I***/
- /*
- * Make sure the first argument of sub->oper points to the
- * same var as sub->lefthand does otherwise we will run
- * into troubles using aggregates (aggno will not be set
- * correctly)
- */
- tmp_lefthand = sub->lefthand;
- foreach(tmp_oper, sub->oper)
- {
- lfirst(((Expr *) lfirst(tmp_oper))->args) =
- lfirst(tmp_lefthand);
- tmp_lefthand = lnext(tmp_lefthand);
- }
- }
- break;
- case T_Query:
- {
- Query *qry = (Query *) node;
- OffsetVarNodes(
- (Node *) (qry->targetList),
- offset,
- sublevels_up);
- OffsetVarNodes(
- (Node *) (qry->qual),
- offset,
- sublevels_up);
- OffsetVarNodes(
- (Node *) (qry->havingQual),
- offset,
- sublevels_up);
- }
- break;
- case T_CaseExpr:
- {
- CaseExpr *exp = (CaseExpr *) node;
- OffsetVarNodes(
- (Node *) (exp->args),
- offset,
- sublevels_up);
- OffsetVarNodes(
- (Node *) (exp->defresult),
- offset,
- sublevels_up);
- }
- break;
- case T_CaseWhen:
- {
- CaseWhen *exp = (CaseWhen *) node;
- OffsetVarNodes(
- (Node *) (exp->expr),
- offset,
- sublevels_up);
- OffsetVarNodes(
- (Node *) (exp->result),
- offset,
- sublevels_up);
- }
- break;
- default:
- elog(NOTICE, "unknown node tag %d in OffsetVarNodes()", nodeTag(node));
- elog(NOTICE, "Node is: %s", nodeToString(node));
- break;
- }
- }
- /*
- * ChangeVarNodes -
- */
- void
- ChangeVarNodes(Node *node, int rt_index, int new_index, int sublevels_up)
- {
- if (node == NULL)
- return;
- switch (nodeTag(node))
- {
- case T_TargetEntry:
- {
- TargetEntry *tle = (TargetEntry *) node;
- ChangeVarNodes(
- (Node *) (tle->expr),
- rt_index,
- new_index,
- sublevels_up);
- }
- break;
- case T_Aggref:
- {
- Aggref *aggref = (Aggref *) node;
- ChangeVarNodes(
- (Node *) (aggref->target),
- rt_index,
- new_index,
- sublevels_up);
- }
- break;
- case T_GroupClause:
- break;
- case T_Expr:
- {
- Expr *exp = (Expr *) node;
- ChangeVarNodes(
- (Node *) (exp->args),
- rt_index,
- new_index,
- sublevels_up);
- }
- break;
- case T_Iter:
- {
- Iter *iter = (Iter *) node;
- ChangeVarNodes(
- (Node *) (iter->iterexpr),
- rt_index,
- new_index,
- sublevels_up);
- }
- break;
- case T_ArrayRef:
- {
- ArrayRef *ref = (ArrayRef *) node;
- ChangeVarNodes(
- (Node *) (ref->refupperindexpr),
- rt_index,
- new_index,
- sublevels_up);
- ChangeVarNodes(
- (Node *) (ref->reflowerindexpr),
- rt_index,
- new_index,
- sublevels_up);
- ChangeVarNodes(
- (Node *) (ref->refexpr),
- rt_index,
- new_index,
- sublevels_up);
- ChangeVarNodes(
- (Node *) (ref->refassgnexpr),
- rt_index,
- new_index,
- sublevels_up);
- }
- break;
- case T_Var:
- {
- Var *var = (Var *) node;
- if (var->varlevelsup == sublevels_up &&
- var->varno == rt_index)
- {
- var->varno = new_index;
- var->varnoold = new_index;
- }
- }
- break;
- case T_Param:
- break;
- case T_Const:
- break;
- case T_List:
- {
- List *l;
- foreach(l, (List *) node)
- ChangeVarNodes(
- (Node *) lfirst(l),
- rt_index,
- new_index,
- sublevels_up);
- }
- break;
- case T_SubLink:
- {
- SubLink *sub = (SubLink *) node;
- List *tmp_oper,
- *tmp_lefthand;
- ChangeVarNodes(
- (Node *) (sub->lefthand),
- rt_index,
- new_index,
- sublevels_up);
- ChangeVarNodes(
- (Node *) (sub->subselect),
- rt_index,
- new_index,
- sublevels_up + 1);
- /***S*I***/
- /*
- * Make sure the first argument of sub->oper points to the
- * same var as sub->lefthand does otherwise we will run
- * into troubles using aggregates (aggno will not be set
- * correctly)
- */
- tmp_lefthand = sub->lefthand;
- foreach(tmp_oper, sub->oper)
- {
- lfirst(((Expr *) lfirst(tmp_oper))->args) =
- lfirst(tmp_lefthand);
- tmp_lefthand = lnext(tmp_lefthand);
- }
- }
- break;
- case T_Query:
- {
- Query *qry = (Query *) node;
- ChangeVarNodes(
- (Node *) (qry->targetList),
- rt_index,
- new_index,
- sublevels_up);
- ChangeVarNodes(
- (Node *) (qry->qual),
- rt_index,
- new_index,
- sublevels_up);
- ChangeVarNodes(
- (Node *) (qry->havingQual),
- rt_index,
- new_index,
- sublevels_up);
- }
- break;
- case T_CaseExpr:
- {
- CaseExpr *exp = (CaseExpr *) node;
- ChangeVarNodes(
- (Node *) (exp->args),
- rt_index,
- new_index,
- sublevels_up);
- ChangeVarNodes(
- (Node *) (exp->defresult),
- rt_index,
- new_index,
- sublevels_up);
- }
- break;
- case T_CaseWhen:
- {
- CaseWhen *exp = (CaseWhen *) node;
- ChangeVarNodes(
- (Node *) (exp->expr),
- rt_index,
- new_index,
- sublevels_up);
- ChangeVarNodes(
- (Node *) (exp->result),
- rt_index,
- new_index,
- sublevels_up);
- }
- break;
- default:
- elog(NOTICE, "unknown node tag %d in ChangeVarNodes()", nodeTag(node));
- elog(NOTICE, "Node is: %s", nodeToString(node));
- break;
- }
- }
- void
- AddQual(Query *parsetree, Node *qual)
- {
- Node *copy,
- *old;
- if (qual == NULL)
- return;
- /***S*I***/
- /* INTERSECT want's the original, but we need to copy - Jan */
- /* copy = qual; */
- copy = copyObject(qual);
- old = parsetree->qual;
- if (old == NULL)
- parsetree->qual = copy;
- else
- parsetree->qual = (Node *) make_andclause(makeList(parsetree->qual, copy, -1));
- }
- /* Adds the given havingQual to the one already contained in the parsetree just as
- * AddQual does for the normal 'where' qual */
- void
- AddHavingQual(Query *parsetree, Node *havingQual)
- {
- Node *copy,
- *old;
- if (havingQual == NULL)
- return;
- /***S*I***/
- /* INTERSECT want's the original, but we need to copy - Jan */
- /* copy = havingQual; */
- copy = copyObject(havingQual);
- old = parsetree->havingQual;
- if (old == NULL)
- parsetree->havingQual = copy;
- else
- parsetree->havingQual = (Node *) make_andclause(makeList(parsetree->havingQual, copy, -1));
- }
- #ifdef NOT_USED
- void
- AddNotHavingQual(Query *parsetree, Node *havingQual)
- {
- Node *copy;
- if (havingQual == NULL)
- return;
- /***S*I***/
- /* INTERSECT want's the original, but we need to copy - Jan */
- /* copy = (Node *) make_notclause((Expr *)havingQual); */
- copy = (Node *) make_notclause((Expr *) copyObject(havingQual));
- AddHavingQual(parsetree, copy);
- }
- #endif
- void
- AddNotQual(Query *parsetree, Node *qual)
- {
- Node *copy;
- if (qual == NULL)
- return;
- /***S*I***/
- /* INTERSECT want's the original, but we need to copy - Jan */
- /* copy = (Node *) make_notclause((Expr *)qual); */
- copy = (Node *) make_notclause((Expr *) copyObject(qual));
- AddQual(parsetree, copy);
- }
- void
- AddGroupClause(Query *parsetree, List *group_by, List *tlist)
- {
- List *l;
- List *tl;
- GroupClause *groupclause;
- TargetEntry *tle;
- int new_resno;
- new_resno = length(parsetree->targetList);
- foreach(l, group_by)
- {
- groupclause = (GroupClause *) copyObject(lfirst(l));
- tle = NULL;
- foreach(tl, tlist)
- {
- if (((TargetEntry *) lfirst(tl))->resdom->resgroupref ==
- groupclause->tleGroupref)
- {
- tle = (TargetEntry *) copyObject(lfirst(tl));
- break;
- }
- }
- if (tle == NULL)
- elog(ERROR, "AddGroupClause(): GROUP BY entry not found in rules targetlist");
- tle->resdom->resno = ++new_resno;
- tle->resdom->resjunk = true;
- tle->resdom->resgroupref = length(parsetree->groupClause) + 1;
- groupclause->tleGroupref = tle->resdom->resgroupref;
- parsetree->targetList = lappend(parsetree->targetList, tle);
- parsetree->groupClause = lappend(parsetree->groupClause, groupclause);
- }
- }
- static Node *
- make_null(Oid type)
- {
- Const *c = makeNode(Const);
- c->consttype = type;
- c->constlen = get_typlen(type);
- c->constvalue = PointerGetDatum(NULL);
- c->constisnull = true;
- c->constbyval = get_typbyval(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
- static Node *
- FindMatchingNew(List *tlist, int attno)
- {
- List *i;
- foreach(i, tlist)
- {
- TargetEntry *tle = lfirst(i);
- if (tle->resdom->resno == attno)
- return tle->expr;
- }
- return NULL;
- }
- static Node *
- FindMatchingTLEntry(List *tlist, char *e_attname)
- {
- List *i;
- foreach(i, tlist)
- {
- TargetEntry *tle = lfirst(i);
- char *resname;
- resname = tle->resdom->resname;
- if (!strcmp(e_attname, resname))
- return tle->expr;
- }
- return NULL;
- }
- static void
- ResolveNew(RewriteInfo *info, List *targetlist, Node **nodePtr,
- int sublevels_up)
- {
- Node *node = *nodePtr;
- if (node == NULL)
- return;
- switch (nodeTag(node))
- {
- case T_TargetEntry:
- ResolveNew(info, targetlist, &((TargetEntry *) node)->expr,
- sublevels_up);
- break;
- case T_Aggref:
- ResolveNew(info, targetlist, &((Aggref *) node)->target,
- sublevels_up);
- break;
- case T_Expr:
- ResolveNew(info, targetlist, (Node **) (&(((Expr *) node)->args)),
- sublevels_up);
- break;
- case T_Iter:
- ResolveNew(info, targetlist, (Node **) (&(((Iter *) node)->iterexpr)),
- sublevels_up);
- break;
- case T_ArrayRef:
- ResolveNew(info, targetlist, (Node **) (&(((ArrayRef *) node)->refupperindexpr)),
- sublevels_up);
- ResolveNew(info, targetlist, (Node **) (&(((ArrayRef *) node)->reflowerindexpr)),
- sublevels_up);
- ResolveNew(info, targetlist, (Node **) (&(((ArrayRef *) node)->refexpr)),
- sublevels_up);
- ResolveNew(info, targetlist, (Node **) (&(((ArrayRef *) node)->refassgnexpr)),
- sublevels_up);
- break;
- case T_Var:
- {
- int this_varno = (int) ((Var *) node)->varno;
- int this_varlevelsup = (int) ((Var *) node)->varlevelsup;
- Node *n;
- if (this_varno == info->new_varno &&
- this_varlevelsup == sublevels_up)
- {
- n = FindMatchingNew(targetlist,
- ((Var *) node)->varattno);
- if (n == NULL)
- {
- if (info->event == CMD_UPDATE)
- {
- *nodePtr = n = copyObject(node);
- ((Var *) n)->varno = info->current_varno;
- ((Var *) n)->varnoold = info->current_varno;
- }
- else
- *nodePtr = make_null(((Var *) node)->vartype);
- }
- else
- {
- *nodePtr = copyObject(n);
- ((Var *) *nodePtr)->varlevelsup = this_varlevelsup;
- }
- }
- break;
- }
- case T_List:
- {
- List *l;
- foreach(l, (List *) node)
- ResolveNew(info, targetlist, (Node **) &(lfirst(l)),
- sublevels_up);
- break;
- }
- case T_SubLink:
- {
- SubLink *sublink = (SubLink *) node;
- Query *query = (Query *) sublink->subselect;
- ResolveNew(info, targetlist, (Node **) &(query->qual), sublevels_up + 1);
- }
- break;
- case T_GroupClause:
- break;
- default:
- /* ignore the others */
- break;
- }
- }
- void
- FixNew(RewriteInfo *info, Query *parsetree)
- {
- ResolveNew(info, parsetree->targetList,
- (Node **) &(info->rule_action->targetList), 0);
- ResolveNew(info, parsetree->targetList,
- (Node **) &info->rule_action->qual, 0);
- ResolveNew(info, parsetree->targetList,
- (Node **) &(info->rule_action->groupClause), 0);
- }
- static void
- nodeHandleRIRAttributeRule(Node **nodePtr,
- List *rtable,
- List *targetlist,
- int rt_index,
- int attr_num,
- int *modified,
- int *badsql,
- int sublevels_up)
- {
- Node *node = *nodePtr;
- if (node == NULL)
- return;
- switch (nodeTag(node))
- {
- case T_TargetEntry:
- {
- TargetEntry *tle = (TargetEntry *) node;
- nodeHandleRIRAttributeRule(&tle->expr, rtable, targetlist,
- rt_index, attr_num, modified, badsql,
- sublevels_up);
- }
- break;
- case T_Aggref:
- {
- Aggref *aggref = (Aggref *) node;
- nodeHandleRIRAttributeRule(&aggref->target, rtable, targetlist,
- rt_index, attr_num, modified, badsql,
- sublevels_up);
- }
- break;
- case T_Expr:
- {
- Expr *expr = (Expr *) node;
- nodeHandleRIRAttributeRule((Node **) (&(expr->args)), rtable,
- targetlist, rt_index, attr_num,
- modified, badsql,
- sublevels_up);
- }
- break;
- case T_Iter:
- {
- Iter *iter = (Iter *) node;
- nodeHandleRIRAttributeRule((Node **) (&(iter->iterexpr)), rtable,
- targetlist, rt_index, attr_num,
- modified, badsql,
- sublevels_up);
- }
- break;
- case T_ArrayRef:
- {
- ArrayRef *ref = (ArrayRef *) node;
- nodeHandleRIRAttributeRule((Node **) (&(ref->refupperindexpr)), rtable,
- targetlist, rt_index, attr_num,
- modified, badsql,
- sublevels_up);
- nodeHandleRIRAttributeRule((Node **) (&(ref->reflowerindexpr)), rtable,
- targetlist, rt_index, attr_num,
- modified, badsql,
- sublevels_up);
- nodeHandleRIRAttributeRule((Node **) (&(ref->refexpr)), rtable,
- targetlist, rt_index, attr_num,
- modified, badsql,
- sublevels_up);
- nodeHandleRIRAttributeRule((Node **) (&(ref->refassgnexpr)), rtable,
- targetlist, rt_index, attr_num,
- modified, badsql,
- sublevels_up);
- }
- break;
- case T_Var:
- {
- int this_varno = ((Var *) node)->varno;
- int this_varattno = ((Var *) node)->varattno;
- int this_varlevelsup = ((Var *) node)->varlevelsup;
- if (this_varno == rt_index &&
- this_varattno == attr_num &&
- this_varlevelsup == sublevels_up)
- {
- if (((Var *) node)->vartype == 32)
- { /* HACK */
- *nodePtr = make_null(((Var *) node)->vartype);
- *modified = TRUE;
- *badsql = TRUE;
- break;
- }
- else
- {
- NameData name_to_look_for;
- name_to_look_for.data[0] = ' ';
- namestrcpy(&name_to_look_for,
- (char *) get_attname(getrelid(this_varno,
- rtable),
- attr_num));
- if (name_to_look_for.data[0])
- {
- Node *n;
- n = FindMatchingTLEntry(targetlist, (char *) &name_to_look_for);
- if (n == NULL)
- *nodePtr = make_null(((Var *) node)->vartype);
- else
- *nodePtr = n;
- *modified = TRUE;
- }
- }
- }
- }
- break;
- case T_List:
- {
- List *i;
- foreach(i, (List *) node)
- {
- nodeHandleRIRAttributeRule((Node **) (&(lfirst(i))), rtable,
- targetlist, rt_index, attr_num,
- modified, badsql, sublevels_up);
- }
- }
- break;
- case T_SubLink:
- {
- SubLink *sublink = (SubLink *) node;
- Query *query = (Query *) sublink->subselect;
- nodeHandleRIRAttributeRule((Node **) &(query->qual), rtable, targetlist,
- rt_index, attr_num, modified, badsql,
- sublevels_up + 1);
- }
- break;
- default:
- /* ignore the others */
- break;
- }
- }
- /*
- * Handles 'on retrieve to relation.attribute
- * do instead retrieve (attribute = expression) w/qual'
- */
- void
- HandleRIRAttributeRule(Query *parsetree,
- List *rtable,
- List *targetlist,
- int rt_index,
- int attr_num,
- int *modified,
- int *badsql)
- {
- nodeHandleRIRAttributeRule((Node **) (&(parsetree->targetList)), rtable,
- targetlist, rt_index, attr_num,
- modified, badsql, 0);
- nodeHandleRIRAttributeRule(&parsetree->qual, rtable, targetlist,
- rt_index, attr_num, modified, badsql, 0);
- }
- #ifdef NOT_USED
- static void
- nodeHandleViewRule(Node **nodePtr,
- List *rtable,
- List *targetlist,
- int rt_index,
- int *modified,
- int sublevels_up)
- {
- Node *node = *nodePtr;
- if (node == NULL)
- return;
- switch (nodeTag(node))
- {
- case T_TargetEntry:
- {
- TargetEntry *tle = (TargetEntry *) node;
- nodeHandleViewRule(&(tle->expr), rtable, targetlist,
- rt_index, modified, sublevels_up);
- }
- break;
- case T_Aggref:
- {
- Aggref *aggref = (Aggref *) node;
- nodeHandleViewRule(&(aggref->target), rtable, targetlist,
- rt_index, modified, sublevels_up);
- }
- break;
- /*
- * This has to be done to make queries using groupclauses work
- * on views
- */
- case T_GroupClause:
- {
- GroupClause *group = (GroupClause *) node;
- nodeHandleViewRule((Node **) (&(group->entry)), rtable, targetlist,
- rt_index, modified, sublevels_up);
- }
- break;
- case T_Expr:
- {
- Expr *expr = (Expr *) node;
- nodeHandleViewRule((Node **) (&(expr->args)),
- rtable, targetlist,
- rt_index, modified, sublevels_up);
- }
- break;
- case T_Iter:
- {
- Iter *iter = (Iter *) node;
- nodeHandleViewRule((Node **) (&(iter->iterexpr)),
- rtable, targetlist,
- rt_index, modified, sublevels_up);
- }
- break;
- case T_ArrayRef:
- {
- ArrayRef *ref = (ArrayRef *) node;
- nodeHandleViewRule((Node **) (&(ref->refupperindexpr)),
- rtable, targetlist,
- rt_index, modified, sublevels_up);
- nodeHandleViewRule((Node **) (&(ref->reflowerindexpr)),
- rtable, targetlist,
- rt_index, modified, sublevels_up);
- nodeHandleViewRule((Node **) (&(ref->refexpr)),
- rtable, targetlist,
- rt_index, modified, sublevels_up);
- nodeHandleViewRule((Node **) (&(ref->refassgnexpr)),
- rtable, targetlist,
- rt_index, modified, sublevels_up);
- }
- break;
- case T_Var:
- {
- Var *var = (Var *) node;
- int this_varno = var->varno;
- int this_varlevelsup = var->varlevelsup;
- Node *n;
- if (this_varno == rt_index &&
- this_varlevelsup == sublevels_up)
- {
- n = FindMatchingTLEntry(targetlist,
- get_attname(getrelid(this_varno,
- rtable),
- var->varattno));
- if (n == NULL)
- *nodePtr = make_null(((Var *) node)->vartype);
- else
- {
- /*
- * This is a hack: The varlevelsup of the orignal
- * variable and the new one should be the same.
- * Normally we adapt the node by changing a
- * pointer to point to a var contained in
- * 'targetlist'. In the targetlist all
- * varlevelsups are 0 so if we want to change it
- * to the original value we have to copy the node
- * before! (Maybe this will cause troubles with
- * some sophisticated queries on views?)
- */
- if (this_varlevelsup > 0)
- *nodePtr = copyObject(n);
- else
- *nodePtr = n;
- if (nodeTag(nodePtr) == T_Var)
- ((Var *) *nodePtr)->varlevelsup = this_varlevelsup;
- else
- nodeHandleViewRule(&n, rtable, targetlist,
- rt_index, modified, sublevels_up);
- }
- *modified = TRUE;
- }
- break;
- }
- case T_List:
- {
- List *l;
- foreach(l, (List *) node)
- {
- nodeHandleViewRule((Node **) (&(lfirst(l))),
- rtable, targetlist,
- rt_index, modified, sublevels_up);
- }
- }
- break;
- case T_SubLink:
- {
- SubLink *sublink = (SubLink *) node;
- Query *query = (Query *) sublink->subselect;
- List *tmp_lefthand,
- *tmp_oper;
- nodeHandleViewRule((Node **) &(query->qual), rtable, targetlist,
- rt_index, modified, sublevels_up + 1);
- /***S*H*D***/
- nodeHandleViewRule((Node **) &(query->havingQual), rtable, targetlist,
- rt_index, modified, sublevels_up + 1);
- nodeHandleViewRule((Node **) &(query->targetList), rtable, targetlist,
- rt_index, modified, sublevels_up + 1);
- /*
- * We also have to adapt the variables used in
- * sublink->lefthand and sublink->oper
- */
- nodeHandleViewRule((Node **) &(sublink->lefthand), rtable,
- targetlist, rt_index, modified, sublevels_up);
- /*
- * Make sure the first argument of sublink->oper points to
- * the same var as sublink->lefthand does otherwise we
- * will run into troubles using aggregates (aggno will not
- * be set correctly
- */
- pfree(lfirst(((Expr *) lfirst(sublink->oper))->args));
- lfirst(((Expr *) lfirst(sublink->oper))->args) =
- lfirst(sublink->lefthand);
- /***S*I***/
- /* INTERSECT want's this - Jan */
- /*
- * tmp_lefthand = sublink->lefthand; foreach(tmp_oper,
- * sublink->oper) { lfirst(((Expr *)
- * lfirst(tmp_oper))->args) = lfirst(tmp_lefthand);
- * tmp_lefthand = lnext(tmp_lefthand); }
- */
- }
- break;
- default:
- /* ignore the others */
- break;
- }
- }
- void
- HandleViewRule(Query *parsetree,
- List *rtable,
- List *targetlist,
- int rt_index,
- int *modified)
- {
- nodeHandleViewRule(&parsetree->qual, rtable, targetlist, rt_index,
- modified, 0);
- nodeHandleViewRule((Node **) (&(parsetree->targetList)), rtable, targetlist,
- rt_index, modified, 0);
- /*
- * The variables in the havingQual and groupClause also have to be
- * adapted
- */
- nodeHandleViewRule(&parsetree->havingQual, rtable, targetlist, rt_index,
- modified, 0);
- nodeHandleViewRule((Node **) (&(parsetree->groupClause)), rtable, targetlist, rt_index,
- modified, 0);
- }
- #endif