]> granicus.if.org Git - postgresql/blob - src/backend/rewrite/rewriteHandler.c
Standard pgindent run for 8.1.
[postgresql] / src / backend / rewrite / rewriteHandler.c
1 /*-------------------------------------------------------------------------
2  *
3  * rewriteHandler.c
4  *              Primary module of query rewriter.
5  *
6  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  * IDENTIFICATION
10  *        $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.158 2005/10/15 02:49:24 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_type.h"
29 #include "parser/parsetree.h"
30 #include "rewrite/rewriteHandler.h"
31 #include "rewrite/rewriteManip.h"
32 #include "utils/builtins.h"
33 #include "utils/lsyscache.h"
34
35
36 /* We use a list of these to detect recursion in RewriteQuery */
37 typedef struct rewrite_event
38 {
39         Oid                     relation;               /* OID of relation having rules */
40         CmdType         event;                  /* type of rule being fired */
41 } rewrite_event;
42
43 static bool acquireLocksOnSubLinks(Node *node, void *context);
44 static Query *rewriteRuleAction(Query *parsetree,
45                                   Query *rule_action,
46                                   Node *rule_qual,
47                                   int rt_index,
48                                   CmdType event);
49 static List *adjustJoinTreeList(Query *parsetree, bool removert, int rt_index);
50 static void rewriteTargetList(Query *parsetree, Relation target_relation);
51 static TargetEntry *process_matched_tle(TargetEntry *src_tle,
52                                         TargetEntry *prior_tle,
53                                         const char *attrName);
54 static Node *get_assignment_input(Node *node);
55 static void markQueryForLocking(Query *qry, bool forUpdate, bool noWait,
56                                         bool skipOldNew);
57 static List *matchLocks(CmdType event, RuleLock *rulelocks,
58                    int varno, Query *parsetree);
59 static Query *fireRIRrules(Query *parsetree, List *activeRIRs);
60
61
62 /*
63  * AcquireRewriteLocks -
64  *        Acquire suitable locks on all the relations mentioned in the Query.
65  *        These locks will ensure that the relation schemas don't change under us
66  *        while we are rewriting and planning the query.
67  *
68  * A secondary purpose of this routine is to fix up JOIN RTE references to
69  * dropped columns (see details below).  Because the RTEs are modified in
70  * place, it is generally appropriate for the caller of this routine to have
71  * first done a copyObject() to make a writable copy of the querytree in the
72  * current memory context.
73  *
74  * This processing can, and for efficiency's sake should, be skipped when the
75  * querytree has just been built by the parser: parse analysis already got
76  * all the same locks we'd get here, and the parser will have omitted dropped
77  * columns from JOINs to begin with.  But we must do this whenever we are
78  * dealing with a querytree produced earlier than the current command.
79  *
80  * About JOINs and dropped columns: although the parser never includes an
81  * already-dropped column in a JOIN RTE's alias var list, it is possible for
82  * such a list in a stored rule to include references to dropped columns.
83  * (If the column is not explicitly referenced anywhere else in the query,
84  * the dependency mechanism won't consider it used by the rule and so won't
85  * prevent the column drop.)  To support get_rte_attribute_is_dropped(),
86  * we replace join alias vars that reference dropped columns with NULL Const
87  * nodes.
88  *
89  * (In PostgreSQL 8.0, we did not do this processing but instead had
90  * get_rte_attribute_is_dropped() recurse to detect dropped columns in joins.
91  * That approach had horrible performance unfortunately; in particular
92  * construction of a nested join was O(N^2) in the nesting depth.)
93  */
94 void
95 AcquireRewriteLocks(Query *parsetree)
96 {
97         ListCell   *l;
98         int                     rt_index;
99
100         /*
101          * First, process RTEs of the current query level.
102          */
103         rt_index = 0;
104         foreach(l, parsetree->rtable)
105         {
106                 RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
107                 Relation        rel;
108                 LOCKMODE        lockmode;
109                 List       *newaliasvars;
110                 Index           curinputvarno;
111                 RangeTblEntry *curinputrte;
112                 ListCell   *ll;
113
114                 ++rt_index;
115                 switch (rte->rtekind)
116                 {
117                         case RTE_RELATION:
118
119                                 /*
120                                  * Grab the appropriate lock type for the relation, and do not
121                                  * release it until end of transaction. This protects the
122                                  * rewriter and planner against schema changes mid-query.
123                                  *
124                                  * If the relation is the query's result relation, then we need
125                                  * RowExclusiveLock.  Otherwise, check to see if the relation
126                                  * is accessed FOR UPDATE/SHARE or not.  We can't just grab
127                                  * AccessShareLock because then the executor would be trying
128                                  * to upgrade the lock, leading to possible deadlocks.
129                                  */
130                                 if (rt_index == parsetree->resultRelation)
131                                         lockmode = RowExclusiveLock;
132                                 else if (list_member_int(parsetree->rowMarks, rt_index))
133                                         lockmode = RowShareLock;
134                                 else
135                                         lockmode = AccessShareLock;
136
137                                 rel = heap_open(rte->relid, lockmode);
138                                 heap_close(rel, NoLock);
139                                 break;
140
141                         case RTE_JOIN:
142
143                                 /*
144                                  * Scan the join's alias var list to see if any columns have
145                                  * been dropped, and if so replace those Vars with NULL
146                                  * Consts.
147                                  *
148                                  * Since a join has only two inputs, we can expect to see
149                                  * multiple references to the same input RTE; optimize away
150                                  * multiple fetches.
151                                  */
152                                 newaliasvars = NIL;
153                                 curinputvarno = 0;
154                                 curinputrte = NULL;
155                                 foreach(ll, rte->joinaliasvars)
156                                 {
157                                         Var                *aliasvar = (Var *) lfirst(ll);
158
159                                         /*
160                                          * If the list item isn't a simple Var, then it must
161                                          * represent a merged column, ie a USING column, and so it
162                                          * couldn't possibly be dropped, since it's referenced in
163                                          * the join clause.  (Conceivably it could also be a NULL
164                                          * constant already?  But that's OK too.)
165                                          */
166                                         if (IsA(aliasvar, Var))
167                                         {
168                                                 /*
169                                                  * The elements of an alias list have to refer to
170                                                  * earlier RTEs of the same rtable, because that's the
171                                                  * order the planner builds things in.  So we already
172                                                  * processed the referenced RTE, and so it's safe to
173                                                  * use get_rte_attribute_is_dropped on it. (This might
174                                                  * not hold after rewriting or planning, but it's OK
175                                                  * to assume here.)
176                                                  */
177                                                 Assert(aliasvar->varlevelsup == 0);
178                                                 if (aliasvar->varno != curinputvarno)
179                                                 {
180                                                         curinputvarno = aliasvar->varno;
181                                                         if (curinputvarno >= rt_index)
182                                                                 elog(ERROR, "unexpected varno %d in JOIN RTE %d",
183                                                                          curinputvarno, rt_index);
184                                                         curinputrte = rt_fetch(curinputvarno,
185                                                                                                    parsetree->rtable);
186                                                 }
187                                                 if (get_rte_attribute_is_dropped(curinputrte,
188                                                                                                                  aliasvar->varattno))
189                                                 {
190                                                         /*
191                                                          * can't use vartype here, since that might be a
192                                                          * now-dropped type OID, but it doesn't really
193                                                          * matter what type the Const claims to be.
194                                                          */
195                                                         aliasvar = (Var *) makeNullConst(INT4OID);
196                                                 }
197                                         }
198                                         newaliasvars = lappend(newaliasvars, aliasvar);
199                                 }
200                                 rte->joinaliasvars = newaliasvars;
201                                 break;
202
203                         case RTE_SUBQUERY:
204
205                                 /*
206                                  * The subquery RTE itself is all right, but we have to
207                                  * recurse to process the represented subquery.
208                                  */
209                                 AcquireRewriteLocks(rte->subquery);
210                                 break;
211
212                         default:
213                                 /* ignore other types of RTEs */
214                                 break;
215                 }
216         }
217
218         /*
219          * Recurse into sublink subqueries, too.  But we already did the ones in
220          * the rtable.
221          */
222         if (parsetree->hasSubLinks)
223                 query_tree_walker(parsetree, acquireLocksOnSubLinks, NULL,
224                                                   QTW_IGNORE_RT_SUBQUERIES);
225 }
226
227 /*
228  * Walker to find sublink subqueries for AcquireRewriteLocks
229  */
230 static bool
231 acquireLocksOnSubLinks(Node *node, void *context)
232 {
233         if (node == NULL)
234                 return false;
235         if (IsA(node, SubLink))
236         {
237                 SubLink    *sub = (SubLink *) node;
238
239                 /* Do what we came for */
240                 AcquireRewriteLocks((Query *) sub->subselect);
241                 /* Fall through to process lefthand args of SubLink */
242         }
243
244         /*
245          * Do NOT recurse into Query nodes, because AcquireRewriteLocks already
246          * processed subselects of subselects for us.
247          */
248         return expression_tree_walker(node, acquireLocksOnSubLinks, context);
249 }
250
251
252 /*
253  * rewriteRuleAction -
254  *        Rewrite the rule action with appropriate qualifiers (taken from
255  *        the triggering query).
256  */
257 static Query *
258 rewriteRuleAction(Query *parsetree,
259                                   Query *rule_action,
260                                   Node *rule_qual,
261                                   int rt_index,
262                                   CmdType event)
263 {
264         int                     current_varno,
265                                 new_varno;
266         int                     rt_length;
267         Query      *sub_action;
268         Query     **sub_action_ptr;
269
270         /*
271          * Make modifiable copies of rule action and qual (what we're passed are
272          * the stored versions in the relcache; don't touch 'em!).
273          */
274         rule_action = (Query *) copyObject(rule_action);
275         rule_qual = (Node *) copyObject(rule_qual);
276
277         /*
278          * Acquire necessary locks and fix any deleted JOIN RTE entries.
279          */
280         AcquireRewriteLocks(rule_action);
281         (void) acquireLocksOnSubLinks(rule_qual, NULL);
282
283         current_varno = rt_index;
284         rt_length = list_length(parsetree->rtable);
285         new_varno = PRS2_NEW_VARNO + rt_length;
286
287         /*
288          * Adjust rule action and qual to offset its varnos, so that we can merge
289          * its rtable with the main parsetree's rtable.
290          *
291          * If the rule action is an INSERT...SELECT, the OLD/NEW rtable entries will
292          * be in the SELECT part, and we have to modify that rather than the
293          * top-level INSERT (kluge!).
294          */
295         sub_action = getInsertSelectQuery(rule_action, &sub_action_ptr);
296
297         OffsetVarNodes((Node *) sub_action, rt_length, 0);
298         OffsetVarNodes(rule_qual, rt_length, 0);
299         /* but references to *OLD* should point at original rt_index */
300         ChangeVarNodes((Node *) sub_action,
301                                    PRS2_OLD_VARNO + rt_length, rt_index, 0);
302         ChangeVarNodes(rule_qual,
303                                    PRS2_OLD_VARNO + rt_length, rt_index, 0);
304
305         /*
306          * Generate expanded rtable consisting of main parsetree's rtable plus
307          * rule action's rtable; this becomes the complete rtable for the rule
308          * action.      Some of the entries may be unused after we finish rewriting,
309          * but we leave them all in place for two reasons:
310          *
311          * We'd have a much harder job to adjust the query's varnos if we selectively
312          * removed RT entries.
313          *
314          * If the rule is INSTEAD, then the original query won't be executed at all,
315          * and so its rtable must be preserved so that the executor will do the
316          * correct permissions checks on it.
317          *
318          * RT entries that are not referenced in the completed jointree will be
319          * ignored by the planner, so they do not affect query semantics.  But any
320          * permissions checks specified in them will be applied during executor
321          * startup (see ExecCheckRTEPerms()).  This allows us to check that the
322          * caller has, say, insert-permission on a view, when the view is not
323          * semantically referenced at all in the resulting query.
324          *
325          * When a rule is not INSTEAD, the permissions checks done on its copied RT
326          * entries will be redundant with those done during execution of the
327          * original query, but we don't bother to treat that case differently.
328          *
329          * NOTE: because planner will destructively alter rtable, we must ensure that
330          * rule action's rtable is separate and shares no substructure with the
331          * main rtable.  Hence do a deep copy here.
332          */
333         sub_action->rtable = list_concat((List *) copyObject(parsetree->rtable),
334                                                                          sub_action->rtable);
335
336         /*
337          * Each rule action's jointree should be the main parsetree's jointree
338          * plus that rule's jointree, but usually *without* the original rtindex
339          * that we're replacing (if present, which it won't be for INSERT). Note
340          * that if the rule action refers to OLD, its jointree will add a
341          * reference to rt_index.  If the rule action doesn't refer to OLD, but
342          * either the rule_qual or the user query quals do, then we need to keep
343          * the original rtindex in the jointree to provide data for the quals.  We
344          * don't want the original rtindex to be joined twice, however, so avoid
345          * keeping it if the rule action mentions it.
346          *
347          * As above, the action's jointree must not share substructure with the main
348          * parsetree's.
349          */
350         if (sub_action->commandType != CMD_UTILITY)
351         {
352                 bool            keeporig;
353                 List       *newjointree;
354
355                 Assert(sub_action->jointree != NULL);
356                 keeporig = (!rangeTableEntry_used((Node *) sub_action->jointree,
357                                                                                   rt_index, 0)) &&
358                         (rangeTableEntry_used(rule_qual, rt_index, 0) ||
359                          rangeTableEntry_used(parsetree->jointree->quals, rt_index, 0));
360                 newjointree = adjustJoinTreeList(parsetree, !keeporig, rt_index);
361                 if (newjointree != NIL)
362                 {
363                         /*
364                          * If sub_action is a setop, manipulating its jointree will do no
365                          * good at all, because the jointree is dummy.  (Perhaps someday
366                          * we could push the joining and quals down to the member
367                          * statements of the setop?)
368                          */
369                         if (sub_action->setOperations != NULL)
370                                 ereport(ERROR,
371                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
372                                                  errmsg("conditional UNION/INTERSECT/EXCEPT statements are not implemented")));
373
374                         sub_action->jointree->fromlist =
375                                 list_concat(newjointree, sub_action->jointree->fromlist);
376                 }
377         }
378
379         /*
380          * Event Qualification forces copying of parsetree and splitting into two
381          * queries one w/rule_qual, one w/NOT rule_qual. Also add user query qual
382          * onto rule action
383          */
384         AddQual(sub_action, rule_qual);
385
386         AddQual(sub_action, parsetree->jointree->quals);
387
388         /*
389          * Rewrite new.attribute w/ right hand side of target-list entry for
390          * appropriate field name in insert/update.
391          *
392          * KLUGE ALERT: since ResolveNew returns a mutated copy, we can't just apply
393          * it to sub_action; we have to remember to update the sublink inside
394          * rule_action, too.
395          */
396         if ((event == CMD_INSERT || event == CMD_UPDATE) &&
397                 sub_action->commandType != CMD_UTILITY)
398         {
399                 sub_action = (Query *) ResolveNew((Node *) sub_action,
400                                                                                   new_varno,
401                                                                                   0,
402                                                                                   rt_fetch(new_varno,
403                                                                                                    sub_action->rtable),
404                                                                                   parsetree->targetList,
405                                                                                   event,
406                                                                                   current_varno);
407                 if (sub_action_ptr)
408                         *sub_action_ptr = sub_action;
409                 else
410                         rule_action = sub_action;
411         }
412
413         return rule_action;
414 }
415
416 /*
417  * Copy the query's jointree list, and optionally attempt to remove any
418  * occurrence of the given rt_index as a top-level join item (we do not look
419  * for it within join items; this is OK because we are only expecting to find
420  * it as an UPDATE or DELETE target relation, which will be at the top level
421  * of the join).  Returns modified jointree list --- this is a separate copy
422  * sharing no nodes with the original.
423  */
424 static List *
425 adjustJoinTreeList(Query *parsetree, bool removert, int rt_index)
426 {
427         List       *newjointree = copyObject(parsetree->jointree->fromlist);
428         ListCell   *l;
429
430         if (removert)
431         {
432                 foreach(l, newjointree)
433                 {
434                         RangeTblRef *rtr = lfirst(l);
435
436                         if (IsA(rtr, RangeTblRef) &&
437                                 rtr->rtindex == rt_index)
438                         {
439                                 newjointree = list_delete_ptr(newjointree, rtr);
440
441                                 /*
442                                  * foreach is safe because we exit loop after list_delete...
443                                  */
444                                 break;
445                         }
446                 }
447         }
448         return newjointree;
449 }
450
451
452 /*
453  * rewriteTargetList - rewrite INSERT/UPDATE targetlist into standard form
454  *
455  * This has the following responsibilities:
456  *
457  * 1. For an INSERT, add tlist entries to compute default values for any
458  * attributes that have defaults and are not assigned to in the given tlist.
459  * (We do not insert anything for default-less attributes, however.  The
460  * planner will later insert NULLs for them, but there's no reason to slow
461  * down rewriter processing with extra tlist nodes.)  Also, for both INSERT
462  * and UPDATE, replace explicit DEFAULT specifications with column default
463  * expressions.
464  *
465  * 2. Merge multiple entries for the same target attribute, or declare error
466  * if we can't.  Multiple entries are only allowed for INSERT/UPDATE of
467  * portions of an array or record field, for example
468  *                      UPDATE table SET foo[2] = 42, foo[4] = 43;
469  * We can merge such operations into a single assignment op.  Essentially,
470  * the expression we want to produce in this case is like
471  *              foo = array_set(array_set(foo, 2, 42), 4, 43)
472  *
473  * 3. Sort the tlist into standard order: non-junk fields in order by resno,
474  * then junk fields (these in no particular order).
475  *
476  * We must do items 1 and 2 before firing rewrite rules, else rewritten
477  * references to NEW.foo will produce wrong or incomplete results.      Item 3
478  * is not needed for rewriting, but will be needed by the planner, and we
479  * can do it essentially for free while handling items 1 and 2.
480  */
481 static void
482 rewriteTargetList(Query *parsetree, Relation target_relation)
483 {
484         CmdType         commandType = parsetree->commandType;
485         TargetEntry **new_tles;
486         List       *new_tlist = NIL;
487         List       *junk_tlist = NIL;
488         Form_pg_attribute att_tup;
489         int                     attrno,
490                                 next_junk_attrno,
491                                 numattrs;
492         ListCell   *temp;
493
494         /*
495          * We process the normal (non-junk) attributes by scanning the input tlist
496          * once and transferring TLEs into an array, then scanning the array to
497          * build an output tlist.  This avoids O(N^2) behavior for large numbers
498          * of attributes.
499          *
500          * Junk attributes are tossed into a separate list during the same tlist
501          * scan, then appended to the reconstructed tlist.
502          */
503         numattrs = RelationGetNumberOfAttributes(target_relation);
504         new_tles = (TargetEntry **) palloc0(numattrs * sizeof(TargetEntry *));
505         next_junk_attrno = numattrs + 1;
506
507         foreach(temp, parsetree->targetList)
508         {
509                 TargetEntry *old_tle = (TargetEntry *) lfirst(temp);
510
511                 if (!old_tle->resjunk)
512                 {
513                         /* Normal attr: stash it into new_tles[] */
514                         attrno = old_tle->resno;
515                         if (attrno < 1 || attrno > numattrs)
516                                 elog(ERROR, "bogus resno %d in targetlist", attrno);
517                         att_tup = target_relation->rd_att->attrs[attrno - 1];
518
519                         /* We can (and must) ignore deleted attributes */
520                         if (att_tup->attisdropped)
521                                 continue;
522
523                         /* Merge with any prior assignment to same attribute */
524                         new_tles[attrno - 1] =
525                                 process_matched_tle(old_tle,
526                                                                         new_tles[attrno - 1],
527                                                                         NameStr(att_tup->attname));
528                 }
529                 else
530                 {
531                         /*
532                          * Copy all resjunk tlist entries to junk_tlist, and assign them
533                          * resnos above the last real resno.
534                          *
535                          * Typical junk entries include ORDER BY or GROUP BY expressions (are
536                          * these actually possible in an INSERT or UPDATE?), system
537                          * attribute references, etc.
538                          */
539
540                         /* Get the resno right, but don't copy unnecessarily */
541                         if (old_tle->resno != next_junk_attrno)
542                         {
543                                 old_tle = flatCopyTargetEntry(old_tle);
544                                 old_tle->resno = next_junk_attrno;
545                         }
546                         junk_tlist = lappend(junk_tlist, old_tle);
547                         next_junk_attrno++;
548                 }
549         }
550
551         for (attrno = 1; attrno <= numattrs; attrno++)
552         {
553                 TargetEntry *new_tle = new_tles[attrno - 1];
554
555                 att_tup = target_relation->rd_att->attrs[attrno - 1];
556
557                 /* We can (and must) ignore deleted attributes */
558                 if (att_tup->attisdropped)
559                         continue;
560
561                 /*
562                  * Handle the two cases where we need to insert a default expression:
563                  * it's an INSERT and there's no tlist entry for the column, or the
564                  * tlist entry is a DEFAULT placeholder node.
565                  */
566                 if ((new_tle == NULL && commandType == CMD_INSERT) ||
567                         (new_tle && new_tle->expr && IsA(new_tle->expr, SetToDefault)))
568                 {
569                         Node       *new_expr;
570
571                         new_expr = build_column_default(target_relation, attrno);
572
573                         /*
574                          * If there is no default (ie, default is effectively NULL), we
575                          * can omit the tlist entry in the INSERT case, since the planner
576                          * can insert a NULL for itself, and there's no point in spending
577                          * any more rewriter cycles on the entry.  But in the UPDATE case
578                          * we've got to explicitly set the column to NULL.
579                          */
580                         if (!new_expr)
581                         {
582                                 if (commandType == CMD_INSERT)
583                                         new_tle = NULL;
584                                 else
585                                 {
586                                         new_expr = (Node *) makeConst(att_tup->atttypid,
587                                                                                                   att_tup->attlen,
588                                                                                                   (Datum) 0,
589                                                                                                   true, /* isnull */
590                                                                                                   att_tup->attbyval);
591                                         /* this is to catch a NOT NULL domain constraint */
592                                         new_expr = coerce_to_domain(new_expr,
593                                                                                                 InvalidOid,
594                                                                                                 att_tup->atttypid,
595                                                                                                 COERCE_IMPLICIT_CAST,
596                                                                                                 false,
597                                                                                                 false);
598                                 }
599                         }
600
601                         if (new_expr)
602                                 new_tle = makeTargetEntry((Expr *) new_expr,
603                                                                                   attrno,
604                                                                                   pstrdup(NameStr(att_tup->attname)),
605                                                                                   false);
606                 }
607
608                 if (new_tle)
609                         new_tlist = lappend(new_tlist, new_tle);
610         }
611
612         pfree(new_tles);
613
614         parsetree->targetList = list_concat(new_tlist, junk_tlist);
615 }
616
617
618 /*
619  * Convert a matched TLE from the original tlist into a correct new TLE.
620  *
621  * This routine detects and handles multiple assignments to the same target
622  * attribute.  (The attribute name is needed only for error messages.)
623  */
624 static TargetEntry *
625 process_matched_tle(TargetEntry *src_tle,
626                                         TargetEntry *prior_tle,
627                                         const char *attrName)
628 {
629         TargetEntry *result;
630         Node       *src_expr;
631         Node       *prior_expr;
632         Node       *src_input;
633         Node       *prior_input;
634         Node       *priorbottom;
635         Node       *newexpr;
636
637         if (prior_tle == NULL)
638         {
639                 /*
640                  * Normal case where this is the first assignment to the attribute.
641                  */
642                 return src_tle;
643         }
644
645         /*----------
646          * Multiple assignments to same attribute.      Allow only if all are
647          * FieldStore or ArrayRef assignment operations.  This is a bit
648          * tricky because what we may actually be looking at is a nest of
649          * such nodes; consider
650          *              UPDATE tab SET col.fld1.subfld1 = x, col.fld2.subfld2 = y
651          * The two expressions produced by the parser will look like
652          *              FieldStore(col, fld1, FieldStore(placeholder, subfld1, x))
653          *              FieldStore(col, fld2, FieldStore(placeholder, subfld2, x))
654          * However, we can ignore the substructure and just consider the top
655          * FieldStore or ArrayRef from each assignment, because it works to
656          * combine these as
657          *              FieldStore(FieldStore(col, fld1,
658          *                                                        FieldStore(placeholder, subfld1, x)),
659          *                                 fld2, FieldStore(placeholder, subfld2, x))
660          * Note the leftmost expression goes on the inside so that the
661          * assignments appear to occur left-to-right.
662          *
663          * For FieldStore, instead of nesting we can generate a single
664          * FieldStore with multiple target fields.      We must nest when
665          * ArrayRefs are involved though.
666          *----------
667          */
668         src_expr = (Node *) src_tle->expr;
669         prior_expr = (Node *) prior_tle->expr;
670         src_input = get_assignment_input(src_expr);
671         prior_input = get_assignment_input(prior_expr);
672         if (src_input == NULL ||
673                 prior_input == NULL ||
674                 exprType(src_expr) != exprType(prior_expr))
675                 ereport(ERROR,
676                                 (errcode(ERRCODE_SYNTAX_ERROR),
677                                  errmsg("multiple assignments to same column \"%s\"",
678                                                 attrName)));
679
680         /*
681          * Prior TLE could be a nest of assignments if we do this more than once.
682          */
683         priorbottom = prior_input;
684         for (;;)
685         {
686                 Node       *newbottom = get_assignment_input(priorbottom);
687
688                 if (newbottom == NULL)
689                         break;                          /* found the original Var reference */
690                 priorbottom = newbottom;
691         }
692         if (!equal(priorbottom, src_input))
693                 ereport(ERROR,
694                                 (errcode(ERRCODE_SYNTAX_ERROR),
695                                  errmsg("multiple assignments to same column \"%s\"",
696                                                 attrName)));
697
698         /*
699          * Looks OK to nest 'em.
700          */
701         if (IsA(src_expr, FieldStore))
702         {
703                 FieldStore *fstore = makeNode(FieldStore);
704
705                 if (IsA(prior_expr, FieldStore))
706                 {
707                         /* combine the two */
708                         memcpy(fstore, prior_expr, sizeof(FieldStore));
709                         fstore->newvals =
710                                 list_concat(list_copy(((FieldStore *) prior_expr)->newvals),
711                                                         list_copy(((FieldStore *) src_expr)->newvals));
712                         fstore->fieldnums =
713                                 list_concat(list_copy(((FieldStore *) prior_expr)->fieldnums),
714                                                         list_copy(((FieldStore *) src_expr)->fieldnums));
715                 }
716                 else
717                 {
718                         /* general case, just nest 'em */
719                         memcpy(fstore, src_expr, sizeof(FieldStore));
720                         fstore->arg = (Expr *) prior_expr;
721                 }
722                 newexpr = (Node *) fstore;
723         }
724         else if (IsA(src_expr, ArrayRef))
725         {
726                 ArrayRef   *aref = makeNode(ArrayRef);
727
728                 memcpy(aref, src_expr, sizeof(ArrayRef));
729                 aref->refexpr = (Expr *) prior_expr;
730                 newexpr = (Node *) aref;
731         }
732         else
733         {
734                 elog(ERROR, "can't happen");
735                 newexpr = NULL;
736         }
737
738         result = flatCopyTargetEntry(src_tle);
739         result->expr = (Expr *) newexpr;
740         return result;
741 }
742
743 /*
744  * If node is an assignment node, return its input; else return NULL
745  */
746 static Node *
747 get_assignment_input(Node *node)
748 {
749         if (node == NULL)
750                 return NULL;
751         if (IsA(node, FieldStore))
752         {
753                 FieldStore *fstore = (FieldStore *) node;
754
755                 return (Node *) fstore->arg;
756         }
757         else if (IsA(node, ArrayRef))
758         {
759                 ArrayRef   *aref = (ArrayRef *) node;
760
761                 if (aref->refassgnexpr == NULL)
762                         return NULL;
763                 return (Node *) aref->refexpr;
764         }
765         return NULL;
766 }
767
768 /*
769  * Make an expression tree for the default value for a column.
770  *
771  * If there is no default, return a NULL instead.
772  */
773 Node *
774 build_column_default(Relation rel, int attrno)
775 {
776         TupleDesc       rd_att = rel->rd_att;
777         Form_pg_attribute att_tup = rd_att->attrs[attrno - 1];
778         Oid                     atttype = att_tup->atttypid;
779         int32           atttypmod = att_tup->atttypmod;
780         Node       *expr = NULL;
781         Oid                     exprtype;
782
783         /*
784          * Scan to see if relation has a default for this column.
785          */
786         if (rd_att->constr && rd_att->constr->num_defval > 0)
787         {
788                 AttrDefault *defval = rd_att->constr->defval;
789                 int                     ndef = rd_att->constr->num_defval;
790
791                 while (--ndef >= 0)
792                 {
793                         if (attrno == defval[ndef].adnum)
794                         {
795                                 /*
796                                  * Found it, convert string representation to node tree.
797                                  */
798                                 expr = stringToNode(defval[ndef].adbin);
799                                 break;
800                         }
801                 }
802         }
803
804         if (expr == NULL)
805         {
806                 /*
807                  * No per-column default, so look for a default for the type itself.
808                  */
809                 expr = get_typdefault(atttype);
810         }
811
812         if (expr == NULL)
813                 return NULL;                    /* No default anywhere */
814
815         /*
816          * Make sure the value is coerced to the target column type; this will
817          * generally be true already, but there seem to be some corner cases
818          * involving domain defaults where it might not be true. This should match
819          * the parser's processing of non-defaulted expressions --- see
820          * updateTargetListEntry().
821          */
822         exprtype = exprType(expr);
823
824         expr = coerce_to_target_type(NULL,      /* no UNKNOWN params here */
825                                                                  expr, exprtype,
826                                                                  atttype, atttypmod,
827                                                                  COERCION_ASSIGNMENT,
828                                                                  COERCE_IMPLICIT_CAST);
829         if (expr == NULL)
830                 ereport(ERROR,
831                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
832                                  errmsg("column \"%s\" is of type %s"
833                                                 " but default expression is of type %s",
834                                                 NameStr(att_tup->attname),
835                                                 format_type_be(atttype),
836                                                 format_type_be(exprtype)),
837                            errhint("You will need to rewrite or cast the expression.")));
838
839         return expr;
840 }
841
842
843 /*
844  * matchLocks -
845  *        match the list of locks and returns the matching rules
846  */
847 static List *
848 matchLocks(CmdType event,
849                    RuleLock *rulelocks,
850                    int varno,
851                    Query *parsetree)
852 {
853         List       *matching_locks = NIL;
854         int                     nlocks;
855         int                     i;
856
857         if (rulelocks == NULL)
858                 return NIL;
859
860         if (parsetree->commandType != CMD_SELECT)
861         {
862                 if (parsetree->resultRelation != varno)
863                         return NIL;
864         }
865
866         nlocks = rulelocks->numLocks;
867
868         for (i = 0; i < nlocks; i++)
869         {
870                 RewriteRule *oneLock = rulelocks->rules[i];
871
872                 if (oneLock->event == event)
873                 {
874                         if (parsetree->commandType != CMD_SELECT ||
875                                 (oneLock->attrno == -1 ?
876                                  rangeTableEntry_used((Node *) parsetree, varno, 0) :
877                                  attribute_used((Node *) parsetree,
878                                                                 varno, oneLock->attrno, 0)))
879                                 matching_locks = lappend(matching_locks, oneLock);
880                 }
881         }
882
883         return matching_locks;
884 }
885
886
887 /*
888  * ApplyRetrieveRule - expand an ON SELECT rule
889  */
890 static Query *
891 ApplyRetrieveRule(Query *parsetree,
892                                   RewriteRule *rule,
893                                   int rt_index,
894                                   bool relation_level,
895                                   Relation relation,
896                                   List *activeRIRs)
897 {
898         Query      *rule_action;
899         RangeTblEntry *rte,
900                            *subrte;
901
902         if (list_length(rule->actions) != 1)
903                 elog(ERROR, "expected just one rule action");
904         if (rule->qual != NULL)
905                 elog(ERROR, "cannot handle qualified ON SELECT rule");
906         if (!relation_level)
907                 elog(ERROR, "cannot handle per-attribute ON SELECT rule");
908
909         /*
910          * Make a modifiable copy of the view query, and acquire needed locks on
911          * the relations it mentions.
912          */
913         rule_action = copyObject(linitial(rule->actions));
914
915         AcquireRewriteLocks(rule_action);
916
917         /*
918          * Recursively expand any view references inside the view.
919          */
920         rule_action = fireRIRrules(rule_action, activeRIRs);
921
922         /*
923          * VIEWs are really easy --- just plug the view query in as a subselect,
924          * replacing the relation's original RTE.
925          */
926         rte = rt_fetch(rt_index, parsetree->rtable);
927
928         rte->rtekind = RTE_SUBQUERY;
929         rte->relid = InvalidOid;
930         rte->subquery = rule_action;
931         rte->inh = false;                       /* must not be set for a subquery */
932
933         /*
934          * We move the view's permission check data down to its rangetable. The
935          * checks will actually be done against the *OLD* entry therein.
936          */
937         subrte = rt_fetch(PRS2_OLD_VARNO, rule_action->rtable);
938         Assert(subrte->relid == relation->rd_id);
939         subrte->requiredPerms = rte->requiredPerms;
940         subrte->checkAsUser = rte->checkAsUser;
941
942         rte->requiredPerms = 0;         /* no permission check on subquery itself */
943         rte->checkAsUser = InvalidOid;
944
945         /*
946          * FOR UPDATE/SHARE of view?
947          */
948         if (list_member_int(parsetree->rowMarks, rt_index))
949         {
950                 /*
951                  * Remove the view from the list of rels that will actually be marked
952                  * FOR UPDATE/SHARE by the executor.  It will still be access- checked
953                  * for write access, though.
954                  */
955                 parsetree->rowMarks = list_delete_int(parsetree->rowMarks, rt_index);
956
957                 /*
958                  * Set up the view's referenced tables as if FOR UPDATE/SHARE.
959                  */
960                 markQueryForLocking(rule_action, parsetree->forUpdate,
961                                                         parsetree->rowNoWait, true);
962         }
963
964         return parsetree;
965 }
966
967 /*
968  * Recursively mark all relations used by a view as FOR UPDATE/SHARE.
969  *
970  * This may generate an invalid query, eg if some sub-query uses an
971  * aggregate.  We leave it to the planner to detect that.
972  *
973  * NB: this must agree with the parser's transformLocking() routine.
974  */
975 static void
976 markQueryForLocking(Query *qry, bool forUpdate, bool noWait, bool skipOldNew)
977 {
978         Index           rti = 0;
979         ListCell   *l;
980
981         if (qry->rowMarks)
982         {
983                 if (forUpdate != qry->forUpdate)
984                         ereport(ERROR,
985                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
986                         errmsg("cannot use both FOR UPDATE and FOR SHARE in one query")));
987                 if (noWait != qry->rowNoWait)
988                         ereport(ERROR,
989                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
990                                          errmsg("cannot use both wait and NOWAIT in one query")));
991         }
992         qry->forUpdate = forUpdate;
993         qry->rowNoWait = noWait;
994
995         foreach(l, qry->rtable)
996         {
997                 RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
998
999                 rti++;
1000
1001                 /* Ignore OLD and NEW entries if we are at top level of view */
1002                 if (skipOldNew &&
1003                         (rti == PRS2_OLD_VARNO || rti == PRS2_NEW_VARNO))
1004                         continue;
1005
1006                 if (rte->rtekind == RTE_RELATION)
1007                 {
1008                         qry->rowMarks = list_append_unique_int(qry->rowMarks, rti);
1009                         rte->requiredPerms |= ACL_SELECT_FOR_UPDATE;
1010                 }
1011                 else if (rte->rtekind == RTE_SUBQUERY)
1012                 {
1013                         /* FOR UPDATE/SHARE of subquery is propagated to subquery's rels */
1014                         markQueryForLocking(rte->subquery, forUpdate, noWait, false);
1015                 }
1016         }
1017 }
1018
1019
1020 /*
1021  * fireRIRonSubLink -
1022  *      Apply fireRIRrules() to each SubLink (subselect in expression) found
1023  *      in the given tree.
1024  *
1025  * NOTE: although this has the form of a walker, we cheat and modify the
1026  * SubLink nodes in-place.      It is caller's responsibility to ensure that
1027  * no unwanted side-effects occur!
1028  *
1029  * This is unlike most of the other routines that recurse into subselects,
1030  * because we must take control at the SubLink node in order to replace
1031  * the SubLink's subselect link with the possibly-rewritten subquery.
1032  */
1033 static bool
1034 fireRIRonSubLink(Node *node, List *activeRIRs)
1035 {
1036         if (node == NULL)
1037                 return false;
1038         if (IsA(node, SubLink))
1039         {
1040                 SubLink    *sub = (SubLink *) node;
1041
1042                 /* Do what we came for */
1043                 sub->subselect = (Node *) fireRIRrules((Query *) sub->subselect,
1044                                                                                            activeRIRs);
1045                 /* Fall through to process lefthand args of SubLink */
1046         }
1047
1048         /*
1049          * Do NOT recurse into Query nodes, because fireRIRrules already processed
1050          * subselects of subselects for us.
1051          */
1052         return expression_tree_walker(node, fireRIRonSubLink,
1053                                                                   (void *) activeRIRs);
1054 }
1055
1056
1057 /*
1058  * fireRIRrules -
1059  *      Apply all RIR rules on each rangetable entry in a query
1060  */
1061 static Query *
1062 fireRIRrules(Query *parsetree, List *activeRIRs)
1063 {
1064         int                     rt_index;
1065
1066         /*
1067          * don't try to convert this into a foreach loop, because rtable list can
1068          * get changed each time through...
1069          */
1070         rt_index = 0;
1071         while (rt_index < list_length(parsetree->rtable))
1072         {
1073                 RangeTblEntry *rte;
1074                 Relation        rel;
1075                 List       *locks;
1076                 RuleLock   *rules;
1077                 RewriteRule *rule;
1078                 int                     i;
1079
1080                 ++rt_index;
1081
1082                 rte = rt_fetch(rt_index, parsetree->rtable);
1083
1084                 /*
1085                  * A subquery RTE can't have associated rules, so there's nothing to
1086                  * do to this level of the query, but we must recurse into the
1087                  * subquery to expand any rule references in it.
1088                  */
1089                 if (rte->rtekind == RTE_SUBQUERY)
1090                 {
1091                         rte->subquery = fireRIRrules(rte->subquery, activeRIRs);
1092                         continue;
1093                 }
1094
1095                 /*
1096                  * Joins and other non-relation RTEs can be ignored completely.
1097                  */
1098                 if (rte->rtekind != RTE_RELATION)
1099                         continue;
1100
1101                 /*
1102                  * If the table is not referenced in the query, then we ignore it.
1103                  * This prevents infinite expansion loop due to new rtable entries
1104                  * inserted by expansion of a rule. A table is referenced if it is
1105                  * part of the join set (a source table), or is referenced by any Var
1106                  * nodes, or is the result table.
1107                  */
1108                 if (rt_index != parsetree->resultRelation &&
1109                         !rangeTableEntry_used((Node *) parsetree, rt_index, 0))
1110                         continue;
1111
1112                 /*
1113                  * We can use NoLock here since either the parser or
1114                  * AcquireRewriteLocks should have locked the rel already.
1115                  */
1116                 rel = heap_open(rte->relid, NoLock);
1117
1118                 /*
1119                  * Collect the RIR rules that we must apply
1120                  */
1121                 rules = rel->rd_rules;
1122                 if (rules == NULL)
1123                 {
1124                         heap_close(rel, NoLock);
1125                         continue;
1126                 }
1127                 locks = NIL;
1128                 for (i = 0; i < rules->numLocks; i++)
1129                 {
1130                         rule = rules->rules[i];
1131                         if (rule->event != CMD_SELECT)
1132                                 continue;
1133
1134                         if (rule->attrno > 0)
1135                         {
1136                                 /* per-attr rule; do we need it? */
1137                                 if (!attribute_used((Node *) parsetree, rt_index,
1138                                                                         rule->attrno, 0))
1139                                         continue;
1140                         }
1141
1142                         locks = lappend(locks, rule);
1143                 }
1144
1145                 /*
1146                  * If we found any, apply them --- but first check for recursion!
1147                  */
1148                 if (locks != NIL)
1149                 {
1150                         ListCell   *l;
1151
1152                         if (list_member_oid(activeRIRs, RelationGetRelid(rel)))
1153                                 ereport(ERROR,
1154                                                 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1155                                                  errmsg("infinite recursion detected in rules for relation \"%s\"",
1156                                                                 RelationGetRelationName(rel))));
1157                         activeRIRs = lcons_oid(RelationGetRelid(rel), activeRIRs);
1158
1159                         foreach(l, locks)
1160                         {
1161                                 rule = lfirst(l);
1162
1163                                 parsetree = ApplyRetrieveRule(parsetree,
1164                                                                                           rule,
1165                                                                                           rt_index,
1166                                                                                           rule->attrno == -1,
1167                                                                                           rel,
1168                                                                                           activeRIRs);
1169                         }
1170
1171                         activeRIRs = list_delete_first(activeRIRs);
1172                 }
1173
1174                 heap_close(rel, NoLock);
1175         }
1176
1177         /*
1178          * Recurse into sublink subqueries, too.  But we already did the ones in
1179          * the rtable.
1180          */
1181         if (parsetree->hasSubLinks)
1182                 query_tree_walker(parsetree, fireRIRonSubLink, (void *) activeRIRs,
1183                                                   QTW_IGNORE_RT_SUBQUERIES);
1184
1185         return parsetree;
1186 }
1187
1188
1189 /*
1190  * Modify the given query by adding 'AND rule_qual IS NOT TRUE' to its
1191  * qualification.  This is used to generate suitable "else clauses" for
1192  * conditional INSTEAD rules.  (Unfortunately we must use "x IS NOT TRUE",
1193  * not just "NOT x" which the planner is much smarter about, else we will
1194  * do the wrong thing when the qual evaluates to NULL.)
1195  *
1196  * The rule_qual may contain references to OLD or NEW.  OLD references are
1197  * replaced by references to the specified rt_index (the relation that the
1198  * rule applies to).  NEW references are only possible for INSERT and UPDATE
1199  * queries on the relation itself, and so they should be replaced by copies
1200  * of the related entries in the query's own targetlist.
1201  */
1202 static Query *
1203 CopyAndAddInvertedQual(Query *parsetree,
1204                                            Node *rule_qual,
1205                                            int rt_index,
1206                                            CmdType event)
1207 {
1208         /* Don't scribble on the passed qual (it's in the relcache!) */
1209         Node       *new_qual = (Node *) copyObject(rule_qual);
1210
1211         /*
1212          * In case there are subqueries in the qual, acquire necessary locks and
1213          * fix any deleted JOIN RTE entries.  (This is somewhat redundant with
1214          * rewriteRuleAction, but not entirely ... consider restructuring so that
1215          * we only need to process the qual this way once.)
1216          */
1217         (void) acquireLocksOnSubLinks(new_qual, NULL);
1218
1219         /* Fix references to OLD */
1220         ChangeVarNodes(new_qual, PRS2_OLD_VARNO, rt_index, 0);
1221         /* Fix references to NEW */
1222         if (event == CMD_INSERT || event == CMD_UPDATE)
1223                 new_qual = ResolveNew(new_qual,
1224                                                           PRS2_NEW_VARNO,
1225                                                           0,
1226                                                           rt_fetch(rt_index, parsetree->rtable),
1227                                                           parsetree->targetList,
1228                                                           event,
1229                                                           rt_index);
1230         /* And attach the fixed qual */
1231         AddInvertedQual(parsetree, new_qual);
1232
1233         return parsetree;
1234 }
1235
1236
1237 /*
1238  *      fireRules -
1239  *         Iterate through rule locks applying rules.
1240  *
1241  * Input arguments:
1242  *      parsetree - original query
1243  *      rt_index - RT index of result relation in original query
1244  *      event - type of rule event
1245  *      locks - list of rules to fire
1246  * Output arguments:
1247  *      *instead_flag - set TRUE if any unqualified INSTEAD rule is found
1248  *                                      (must be initialized to FALSE)
1249  *      *qual_product - filled with modified original query if any qualified
1250  *                                      INSTEAD rule is found (must be initialized to NULL)
1251  * Return value:
1252  *      list of rule actions adjusted for use with this query
1253  *
1254  * Qualified INSTEAD rules generate their action with the qualification
1255  * condition added.  They also generate a modified version of the original
1256  * query with the negated qualification added, so that it will run only for
1257  * rows that the qualified action doesn't act on.  (If there are multiple
1258  * qualified INSTEAD rules, we AND all the negated quals onto a single
1259  * modified original query.)  We won't execute the original, unmodified
1260  * query if we find either qualified or unqualified INSTEAD rules.      If
1261  * we find both, the modified original query is discarded too.
1262  */
1263 static List *
1264 fireRules(Query *parsetree,
1265                   int rt_index,
1266                   CmdType event,
1267                   List *locks,
1268                   bool *instead_flag,
1269                   Query **qual_product)
1270 {
1271         List       *results = NIL;
1272         ListCell   *l;
1273
1274         foreach(l, locks)
1275         {
1276                 RewriteRule *rule_lock = (RewriteRule *) lfirst(l);
1277                 Node       *event_qual = rule_lock->qual;
1278                 List       *actions = rule_lock->actions;
1279                 QuerySource qsrc;
1280                 ListCell   *r;
1281
1282                 /* Determine correct QuerySource value for actions */
1283                 if (rule_lock->isInstead)
1284                 {
1285                         if (event_qual != NULL)
1286                                 qsrc = QSRC_QUAL_INSTEAD_RULE;
1287                         else
1288                         {
1289                                 qsrc = QSRC_INSTEAD_RULE;
1290                                 *instead_flag = true;   /* report unqualified INSTEAD */
1291                         }
1292                 }
1293                 else
1294                         qsrc = QSRC_NON_INSTEAD_RULE;
1295
1296                 if (qsrc == QSRC_QUAL_INSTEAD_RULE)
1297                 {
1298                         /*
1299                          * If there are INSTEAD rules with qualifications, the original
1300                          * query is still performed. But all the negated rule
1301                          * qualifications of the INSTEAD rules are added so it does its
1302                          * actions only in cases where the rule quals of all INSTEAD rules
1303                          * are false. Think of it as the default action in a case. We save
1304                          * this in *qual_product so RewriteQuery() can add it to the query
1305                          * list after we mangled it up enough.
1306                          *
1307                          * If we have already found an unqualified INSTEAD rule, then
1308                          * *qual_product won't be used, so don't bother building it.
1309                          */
1310                         if (!*instead_flag)
1311                         {
1312                                 if (*qual_product == NULL)
1313                                         *qual_product = copyObject(parsetree);
1314                                 *qual_product = CopyAndAddInvertedQual(*qual_product,
1315                                                                                                            event_qual,
1316                                                                                                            rt_index,
1317                                                                                                            event);
1318                         }
1319                 }
1320
1321                 /* Now process the rule's actions and add them to the result list */
1322                 foreach(r, actions)
1323                 {
1324                         Query      *rule_action = lfirst(r);
1325
1326                         if (rule_action->commandType == CMD_NOTHING)
1327                                 continue;
1328
1329                         rule_action = rewriteRuleAction(parsetree, rule_action,
1330                                                                                         event_qual, rt_index, event);
1331
1332                         rule_action->querySource = qsrc;
1333                         rule_action->canSetTag = false;         /* might change later */
1334
1335                         results = lappend(results, rule_action);
1336                 }
1337         }
1338
1339         return results;
1340 }
1341
1342
1343 /*
1344  * RewriteQuery -
1345  *        rewrites the query and apply the rules again on the queries rewritten
1346  *
1347  * rewrite_events is a list of open query-rewrite actions, so we can detect
1348  * infinite recursion.
1349  */
1350 static List *
1351 RewriteQuery(Query *parsetree, List *rewrite_events)
1352 {
1353         CmdType         event = parsetree->commandType;
1354         bool            instead = false;
1355         Query      *qual_product = NULL;
1356         List       *rewritten = NIL;
1357
1358         /*
1359          * If the statement is an update, insert or delete - fire rules on it.
1360          *
1361          * SELECT rules are handled later when we have all the queries that should
1362          * get executed.  Also, utilities aren't rewritten at all (do we still
1363          * need that check?)
1364          */
1365         if (event != CMD_SELECT && event != CMD_UTILITY)
1366         {
1367                 int                     result_relation;
1368                 RangeTblEntry *rt_entry;
1369                 Relation        rt_entry_relation;
1370                 List       *locks;
1371
1372                 result_relation = parsetree->resultRelation;
1373                 Assert(result_relation != 0);
1374                 rt_entry = rt_fetch(result_relation, parsetree->rtable);
1375                 Assert(rt_entry->rtekind == RTE_RELATION);
1376
1377                 /*
1378                  * We can use NoLock here since either the parser or
1379                  * AcquireRewriteLocks should have locked the rel already.
1380                  */
1381                 rt_entry_relation = heap_open(rt_entry->relid, NoLock);
1382
1383                 /*
1384                  * If it's an INSERT or UPDATE, rewrite the targetlist into standard
1385                  * form.  This will be needed by the planner anyway, and doing it now
1386                  * ensures that any references to NEW.field will behave sanely.
1387                  */
1388                 if (event == CMD_INSERT || event == CMD_UPDATE)
1389                         rewriteTargetList(parsetree, rt_entry_relation);
1390
1391                 /*
1392                  * Collect and apply the appropriate rules.
1393                  */
1394                 locks = matchLocks(event, rt_entry_relation->rd_rules,
1395                                                    result_relation, parsetree);
1396
1397                 if (locks != NIL)
1398                 {
1399                         List       *product_queries;
1400
1401                         product_queries = fireRules(parsetree,
1402                                                                                 result_relation,
1403                                                                                 event,
1404                                                                                 locks,
1405                                                                                 &instead,
1406                                                                                 &qual_product);
1407
1408                         /*
1409                          * If we got any product queries, recursively rewrite them --- but
1410                          * first check for recursion!
1411                          */
1412                         if (product_queries != NIL)
1413                         {
1414                                 ListCell   *n;
1415                                 rewrite_event *rev;
1416
1417                                 foreach(n, rewrite_events)
1418                                 {
1419                                         rev = (rewrite_event *) lfirst(n);
1420                                         if (rev->relation == RelationGetRelid(rt_entry_relation) &&
1421                                                 rev->event == event)
1422                                                 ereport(ERROR,
1423                                                                 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1424                                                                  errmsg("infinite recursion detected in rules for relation \"%s\"",
1425                                                            RelationGetRelationName(rt_entry_relation))));
1426                                 }
1427
1428                                 rev = (rewrite_event *) palloc(sizeof(rewrite_event));
1429                                 rev->relation = RelationGetRelid(rt_entry_relation);
1430                                 rev->event = event;
1431                                 rewrite_events = lcons(rev, rewrite_events);
1432
1433                                 foreach(n, product_queries)
1434                                 {
1435                                         Query      *pt = (Query *) lfirst(n);
1436                                         List       *newstuff;
1437
1438                                         newstuff = RewriteQuery(pt, rewrite_events);
1439                                         rewritten = list_concat(rewritten, newstuff);
1440                                 }
1441
1442                                 rewrite_events = list_delete_first(rewrite_events);
1443                         }
1444                 }
1445
1446                 heap_close(rt_entry_relation, NoLock);
1447         }
1448
1449         /*
1450          * For INSERTs, the original query is done first; for UPDATE/DELETE, it is
1451          * done last.  This is needed because update and delete rule actions might
1452          * not do anything if they are invoked after the update or delete is
1453          * performed. The command counter increment between the query executions
1454          * makes the deleted (and maybe the updated) tuples disappear so the scans
1455          * for them in the rule actions cannot find them.
1456          *
1457          * If we found any unqualified INSTEAD, the original query is not done at
1458          * all, in any form.  Otherwise, we add the modified form if qualified
1459          * INSTEADs were found, else the unmodified form.
1460          */
1461         if (!instead)
1462         {
1463                 if (parsetree->commandType == CMD_INSERT)
1464                 {
1465                         if (qual_product != NULL)
1466                                 rewritten = lcons(qual_product, rewritten);
1467                         else
1468                                 rewritten = lcons(parsetree, rewritten);
1469                 }
1470                 else
1471                 {
1472                         if (qual_product != NULL)
1473                                 rewritten = lappend(rewritten, qual_product);
1474                         else
1475                                 rewritten = lappend(rewritten, parsetree);
1476                 }
1477         }
1478
1479         return rewritten;
1480 }
1481
1482
1483 /*
1484  * QueryRewrite -
1485  *        Primary entry point to the query rewriter.
1486  *        Rewrite one query via query rewrite system, possibly returning 0
1487  *        or many queries.
1488  *
1489  * NOTE: the parsetree must either have come straight from the parser,
1490  * or have been scanned by AcquireRewriteLocks to acquire suitable locks.
1491  */
1492 List *
1493 QueryRewrite(Query *parsetree)
1494 {
1495         List       *querylist;
1496         List       *results = NIL;
1497         ListCell   *l;
1498         CmdType         origCmdType;
1499         bool            foundOriginalQuery;
1500         Query      *lastInstead;
1501
1502         /*
1503          * Step 1
1504          *
1505          * Apply all non-SELECT rules possibly getting 0 or many queries
1506          */
1507         querylist = RewriteQuery(parsetree, NIL);
1508
1509         /*
1510          * Step 2
1511          *
1512          * Apply all the RIR rules on each query
1513          */
1514         foreach(l, querylist)
1515         {
1516                 Query      *query = (Query *) lfirst(l);
1517
1518                 query = fireRIRrules(query, NIL);
1519
1520                 /*
1521                  * If the query target was rewritten as a view, complain.
1522                  */
1523                 if (query->resultRelation)
1524                 {
1525                         RangeTblEntry *rte = rt_fetch(query->resultRelation,
1526                                                                                   query->rtable);
1527
1528                         if (rte->rtekind == RTE_SUBQUERY)
1529                         {
1530                                 switch (query->commandType)
1531                                 {
1532                                         case CMD_INSERT:
1533                                                 ereport(ERROR,
1534                                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1535                                                                  errmsg("cannot insert into a view"),
1536                                                                  errhint("You need an unconditional ON INSERT DO INSTEAD rule.")));
1537                                                 break;
1538                                         case CMD_UPDATE:
1539                                                 ereport(ERROR,
1540                                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1541                                                                  errmsg("cannot update a view"),
1542                                                                  errhint("You need an unconditional ON UPDATE DO INSTEAD rule.")));
1543                                                 break;
1544                                         case CMD_DELETE:
1545                                                 ereport(ERROR,
1546                                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1547                                                                  errmsg("cannot delete from a view"),
1548                                                                  errhint("You need an unconditional ON DELETE DO INSTEAD rule.")));
1549                                                 break;
1550                                         default:
1551                                                 elog(ERROR, "unrecognized commandType: %d",
1552                                                          (int) query->commandType);
1553                                                 break;
1554                                 }
1555                         }
1556                 }
1557
1558                 results = lappend(results, query);
1559         }
1560
1561         /*
1562          * Step 3
1563          *
1564          * Determine which, if any, of the resulting queries is supposed to set the
1565          * command-result tag; and update the canSetTag fields accordingly.
1566          *
1567          * If the original query is still in the list, it sets the command tag.
1568          * Otherwise, the last INSTEAD query of the same kind as the original is
1569          * allowed to set the tag.      (Note these rules can leave us with no query
1570          * setting the tag.  The tcop code has to cope with this by setting up a
1571          * default tag based on the original un-rewritten query.)
1572          *
1573          * The Asserts verify that at most one query in the result list is marked
1574          * canSetTag.  If we aren't checking asserts, we can fall out of the loop
1575          * as soon as we find the original query.
1576          */
1577         origCmdType = parsetree->commandType;
1578         foundOriginalQuery = false;
1579         lastInstead = NULL;
1580
1581         foreach(l, results)
1582         {
1583                 Query      *query = (Query *) lfirst(l);
1584
1585                 if (query->querySource == QSRC_ORIGINAL)
1586                 {
1587                         Assert(query->canSetTag);
1588                         Assert(!foundOriginalQuery);
1589                         foundOriginalQuery = true;
1590 #ifndef USE_ASSERT_CHECKING
1591                         break;
1592 #endif
1593                 }
1594                 else
1595                 {
1596                         Assert(!query->canSetTag);
1597                         if (query->commandType == origCmdType &&
1598                                 (query->querySource == QSRC_INSTEAD_RULE ||
1599                                  query->querySource == QSRC_QUAL_INSTEAD_RULE))
1600                                 lastInstead = query;
1601                 }
1602         }
1603
1604         if (!foundOriginalQuery && lastInstead != NULL)
1605                 lastInstead->canSetTag = true;
1606
1607         return results;
1608 }