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