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