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