1 /*-------------------------------------------------------------------------
5 * Copyright (c) 1994, Regents of the University of California
9 * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.1.1.1 1996/07/09 06:21:52 scrappy Exp $
11 *-------------------------------------------------------------------------
14 #include "nodes/pg_list.h"
15 #include "utils/elog.h"
16 #include "nodes/nodes.h"
17 #include "nodes/relation.h"
18 #include "nodes/primnodes.h"
19 #include "parser/parsetree.h" /* for getrelid() */
20 #include "utils/lsyscache.h"
21 #include "utils/builtins.h"
22 #include "rewrite/rewriteHandler.h"
23 #include "rewrite/rewriteSupport.h"
24 #include "rewrite/locks.h"
26 #include "nodes/plannodes.h"
27 #include "optimizer/clauses.h"
29 static void ResolveNew(RewriteInfo *info, List *targetlist, Node **node);
34 OffsetVarNodes(Node *node, int offset)
38 switch (nodeTag(node)) {
41 TargetEntry *tle = (TargetEntry *)node;
42 OffsetVarNodes(tle->expr, offset);
47 Expr *expr = (Expr*)node;
48 OffsetVarNodes((Node*)expr->args, offset);
53 Var *var = (Var*)node;
55 var->varnoold += offset;
62 foreach(l, (List*)node) {
63 OffsetVarNodes(lfirst(l), offset);
68 /* ignore the others */
74 ChangeVarNodes(Node *node, int old_varno, int new_varno)
78 switch (nodeTag(node)) {
81 TargetEntry *tle = (TargetEntry *)node;
82 ChangeVarNodes(tle->expr, old_varno, new_varno);
87 Expr *expr = (Expr*)node;
88 ChangeVarNodes((Node*)expr->args, old_varno, new_varno);
93 Var *var = (Var*)node;
94 if (var->varno == old_varno) {
95 var->varno = new_varno;
96 var->varnoold = new_varno;
103 foreach (l, (List*)node) {
104 ChangeVarNodes(lfirst(l), old_varno, new_varno);
109 /* ignore the others */
115 AddQual(Query *parsetree, Node *qual)
122 copy = copyObject(qual);
123 old = parsetree->qual;
125 parsetree->qual = copy;
128 (Node*)make_andclause(makeList(parsetree->qual, copy, -1));
132 AddNotQual(Query *parsetree, Node *qual)
136 if (qual == NULL) return;
138 copy = (Node*)make_notclause(copyObject(qual));
140 AddQual(parsetree,copy);
146 Const *c = makeNode(Const);
149 c->constlen = get_typlen(type);
150 c->constvalue = PointerGetDatum(NULL);
151 c->constisnull = true;
152 c->constbyval = get_typbyval(type);
157 FixResdomTypes (List *tlist)
162 TargetEntry *tle = lfirst(i);
164 if (nodeTag(tle->expr) == T_Var) {
165 Var *var = (Var*)tle->expr;
167 tle->resdom->restype = var->vartype;
168 tle->resdom->reslen = get_typlen(var->vartype);
174 FindMatchingNew(List *tlist, int attno)
178 foreach (i, tlist ) {
179 TargetEntry *tle = lfirst(i);
181 if (tle->resdom->resno == attno ) {
189 FindMatchingTLEntry(List *tlist, char *e_attname)
194 TargetEntry *tle = lfirst(i);
197 resname = tle->resdom->resname;
198 if (!strcmp(e_attname, resname))
205 ResolveNew(RewriteInfo *info, List *targetlist, Node **nodePtr)
207 Node *node = *nodePtr;
212 switch(nodeTag(node)) {
214 ResolveNew(info, targetlist, &((TargetEntry*)node)->expr);
217 ResolveNew(info, targetlist, (Node**)(&(((Expr*)node)->args)));
220 int this_varno = (int)((Var*)node)->varno;
223 if (this_varno == info->new_varno) {
224 n = FindMatchingNew(targetlist,
225 ((Var*)node)->varattno);
227 if (info->event == CMD_UPDATE) {
228 ((Var*)node)->varno = info->current_varno;
229 ((Var*)node)->varnoold = info->current_varno;
231 *nodePtr = make_null(((Var*)node)->vartype);
241 foreach(l, (List*)node) {
242 ResolveNew(info, targetlist, (Node**)&(lfirst(l)));
247 /* ignore the others */
253 FixNew(RewriteInfo* info, Query *parsetree)
255 ResolveNew(info, parsetree->targetList,
256 (Node**)&(info->rule_action->targetList));
257 ResolveNew(info, parsetree->targetList, &info->rule_action->qual);
261 nodeHandleRIRAttributeRule(Node **nodePtr,
269 Node *node = *nodePtr;
273 switch (nodeTag(node)) {
277 foreach(i, (List*)node) {
278 nodeHandleRIRAttributeRule((Node**)(&(lfirst(i))), rtable,
279 targetlist, rt_index, attr_num,
286 TargetEntry *tle = (TargetEntry *)node;
287 nodeHandleRIRAttributeRule(&tle->expr, rtable, targetlist,
288 rt_index, attr_num, modified, badsql);
293 Expr *expr = (Expr *)node;
294 nodeHandleRIRAttributeRule((Node**)(&(expr->args)), rtable,
295 targetlist, rt_index, attr_num,
301 int this_varno = (int) ((Var*)node)->varno;
302 NameData name_to_look_for;
303 memset(name_to_look_for.data, 0, NAMEDATALEN);
305 if (this_varno == rt_index &&
306 ((Var*) node)->varattno == attr_num) {
307 if (((Var*)node)->vartype == 32) { /* HACK */
308 *nodePtr = make_null(((Var*)node)->vartype);
313 namestrcpy(&name_to_look_for,
314 (char *)get_attname(getrelid(this_varno,
319 if (name_to_look_for.data[0]) {
322 n = FindMatchingTLEntry(targetlist, &name_to_look_for);
324 *nodePtr = make_null(((Var*) node)->vartype);
333 /* ignore the others */
339 * Handles 'on retrieve to relation.attribute
340 * do instead retrieve (attribute = expression) w/qual'
343 HandleRIRAttributeRule(Query *parsetree,
351 nodeHandleRIRAttributeRule((Node**)(&(parsetree->targetList)), rtable,
352 targetlist, rt_index, attr_num,
354 nodeHandleRIRAttributeRule(&parsetree->qual, rtable, targetlist,
355 rt_index, attr_num, modified, badsql);
360 nodeHandleViewRule(Node **nodePtr,
366 Node *node = *nodePtr;
371 switch (nodeTag(node)) {
375 foreach (l, (List*)node) {
376 nodeHandleViewRule((Node**) (&(lfirst(l))),
384 TargetEntry *tle = (TargetEntry *)node;
385 nodeHandleViewRule(&(tle->expr), rtable, targetlist,
391 Expr *expr = (Expr*)node;
392 nodeHandleViewRule((Node**)(&(expr->args)),
399 Var *var = (Var*)node;
400 int this_varno = var->varno;
403 if (this_varno == rt_index) {
404 n = FindMatchingTLEntry(targetlist,
405 get_attname(getrelid(this_varno,
409 *nodePtr = make_null(((Var*) node)->vartype);
418 /* ignore the others */
424 HandleViewRule(Query *parsetree,
430 nodeHandleViewRule(&parsetree->qual, rtable, targetlist, rt_index,
432 nodeHandleViewRule((Node**)(&(parsetree->targetList)), rtable, targetlist,