1 /*-------------------------------------------------------------------------
5 * Copyright (c) 1994, Regents of the University of California
9 * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.8 1997/09/18 20:21:11 momjian Exp $
11 *-------------------------------------------------------------------------
15 #include "nodes/pg_list.h"
16 #include "utils/elog.h"
17 #include "nodes/nodes.h"
18 #include "nodes/relation.h"
19 #include "nodes/primnodes.h"
20 #include "parser/parsetree.h" /* for getrelid() */
21 #include "utils/lsyscache.h"
22 #include "utils/builtins.h"
23 #include "rewrite/rewriteHandler.h"
24 #include "rewrite/rewriteManip.h"
25 #include "rewrite/rewriteSupport.h"
26 #include "rewrite/locks.h"
28 #include "nodes/plannodes.h"
29 #include "optimizer/clauses.h"
31 static void ResolveNew(RewriteInfo *info, List *targetlist, Node **node);
36 OffsetVarNodes(Node *node, int offset)
40 switch (nodeTag(node))
44 TargetEntry *tle = (TargetEntry *) node;
46 OffsetVarNodes(tle->expr, offset);
51 Expr *expr = (Expr *) node;
53 OffsetVarNodes((Node *) expr->args, offset);
58 Var *var = (Var *) node;
61 var->varnoold += offset;
68 foreach(l, (List *) node)
70 OffsetVarNodes(lfirst(l), offset);
75 /* ignore the others */
81 ChangeVarNodes(Node *node, int old_varno, int new_varno)
85 switch (nodeTag(node))
89 TargetEntry *tle = (TargetEntry *) node;
91 ChangeVarNodes(tle->expr, old_varno, new_varno);
96 Expr *expr = (Expr *) node;
98 ChangeVarNodes((Node *) expr->args, old_varno, new_varno);
103 Var *var = (Var *) node;
105 if (var->varno == old_varno)
107 var->varno = new_varno;
108 var->varnoold = new_varno;
116 foreach(l, (List *) node)
118 ChangeVarNodes(lfirst(l), old_varno, new_varno);
123 /* ignore the others */
129 AddQual(Query *parsetree, Node *qual)
137 copy = copyObject(qual);
138 old = parsetree->qual;
140 parsetree->qual = copy;
143 (Node *) make_andclause(makeList(parsetree->qual, copy, -1));
147 AddNotQual(Query *parsetree, Node *qual)
154 copy = (Node *) make_notclause(copyObject(qual));
156 AddQual(parsetree, copy);
162 Const *c = makeNode(Const);
165 c->constlen = get_typlen(type);
166 c->constvalue = PointerGetDatum(NULL);
167 c->constisnull = true;
168 c->constbyval = get_typbyval(type);
173 FixResdomTypes(List *tlist)
179 TargetEntry *tle = lfirst(i);
181 if (nodeTag(tle->expr) == T_Var)
183 Var *var = (Var *) tle->expr;
185 tle->resdom->restype = var->vartype;
186 tle->resdom->reslen = get_typlen(var->vartype);
192 FindMatchingNew(List *tlist, int attno)
198 TargetEntry *tle = lfirst(i);
200 if (tle->resdom->resno == attno)
209 FindMatchingTLEntry(List *tlist, char *e_attname)
215 TargetEntry *tle = lfirst(i);
218 resname = tle->resdom->resname;
219 if (!strcmp(e_attname, resname))
226 ResolveNew(RewriteInfo *info, List *targetlist, Node **nodePtr)
228 Node *node = *nodePtr;
233 switch (nodeTag(node))
236 ResolveNew(info, targetlist, &((TargetEntry *) node)->expr);
239 ResolveNew(info, targetlist, (Node **) (&(((Expr *) node)->args)));
243 int this_varno = (int) ((Var *) node)->varno;
246 if (this_varno == info->new_varno)
248 n = FindMatchingNew(targetlist,
249 ((Var *) node)->varattno);
252 if (info->event == CMD_UPDATE)
254 ((Var *) node)->varno = info->current_varno;
255 ((Var *) node)->varnoold = info->current_varno;
259 *nodePtr = make_null(((Var *) node)->vartype);
273 foreach(l, (List *) node)
275 ResolveNew(info, targetlist, (Node **) &(lfirst(l)));
280 /* ignore the others */
286 FixNew(RewriteInfo *info, Query *parsetree)
288 ResolveNew(info, parsetree->targetList,
289 (Node **) &(info->rule_action->targetList));
290 ResolveNew(info, parsetree->targetList, &info->rule_action->qual);
294 nodeHandleRIRAttributeRule(Node **nodePtr,
302 Node *node = *nodePtr;
306 switch (nodeTag(node))
312 foreach(i, (List *) node)
314 nodeHandleRIRAttributeRule((Node **) (&(lfirst(i))), rtable,
315 targetlist, rt_index, attr_num,
322 TargetEntry *tle = (TargetEntry *) node;
324 nodeHandleRIRAttributeRule(&tle->expr, rtable, targetlist,
325 rt_index, attr_num, modified, badsql);
330 Expr *expr = (Expr *) node;
332 nodeHandleRIRAttributeRule((Node **) (&(expr->args)), rtable,
333 targetlist, rt_index, attr_num,
339 int this_varno = (int) ((Var *) node)->varno;
340 NameData name_to_look_for;
342 MemSet(name_to_look_for.data, 0, NAMEDATALEN);
344 if (this_varno == rt_index &&
345 ((Var *) node)->varattno == attr_num)
347 if (((Var *) node)->vartype == 32)
349 *nodePtr = make_null(((Var *) node)->vartype);
356 namestrcpy(&name_to_look_for,
357 (char *) get_attname(getrelid(this_varno,
362 if (name_to_look_for.data[0])
366 n = FindMatchingTLEntry(targetlist, (char *) &name_to_look_for);
369 *nodePtr = make_null(((Var *) node)->vartype);
380 /* ignore the others */
386 * Handles 'on retrieve to relation.attribute
387 * do instead retrieve (attribute = expression) w/qual'
390 HandleRIRAttributeRule(Query *parsetree,
398 nodeHandleRIRAttributeRule((Node **) (&(parsetree->targetList)), rtable,
399 targetlist, rt_index, attr_num,
401 nodeHandleRIRAttributeRule(&parsetree->qual, rtable, targetlist,
402 rt_index, attr_num, modified, badsql);
407 nodeHandleViewRule(Node **nodePtr,
413 Node *node = *nodePtr;
418 switch (nodeTag(node))
424 foreach(l, (List *) node)
426 nodeHandleViewRule((Node **) (&(lfirst(l))),
434 TargetEntry *tle = (TargetEntry *) node;
436 nodeHandleViewRule(&(tle->expr), rtable, targetlist,
442 Expr *expr = (Expr *) node;
444 nodeHandleViewRule((Node **) (&(expr->args)),
451 Var *var = (Var *) node;
452 int this_varno = var->varno;
455 if (this_varno == rt_index)
457 n = FindMatchingTLEntry(targetlist,
458 get_attname(getrelid(this_varno,
463 *nodePtr = make_null(((Var *) node)->vartype);
474 /* ignore the others */
480 HandleViewRule(Query *parsetree,
486 nodeHandleViewRule(&parsetree->qual, rtable, targetlist, rt_index,
488 nodeHandleViewRule((Node **) (&(parsetree->targetList)), rtable, targetlist,