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