]> granicus.if.org Git - postgresql/blob - src/backend/rewrite/rewriteHandler.c
a1d9122f828e9146974fa1571ed77e3dbc78078a
[postgresql] / src / backend / rewrite / rewriteHandler.c
1 /*-------------------------------------------------------------------------
2  *
3  * rewriteHandler.c
4  *              Primary module of query rewriter.
5  *
6  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  * IDENTIFICATION
10  *        $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.122 2003/07/03 16:34:25 tgl Exp $
11  *
12  *-------------------------------------------------------------------------
13  */
14 #include "postgres.h"
15
16 #include "access/heapam.h"
17 #include "catalog/pg_operator.h"
18 #include "catalog/pg_type.h"
19 #include "miscadmin.h"
20 #include "nodes/makefuncs.h"
21 #include "optimizer/clauses.h"
22 #include "optimizer/prep.h"
23 #include "optimizer/var.h"
24 #include "parser/analyze.h"
25 #include "parser/parse_coerce.h"
26 #include "parser/parse_expr.h"
27 #include "parser/parse_oper.h"
28 #include "parser/parse_type.h"
29 #include "parser/parsetree.h"
30 #include "rewrite/rewriteHandler.h"
31 #include "rewrite/rewriteManip.h"
32 #include "utils/builtins.h"
33 #include "utils/lsyscache.h"
34
35
36 /* We use a list of these to detect recursion in RewriteQuery */
37 typedef struct rewrite_event {
38         Oid                     relation;               /* OID of relation having rules */
39         CmdType         event;                  /* type of rule being fired */
40 } rewrite_event;
41
42 static Query *rewriteRuleAction(Query *parsetree,
43                                   Query *rule_action,
44                                   Node *rule_qual,
45                                   int rt_index,
46                                   CmdType event);
47 static List *adjustJoinTreeList(Query *parsetree, bool removert, int rt_index);
48 static void rewriteTargetList(Query *parsetree, Relation target_relation);
49 static TargetEntry *process_matched_tle(TargetEntry *src_tle,
50                                         TargetEntry *prior_tle);
51 static void markQueryForUpdate(Query *qry, bool skipOldNew);
52 static List *matchLocks(CmdType event, RuleLock *rulelocks,
53                    int varno, Query *parsetree);
54 static Query *fireRIRrules(Query *parsetree, List *activeRIRs);
55
56
57 /*
58  * rewriteRuleAction -
59  *        Rewrite the rule action with appropriate qualifiers (taken from
60  *        the triggering query).
61  */
62 static Query *
63 rewriteRuleAction(Query *parsetree,
64                                   Query *rule_action,
65                                   Node *rule_qual,
66                                   int rt_index,
67                                   CmdType event)
68 {
69         int                     current_varno,
70                                 new_varno;
71         List       *main_rtable;
72         int                     rt_length;
73         Query      *sub_action;
74         Query     **sub_action_ptr;
75         List       *rt;
76
77         /*
78          * Make modifiable copies of rule action and qual (what we're passed
79          * are the stored versions in the relcache; don't touch 'em!).
80          */
81         rule_action = (Query *) copyObject(rule_action);
82         rule_qual = (Node *) copyObject(rule_qual);
83
84         current_varno = rt_index;
85         rt_length = length(parsetree->rtable);
86         new_varno = PRS2_NEW_VARNO + rt_length;
87
88         /*
89          * Adjust rule action and qual to offset its varnos, so that we can
90          * merge its rtable with the main parsetree's rtable.
91          *
92          * If the rule action is an INSERT...SELECT, the OLD/NEW rtable entries
93          * will be in the SELECT part, and we have to modify that rather than
94          * the top-level INSERT (kluge!).
95          */
96         sub_action = getInsertSelectQuery(rule_action, &sub_action_ptr);
97
98         OffsetVarNodes((Node *) sub_action, rt_length, 0);
99         OffsetVarNodes(rule_qual, rt_length, 0);
100         /* but references to *OLD* should point at original rt_index */
101         ChangeVarNodes((Node *) sub_action,
102                                    PRS2_OLD_VARNO + rt_length, rt_index, 0);
103         ChangeVarNodes(rule_qual,
104                                    PRS2_OLD_VARNO + rt_length, rt_index, 0);
105
106         /*
107          * Generate expanded rtable consisting of main parsetree's rtable plus
108          * rule action's rtable; this becomes the complete rtable for the rule
109          * action.      Some of the entries may be unused after we finish
110          * rewriting, but if we tried to remove them we'd have a much
111          * harder job to adjust RT indexes in the query's Vars.  It's OK to
112          * have unused RT entries, since planner will ignore them.
113          *
114          * NOTE: because planner will destructively alter rtable, we must ensure
115          * that rule action's rtable is separate and shares no substructure
116          * with the main rtable.  Hence do a deep copy here.
117          *
118          * Also, we must disable write-access checking in all the RT entries
119          * copied from the main query.  This is safe since in fact the rule action
120          * won't write on them, and it's necessary because the rule action may
121          * have a different commandType than the main query, causing
122          * ExecCheckRTEPerms() to make an inappropriate check.  The read-access
123          * checks can be left enabled, although they're probably redundant.
124          */
125         main_rtable = (List *) copyObject(parsetree->rtable);
126
127         foreach(rt, main_rtable)
128         {
129                 RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
130
131                 rte->checkForWrite = false;
132         }
133
134         sub_action->rtable = nconc(main_rtable, sub_action->rtable);
135
136         /*
137          * Each rule action's jointree should be the main parsetree's jointree
138          * plus that rule's jointree, but usually *without* the original
139          * rtindex that we're replacing (if present, which it won't be for
140          * INSERT). Note that if the rule action refers to OLD, its jointree
141          * will add a reference to rt_index.  If the rule action doesn't refer
142          * to OLD, but either the rule_qual or the user query quals do, then
143          * we need to keep the original rtindex in the jointree to provide
144          * data for the quals.  We don't want the original rtindex to be
145          * joined twice, however, so avoid keeping it if the rule action
146          * mentions it.
147          *
148          * As above, the action's jointree must not share substructure with the
149          * main parsetree's.
150          */
151         if (sub_action->jointree != NULL)
152         {
153                 bool            keeporig;
154                 List       *newjointree;
155
156                 keeporig = (!rangeTableEntry_used((Node *) sub_action->jointree,
157                                                                                   rt_index, 0)) &&
158                         (rangeTableEntry_used(rule_qual, rt_index, 0) ||
159                   rangeTableEntry_used(parsetree->jointree->quals, rt_index, 0));
160                 newjointree = adjustJoinTreeList(parsetree, !keeporig, rt_index);
161                 sub_action->jointree->fromlist =
162                         nconc(newjointree, sub_action->jointree->fromlist);
163         }
164
165         /*
166          * We copy the qualifications of the parsetree to the action and vice
167          * versa. So force hasSubLinks if one of them has it. If this is not
168          * right, the flag will get cleared later, but we mustn't risk having
169          * it not set when it needs to be.      (XXX this should probably be
170          * handled by AddQual and friends, not here...)
171          */
172         if (parsetree->hasSubLinks)
173                 sub_action->hasSubLinks = TRUE;
174         else if (sub_action->hasSubLinks)
175                 parsetree->hasSubLinks = TRUE;
176
177         /*
178          * Event Qualification forces copying of parsetree and splitting into
179          * two queries one w/rule_qual, one w/NOT rule_qual. Also add user
180          * query qual onto rule action
181          */
182         AddQual(sub_action, rule_qual);
183
184         AddQual(sub_action, parsetree->jointree->quals);
185
186         /*
187          * Rewrite new.attribute w/ right hand side of target-list entry for
188          * appropriate field name in insert/update.
189          *
190          * KLUGE ALERT: since ResolveNew returns a mutated copy, we can't just
191          * apply it to sub_action; we have to remember to update the sublink
192          * inside rule_action, too.
193          */
194         if (event == CMD_INSERT || event == CMD_UPDATE)
195         {
196                 sub_action = (Query *) ResolveNew((Node *) sub_action,
197                                                                                   new_varno,
198                                                                                   0,
199                                                                                   parsetree->targetList,
200                                                                                   event,
201                                                                                   current_varno);
202                 if (sub_action_ptr)
203                         *sub_action_ptr = sub_action;
204                 else
205                         rule_action = sub_action;
206         }
207
208         return rule_action;
209 }
210
211 /*
212  * Copy the query's jointree list, and optionally attempt to remove any
213  * occurrence of the given rt_index as a top-level join item (we do not look
214  * for it within join items; this is OK because we are only expecting to find
215  * it as an UPDATE or DELETE target relation, which will be at the top level
216  * of the join).  Returns modified jointree list --- this is a separate copy
217  * sharing no nodes with the original.
218  */
219 static List *
220 adjustJoinTreeList(Query *parsetree, bool removert, int rt_index)
221 {
222         List       *newjointree = copyObject(parsetree->jointree->fromlist);
223         List       *jjt;
224
225         if (removert)
226         {
227                 foreach(jjt, newjointree)
228                 {
229                         RangeTblRef *rtr = lfirst(jjt);
230
231                         if (IsA(rtr, RangeTblRef) &&
232                                 rtr->rtindex == rt_index)
233                         {
234                                 newjointree = lremove(rtr, newjointree);
235                                 /* foreach is safe because we exit loop after lremove... */
236                                 break;
237                         }
238                 }
239         }
240         return newjointree;
241 }
242
243
244 /*
245  * rewriteTargetList - rewrite INSERT/UPDATE targetlist into standard form
246  *
247  * This has the following responsibilities:
248  *
249  * 1. For an INSERT, add tlist entries to compute default values for any
250  * attributes that have defaults and are not assigned to in the given tlist.
251  * (We do not insert anything for default-less attributes, however.  The
252  * planner will later insert NULLs for them, but there's no reason to slow
253  * down rewriter processing with extra tlist nodes.)  Also, for both INSERT
254  * and UPDATE, replace explicit DEFAULT specifications with column default
255  * expressions.
256  *
257  * 2. Merge multiple entries for the same target attribute, or declare error
258  * if we can't.  Presently, multiple entries are only allowed for UPDATE of
259  * an array field, for example "UPDATE table SET foo[2] = 42, foo[4] = 43".
260  * We can merge such operations into a single assignment op.  Essentially,
261  * the expression we want to produce in this case is like
262  *              foo = array_set(array_set(foo, 2, 42), 4, 43)
263  *
264  * 3. Sort the tlist into standard order: non-junk fields in order by resno,
265  * then junk fields (these in no particular order).
266  *
267  * We must do items 1 and 2 before firing rewrite rules, else rewritten
268  * references to NEW.foo will produce wrong or incomplete results.      Item 3
269  * is not needed for rewriting, but will be needed by the planner, and we
270  * can do it essentially for free while handling items 1 and 2.
271  */
272 static void
273 rewriteTargetList(Query *parsetree, Relation target_relation)
274 {
275         CmdType         commandType = parsetree->commandType;
276         List       *tlist = parsetree->targetList;
277         List       *new_tlist = NIL;
278         int                     attrno,
279                                 numattrs;
280         List       *temp;
281
282         /*
283          * Scan the tuple description in the relation's relcache entry to make
284          * sure we have all the user attributes in the right order.
285          */
286         numattrs = RelationGetNumberOfAttributes(target_relation);
287
288         for (attrno = 1; attrno <= numattrs; attrno++)
289         {
290                 Form_pg_attribute att_tup = target_relation->rd_att->attrs[attrno - 1];
291                 TargetEntry *new_tle = NULL;
292
293                 /* We can ignore deleted attributes */
294                 if (att_tup->attisdropped)
295                         continue;
296
297                 /*
298                  * Look for targetlist entries matching this attr.      We match by
299                  * resno, but the resname should match too.
300                  *
301                  * Junk attributes are not candidates to be matched.
302                  */
303                 foreach(temp, tlist)
304                 {
305                         TargetEntry *old_tle = (TargetEntry *) lfirst(temp);
306                         Resdom     *resdom = old_tle->resdom;
307
308                         if (!resdom->resjunk && resdom->resno == attrno)
309                         {
310                                 Assert(strcmp(resdom->resname,
311                                                           NameStr(att_tup->attname)) == 0);
312                                 new_tle = process_matched_tle(old_tle, new_tle);
313                                 /* keep scanning to detect multiple assignments to attr */
314                         }
315                 }
316
317                 /*
318                  * Handle the two cases where we need to insert a default expression:
319                  * it's an INSERT and there's no tlist entry for the column, or the
320                  * tlist entry is a DEFAULT placeholder node.
321                  */
322                 if ((new_tle == NULL && commandType == CMD_INSERT) ||
323                         (new_tle && new_tle->expr && IsA(new_tle->expr, SetToDefault)))
324                 {
325                         Node       *new_expr;
326
327                         new_expr = build_column_default(target_relation, attrno);
328
329                         /*
330                          * If there is no default (ie, default is effectively NULL),
331                          * we can omit the tlist entry in the INSERT case, since the
332                          * planner can insert a NULL for itself, and there's no point
333                          * in spending any more rewriter cycles on the entry.  But in the
334                          * UPDATE case we've got to explicitly set the column to NULL.
335                          */
336                         if (!new_expr)
337                         {
338                                 if (commandType == CMD_INSERT)
339                                         new_tle = NULL;
340                                 else
341                                 {
342                                         new_expr = (Node *) makeConst(att_tup->atttypid,
343                                                                                                   att_tup->attlen,
344                                                                                                   (Datum) 0,
345                                                                                                   true, /* isnull */
346                                                                                                   att_tup->attbyval);
347                                         /* this is to catch a NOT NULL domain constraint */
348                                         new_expr = coerce_to_domain(new_expr,
349                                                                                                 InvalidOid,
350                                                                                                 att_tup->atttypid,
351                                                                                                 COERCE_IMPLICIT_CAST);
352                                 }
353                         }
354
355                         if (new_expr)
356                                 new_tle = makeTargetEntry(makeResdom(attrno,
357                                                                                                          att_tup->atttypid,
358                                                                                                          att_tup->atttypmod,
359                                                                           pstrdup(NameStr(att_tup->attname)),
360                                                                                                          false),
361                                                                                   (Expr *) new_expr);
362                 }
363
364                 if (new_tle)
365                         new_tlist = lappend(new_tlist, new_tle);
366         }
367
368         /*
369          * Copy all resjunk tlist entries to the end of the new tlist, and
370          * assign them resnos above the last real resno.
371          *
372          * Typical junk entries include ORDER BY or GROUP BY expressions (are
373          * these actually possible in an INSERT or UPDATE?), system attribute
374          * references, etc.
375          */
376         foreach(temp, tlist)
377         {
378                 TargetEntry *old_tle = (TargetEntry *) lfirst(temp);
379                 Resdom     *resdom = old_tle->resdom;
380
381                 if (resdom->resjunk)
382                 {
383                         /* Get the resno right, but don't copy unnecessarily */
384                         if (resdom->resno != attrno)
385                         {
386                                 resdom = (Resdom *) copyObject((Node *) resdom);
387                                 resdom->resno = attrno;
388                                 old_tle = makeTargetEntry(resdom, old_tle->expr);
389                         }
390                         new_tlist = lappend(new_tlist, old_tle);
391                         attrno++;
392                 }
393                 else
394                 {
395                         /* Let's just make sure we processed all the non-junk items */
396                         if (resdom->resno < 1 || resdom->resno > numattrs)
397                                 elog(ERROR, "rewriteTargetList: bogus resno %d in targetlist",
398                                          resdom->resno);
399                 }
400         }
401
402         parsetree->targetList = new_tlist;
403 }
404
405
406 /*
407  * Convert a matched TLE from the original tlist into a correct new TLE.
408  *
409  * This routine detects and handles multiple assignments to the same target
410  * attribute.
411  */
412 static TargetEntry *
413 process_matched_tle(TargetEntry *src_tle,
414                                         TargetEntry *prior_tle)
415 {
416         Resdom     *resdom = src_tle->resdom;
417         Node       *priorbottom;
418         ArrayRef   *newexpr;
419
420         if (prior_tle == NULL)
421         {
422                 /*
423                  * Normal case where this is the first assignment to the
424                  * attribute.
425                  */
426                 return src_tle;
427         }
428
429         /*
430          * Multiple assignments to same attribute.      Allow only if all are
431          * array-assign operators with same bottom array object.
432          */
433         if (src_tle->expr == NULL || !IsA(src_tle->expr, ArrayRef) ||
434                 ((ArrayRef *) src_tle->expr)->refassgnexpr == NULL ||
435                 prior_tle->expr == NULL || !IsA(prior_tle->expr, ArrayRef) ||
436                 ((ArrayRef *) prior_tle->expr)->refassgnexpr == NULL ||
437                 ((ArrayRef *) src_tle->expr)->refrestype !=
438                 ((ArrayRef *) prior_tle->expr)->refrestype)
439                 elog(ERROR, "Multiple assignments to same attribute \"%s\"",
440                          resdom->resname);
441
442         /*
443          * Prior TLE could be a nest of ArrayRefs if we do this more than
444          * once.
445          */
446         priorbottom = (Node *) ((ArrayRef *) prior_tle->expr)->refexpr;
447         while (priorbottom != NULL && IsA(priorbottom, ArrayRef) &&
448                    ((ArrayRef *) priorbottom)->refassgnexpr != NULL)
449                 priorbottom = (Node *) ((ArrayRef *) priorbottom)->refexpr;
450         if (!equal(priorbottom, ((ArrayRef *) src_tle->expr)->refexpr))
451                 elog(ERROR, "Multiple assignments to same attribute \"%s\"",
452                          resdom->resname);
453
454         /*
455          * Looks OK to nest 'em.
456          */
457         newexpr = makeNode(ArrayRef);
458         memcpy(newexpr, src_tle->expr, sizeof(ArrayRef));
459         newexpr->refexpr = prior_tle->expr;
460
461         return makeTargetEntry(resdom, (Expr *) newexpr);
462 }
463
464
465 /*
466  * Make an expression tree for the default value for a column.
467  *
468  * If there is no default, return a NULL instead.
469  */
470 Node *
471 build_column_default(Relation rel, int attrno)
472 {
473         TupleDesc       rd_att = rel->rd_att;
474         Form_pg_attribute att_tup = rd_att->attrs[attrno - 1];
475         Oid                     atttype = att_tup->atttypid;
476         int32           atttypmod = att_tup->atttypmod;
477         Node       *expr = NULL;
478         Oid                     exprtype;
479
480         /*
481          * Scan to see if relation has a default for this column.
482          */
483         if (rd_att->constr && rd_att->constr->num_defval > 0)
484         {
485                 AttrDefault *defval = rd_att->constr->defval;
486                 int                     ndef = rd_att->constr->num_defval;
487
488                 while (--ndef >= 0)
489                 {
490                         if (attrno == defval[ndef].adnum)
491                         {
492                                 /*
493                                  * Found it, convert string representation to node tree.
494                                  */
495                                 expr = stringToNode(defval[ndef].adbin);
496                                 break;
497                         }
498                 }
499         }
500
501         if (expr == NULL)
502         {
503                 /*
504                  * No per-column default, so look for a default for the type
505                  * itself.
506                  */
507                 if (att_tup->attisset)
508                 {
509                         /*
510                          * Set attributes are represented as OIDs no matter what the
511                          * set element type is, and the element type's default is
512                          * irrelevant too.
513                          */
514                 }
515                 else
516                         expr = get_typdefault(atttype);
517         }
518
519         if (expr == NULL)
520                 return NULL;                    /* No default anywhere */
521
522         /*
523          * Make sure the value is coerced to the target column type (might not
524          * be right type yet if it's not a constant!)  This should match the
525          * parser's processing of non-defaulted expressions --- see
526          * updateTargetListEntry().
527          */
528         exprtype = exprType(expr);
529
530         expr = coerce_to_target_type(NULL, /* no UNKNOWN params here */
531                                                                  expr, exprtype,
532                                                                  atttype, atttypmod,
533                                                                  COERCION_ASSIGNMENT,
534                                                                  COERCE_IMPLICIT_CAST);
535         /*
536          * This really shouldn't fail; should have checked the default's
537          * type when it was created ...
538          */
539         if (expr == NULL)
540                 elog(ERROR, "Column \"%s\" is of type %s"
541                          " but default expression is of type %s"
542                          "\n\tYou will need to rewrite or cast the expression",
543                          NameStr(att_tup->attname),
544                          format_type_be(atttype),
545                          format_type_be(exprtype));
546
547         return expr;
548 }
549
550
551 /*
552  * matchLocks -
553  *        match the list of locks and returns the matching rules
554  */
555 static List *
556 matchLocks(CmdType event,
557                    RuleLock *rulelocks,
558                    int varno,
559                    Query *parsetree)
560 {
561         List       *matching_locks = NIL;
562         int                     nlocks;
563         int                     i;
564
565         if (rulelocks == NULL)
566                 return NIL;
567
568         if (parsetree->commandType != CMD_SELECT)
569         {
570                 if (parsetree->resultRelation != varno)
571                         return NIL;
572         }
573
574         nlocks = rulelocks->numLocks;
575
576         for (i = 0; i < nlocks; i++)
577         {
578                 RewriteRule *oneLock = rulelocks->rules[i];
579
580                 if (oneLock->event == event)
581                 {
582                         if (parsetree->commandType != CMD_SELECT ||
583                                 (oneLock->attrno == -1 ?
584                                  rangeTableEntry_used((Node *) parsetree, varno, 0) :
585                                  attribute_used((Node *) parsetree,
586                                                                 varno, oneLock->attrno, 0)))
587                                 matching_locks = lappend(matching_locks, oneLock);
588                 }
589         }
590
591         return matching_locks;
592 }
593
594
595 static Query *
596 ApplyRetrieveRule(Query *parsetree,
597                                   RewriteRule *rule,
598                                   int rt_index,
599                                   bool relation_level,
600                                   Relation relation,
601                                   bool relIsUsed,
602                                   List *activeRIRs)
603 {
604         Query      *rule_action;
605         RangeTblEntry *rte,
606                            *subrte;
607
608         if (length(rule->actions) != 1)
609                 elog(ERROR, "ApplyRetrieveRule: expected just one rule action");
610         if (rule->qual != NULL)
611                 elog(ERROR, "ApplyRetrieveRule: can't handle qualified ON SELECT rule");
612         if (!relation_level)
613                 elog(ERROR, "ApplyRetrieveRule: can't handle per-attribute ON SELECT rule");
614
615         /*
616          * Make a modifiable copy of the view query, and recursively expand
617          * any view references inside it.
618          */
619         rule_action = copyObject(lfirst(rule->actions));
620
621         rule_action = fireRIRrules(rule_action, activeRIRs);
622
623         /*
624          * VIEWs are really easy --- just plug the view query in as a
625          * subselect, replacing the relation's original RTE.
626          */
627         rte = rt_fetch(rt_index, parsetree->rtable);
628
629         rte->rtekind = RTE_SUBQUERY;
630         rte->relid = InvalidOid;
631         rte->subquery = rule_action;
632         rte->inh = false;                       /* must not be set for a subquery */
633
634         /*
635          * We move the view's permission check data down to its rangetable.
636          * The checks will actually be done against the *OLD* entry therein.
637          */
638         subrte = rt_fetch(PRS2_OLD_VARNO, rule_action->rtable);
639         Assert(subrte->relid == relation->rd_id);
640         subrte->checkForRead = rte->checkForRead;
641         subrte->checkForWrite = rte->checkForWrite;
642         subrte->checkAsUser = rte->checkAsUser;
643
644         rte->checkForRead = false;      /* no permission check on subquery itself */
645         rte->checkForWrite = false;
646         rte->checkAsUser = InvalidOid;
647
648         /*
649          * FOR UPDATE of view?
650          */
651         if (intMember(rt_index, parsetree->rowMarks))
652         {
653                 /*
654                  * Remove the view from the list of rels that will actually be
655                  * marked FOR UPDATE by the executor.  It will still be access-
656                  * checked for write access, though.
657                  */
658                 parsetree->rowMarks = lremovei(rt_index, parsetree->rowMarks);
659
660                 /*
661                  * Set up the view's referenced tables as if FOR UPDATE.
662                  */
663                 markQueryForUpdate(rule_action, true);
664         }
665
666         return parsetree;
667 }
668
669 /*
670  * Recursively mark all relations used by a view as FOR UPDATE.
671  *
672  * This may generate an invalid query, eg if some sub-query uses an
673  * aggregate.  We leave it to the planner to detect that.
674  *
675  * NB: this must agree with the parser's transformForUpdate() routine.
676  */
677 static void
678 markQueryForUpdate(Query *qry, bool skipOldNew)
679 {
680         Index           rti = 0;
681         List       *l;
682
683         foreach(l, qry->rtable)
684         {
685                 RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
686
687                 rti++;
688
689                 /* Ignore OLD and NEW entries if we are at top level of view */
690                 if (skipOldNew &&
691                         (rti == PRS2_OLD_VARNO || rti == PRS2_NEW_VARNO))
692                         continue;
693
694                 if (rte->rtekind == RTE_RELATION)
695                 {
696                         if (!intMember(rti, qry->rowMarks))
697                                 qry->rowMarks = lappendi(qry->rowMarks, rti);
698                         rte->checkForWrite = true;
699                 }
700                 else if (rte->rtekind == RTE_SUBQUERY)
701                 {
702                         /* FOR UPDATE of subquery is propagated to subquery's rels */
703                         markQueryForUpdate(rte->subquery, false);
704                 }
705         }
706 }
707
708
709 /*
710  * fireRIRonSubLink -
711  *      Apply fireRIRrules() to each SubLink (subselect in expression) found
712  *      in the given tree.
713  *
714  * NOTE: although this has the form of a walker, we cheat and modify the
715  * SubLink nodes in-place.      It is caller's responsibility to ensure that
716  * no unwanted side-effects occur!
717  *
718  * This is unlike most of the other routines that recurse into subselects,
719  * because we must take control at the SubLink node in order to replace
720  * the SubLink's subselect link with the possibly-rewritten subquery.
721  */
722 static bool
723 fireRIRonSubLink(Node *node, List *activeRIRs)
724 {
725         if (node == NULL)
726                 return false;
727         if (IsA(node, SubLink))
728         {
729                 SubLink    *sub = (SubLink *) node;
730
731                 /* Do what we came for */
732                 sub->subselect = (Node *) fireRIRrules((Query *) sub->subselect,
733                                                                                            activeRIRs);
734                 /* Fall through to process lefthand args of SubLink */
735         }
736
737         /*
738          * Do NOT recurse into Query nodes, because fireRIRrules already
739          * processed subselects of subselects for us.
740          */
741         return expression_tree_walker(node, fireRIRonSubLink,
742                                                                   (void *) activeRIRs);
743 }
744
745
746 /*
747  * fireRIRrules -
748  *      Apply all RIR rules on each rangetable entry in a query
749  */
750 static Query *
751 fireRIRrules(Query *parsetree, List *activeRIRs)
752 {
753         int                     rt_index;
754
755         /*
756          * don't try to convert this into a foreach loop, because rtable list
757          * can get changed each time through...
758          */
759         rt_index = 0;
760         while (rt_index < length(parsetree->rtable))
761         {
762                 RangeTblEntry *rte;
763                 Relation        rel;
764                 List       *locks;
765                 RuleLock   *rules;
766                 RewriteRule *rule;
767                 LOCKMODE        lockmode;
768                 bool            relIsUsed;
769                 int                     i;
770
771                 ++rt_index;
772
773                 rte = rt_fetch(rt_index, parsetree->rtable);
774
775                 /*
776                  * A subquery RTE can't have associated rules, so there's nothing
777                  * to do to this level of the query, but we must recurse into the
778                  * subquery to expand any rule references in it.
779                  */
780                 if (rte->rtekind == RTE_SUBQUERY)
781                 {
782                         rte->subquery = fireRIRrules(rte->subquery, activeRIRs);
783                         continue;
784                 }
785
786                 /*
787                  * Joins and other non-relation RTEs can be ignored completely.
788                  */
789                 if (rte->rtekind != RTE_RELATION)
790                         continue;
791
792                 /*
793                  * If the table is not referenced in the query, then we ignore it.
794                  * This prevents infinite expansion loop due to new rtable entries
795                  * inserted by expansion of a rule. A table is referenced if it is
796                  * part of the join set (a source table), or is referenced by any
797                  * Var nodes, or is the result table.
798                  */
799                 relIsUsed = rangeTableEntry_used((Node *) parsetree, rt_index, 0);
800
801                 if (!relIsUsed && rt_index != parsetree->resultRelation)
802                         continue;
803
804                 /*
805                  * This may well be the first access to the relation during the
806                  * current statement (it will be, if this Query was extracted from
807                  * a rule or somehow got here other than via the parser).
808                  * Therefore, grab the appropriate lock type for the relation, and
809                  * do not release it until end of transaction.  This protects the
810                  * rewriter and planner against schema changes mid-query.
811                  *
812                  * If the relation is the query's result relation, then
813                  * RewriteQuery() already got the right lock on it, so we need no
814                  * additional lock. Otherwise, check to see if the relation is
815                  * accessed FOR UPDATE or not.
816                  */
817                 if (rt_index == parsetree->resultRelation)
818                         lockmode = NoLock;
819                 else if (intMember(rt_index, parsetree->rowMarks))
820                         lockmode = RowShareLock;
821                 else
822                         lockmode = AccessShareLock;
823
824                 rel = heap_open(rte->relid, lockmode);
825
826                 /*
827                  * Collect the RIR rules that we must apply
828                  */
829                 rules = rel->rd_rules;
830                 if (rules == NULL)
831                 {
832                         heap_close(rel, NoLock);
833                         continue;
834                 }
835                 locks = NIL;
836                 for (i = 0; i < rules->numLocks; i++)
837                 {
838                         rule = rules->rules[i];
839                         if (rule->event != CMD_SELECT)
840                                 continue;
841
842                         if (rule->attrno > 0)
843                         {
844                                 /* per-attr rule; do we need it? */
845                                 if (!attribute_used((Node *) parsetree, rt_index,
846                                                                         rule->attrno, 0))
847                                         continue;
848                         }
849
850                         locks = lappend(locks, rule);
851                 }
852
853                 /*
854                  * If we found any, apply them --- but first check for recursion!
855                  */
856                 if (locks != NIL)
857                 {
858                         List       *newActiveRIRs;
859                         List       *l;
860
861                         if (oidMember(RelationGetRelid(rel), activeRIRs))
862                                 elog(ERROR, "Infinite recursion detected in rules for relation %s",
863                                          RelationGetRelationName(rel));
864                         newActiveRIRs = lconso(RelationGetRelid(rel), activeRIRs);
865
866                         foreach(l, locks)
867                         {
868                                 rule = lfirst(l);
869
870                                 parsetree = ApplyRetrieveRule(parsetree,
871                                                                                           rule,
872                                                                                           rt_index,
873                                                                                           rule->attrno == -1,
874                                                                                           rel,
875                                                                                           relIsUsed,
876                                                                                           newActiveRIRs);
877                         }
878                 }
879
880                 heap_close(rel, NoLock);
881         }
882
883         /*
884          * Recurse into sublink subqueries, too.  But we already did the ones
885          * in the rtable.
886          */
887         if (parsetree->hasSubLinks)
888                 query_tree_walker(parsetree, fireRIRonSubLink, (void *) activeRIRs,
889                                                   QTW_IGNORE_RT_SUBQUERIES);
890
891         /*
892          * If the query was marked having aggregates, check if this is still
893          * true after rewriting.  Ditto for sublinks.  Note there should be no
894          * aggs in the qual at this point.      (Does this code still do anything
895          * useful?      The view-becomes-subselect-in-FROM approach doesn't look
896          * like it could remove aggs or sublinks...)
897          */
898         if (parsetree->hasAggs)
899         {
900                 parsetree->hasAggs = checkExprHasAggs((Node *) parsetree);
901                 if (parsetree->hasAggs)
902                         if (checkExprHasAggs((Node *) parsetree->jointree))
903                                 elog(ERROR, "fireRIRrules: failed to remove aggs from qual");
904         }
905         if (parsetree->hasSubLinks)
906                 parsetree->hasSubLinks = checkExprHasSubLink((Node *) parsetree);
907
908         return parsetree;
909 }
910
911
912 /*
913  * Modify the given query by adding 'AND rule_qual IS NOT TRUE' to its
914  * qualification.  This is used to generate suitable "else clauses" for
915  * conditional INSTEAD rules.  (Unfortunately we must use "x IS NOT TRUE",
916  * not just "NOT x" which the planner is much smarter about, else we will
917  * do the wrong thing when the qual evaluates to NULL.)
918  *
919  * The rule_qual may contain references to OLD or NEW.  OLD references are
920  * replaced by references to the specified rt_index (the relation that the
921  * rule applies to).  NEW references are only possible for INSERT and UPDATE
922  * queries on the relation itself, and so they should be replaced by copies
923  * of the related entries in the query's own targetlist.
924  */
925 static Query *
926 CopyAndAddInvertedQual(Query *parsetree,
927                                            Node *rule_qual,
928                                            int rt_index,
929                                            CmdType event)
930 {
931         Query      *new_tree = (Query *) copyObject(parsetree);
932         Node       *new_qual = (Node *) copyObject(rule_qual);
933
934         /* Fix references to OLD */
935         ChangeVarNodes(new_qual, PRS2_OLD_VARNO, rt_index, 0);
936         /* Fix references to NEW */
937         if (event == CMD_INSERT || event == CMD_UPDATE)
938                 new_qual = ResolveNew(new_qual,
939                                                           PRS2_NEW_VARNO,
940                                                           0,
941                                                           parsetree->targetList,
942                                                           event,
943                                                           rt_index);
944         /* And attach the fixed qual */
945         AddInvertedQual(new_tree, new_qual);
946
947         return new_tree;
948 }
949
950
951 /*
952  *      fireRules -
953  *         Iterate through rule locks applying rules.
954  *
955  * Input arguments:
956  *      parsetree - original query
957  *      rt_index - RT index of result relation in original query
958  *      event - type of rule event
959  *      locks - list of rules to fire
960  * Output arguments:
961  *      *instead_flag - set TRUE if any unqualified INSTEAD rule is found
962  *                                      (must be initialized to FALSE)
963  *      *qual_product - filled with modified original query if any qualified
964  *                                      INSTEAD rule is found (must be initialized to NULL)
965  * Return value:
966  *      list of rule actions adjusted for use with this query
967  *
968  * Qualified INSTEAD rules generate their action with the qualification
969  * condition added.  They also generate a modified version of the original
970  * query with the negated qualification added, so that it will run only for
971  * rows that the qualified action doesn't act on.  (If there are multiple
972  * qualified INSTEAD rules, we AND all the negated quals onto a single
973  * modified original query.)  We won't execute the original, unmodified
974  * query if we find either qualified or unqualified INSTEAD rules.  If
975  * we find both, the modified original query is discarded too.
976  */
977 static List *
978 fireRules(Query *parsetree,
979                   int rt_index,
980                   CmdType event,
981                   List *locks,
982                   bool *instead_flag,
983                   Query **qual_product)
984 {
985         List       *results = NIL;
986         List       *i;
987
988         foreach(i, locks)
989         {
990                 RewriteRule *rule_lock = (RewriteRule *) lfirst(i);
991                 Node       *event_qual = rule_lock->qual;
992                 List       *actions = rule_lock->actions;
993                 QuerySource     qsrc;
994                 List       *r;
995
996                 /* Determine correct QuerySource value for actions */
997                 if (rule_lock->isInstead)
998                 {
999                         if (event_qual != NULL)
1000                                 qsrc = QSRC_QUAL_INSTEAD_RULE;
1001                         else
1002                         {
1003                                 qsrc = QSRC_INSTEAD_RULE;
1004                                 *instead_flag = true; /* report unqualified INSTEAD */
1005                         }
1006                 }
1007                 else
1008                         qsrc = QSRC_NON_INSTEAD_RULE;
1009
1010                 if (qsrc == QSRC_QUAL_INSTEAD_RULE)
1011                 {
1012                         /*
1013                          * If there are INSTEAD rules with qualifications, the
1014                          * original query is still performed. But all the negated rule
1015                          * qualifications of the INSTEAD rules are added so it does
1016                          * its actions only in cases where the rule quals of all
1017                          * INSTEAD rules are false. Think of it as the default action
1018                          * in a case. We save this in *qual_product so
1019                          * RewriteQuery() can add it to the query list after we
1020                          * mangled it up enough.
1021                          *
1022                          * If we have already found an unqualified INSTEAD rule,
1023                          * then *qual_product won't be used, so don't bother building it.
1024                          */
1025                         if (! *instead_flag)
1026                         {
1027                                 if (*qual_product == NULL)
1028                                         *qual_product = parsetree;
1029                                 *qual_product = CopyAndAddInvertedQual(*qual_product,
1030                                                                                                            event_qual,
1031                                                                                                            rt_index,
1032                                                                                                            event);
1033                         }
1034                 }
1035
1036                 /* Now process the rule's actions and add them to the result list */
1037                 foreach(r, actions)
1038                 {
1039                         Query      *rule_action = lfirst(r);
1040
1041                         if (rule_action->commandType == CMD_NOTHING)
1042                                 continue;
1043
1044                         rule_action = rewriteRuleAction(parsetree, rule_action,
1045                                                                                         event_qual, rt_index, event);
1046
1047                         rule_action->querySource = qsrc;
1048                         rule_action->canSetTag = false;         /* might change later */
1049
1050                         results = lappend(results, rule_action);
1051                 }
1052         }
1053
1054         return results;
1055 }
1056
1057
1058 /*
1059  * RewriteQuery -
1060  *        rewrites the query and apply the rules again on the queries rewritten
1061  *
1062  * rewrite_events is a list of open query-rewrite actions, so we can detect
1063  * infinite recursion.
1064  */
1065 static List *
1066 RewriteQuery(Query *parsetree, List *rewrite_events)
1067 {
1068         CmdType         event = parsetree->commandType;
1069         bool            instead = false;
1070         Query      *qual_product = NULL;
1071         List       *rewritten = NIL;
1072
1073         /*
1074          * If the statement is an update, insert or delete - fire rules on it.
1075          *
1076          * SELECT rules are handled later when we have all the queries that
1077          * should get executed.  Also, utilities aren't rewritten at all
1078          * (do we still need that check?)
1079          */
1080         if (event != CMD_SELECT && event != CMD_UTILITY)
1081         {
1082                 int                     result_relation;
1083                 RangeTblEntry *rt_entry;
1084                 Relation        rt_entry_relation;
1085                 List       *locks;
1086
1087                 result_relation = parsetree->resultRelation;
1088                 Assert(result_relation != 0);
1089                 rt_entry = rt_fetch(result_relation, parsetree->rtable);
1090                 Assert(rt_entry->rtekind == RTE_RELATION);
1091
1092                 /*
1093                  * This may well be the first access to the result relation during the
1094                  * current statement (it will be, if this Query was extracted from a
1095                  * rule or somehow got here other than via the parser). Therefore,
1096                  * grab the appropriate lock type for a result relation, and do not
1097                  * release it until end of transaction.  This protects the rewriter
1098                  * and planner against schema changes mid-query.
1099                  */
1100                 rt_entry_relation = heap_open(rt_entry->relid, RowExclusiveLock);
1101
1102                 /*
1103                  * If it's an INSERT or UPDATE, rewrite the targetlist into standard
1104                  * form.  This will be needed by the planner anyway, and doing it now
1105                  * ensures that any references to NEW.field will behave sanely.
1106                  */
1107                 if (event == CMD_INSERT || event == CMD_UPDATE)
1108                         rewriteTargetList(parsetree, rt_entry_relation);
1109
1110                 /*
1111                  * Collect and apply the appropriate rules.
1112                  */
1113                 locks = matchLocks(event, rt_entry_relation->rd_rules,
1114                                                    result_relation, parsetree);
1115
1116                 if (locks != NIL)
1117                 {
1118                         List       *product_queries;
1119
1120                         product_queries = fireRules(parsetree,
1121                                                                                 result_relation,
1122                                                                                 event,
1123                                                                                 locks,
1124                                                                                 &instead,
1125                                                                                 &qual_product);
1126
1127                         /*
1128                          * If we got any product queries, recursively rewrite them
1129                          * --- but first check for recursion!
1130                          */
1131                         if (product_queries != NIL)
1132                         {
1133                                 List       *n;
1134                                 rewrite_event *rev;
1135
1136                                 foreach(n, rewrite_events)
1137                                 {
1138                                         rev = (rewrite_event *) lfirst(n);
1139                                         if (rev->relation == RelationGetRelid(rt_entry_relation) &&
1140                                                 rev->event == event)
1141                                                 elog(ERROR, "Infinite recursion detected in rules for relation %s",
1142                                                          RelationGetRelationName(rt_entry_relation));
1143                                 }
1144
1145                                 rev = (rewrite_event *) palloc(sizeof(rewrite_event));
1146                                 rev->relation = RelationGetRelid(rt_entry_relation);
1147                                 rev->event = event;
1148                                 rewrite_events = lcons(rev, rewrite_events);
1149
1150                                 foreach(n, product_queries)
1151                                 {
1152                                         Query      *pt = (Query *) lfirst(n);
1153                                         List       *newstuff;
1154
1155                                         newstuff = RewriteQuery(pt, rewrite_events);
1156                                         rewritten = nconc(rewritten, newstuff);
1157                                 }
1158                         }
1159                 }
1160
1161                 heap_close(rt_entry_relation, NoLock);          /* keep lock! */
1162         }
1163
1164         /*
1165          * For INSERTs, the original query is done first; for UPDATE/DELETE,
1166          * it is done last.  This is needed because update and delete rule
1167          * actions might not do anything if they are invoked after the update
1168          * or delete is performed. The command counter increment between the
1169          * query executions makes the deleted (and maybe the updated) tuples
1170          * disappear so the scans for them in the rule actions cannot find
1171          * them.
1172          *
1173          * If we found any unqualified INSTEAD, the original query is not
1174          * done at all, in any form.  Otherwise, we add the modified form
1175          * if qualified INSTEADs were found, else the unmodified form.
1176          */
1177         if (!instead)
1178         {
1179                 if (parsetree->commandType == CMD_INSERT)
1180                 {
1181                         if (qual_product != NULL)
1182                                 rewritten = lcons(qual_product, rewritten);
1183                         else
1184                                 rewritten = lcons(parsetree, rewritten);
1185                 }
1186                 else
1187                 {
1188                         if (qual_product != NULL)
1189                                 rewritten = lappend(rewritten, qual_product);
1190                         else
1191                                 rewritten = lappend(rewritten, parsetree);
1192                 }
1193         }
1194
1195         return rewritten;
1196 }
1197
1198
1199 /*
1200  * QueryRewrite -
1201  *        Primary entry point to the query rewriter.
1202  *        Rewrite one query via query rewrite system, possibly returning 0
1203  *        or many queries.
1204  *
1205  * NOTE: The code in QueryRewrite was formerly in pg_parse_and_plan(), and was
1206  * moved here so that it would be invoked during EXPLAIN.
1207  */
1208 List *
1209 QueryRewrite(Query *parsetree)
1210 {
1211         List       *querylist;
1212         List       *results = NIL;
1213         List       *l;
1214         CmdType         origCmdType;
1215         bool            foundOriginalQuery;
1216         Query      *lastInstead;
1217
1218         /*
1219          * Step 1
1220          *
1221          * Apply all non-SELECT rules possibly getting 0 or many queries
1222          */
1223         querylist = RewriteQuery(parsetree, NIL);
1224
1225         /*
1226          * Step 2
1227          *
1228          * Apply all the RIR rules on each query
1229          */
1230         foreach(l, querylist)
1231         {
1232                 Query      *query = (Query *) lfirst(l);
1233
1234                 query = fireRIRrules(query, NIL);
1235
1236                 /*
1237                  * If the query target was rewritten as a view, complain.
1238                  */
1239                 if (query->resultRelation)
1240                 {
1241                         RangeTblEntry *rte = rt_fetch(query->resultRelation,
1242                                                                                   query->rtable);
1243
1244                         if (rte->rtekind == RTE_SUBQUERY)
1245                         {
1246                                 switch (query->commandType)
1247                                 {
1248                                         case CMD_INSERT:
1249                                                 elog(ERROR, "Cannot insert into a view"
1250                                                          "\n\tYou need an unconditional ON INSERT DO INSTEAD rule");
1251                                                 break;
1252                                         case CMD_UPDATE:
1253                                                 elog(ERROR, "Cannot update a view"
1254                                                          "\n\tYou need an unconditional ON UPDATE DO INSTEAD rule");
1255                                                 break;
1256                                         case CMD_DELETE:
1257                                                 elog(ERROR, "Cannot delete from a view"
1258                                                          "\n\tYou need an unconditional ON DELETE DO INSTEAD rule");
1259                                                 break;
1260                                         default:
1261                                                 elog(ERROR, "QueryRewrite: unexpected commandType %d",
1262                                                          (int) query->commandType);
1263                                                 break;
1264                                 }
1265                         }
1266                 }
1267
1268                 results = lappend(results, query);
1269         }
1270
1271         /*
1272          * Step 3
1273          *
1274          * Determine which, if any, of the resulting queries is supposed to set
1275          * the command-result tag; and update the canSetTag fields accordingly.
1276          *
1277          * If the original query is still in the list, it sets the command tag.
1278          * Otherwise, the last INSTEAD query of the same kind as the original
1279          * is allowed to set the tag.  (Note these rules can leave us with no
1280          * query setting the tag.  The tcop code has to cope with this by
1281          * setting up a default tag based on the original un-rewritten query.)
1282          *
1283          * The Asserts verify that at most one query in the result list is marked
1284          * canSetTag.  If we aren't checking asserts, we can fall out of the loop
1285          * as soon as we find the original query.
1286          */
1287         origCmdType = parsetree->commandType;
1288         foundOriginalQuery = false;
1289         lastInstead = NULL;
1290
1291         foreach(l, results)
1292         {
1293                 Query      *query = (Query *) lfirst(l);
1294
1295                 if (query->querySource == QSRC_ORIGINAL)
1296                 {
1297                         Assert(query->canSetTag);
1298                         Assert(!foundOriginalQuery);
1299                         foundOriginalQuery = true;
1300 #ifndef USE_ASSERT_CHECKING
1301                         break;
1302 #endif
1303                 }
1304                 else
1305                 {
1306                         Assert(!query->canSetTag);
1307                         if (query->commandType == origCmdType &&
1308                                 (query->querySource == QSRC_INSTEAD_RULE ||
1309                                  query->querySource == QSRC_QUAL_INSTEAD_RULE))
1310                                 lastInstead = query;
1311                 }
1312         }
1313
1314         if (!foundOriginalQuery && lastInstead != NULL)
1315                 lastInstead->canSetTag = true;
1316
1317         return results;
1318 }