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