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