Header And Logo

PostgreSQL
| The world's most advanced open source database.

rewriteHandler.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * rewriteHandler.c
00004  *      Primary module of query rewriter.
00005  *
00006  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00007  * Portions Copyright (c) 1994, Regents of the University of California
00008  *
00009  * IDENTIFICATION
00010  *    src/backend/rewrite/rewriteHandler.c
00011  *
00012  *-------------------------------------------------------------------------
00013  */
00014 #include "postgres.h"
00015 
00016 #include "access/sysattr.h"
00017 #include "catalog/pg_type.h"
00018 #include "commands/trigger.h"
00019 #include "foreign/fdwapi.h"
00020 #include "nodes/makefuncs.h"
00021 #include "nodes/nodeFuncs.h"
00022 #include "parser/analyze.h"
00023 #include "parser/parse_coerce.h"
00024 #include "parser/parsetree.h"
00025 #include "rewrite/rewriteDefine.h"
00026 #include "rewrite/rewriteHandler.h"
00027 #include "rewrite/rewriteManip.h"
00028 #include "utils/builtins.h"
00029 #include "utils/lsyscache.h"
00030 #include "utils/rel.h"
00031 
00032 
00033 /* We use a list of these to detect recursion in RewriteQuery */
00034 typedef struct rewrite_event
00035 {
00036     Oid         relation;       /* OID of relation having rules */
00037     CmdType     event;          /* type of rule being fired */
00038 } rewrite_event;
00039 
00040 static bool acquireLocksOnSubLinks(Node *node, void *context);
00041 static Query *rewriteRuleAction(Query *parsetree,
00042                   Query *rule_action,
00043                   Node *rule_qual,
00044                   int rt_index,
00045                   CmdType event,
00046                   bool *returning_flag);
00047 static List *adjustJoinTreeList(Query *parsetree, bool removert, int rt_index);
00048 static void rewriteTargetListIU(Query *parsetree, Relation target_relation,
00049                     List **attrno_list);
00050 static TargetEntry *process_matched_tle(TargetEntry *src_tle,
00051                     TargetEntry *prior_tle,
00052                     const char *attrName);
00053 static Node *get_assignment_input(Node *node);
00054 static void rewriteValuesRTE(RangeTblEntry *rte, Relation target_relation,
00055                  List *attrnos);
00056 static void rewriteTargetListUD(Query *parsetree, RangeTblEntry *target_rte,
00057                     Relation target_relation);
00058 static void markQueryForLocking(Query *qry, Node *jtnode,
00059                     LockClauseStrength strength, bool noWait, bool pushedDown);
00060 static List *matchLocks(CmdType event, RuleLock *rulelocks,
00061            int varno, Query *parsetree);
00062 static Query *fireRIRrules(Query *parsetree, List *activeRIRs,
00063              bool forUpdatePushedDown);
00064 
00065 
00066 /*
00067  * AcquireRewriteLocks -
00068  *    Acquire suitable locks on all the relations mentioned in the Query.
00069  *    These locks will ensure that the relation schemas don't change under us
00070  *    while we are rewriting and planning the query.
00071  *
00072  * forUpdatePushedDown indicates that a pushed-down FOR [KEY] UPDATE/SHARE applies
00073  * to the current subquery, requiring all rels to be opened with RowShareLock.
00074  * This should always be false at the start of the recursion.
00075  *
00076  * A secondary purpose of this routine is to fix up JOIN RTE references to
00077  * dropped columns (see details below).  Because the RTEs are modified in
00078  * place, it is generally appropriate for the caller of this routine to have
00079  * first done a copyObject() to make a writable copy of the querytree in the
00080  * current memory context.
00081  *
00082  * This processing can, and for efficiency's sake should, be skipped when the
00083  * querytree has just been built by the parser: parse analysis already got
00084  * all the same locks we'd get here, and the parser will have omitted dropped
00085  * columns from JOINs to begin with.  But we must do this whenever we are
00086  * dealing with a querytree produced earlier than the current command.
00087  *
00088  * About JOINs and dropped columns: although the parser never includes an
00089  * already-dropped column in a JOIN RTE's alias var list, it is possible for
00090  * such a list in a stored rule to include references to dropped columns.
00091  * (If the column is not explicitly referenced anywhere else in the query,
00092  * the dependency mechanism won't consider it used by the rule and so won't
00093  * prevent the column drop.)  To support get_rte_attribute_is_dropped(),
00094  * we replace join alias vars that reference dropped columns with NULL Const
00095  * nodes.
00096  *
00097  * (In PostgreSQL 8.0, we did not do this processing but instead had
00098  * get_rte_attribute_is_dropped() recurse to detect dropped columns in joins.
00099  * That approach had horrible performance unfortunately; in particular
00100  * construction of a nested join was O(N^2) in the nesting depth.)
00101  */
00102 void
00103 AcquireRewriteLocks(Query *parsetree, bool forUpdatePushedDown)
00104 {
00105     ListCell   *l;
00106     int         rt_index;
00107 
00108     /*
00109      * First, process RTEs of the current query level.
00110      */
00111     rt_index = 0;
00112     foreach(l, parsetree->rtable)
00113     {
00114         RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
00115         Relation    rel;
00116         LOCKMODE    lockmode;
00117         List       *newaliasvars;
00118         Index       curinputvarno;
00119         RangeTblEntry *curinputrte;
00120         ListCell   *ll;
00121 
00122         ++rt_index;
00123         switch (rte->rtekind)
00124         {
00125             case RTE_RELATION:
00126 
00127                 /*
00128                  * Grab the appropriate lock type for the relation, and do not
00129                  * release it until end of transaction. This protects the
00130                  * rewriter and planner against schema changes mid-query.
00131                  *
00132                  * If the relation is the query's result relation, then we
00133                  * need RowExclusiveLock.  Otherwise, check to see if the
00134                  * relation is accessed FOR [KEY] UPDATE/SHARE or not.  We can't
00135                  * just grab AccessShareLock because then the executor would
00136                  * be trying to upgrade the lock, leading to possible
00137                  * deadlocks.
00138                  */
00139                 if (rt_index == parsetree->resultRelation)
00140                     lockmode = RowExclusiveLock;
00141                 else if (forUpdatePushedDown ||
00142                          get_parse_rowmark(parsetree, rt_index) != NULL)
00143                     lockmode = RowShareLock;
00144                 else
00145                     lockmode = AccessShareLock;
00146 
00147                 rel = heap_open(rte->relid, lockmode);
00148 
00149                 /*
00150                  * While we have the relation open, update the RTE's relkind,
00151                  * just in case it changed since this rule was made.
00152                  */
00153                 rte->relkind = rel->rd_rel->relkind;
00154 
00155                 heap_close(rel, NoLock);
00156                 break;
00157 
00158             case RTE_JOIN:
00159 
00160                 /*
00161                  * Scan the join's alias var list to see if any columns have
00162                  * been dropped, and if so replace those Vars with NULL
00163                  * Consts.
00164                  *
00165                  * Since a join has only two inputs, we can expect to see
00166                  * multiple references to the same input RTE; optimize away
00167                  * multiple fetches.
00168                  */
00169                 newaliasvars = NIL;
00170                 curinputvarno = 0;
00171                 curinputrte = NULL;
00172                 foreach(ll, rte->joinaliasvars)
00173                 {
00174                     Var        *aliasvar = (Var *) lfirst(ll);
00175 
00176                     /*
00177                      * If the list item isn't a simple Var, then it must
00178                      * represent a merged column, ie a USING column, and so it
00179                      * couldn't possibly be dropped, since it's referenced in
00180                      * the join clause.  (Conceivably it could also be a NULL
00181                      * constant already?  But that's OK too.)
00182                      */
00183                     if (IsA(aliasvar, Var))
00184                     {
00185                         /*
00186                          * The elements of an alias list have to refer to
00187                          * earlier RTEs of the same rtable, because that's the
00188                          * order the planner builds things in.  So we already
00189                          * processed the referenced RTE, and so it's safe to
00190                          * use get_rte_attribute_is_dropped on it. (This might
00191                          * not hold after rewriting or planning, but it's OK
00192                          * to assume here.)
00193                          */
00194                         Assert(aliasvar->varlevelsup == 0);
00195                         if (aliasvar->varno != curinputvarno)
00196                         {
00197                             curinputvarno = aliasvar->varno;
00198                             if (curinputvarno >= rt_index)
00199                                 elog(ERROR, "unexpected varno %d in JOIN RTE %d",
00200                                      curinputvarno, rt_index);
00201                             curinputrte = rt_fetch(curinputvarno,
00202                                                    parsetree->rtable);
00203                         }
00204                         if (get_rte_attribute_is_dropped(curinputrte,
00205                                                          aliasvar->varattno))
00206                         {
00207                             /*
00208                              * can't use vartype here, since that might be a
00209                              * now-dropped type OID, but it doesn't really
00210                              * matter what type the Const claims to be.
00211                              */
00212                             aliasvar = (Var *) makeNullConst(INT4OID, -1, InvalidOid);
00213                         }
00214                     }
00215                     newaliasvars = lappend(newaliasvars, aliasvar);
00216                 }
00217                 rte->joinaliasvars = newaliasvars;
00218                 break;
00219 
00220             case RTE_SUBQUERY:
00221 
00222                 /*
00223                  * The subquery RTE itself is all right, but we have to
00224                  * recurse to process the represented subquery.
00225                  */
00226                 AcquireRewriteLocks(rte->subquery,
00227                                     (forUpdatePushedDown ||
00228                             get_parse_rowmark(parsetree, rt_index) != NULL));
00229                 break;
00230 
00231             default:
00232                 /* ignore other types of RTEs */
00233                 break;
00234         }
00235     }
00236 
00237     /* Recurse into subqueries in WITH */
00238     foreach(l, parsetree->cteList)
00239     {
00240         CommonTableExpr *cte = (CommonTableExpr *) lfirst(l);
00241 
00242         AcquireRewriteLocks((Query *) cte->ctequery, false);
00243     }
00244 
00245     /*
00246      * Recurse into sublink subqueries, too.  But we already did the ones in
00247      * the rtable and cteList.
00248      */
00249     if (parsetree->hasSubLinks)
00250         query_tree_walker(parsetree, acquireLocksOnSubLinks, NULL,
00251                           QTW_IGNORE_RC_SUBQUERIES);
00252 }
00253 
00254 /*
00255  * Walker to find sublink subqueries for AcquireRewriteLocks
00256  */
00257 static bool
00258 acquireLocksOnSubLinks(Node *node, void *context)
00259 {
00260     if (node == NULL)
00261         return false;
00262     if (IsA(node, SubLink))
00263     {
00264         SubLink    *sub = (SubLink *) node;
00265 
00266         /* Do what we came for */
00267         AcquireRewriteLocks((Query *) sub->subselect, false);
00268         /* Fall through to process lefthand args of SubLink */
00269     }
00270 
00271     /*
00272      * Do NOT recurse into Query nodes, because AcquireRewriteLocks already
00273      * processed subselects of subselects for us.
00274      */
00275     return expression_tree_walker(node, acquireLocksOnSubLinks, context);
00276 }
00277 
00278 
00279 /*
00280  * rewriteRuleAction -
00281  *    Rewrite the rule action with appropriate qualifiers (taken from
00282  *    the triggering query).
00283  *
00284  * Input arguments:
00285  *  parsetree - original query
00286  *  rule_action - one action (query) of a rule
00287  *  rule_qual - WHERE condition of rule, or NULL if unconditional
00288  *  rt_index - RT index of result relation in original query
00289  *  event - type of rule event
00290  * Output arguments:
00291  *  *returning_flag - set TRUE if we rewrite RETURNING clause in rule_action
00292  *                  (must be initialized to FALSE)
00293  * Return value:
00294  *  rewritten form of rule_action
00295  */
00296 static Query *
00297 rewriteRuleAction(Query *parsetree,
00298                   Query *rule_action,
00299                   Node *rule_qual,
00300                   int rt_index,
00301                   CmdType event,
00302                   bool *returning_flag)
00303 {
00304     int         current_varno,
00305                 new_varno;
00306     int         rt_length;
00307     Query      *sub_action;
00308     Query     **sub_action_ptr;
00309 
00310     /*
00311      * Make modifiable copies of rule action and qual (what we're passed are
00312      * the stored versions in the relcache; don't touch 'em!).
00313      */
00314     rule_action = (Query *) copyObject(rule_action);
00315     rule_qual = (Node *) copyObject(rule_qual);
00316 
00317     /*
00318      * Acquire necessary locks and fix any deleted JOIN RTE entries.
00319      */
00320     AcquireRewriteLocks(rule_action, false);
00321     (void) acquireLocksOnSubLinks(rule_qual, NULL);
00322 
00323     current_varno = rt_index;
00324     rt_length = list_length(parsetree->rtable);
00325     new_varno = PRS2_NEW_VARNO + rt_length;
00326 
00327     /*
00328      * Adjust rule action and qual to offset its varnos, so that we can merge
00329      * its rtable with the main parsetree's rtable.
00330      *
00331      * If the rule action is an INSERT...SELECT, the OLD/NEW rtable entries
00332      * will be in the SELECT part, and we have to modify that rather than the
00333      * top-level INSERT (kluge!).
00334      */
00335     sub_action = getInsertSelectQuery(rule_action, &sub_action_ptr);
00336 
00337     OffsetVarNodes((Node *) sub_action, rt_length, 0);
00338     OffsetVarNodes(rule_qual, rt_length, 0);
00339     /* but references to OLD should point at original rt_index */
00340     ChangeVarNodes((Node *) sub_action,
00341                    PRS2_OLD_VARNO + rt_length, rt_index, 0);
00342     ChangeVarNodes(rule_qual,
00343                    PRS2_OLD_VARNO + rt_length, rt_index, 0);
00344 
00345     /*
00346      * Generate expanded rtable consisting of main parsetree's rtable plus
00347      * rule action's rtable; this becomes the complete rtable for the rule
00348      * action.  Some of the entries may be unused after we finish rewriting,
00349      * but we leave them all in place for two reasons:
00350      *
00351      * We'd have a much harder job to adjust the query's varnos if we
00352      * selectively removed RT entries.
00353      *
00354      * If the rule is INSTEAD, then the original query won't be executed at
00355      * all, and so its rtable must be preserved so that the executor will do
00356      * the correct permissions checks on it.
00357      *
00358      * RT entries that are not referenced in the completed jointree will be
00359      * ignored by the planner, so they do not affect query semantics.  But any
00360      * permissions checks specified in them will be applied during executor
00361      * startup (see ExecCheckRTEPerms()).  This allows us to check that the
00362      * caller has, say, insert-permission on a view, when the view is not
00363      * semantically referenced at all in the resulting query.
00364      *
00365      * When a rule is not INSTEAD, the permissions checks done on its copied
00366      * RT entries will be redundant with those done during execution of the
00367      * original query, but we don't bother to treat that case differently.
00368      *
00369      * NOTE: because planner will destructively alter rtable, we must ensure
00370      * that rule action's rtable is separate and shares no substructure with
00371      * the main rtable.  Hence do a deep copy here.
00372      */
00373     sub_action->rtable = list_concat((List *) copyObject(parsetree->rtable),
00374                                      sub_action->rtable);
00375 
00376     /*
00377      * There could have been some SubLinks in parsetree's rtable, in which
00378      * case we'd better mark the sub_action correctly.
00379      */
00380     if (parsetree->hasSubLinks && !sub_action->hasSubLinks)
00381     {
00382         ListCell   *lc;
00383 
00384         foreach(lc, parsetree->rtable)
00385         {
00386             RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc);
00387 
00388             switch (rte->rtekind)
00389             {
00390                 case RTE_FUNCTION:
00391                     sub_action->hasSubLinks =
00392                         checkExprHasSubLink(rte->funcexpr);
00393                     break;
00394                 case RTE_VALUES:
00395                     sub_action->hasSubLinks =
00396                         checkExprHasSubLink((Node *) rte->values_lists);
00397                     break;
00398                 default:
00399                     /* other RTE types don't contain bare expressions */
00400                     break;
00401             }
00402             if (sub_action->hasSubLinks)
00403                 break;          /* no need to keep scanning rtable */
00404         }
00405     }
00406 
00407     /*
00408      * Each rule action's jointree should be the main parsetree's jointree
00409      * plus that rule's jointree, but usually *without* the original rtindex
00410      * that we're replacing (if present, which it won't be for INSERT). Note
00411      * that if the rule action refers to OLD, its jointree will add a
00412      * reference to rt_index.  If the rule action doesn't refer to OLD, but
00413      * either the rule_qual or the user query quals do, then we need to keep
00414      * the original rtindex in the jointree to provide data for the quals.  We
00415      * don't want the original rtindex to be joined twice, however, so avoid
00416      * keeping it if the rule action mentions it.
00417      *
00418      * As above, the action's jointree must not share substructure with the
00419      * main parsetree's.
00420      */
00421     if (sub_action->commandType != CMD_UTILITY)
00422     {
00423         bool        keeporig;
00424         List       *newjointree;
00425 
00426         Assert(sub_action->jointree != NULL);
00427         keeporig = (!rangeTableEntry_used((Node *) sub_action->jointree,
00428                                           rt_index, 0)) &&
00429             (rangeTableEntry_used(rule_qual, rt_index, 0) ||
00430              rangeTableEntry_used(parsetree->jointree->quals, rt_index, 0));
00431         newjointree = adjustJoinTreeList(parsetree, !keeporig, rt_index);
00432         if (newjointree != NIL)
00433         {
00434             /*
00435              * If sub_action is a setop, manipulating its jointree will do no
00436              * good at all, because the jointree is dummy.  (Perhaps someday
00437              * we could push the joining and quals down to the member
00438              * statements of the setop?)
00439              */
00440             if (sub_action->setOperations != NULL)
00441                 ereport(ERROR,
00442                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
00443                          errmsg("conditional UNION/INTERSECT/EXCEPT statements are not implemented")));
00444 
00445             sub_action->jointree->fromlist =
00446                 list_concat(newjointree, sub_action->jointree->fromlist);
00447 
00448             /*
00449              * There could have been some SubLinks in newjointree, in which
00450              * case we'd better mark the sub_action correctly.
00451              */
00452             if (parsetree->hasSubLinks && !sub_action->hasSubLinks)
00453                 sub_action->hasSubLinks =
00454                     checkExprHasSubLink((Node *) newjointree);
00455         }
00456     }
00457 
00458     /*
00459      * If the original query has any CTEs, copy them into the rule action. But
00460      * we don't need them for a utility action.
00461      */
00462     if (parsetree->cteList != NIL && sub_action->commandType != CMD_UTILITY)
00463     {
00464         ListCell   *lc;
00465 
00466         /*
00467          * Annoying implementation restriction: because CTEs are identified by
00468          * name within a cteList, we can't merge a CTE from the original query
00469          * if it has the same name as any CTE in the rule action.
00470          *
00471          * This could possibly be fixed by using some sort of internally
00472          * generated ID, instead of names, to link CTE RTEs to their CTEs.
00473          */
00474         foreach(lc, parsetree->cteList)
00475         {
00476             CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
00477             ListCell   *lc2;
00478 
00479             foreach(lc2, sub_action->cteList)
00480             {
00481                 CommonTableExpr *cte2 = (CommonTableExpr *) lfirst(lc2);
00482 
00483                 if (strcmp(cte->ctename, cte2->ctename) == 0)
00484                     ereport(ERROR,
00485                             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
00486                              errmsg("WITH query name \"%s\" appears in both a rule action and the query being rewritten",
00487                                     cte->ctename)));
00488             }
00489         }
00490 
00491         /* OK, it's safe to combine the CTE lists */
00492         sub_action->cteList = list_concat(sub_action->cteList,
00493                                           copyObject(parsetree->cteList));
00494     }
00495 
00496     /*
00497      * Event Qualification forces copying of parsetree and splitting into two
00498      * queries one w/rule_qual, one w/NOT rule_qual. Also add user query qual
00499      * onto rule action
00500      */
00501     AddQual(sub_action, rule_qual);
00502 
00503     AddQual(sub_action, parsetree->jointree->quals);
00504 
00505     /*
00506      * Rewrite new.attribute with right hand side of target-list entry for
00507      * appropriate field name in insert/update.
00508      *
00509      * KLUGE ALERT: since ReplaceVarsFromTargetList returns a mutated copy, we
00510      * can't just apply it to sub_action; we have to remember to update the
00511      * sublink inside rule_action, too.
00512      */
00513     if ((event == CMD_INSERT || event == CMD_UPDATE) &&
00514         sub_action->commandType != CMD_UTILITY)
00515     {
00516         sub_action = (Query *)
00517             ReplaceVarsFromTargetList((Node *) sub_action,
00518                                       new_varno,
00519                                       0,
00520                                       rt_fetch(new_varno, sub_action->rtable),
00521                                       parsetree->targetList,
00522                                       (event == CMD_UPDATE) ?
00523                                       REPLACEVARS_CHANGE_VARNO :
00524                                       REPLACEVARS_SUBSTITUTE_NULL,
00525                                       current_varno,
00526                                       NULL);
00527         if (sub_action_ptr)
00528             *sub_action_ptr = sub_action;
00529         else
00530             rule_action = sub_action;
00531     }
00532 
00533     /*
00534      * If rule_action has a RETURNING clause, then either throw it away if the
00535      * triggering query has no RETURNING clause, or rewrite it to emit what
00536      * the triggering query's RETURNING clause asks for.  Throw an error if
00537      * more than one rule has a RETURNING clause.
00538      */
00539     if (!parsetree->returningList)
00540         rule_action->returningList = NIL;
00541     else if (rule_action->returningList)
00542     {
00543         if (*returning_flag)
00544             ereport(ERROR,
00545                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
00546                    errmsg("cannot have RETURNING lists in multiple rules")));
00547         *returning_flag = true;
00548         rule_action->returningList = (List *)
00549             ReplaceVarsFromTargetList((Node *) parsetree->returningList,
00550                                       parsetree->resultRelation,
00551                                       0,
00552                                       rt_fetch(parsetree->resultRelation,
00553                                                parsetree->rtable),
00554                                       rule_action->returningList,
00555                                       REPLACEVARS_REPORT_ERROR,
00556                                       0,
00557                                       &rule_action->hasSubLinks);
00558 
00559         /*
00560          * There could have been some SubLinks in parsetree's returningList,
00561          * in which case we'd better mark the rule_action correctly.
00562          */
00563         if (parsetree->hasSubLinks && !rule_action->hasSubLinks)
00564             rule_action->hasSubLinks =
00565                 checkExprHasSubLink((Node *) rule_action->returningList);
00566     }
00567 
00568     return rule_action;
00569 }
00570 
00571 /*
00572  * Copy the query's jointree list, and optionally attempt to remove any
00573  * occurrence of the given rt_index as a top-level join item (we do not look
00574  * for it within join items; this is OK because we are only expecting to find
00575  * it as an UPDATE or DELETE target relation, which will be at the top level
00576  * of the join).  Returns modified jointree list --- this is a separate copy
00577  * sharing no nodes with the original.
00578  */
00579 static List *
00580 adjustJoinTreeList(Query *parsetree, bool removert, int rt_index)
00581 {
00582     List       *newjointree = copyObject(parsetree->jointree->fromlist);
00583     ListCell   *l;
00584 
00585     if (removert)
00586     {
00587         foreach(l, newjointree)
00588         {
00589             RangeTblRef *rtr = lfirst(l);
00590 
00591             if (IsA(rtr, RangeTblRef) &&
00592                 rtr->rtindex == rt_index)
00593             {
00594                 newjointree = list_delete_ptr(newjointree, rtr);
00595 
00596                 /*
00597                  * foreach is safe because we exit loop after list_delete...
00598                  */
00599                 break;
00600             }
00601         }
00602     }
00603     return newjointree;
00604 }
00605 
00606 
00607 /*
00608  * rewriteTargetListIU - rewrite INSERT/UPDATE targetlist into standard form
00609  *
00610  * This has the following responsibilities:
00611  *
00612  * 1. For an INSERT, add tlist entries to compute default values for any
00613  * attributes that have defaults and are not assigned to in the given tlist.
00614  * (We do not insert anything for default-less attributes, however.  The
00615  * planner will later insert NULLs for them, but there's no reason to slow
00616  * down rewriter processing with extra tlist nodes.)  Also, for both INSERT
00617  * and UPDATE, replace explicit DEFAULT specifications with column default
00618  * expressions.
00619  *
00620  * 2. For an UPDATE on a view, add tlist entries for any unassigned-to
00621  * attributes, assigning them their old values.  These will later get
00622  * expanded to the output values of the view.  (This is equivalent to what
00623  * the planner's expand_targetlist() will do for UPDATE on a regular table,
00624  * but it's more convenient to do it here while we still have easy access
00625  * to the view's original RT index.)
00626  *
00627  * 3. Merge multiple entries for the same target attribute, or declare error
00628  * if we can't.  Multiple entries are only allowed for INSERT/UPDATE of
00629  * portions of an array or record field, for example
00630  *          UPDATE table SET foo[2] = 42, foo[4] = 43;
00631  * We can merge such operations into a single assignment op.  Essentially,
00632  * the expression we want to produce in this case is like
00633  *      foo = array_set(array_set(foo, 2, 42), 4, 43)
00634  *
00635  * 4. Sort the tlist into standard order: non-junk fields in order by resno,
00636  * then junk fields (these in no particular order).
00637  *
00638  * We must do items 1,2,3 before firing rewrite rules, else rewritten
00639  * references to NEW.foo will produce wrong or incomplete results.  Item 4
00640  * is not needed for rewriting, but will be needed by the planner, and we
00641  * can do it essentially for free while handling the other items.
00642  *
00643  * If attrno_list isn't NULL, we return an additional output besides the
00644  * rewritten targetlist: an integer list of the assigned-to attnums, in
00645  * order of the original tlist's non-junk entries.  This is needed for
00646  * processing VALUES RTEs.
00647  */
00648 static void
00649 rewriteTargetListIU(Query *parsetree, Relation target_relation,
00650                     List **attrno_list)
00651 {
00652     CmdType     commandType = parsetree->commandType;
00653     TargetEntry **new_tles;
00654     List       *new_tlist = NIL;
00655     List       *junk_tlist = NIL;
00656     Form_pg_attribute att_tup;
00657     int         attrno,
00658                 next_junk_attrno,
00659                 numattrs;
00660     ListCell   *temp;
00661 
00662     if (attrno_list)            /* initialize optional result list */
00663         *attrno_list = NIL;
00664 
00665     /*
00666      * We process the normal (non-junk) attributes by scanning the input tlist
00667      * once and transferring TLEs into an array, then scanning the array to
00668      * build an output tlist.  This avoids O(N^2) behavior for large numbers
00669      * of attributes.
00670      *
00671      * Junk attributes are tossed into a separate list during the same tlist
00672      * scan, then appended to the reconstructed tlist.
00673      */
00674     numattrs = RelationGetNumberOfAttributes(target_relation);
00675     new_tles = (TargetEntry **) palloc0(numattrs * sizeof(TargetEntry *));
00676     next_junk_attrno = numattrs + 1;
00677 
00678     foreach(temp, parsetree->targetList)
00679     {
00680         TargetEntry *old_tle = (TargetEntry *) lfirst(temp);
00681 
00682         if (!old_tle->resjunk)
00683         {
00684             /* Normal attr: stash it into new_tles[] */
00685             attrno = old_tle->resno;
00686             if (attrno < 1 || attrno > numattrs)
00687                 elog(ERROR, "bogus resno %d in targetlist", attrno);
00688             att_tup = target_relation->rd_att->attrs[attrno - 1];
00689 
00690             /* put attrno into attrno_list even if it's dropped */
00691             if (attrno_list)
00692                 *attrno_list = lappend_int(*attrno_list, attrno);
00693 
00694             /* We can (and must) ignore deleted attributes */
00695             if (att_tup->attisdropped)
00696                 continue;
00697 
00698             /* Merge with any prior assignment to same attribute */
00699             new_tles[attrno - 1] =
00700                 process_matched_tle(old_tle,
00701                                     new_tles[attrno - 1],
00702                                     NameStr(att_tup->attname));
00703         }
00704         else
00705         {
00706             /*
00707              * Copy all resjunk tlist entries to junk_tlist, and assign them
00708              * resnos above the last real resno.
00709              *
00710              * Typical junk entries include ORDER BY or GROUP BY expressions
00711              * (are these actually possible in an INSERT or UPDATE?), system
00712              * attribute references, etc.
00713              */
00714 
00715             /* Get the resno right, but don't copy unnecessarily */
00716             if (old_tle->resno != next_junk_attrno)
00717             {
00718                 old_tle = flatCopyTargetEntry(old_tle);
00719                 old_tle->resno = next_junk_attrno;
00720             }
00721             junk_tlist = lappend(junk_tlist, old_tle);
00722             next_junk_attrno++;
00723         }
00724     }
00725 
00726     for (attrno = 1; attrno <= numattrs; attrno++)
00727     {
00728         TargetEntry *new_tle = new_tles[attrno - 1];
00729 
00730         att_tup = target_relation->rd_att->attrs[attrno - 1];
00731 
00732         /* We can (and must) ignore deleted attributes */
00733         if (att_tup->attisdropped)
00734             continue;
00735 
00736         /*
00737          * Handle the two cases where we need to insert a default expression:
00738          * it's an INSERT and there's no tlist entry for the column, or the
00739          * tlist entry is a DEFAULT placeholder node.
00740          */
00741         if ((new_tle == NULL && commandType == CMD_INSERT) ||
00742             (new_tle && new_tle->expr && IsA(new_tle->expr, SetToDefault)))
00743         {
00744             Node       *new_expr;
00745 
00746             new_expr = build_column_default(target_relation, attrno);
00747 
00748             /*
00749              * If there is no default (ie, default is effectively NULL), we
00750              * can omit the tlist entry in the INSERT case, since the planner
00751              * can insert a NULL for itself, and there's no point in spending
00752              * any more rewriter cycles on the entry.  But in the UPDATE case
00753              * we've got to explicitly set the column to NULL.
00754              */
00755             if (!new_expr)
00756             {
00757                 if (commandType == CMD_INSERT)
00758                     new_tle = NULL;
00759                 else
00760                 {
00761                     new_expr = (Node *) makeConst(att_tup->atttypid,
00762                                                   -1,
00763                                                   att_tup->attcollation,
00764                                                   att_tup->attlen,
00765                                                   (Datum) 0,
00766                                                   true, /* isnull */
00767                                                   att_tup->attbyval);
00768                     /* this is to catch a NOT NULL domain constraint */
00769                     new_expr = coerce_to_domain(new_expr,
00770                                                 InvalidOid, -1,
00771                                                 att_tup->atttypid,
00772                                                 COERCE_IMPLICIT_CAST,
00773                                                 -1,
00774                                                 false,
00775                                                 false);
00776                 }
00777             }
00778 
00779             if (new_expr)
00780                 new_tle = makeTargetEntry((Expr *) new_expr,
00781                                           attrno,
00782                                           pstrdup(NameStr(att_tup->attname)),
00783                                           false);
00784         }
00785 
00786         /*
00787          * For an UPDATE on a view, provide a dummy entry whenever there is no
00788          * explicit assignment.
00789          */
00790         if (new_tle == NULL && commandType == CMD_UPDATE &&
00791             target_relation->rd_rel->relkind == RELKIND_VIEW)
00792         {
00793             Node       *new_expr;
00794 
00795             new_expr = (Node *) makeVar(parsetree->resultRelation,
00796                                         attrno,
00797                                         att_tup->atttypid,
00798                                         att_tup->atttypmod,
00799                                         att_tup->attcollation,
00800                                         0);
00801 
00802             new_tle = makeTargetEntry((Expr *) new_expr,
00803                                       attrno,
00804                                       pstrdup(NameStr(att_tup->attname)),
00805                                       false);
00806         }
00807 
00808         if (new_tle)
00809             new_tlist = lappend(new_tlist, new_tle);
00810     }
00811 
00812     pfree(new_tles);
00813 
00814     parsetree->targetList = list_concat(new_tlist, junk_tlist);
00815 }
00816 
00817 
00818 /*
00819  * Convert a matched TLE from the original tlist into a correct new TLE.
00820  *
00821  * This routine detects and handles multiple assignments to the same target
00822  * attribute.  (The attribute name is needed only for error messages.)
00823  */
00824 static TargetEntry *
00825 process_matched_tle(TargetEntry *src_tle,
00826                     TargetEntry *prior_tle,
00827                     const char *attrName)
00828 {
00829     TargetEntry *result;
00830     Node       *src_expr;
00831     Node       *prior_expr;
00832     Node       *src_input;
00833     Node       *prior_input;
00834     Node       *priorbottom;
00835     Node       *newexpr;
00836 
00837     if (prior_tle == NULL)
00838     {
00839         /*
00840          * Normal case where this is the first assignment to the attribute.
00841          */
00842         return src_tle;
00843     }
00844 
00845     /*----------
00846      * Multiple assignments to same attribute.  Allow only if all are
00847      * FieldStore or ArrayRef assignment operations.  This is a bit
00848      * tricky because what we may actually be looking at is a nest of
00849      * such nodes; consider
00850      *      UPDATE tab SET col.fld1.subfld1 = x, col.fld2.subfld2 = y
00851      * The two expressions produced by the parser will look like
00852      *      FieldStore(col, fld1, FieldStore(placeholder, subfld1, x))
00853      *      FieldStore(col, fld2, FieldStore(placeholder, subfld2, x))
00854      * However, we can ignore the substructure and just consider the top
00855      * FieldStore or ArrayRef from each assignment, because it works to
00856      * combine these as
00857      *      FieldStore(FieldStore(col, fld1,
00858      *                            FieldStore(placeholder, subfld1, x)),
00859      *                 fld2, FieldStore(placeholder, subfld2, x))
00860      * Note the leftmost expression goes on the inside so that the
00861      * assignments appear to occur left-to-right.
00862      *
00863      * For FieldStore, instead of nesting we can generate a single
00864      * FieldStore with multiple target fields.  We must nest when
00865      * ArrayRefs are involved though.
00866      *----------
00867      */
00868     src_expr = (Node *) src_tle->expr;
00869     prior_expr = (Node *) prior_tle->expr;
00870     src_input = get_assignment_input(src_expr);
00871     prior_input = get_assignment_input(prior_expr);
00872     if (src_input == NULL ||
00873         prior_input == NULL ||
00874         exprType(src_expr) != exprType(prior_expr))
00875         ereport(ERROR,
00876                 (errcode(ERRCODE_SYNTAX_ERROR),
00877                  errmsg("multiple assignments to same column \"%s\"",
00878                         attrName)));
00879 
00880     /*
00881      * Prior TLE could be a nest of assignments if we do this more than once.
00882      */
00883     priorbottom = prior_input;
00884     for (;;)
00885     {
00886         Node       *newbottom = get_assignment_input(priorbottom);
00887 
00888         if (newbottom == NULL)
00889             break;              /* found the original Var reference */
00890         priorbottom = newbottom;
00891     }
00892     if (!equal(priorbottom, src_input))
00893         ereport(ERROR,
00894                 (errcode(ERRCODE_SYNTAX_ERROR),
00895                  errmsg("multiple assignments to same column \"%s\"",
00896                         attrName)));
00897 
00898     /*
00899      * Looks OK to nest 'em.
00900      */
00901     if (IsA(src_expr, FieldStore))
00902     {
00903         FieldStore *fstore = makeNode(FieldStore);
00904 
00905         if (IsA(prior_expr, FieldStore))
00906         {
00907             /* combine the two */
00908             memcpy(fstore, prior_expr, sizeof(FieldStore));
00909             fstore->newvals =
00910                 list_concat(list_copy(((FieldStore *) prior_expr)->newvals),
00911                             list_copy(((FieldStore *) src_expr)->newvals));
00912             fstore->fieldnums =
00913                 list_concat(list_copy(((FieldStore *) prior_expr)->fieldnums),
00914                             list_copy(((FieldStore *) src_expr)->fieldnums));
00915         }
00916         else
00917         {
00918             /* general case, just nest 'em */
00919             memcpy(fstore, src_expr, sizeof(FieldStore));
00920             fstore->arg = (Expr *) prior_expr;
00921         }
00922         newexpr = (Node *) fstore;
00923     }
00924     else if (IsA(src_expr, ArrayRef))
00925     {
00926         ArrayRef   *aref = makeNode(ArrayRef);
00927 
00928         memcpy(aref, src_expr, sizeof(ArrayRef));
00929         aref->refexpr = (Expr *) prior_expr;
00930         newexpr = (Node *) aref;
00931     }
00932     else
00933     {
00934         elog(ERROR, "cannot happen");
00935         newexpr = NULL;
00936     }
00937 
00938     result = flatCopyTargetEntry(src_tle);
00939     result->expr = (Expr *) newexpr;
00940     return result;
00941 }
00942 
00943 /*
00944  * If node is an assignment node, return its input; else return NULL
00945  */
00946 static Node *
00947 get_assignment_input(Node *node)
00948 {
00949     if (node == NULL)
00950         return NULL;
00951     if (IsA(node, FieldStore))
00952     {
00953         FieldStore *fstore = (FieldStore *) node;
00954 
00955         return (Node *) fstore->arg;
00956     }
00957     else if (IsA(node, ArrayRef))
00958     {
00959         ArrayRef   *aref = (ArrayRef *) node;
00960 
00961         if (aref->refassgnexpr == NULL)
00962             return NULL;
00963         return (Node *) aref->refexpr;
00964     }
00965     return NULL;
00966 }
00967 
00968 /*
00969  * Make an expression tree for the default value for a column.
00970  *
00971  * If there is no default, return a NULL instead.
00972  */
00973 Node *
00974 build_column_default(Relation rel, int attrno)
00975 {
00976     TupleDesc   rd_att = rel->rd_att;
00977     Form_pg_attribute att_tup = rd_att->attrs[attrno - 1];
00978     Oid         atttype = att_tup->atttypid;
00979     int32       atttypmod = att_tup->atttypmod;
00980     Node       *expr = NULL;
00981     Oid         exprtype;
00982 
00983     /*
00984      * Scan to see if relation has a default for this column.
00985      */
00986     if (rd_att->constr && rd_att->constr->num_defval > 0)
00987     {
00988         AttrDefault *defval = rd_att->constr->defval;
00989         int         ndef = rd_att->constr->num_defval;
00990 
00991         while (--ndef >= 0)
00992         {
00993             if (attrno == defval[ndef].adnum)
00994             {
00995                 /*
00996                  * Found it, convert string representation to node tree.
00997                  */
00998                 expr = stringToNode(defval[ndef].adbin);
00999                 break;
01000             }
01001         }
01002     }
01003 
01004     if (expr == NULL)
01005     {
01006         /*
01007          * No per-column default, so look for a default for the type itself.
01008          */
01009         expr = get_typdefault(atttype);
01010     }
01011 
01012     if (expr == NULL)
01013         return NULL;            /* No default anywhere */
01014 
01015     /*
01016      * Make sure the value is coerced to the target column type; this will
01017      * generally be true already, but there seem to be some corner cases
01018      * involving domain defaults where it might not be true. This should match
01019      * the parser's processing of non-defaulted expressions --- see
01020      * transformAssignedExpr().
01021      */
01022     exprtype = exprType(expr);
01023 
01024     expr = coerce_to_target_type(NULL,  /* no UNKNOWN params here */
01025                                  expr, exprtype,
01026                                  atttype, atttypmod,
01027                                  COERCION_ASSIGNMENT,
01028                                  COERCE_IMPLICIT_CAST,
01029                                  -1);
01030     if (expr == NULL)
01031         ereport(ERROR,
01032                 (errcode(ERRCODE_DATATYPE_MISMATCH),
01033                  errmsg("column \"%s\" is of type %s"
01034                         " but default expression is of type %s",
01035                         NameStr(att_tup->attname),
01036                         format_type_be(atttype),
01037                         format_type_be(exprtype)),
01038                errhint("You will need to rewrite or cast the expression.")));
01039 
01040     return expr;
01041 }
01042 
01043 
01044 /* Does VALUES RTE contain any SetToDefault items? */
01045 static bool
01046 searchForDefault(RangeTblEntry *rte)
01047 {
01048     ListCell   *lc;
01049 
01050     foreach(lc, rte->values_lists)
01051     {
01052         List       *sublist = (List *) lfirst(lc);
01053         ListCell   *lc2;
01054 
01055         foreach(lc2, sublist)
01056         {
01057             Node       *col = (Node *) lfirst(lc2);
01058 
01059             if (IsA(col, SetToDefault))
01060                 return true;
01061         }
01062     }
01063     return false;
01064 }
01065 
01066 /*
01067  * When processing INSERT ... VALUES with a VALUES RTE (ie, multiple VALUES
01068  * lists), we have to replace any DEFAULT items in the VALUES lists with
01069  * the appropriate default expressions.  The other aspects of targetlist
01070  * rewriting need be applied only to the query's targetlist proper.
01071  *
01072  * Note that we currently can't support subscripted or field assignment
01073  * in the multi-VALUES case.  The targetlist will contain simple Vars
01074  * referencing the VALUES RTE, and therefore process_matched_tle() will
01075  * reject any such attempt with "multiple assignments to same column".
01076  */
01077 static void
01078 rewriteValuesRTE(RangeTblEntry *rte, Relation target_relation, List *attrnos)
01079 {
01080     List       *newValues;
01081     ListCell   *lc;
01082 
01083     /*
01084      * Rebuilding all the lists is a pretty expensive proposition in a big
01085      * VALUES list, and it's a waste of time if there aren't any DEFAULT
01086      * placeholders.  So first scan to see if there are any.
01087      */
01088     if (!searchForDefault(rte))
01089         return;                 /* nothing to do */
01090 
01091     /* Check list lengths (we can assume all the VALUES sublists are alike) */
01092     Assert(list_length(attrnos) == list_length(linitial(rte->values_lists)));
01093 
01094     newValues = NIL;
01095     foreach(lc, rte->values_lists)
01096     {
01097         List       *sublist = (List *) lfirst(lc);
01098         List       *newList = NIL;
01099         ListCell   *lc2;
01100         ListCell   *lc3;
01101 
01102         forboth(lc2, sublist, lc3, attrnos)
01103         {
01104             Node       *col = (Node *) lfirst(lc2);
01105             int         attrno = lfirst_int(lc3);
01106 
01107             if (IsA(col, SetToDefault))
01108             {
01109                 Form_pg_attribute att_tup;
01110                 Node       *new_expr;
01111 
01112                 att_tup = target_relation->rd_att->attrs[attrno - 1];
01113 
01114                 if (!att_tup->attisdropped)
01115                     new_expr = build_column_default(target_relation, attrno);
01116                 else
01117                     new_expr = NULL;    /* force a NULL if dropped */
01118 
01119                 /*
01120                  * If there is no default (ie, default is effectively NULL),
01121                  * we've got to explicitly set the column to NULL.
01122                  */
01123                 if (!new_expr)
01124                 {
01125                     new_expr = (Node *) makeConst(att_tup->atttypid,
01126                                                   -1,
01127                                                   att_tup->attcollation,
01128                                                   att_tup->attlen,
01129                                                   (Datum) 0,
01130                                                   true, /* isnull */
01131                                                   att_tup->attbyval);
01132                     /* this is to catch a NOT NULL domain constraint */
01133                     new_expr = coerce_to_domain(new_expr,
01134                                                 InvalidOid, -1,
01135                                                 att_tup->atttypid,
01136                                                 COERCE_IMPLICIT_CAST,
01137                                                 -1,
01138                                                 false,
01139                                                 false);
01140                 }
01141                 newList = lappend(newList, new_expr);
01142             }
01143             else
01144                 newList = lappend(newList, col);
01145         }
01146         newValues = lappend(newValues, newList);
01147     }
01148     rte->values_lists = newValues;
01149 }
01150 
01151 
01152 /*
01153  * rewriteTargetListUD - rewrite UPDATE/DELETE targetlist as needed
01154  *
01155  * This function adds a "junk" TLE that is needed to allow the executor to
01156  * find the original row for the update or delete.  When the target relation
01157  * is a regular table, the junk TLE emits the ctid attribute of the original
01158  * row.  When the target relation is a view, there is no ctid, so we instead
01159  * emit a whole-row Var that will contain the "old" values of the view row.
01160  * If it's a foreign table, we let the FDW decide what to add.
01161  *
01162  * For UPDATE queries, this is applied after rewriteTargetListIU.  The
01163  * ordering isn't actually critical at the moment.
01164  */
01165 static void
01166 rewriteTargetListUD(Query *parsetree, RangeTblEntry *target_rte,
01167                     Relation target_relation)
01168 {
01169     Var        *var;
01170     const char *attrname;
01171     TargetEntry *tle;
01172 
01173     if (target_relation->rd_rel->relkind == RELKIND_RELATION ||
01174         target_relation->rd_rel->relkind == RELKIND_MATVIEW)
01175     {
01176         /*
01177          * Emit CTID so that executor can find the row to update or delete.
01178          */
01179         var = makeVar(parsetree->resultRelation,
01180                       SelfItemPointerAttributeNumber,
01181                       TIDOID,
01182                       -1,
01183                       InvalidOid,
01184                       0);
01185 
01186         attrname = "ctid";
01187     }
01188     else if (target_relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
01189     {
01190         /*
01191          * Let the foreign table's FDW add whatever junk TLEs it wants.
01192          */
01193         FdwRoutine *fdwroutine;
01194 
01195         fdwroutine = GetFdwRoutineForRelation(target_relation, false);
01196 
01197         if (fdwroutine->AddForeignUpdateTargets != NULL)
01198             fdwroutine->AddForeignUpdateTargets(parsetree, target_rte,
01199                                                 target_relation);
01200 
01201         return;
01202     }
01203     else
01204     {
01205         /*
01206          * Emit whole-row Var so that executor will have the "old" view row to
01207          * pass to the INSTEAD OF trigger.
01208          */
01209         var = makeWholeRowVar(target_rte,
01210                               parsetree->resultRelation,
01211                               0,
01212                               false);
01213 
01214         attrname = "wholerow";
01215     }
01216 
01217     tle = makeTargetEntry((Expr *) var,
01218                           list_length(parsetree->targetList) + 1,
01219                           pstrdup(attrname),
01220                           true);
01221 
01222     parsetree->targetList = lappend(parsetree->targetList, tle);
01223 }
01224 
01225 
01226 /*
01227  * matchLocks -
01228  *    match the list of locks and returns the matching rules
01229  */
01230 static List *
01231 matchLocks(CmdType event,
01232            RuleLock *rulelocks,
01233            int varno,
01234            Query *parsetree)
01235 {
01236     List       *matching_locks = NIL;
01237     int         nlocks;
01238     int         i;
01239 
01240     if (rulelocks == NULL)
01241         return NIL;
01242 
01243     if (parsetree->commandType != CMD_SELECT)
01244     {
01245         if (parsetree->resultRelation != varno)
01246             return NIL;
01247     }
01248 
01249     nlocks = rulelocks->numLocks;
01250 
01251     for (i = 0; i < nlocks; i++)
01252     {
01253         RewriteRule *oneLock = rulelocks->rules[i];
01254 
01255         /*
01256          * Suppress ON INSERT/UPDATE/DELETE rules that are disabled or
01257          * configured to not fire during the current sessions replication
01258          * role. ON SELECT rules will always be applied in order to keep views
01259          * working even in LOCAL or REPLICA role.
01260          */
01261         if (oneLock->event != CMD_SELECT)
01262         {
01263             if (SessionReplicationRole == SESSION_REPLICATION_ROLE_REPLICA)
01264             {
01265                 if (oneLock->enabled == RULE_FIRES_ON_ORIGIN ||
01266                     oneLock->enabled == RULE_DISABLED)
01267                     continue;
01268             }
01269             else    /* ORIGIN or LOCAL ROLE */
01270             {
01271                 if (oneLock->enabled == RULE_FIRES_ON_REPLICA ||
01272                     oneLock->enabled == RULE_DISABLED)
01273                     continue;
01274             }
01275         }
01276 
01277         if (oneLock->event == event)
01278         {
01279             if (parsetree->commandType != CMD_SELECT ||
01280                 (oneLock->attrno == -1 ?
01281                  rangeTableEntry_used((Node *) parsetree, varno, 0) :
01282                  attribute_used((Node *) parsetree,
01283                                 varno, oneLock->attrno, 0)))
01284                 matching_locks = lappend(matching_locks, oneLock);
01285         }
01286     }
01287 
01288     return matching_locks;
01289 }
01290 
01291 
01292 /*
01293  * ApplyRetrieveRule - expand an ON SELECT rule
01294  */
01295 static Query *
01296 ApplyRetrieveRule(Query *parsetree,
01297                   RewriteRule *rule,
01298                   int rt_index,
01299                   bool relation_level,
01300                   Relation relation,
01301                   List *activeRIRs,
01302                   bool forUpdatePushedDown)
01303 {
01304     Query      *rule_action;
01305     RangeTblEntry *rte,
01306                *subrte;
01307     RowMarkClause *rc;
01308 
01309     if (list_length(rule->actions) != 1)
01310         elog(ERROR, "expected just one rule action");
01311     if (rule->qual != NULL)
01312         elog(ERROR, "cannot handle qualified ON SELECT rule");
01313     if (!relation_level)
01314         elog(ERROR, "cannot handle per-attribute ON SELECT rule");
01315 
01316     if (rt_index == parsetree->resultRelation)
01317     {
01318         /*
01319          * We have a view as the result relation of the query, and it wasn't
01320          * rewritten by any rule.  This case is supported if there is an
01321          * INSTEAD OF trigger that will trap attempts to insert/update/delete
01322          * view rows.  The executor will check that; for the moment just plow
01323          * ahead.  We have two cases:
01324          *
01325          * For INSERT, we needn't do anything.  The unmodified RTE will serve
01326          * fine as the result relation.
01327          *
01328          * For UPDATE/DELETE, we need to expand the view so as to have source
01329          * data for the operation.  But we also need an unmodified RTE to
01330          * serve as the target.  So, copy the RTE and add the copy to the
01331          * rangetable.  Note that the copy does not get added to the jointree.
01332          * Also note that there's a hack in fireRIRrules to avoid calling this
01333          * function again when it arrives at the copied RTE.
01334          */
01335         if (parsetree->commandType == CMD_INSERT)
01336             return parsetree;
01337         else if (parsetree->commandType == CMD_UPDATE ||
01338                  parsetree->commandType == CMD_DELETE)
01339         {
01340             RangeTblEntry *newrte;
01341 
01342             rte = rt_fetch(rt_index, parsetree->rtable);
01343             newrte = copyObject(rte);
01344             parsetree->rtable = lappend(parsetree->rtable, newrte);
01345             parsetree->resultRelation = list_length(parsetree->rtable);
01346 
01347             /*
01348              * There's no need to do permissions checks twice, so wipe out the
01349              * permissions info for the original RTE (we prefer to keep the
01350              * bits set on the result RTE).
01351              */
01352             rte->requiredPerms = 0;
01353             rte->checkAsUser = InvalidOid;
01354             rte->selectedCols = NULL;
01355             rte->modifiedCols = NULL;
01356 
01357             /*
01358              * For the most part, Vars referencing the view should remain as
01359              * they are, meaning that they implicitly represent OLD values.
01360              * But in the RETURNING list if any, we want such Vars to
01361              * represent NEW values, so change them to reference the new RTE.
01362              *
01363              * Since ChangeVarNodes scribbles on the tree in-place, copy the
01364              * RETURNING list first for safety.
01365              */
01366             parsetree->returningList = copyObject(parsetree->returningList);
01367             ChangeVarNodes((Node *) parsetree->returningList, rt_index,
01368                            parsetree->resultRelation, 0);
01369 
01370             /* Now, continue with expanding the original view RTE */
01371         }
01372         else
01373             elog(ERROR, "unrecognized commandType: %d",
01374                  (int) parsetree->commandType);
01375     }
01376 
01377     /*
01378      * If FOR [KEY] UPDATE/SHARE of view, be sure we get right initial lock on the
01379      * relations it references.
01380      */
01381     rc = get_parse_rowmark(parsetree, rt_index);
01382     forUpdatePushedDown |= (rc != NULL);
01383 
01384     /*
01385      * Make a modifiable copy of the view query, and acquire needed locks on
01386      * the relations it mentions.
01387      */
01388     rule_action = copyObject(linitial(rule->actions));
01389 
01390     AcquireRewriteLocks(rule_action, forUpdatePushedDown);
01391 
01392     /*
01393      * Recursively expand any view references inside the view.
01394      */
01395     rule_action = fireRIRrules(rule_action, activeRIRs, forUpdatePushedDown);
01396 
01397     /*
01398      * Now, plug the view query in as a subselect, replacing the relation's
01399      * original RTE.
01400      */
01401     rte = rt_fetch(rt_index, parsetree->rtable);
01402 
01403     rte->rtekind = RTE_SUBQUERY;
01404     rte->relid = InvalidOid;
01405     rte->security_barrier = RelationIsSecurityView(relation);
01406     rte->subquery = rule_action;
01407     rte->inh = false;           /* must not be set for a subquery */
01408 
01409     /*
01410      * We move the view's permission check data down to its rangetable. The
01411      * checks will actually be done against the OLD entry therein.
01412      */
01413     subrte = rt_fetch(PRS2_OLD_VARNO, rule_action->rtable);
01414     Assert(subrte->relid == relation->rd_id);
01415     subrte->requiredPerms = rte->requiredPerms;
01416     subrte->checkAsUser = rte->checkAsUser;
01417     subrte->selectedCols = rte->selectedCols;
01418     subrte->modifiedCols = rte->modifiedCols;
01419 
01420     rte->requiredPerms = 0;     /* no permission check on subquery itself */
01421     rte->checkAsUser = InvalidOid;
01422     rte->selectedCols = NULL;
01423     rte->modifiedCols = NULL;
01424 
01425     /*
01426      * If FOR [KEY] UPDATE/SHARE of view, mark all the contained tables as implicit
01427      * FOR [KEY] UPDATE/SHARE, the same as the parser would have done if the view's
01428      * subquery had been written out explicitly.
01429      *
01430      * Note: we don't consider forUpdatePushedDown here; such marks will be
01431      * made by recursing from the upper level in markQueryForLocking.
01432      */
01433     if (rc != NULL)
01434         markQueryForLocking(rule_action, (Node *) rule_action->jointree,
01435                             rc->strength, rc->noWait, true);
01436 
01437     return parsetree;
01438 }
01439 
01440 /*
01441  * Recursively mark all relations used by a view as FOR [KEY] UPDATE/SHARE.
01442  *
01443  * This may generate an invalid query, eg if some sub-query uses an
01444  * aggregate.  We leave it to the planner to detect that.
01445  *
01446  * NB: this must agree with the parser's transformLockingClause() routine.
01447  * However, unlike the parser we have to be careful not to mark a view's
01448  * OLD and NEW rels for updating.  The best way to handle that seems to be
01449  * to scan the jointree to determine which rels are used.
01450  */
01451 static void
01452 markQueryForLocking(Query *qry, Node *jtnode,
01453                     LockClauseStrength strength, bool noWait, bool pushedDown)
01454 {
01455     if (jtnode == NULL)
01456         return;
01457     if (IsA(jtnode, RangeTblRef))
01458     {
01459         int         rti = ((RangeTblRef *) jtnode)->rtindex;
01460         RangeTblEntry *rte = rt_fetch(rti, qry->rtable);
01461 
01462         if (rte->rtekind == RTE_RELATION)
01463         {
01464             applyLockingClause(qry, rti, strength, noWait, pushedDown);
01465             rte->requiredPerms |= ACL_SELECT_FOR_UPDATE;
01466         }
01467         else if (rte->rtekind == RTE_SUBQUERY)
01468         {
01469             applyLockingClause(qry, rti, strength, noWait, pushedDown);
01470             /* FOR UPDATE/SHARE of subquery is propagated to subquery's rels */
01471             markQueryForLocking(rte->subquery, (Node *) rte->subquery->jointree,
01472                                 strength, noWait, true);
01473         }
01474         /* other RTE types are unaffected by FOR UPDATE */
01475     }
01476     else if (IsA(jtnode, FromExpr))
01477     {
01478         FromExpr   *f = (FromExpr *) jtnode;
01479         ListCell   *l;
01480 
01481         foreach(l, f->fromlist)
01482             markQueryForLocking(qry, lfirst(l), strength, noWait, pushedDown);
01483     }
01484     else if (IsA(jtnode, JoinExpr))
01485     {
01486         JoinExpr   *j = (JoinExpr *) jtnode;
01487 
01488         markQueryForLocking(qry, j->larg, strength, noWait, pushedDown);
01489         markQueryForLocking(qry, j->rarg, strength, noWait, pushedDown);
01490     }
01491     else
01492         elog(ERROR, "unrecognized node type: %d",
01493              (int) nodeTag(jtnode));
01494 }
01495 
01496 
01497 /*
01498  * fireRIRonSubLink -
01499  *  Apply fireRIRrules() to each SubLink (subselect in expression) found
01500  *  in the given tree.
01501  *
01502  * NOTE: although this has the form of a walker, we cheat and modify the
01503  * SubLink nodes in-place.  It is caller's responsibility to ensure that
01504  * no unwanted side-effects occur!
01505  *
01506  * This is unlike most of the other routines that recurse into subselects,
01507  * because we must take control at the SubLink node in order to replace
01508  * the SubLink's subselect link with the possibly-rewritten subquery.
01509  */
01510 static bool
01511 fireRIRonSubLink(Node *node, List *activeRIRs)
01512 {
01513     if (node == NULL)
01514         return false;
01515     if (IsA(node, SubLink))
01516     {
01517         SubLink    *sub = (SubLink *) node;
01518 
01519         /* Do what we came for */
01520         sub->subselect = (Node *) fireRIRrules((Query *) sub->subselect,
01521                                                activeRIRs, false);
01522         /* Fall through to process lefthand args of SubLink */
01523     }
01524 
01525     /*
01526      * Do NOT recurse into Query nodes, because fireRIRrules already processed
01527      * subselects of subselects for us.
01528      */
01529     return expression_tree_walker(node, fireRIRonSubLink,
01530                                   (void *) activeRIRs);
01531 }
01532 
01533 
01534 /*
01535  * fireRIRrules -
01536  *  Apply all RIR rules on each rangetable entry in a query
01537  */
01538 static Query *
01539 fireRIRrules(Query *parsetree, List *activeRIRs, bool forUpdatePushedDown)
01540 {
01541     int         origResultRelation = parsetree->resultRelation;
01542     int         rt_index;
01543     ListCell   *lc;
01544 
01545     /*
01546      * don't try to convert this into a foreach loop, because rtable list can
01547      * get changed each time through...
01548      */
01549     rt_index = 0;
01550     while (rt_index < list_length(parsetree->rtable))
01551     {
01552         RangeTblEntry *rte;
01553         Relation    rel;
01554         List       *locks;
01555         RuleLock   *rules;
01556         RewriteRule *rule;
01557         int         i;
01558 
01559         ++rt_index;
01560 
01561         rte = rt_fetch(rt_index, parsetree->rtable);
01562 
01563         /*
01564          * A subquery RTE can't have associated rules, so there's nothing to
01565          * do to this level of the query, but we must recurse into the
01566          * subquery to expand any rule references in it.
01567          */
01568         if (rte->rtekind == RTE_SUBQUERY)
01569         {
01570             rte->subquery = fireRIRrules(rte->subquery, activeRIRs,
01571                                          (forUpdatePushedDown ||
01572                             get_parse_rowmark(parsetree, rt_index) != NULL));
01573             continue;
01574         }
01575 
01576         /*
01577          * Joins and other non-relation RTEs can be ignored completely.
01578          */
01579         if (rte->rtekind != RTE_RELATION)
01580             continue;
01581 
01582         /*
01583          * Always ignore RIR rules for materialized views referenced in
01584          * queries.  (This does not prevent refreshing MVs, since they aren't
01585          * referenced in their own query definitions.)
01586          *
01587          * Note: in the future we might want to allow MVs to be conditionally
01588          * expanded as if they were regular views, if they are not scannable.
01589          * In that case this test would need to be postponed till after we've
01590          * opened the rel, so that we could check its state.
01591          */
01592         if (rte->relkind == RELKIND_MATVIEW)
01593             continue;
01594 
01595         /*
01596          * If the table is not referenced in the query, then we ignore it.
01597          * This prevents infinite expansion loop due to new rtable entries
01598          * inserted by expansion of a rule. A table is referenced if it is
01599          * part of the join set (a source table), or is referenced by any Var
01600          * nodes, or is the result table.
01601          */
01602         if (rt_index != parsetree->resultRelation &&
01603             !rangeTableEntry_used((Node *) parsetree, rt_index, 0))
01604             continue;
01605 
01606         /*
01607          * Also, if this is a new result relation introduced by
01608          * ApplyRetrieveRule, we don't want to do anything more with it.
01609          */
01610         if (rt_index == parsetree->resultRelation &&
01611             rt_index != origResultRelation)
01612             continue;
01613 
01614         /*
01615          * We can use NoLock here since either the parser or
01616          * AcquireRewriteLocks should have locked the rel already.
01617          */
01618         rel = heap_open(rte->relid, NoLock);
01619 
01620         /*
01621          * Collect the RIR rules that we must apply
01622          */
01623         rules = rel->rd_rules;
01624         if (rules == NULL)
01625         {
01626             heap_close(rel, NoLock);
01627             continue;
01628         }
01629         locks = NIL;
01630         for (i = 0; i < rules->numLocks; i++)
01631         {
01632             rule = rules->rules[i];
01633             if (rule->event != CMD_SELECT)
01634                 continue;
01635 
01636             if (rule->attrno > 0)
01637             {
01638                 /* per-attr rule; do we need it? */
01639                 if (!attribute_used((Node *) parsetree, rt_index,
01640                                     rule->attrno, 0))
01641                     continue;
01642             }
01643 
01644             locks = lappend(locks, rule);
01645         }
01646 
01647         /*
01648          * If we found any, apply them --- but first check for recursion!
01649          */
01650         if (locks != NIL)
01651         {
01652             ListCell   *l;
01653 
01654             if (list_member_oid(activeRIRs, RelationGetRelid(rel)))
01655                 ereport(ERROR,
01656                         (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
01657                          errmsg("infinite recursion detected in rules for relation \"%s\"",
01658                                 RelationGetRelationName(rel))));
01659             activeRIRs = lcons_oid(RelationGetRelid(rel), activeRIRs);
01660 
01661             foreach(l, locks)
01662             {
01663                 rule = lfirst(l);
01664 
01665                 parsetree = ApplyRetrieveRule(parsetree,
01666                                               rule,
01667                                               rt_index,
01668                                               rule->attrno == -1,
01669                                               rel,
01670                                               activeRIRs,
01671                                               forUpdatePushedDown);
01672             }
01673 
01674             activeRIRs = list_delete_first(activeRIRs);
01675         }
01676 
01677         heap_close(rel, NoLock);
01678     }
01679 
01680     /* Recurse into subqueries in WITH */
01681     foreach(lc, parsetree->cteList)
01682     {
01683         CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
01684 
01685         cte->ctequery = (Node *)
01686             fireRIRrules((Query *) cte->ctequery, activeRIRs, false);
01687     }
01688 
01689     /*
01690      * Recurse into sublink subqueries, too.  But we already did the ones in
01691      * the rtable and cteList.
01692      */
01693     if (parsetree->hasSubLinks)
01694         query_tree_walker(parsetree, fireRIRonSubLink, (void *) activeRIRs,
01695                           QTW_IGNORE_RC_SUBQUERIES);
01696 
01697     return parsetree;
01698 }
01699 
01700 
01701 /*
01702  * Modify the given query by adding 'AND rule_qual IS NOT TRUE' to its
01703  * qualification.  This is used to generate suitable "else clauses" for
01704  * conditional INSTEAD rules.  (Unfortunately we must use "x IS NOT TRUE",
01705  * not just "NOT x" which the planner is much smarter about, else we will
01706  * do the wrong thing when the qual evaluates to NULL.)
01707  *
01708  * The rule_qual may contain references to OLD or NEW.  OLD references are
01709  * replaced by references to the specified rt_index (the relation that the
01710  * rule applies to).  NEW references are only possible for INSERT and UPDATE
01711  * queries on the relation itself, and so they should be replaced by copies
01712  * of the related entries in the query's own targetlist.
01713  */
01714 static Query *
01715 CopyAndAddInvertedQual(Query *parsetree,
01716                        Node *rule_qual,
01717                        int rt_index,
01718                        CmdType event)
01719 {
01720     /* Don't scribble on the passed qual (it's in the relcache!) */
01721     Node       *new_qual = (Node *) copyObject(rule_qual);
01722 
01723     /*
01724      * In case there are subqueries in the qual, acquire necessary locks and
01725      * fix any deleted JOIN RTE entries.  (This is somewhat redundant with
01726      * rewriteRuleAction, but not entirely ... consider restructuring so that
01727      * we only need to process the qual this way once.)
01728      */
01729     (void) acquireLocksOnSubLinks(new_qual, NULL);
01730 
01731     /* Fix references to OLD */
01732     ChangeVarNodes(new_qual, PRS2_OLD_VARNO, rt_index, 0);
01733     /* Fix references to NEW */
01734     if (event == CMD_INSERT || event == CMD_UPDATE)
01735         new_qual = ReplaceVarsFromTargetList(new_qual,
01736                                              PRS2_NEW_VARNO,
01737                                              0,
01738                                              rt_fetch(rt_index,
01739                                                       parsetree->rtable),
01740                                              parsetree->targetList,
01741                                              (event == CMD_UPDATE) ?
01742                                              REPLACEVARS_CHANGE_VARNO :
01743                                              REPLACEVARS_SUBSTITUTE_NULL,
01744                                              rt_index,
01745                                              &parsetree->hasSubLinks);
01746     /* And attach the fixed qual */
01747     AddInvertedQual(parsetree, new_qual);
01748 
01749     return parsetree;
01750 }
01751 
01752 
01753 /*
01754  *  fireRules -
01755  *     Iterate through rule locks applying rules.
01756  *
01757  * Input arguments:
01758  *  parsetree - original query
01759  *  rt_index - RT index of result relation in original query
01760  *  event - type of rule event
01761  *  locks - list of rules to fire
01762  * Output arguments:
01763  *  *instead_flag - set TRUE if any unqualified INSTEAD rule is found
01764  *                  (must be initialized to FALSE)
01765  *  *returning_flag - set TRUE if we rewrite RETURNING clause in any rule
01766  *                  (must be initialized to FALSE)
01767  *  *qual_product - filled with modified original query if any qualified
01768  *                  INSTEAD rule is found (must be initialized to NULL)
01769  * Return value:
01770  *  list of rule actions adjusted for use with this query
01771  *
01772  * Qualified INSTEAD rules generate their action with the qualification
01773  * condition added.  They also generate a modified version of the original
01774  * query with the negated qualification added, so that it will run only for
01775  * rows that the qualified action doesn't act on.  (If there are multiple
01776  * qualified INSTEAD rules, we AND all the negated quals onto a single
01777  * modified original query.)  We won't execute the original, unmodified
01778  * query if we find either qualified or unqualified INSTEAD rules.  If
01779  * we find both, the modified original query is discarded too.
01780  */
01781 static List *
01782 fireRules(Query *parsetree,
01783           int rt_index,
01784           CmdType event,
01785           List *locks,
01786           bool *instead_flag,
01787           bool *returning_flag,
01788           Query **qual_product)
01789 {
01790     List       *results = NIL;
01791     ListCell   *l;
01792 
01793     foreach(l, locks)
01794     {
01795         RewriteRule *rule_lock = (RewriteRule *) lfirst(l);
01796         Node       *event_qual = rule_lock->qual;
01797         List       *actions = rule_lock->actions;
01798         QuerySource qsrc;
01799         ListCell   *r;
01800 
01801         /* Determine correct QuerySource value for actions */
01802         if (rule_lock->isInstead)
01803         {
01804             if (event_qual != NULL)
01805                 qsrc = QSRC_QUAL_INSTEAD_RULE;
01806             else
01807             {
01808                 qsrc = QSRC_INSTEAD_RULE;
01809                 *instead_flag = true;   /* report unqualified INSTEAD */
01810             }
01811         }
01812         else
01813             qsrc = QSRC_NON_INSTEAD_RULE;
01814 
01815         if (qsrc == QSRC_QUAL_INSTEAD_RULE)
01816         {
01817             /*
01818              * If there are INSTEAD rules with qualifications, the original
01819              * query is still performed. But all the negated rule
01820              * qualifications of the INSTEAD rules are added so it does its
01821              * actions only in cases where the rule quals of all INSTEAD rules
01822              * are false. Think of it as the default action in a case. We save
01823              * this in *qual_product so RewriteQuery() can add it to the query
01824              * list after we mangled it up enough.
01825              *
01826              * If we have already found an unqualified INSTEAD rule, then
01827              * *qual_product won't be used, so don't bother building it.
01828              */
01829             if (!*instead_flag)
01830             {
01831                 if (*qual_product == NULL)
01832                     *qual_product = copyObject(parsetree);
01833                 *qual_product = CopyAndAddInvertedQual(*qual_product,
01834                                                        event_qual,
01835                                                        rt_index,
01836                                                        event);
01837             }
01838         }
01839 
01840         /* Now process the rule's actions and add them to the result list */
01841         foreach(r, actions)
01842         {
01843             Query      *rule_action = lfirst(r);
01844 
01845             if (rule_action->commandType == CMD_NOTHING)
01846                 continue;
01847 
01848             rule_action = rewriteRuleAction(parsetree, rule_action,
01849                                             event_qual, rt_index, event,
01850                                             returning_flag);
01851 
01852             rule_action->querySource = qsrc;
01853             rule_action->canSetTag = false;     /* might change later */
01854 
01855             results = lappend(results, rule_action);
01856         }
01857     }
01858 
01859     return results;
01860 }
01861 
01862 
01863 /*
01864  * get_view_query - get the Query from a view's _RETURN rule.
01865  *
01866  * Caller should have verified that the relation is a view, and therefore
01867  * we should find an ON SELECT action.
01868  */
01869 static Query *
01870 get_view_query(Relation view)
01871 {
01872     int         i;
01873 
01874     Assert(view->rd_rel->relkind == RELKIND_VIEW);
01875 
01876     for (i = 0; i < view->rd_rules->numLocks; i++)
01877     {
01878         RewriteRule *rule = view->rd_rules->rules[i];
01879 
01880         if (rule->event == CMD_SELECT)
01881         {
01882             /* A _RETURN rule should have only one action */
01883             if (list_length(rule->actions) != 1)
01884                 elog(ERROR, "invalid _RETURN rule action specification");
01885 
01886             return (Query *) linitial(rule->actions);
01887         }
01888     }
01889 
01890     elog(ERROR, "failed to find _RETURN rule for view");
01891     return NULL;                /* keep compiler quiet */
01892 }
01893 
01894 
01895 /*
01896  * view_has_instead_trigger - does view have an INSTEAD OF trigger for event?
01897  *
01898  * If it does, we don't want to treat it as auto-updatable.  This test can't
01899  * be folded into view_is_auto_updatable because it's not an error condition.
01900  */
01901 static bool
01902 view_has_instead_trigger(Relation view, CmdType event)
01903 {
01904     TriggerDesc *trigDesc = view->trigdesc;
01905 
01906     switch (event)
01907     {
01908         case CMD_INSERT:
01909             if (trigDesc && trigDesc->trig_insert_instead_row)
01910                 return true;
01911             break;
01912         case CMD_UPDATE:
01913             if (trigDesc && trigDesc->trig_update_instead_row)
01914                 return true;
01915             break;
01916         case CMD_DELETE:
01917             if (trigDesc && trigDesc->trig_delete_instead_row)
01918                 return true;
01919             break;
01920         default:
01921             elog(ERROR, "unrecognized CmdType: %d", (int) event);
01922             break;
01923     }
01924     return false;
01925 }
01926 
01927 
01928 /*
01929  * view_is_auto_updatable -
01930  *    Test if the specified view can be automatically updated. This will
01931  *    either return NULL (if the view can be updated) or a message string
01932  *    giving the reason that it cannot be.
01933  *
01934  * Caller must have verified that relation is a view!
01935  *
01936  * Note that the checks performed here are local to this view.  We do not
01937  * check whether the view's underlying base relation is updatable; that
01938  * will be dealt with in later, recursive processing.
01939  *
01940  * Also note that we don't check for INSTEAD triggers or rules here; those
01941  * also prevent auto-update, but they must be checked for by the caller.
01942  */
01943 static const char *
01944 view_is_auto_updatable(Relation view)
01945 {
01946     Query      *viewquery = get_view_query(view);
01947     RangeTblRef *rtr;
01948     RangeTblEntry *base_rte;
01949     Bitmapset  *bms;
01950     ListCell   *cell;
01951 
01952     /*----------
01953      * Check if the view is simply updatable.  According to SQL-92 this means:
01954      *  - No DISTINCT clause.
01955      *  - Each TLE is a column reference, and each column appears at most once.
01956      *  - FROM contains exactly one base relation.
01957      *  - No GROUP BY or HAVING clauses.
01958      *  - No set operations (UNION, INTERSECT or EXCEPT).
01959      *  - No sub-queries in the WHERE clause that reference the target table.
01960      *
01961      * We ignore that last restriction since it would be complex to enforce
01962      * and there isn't any actual benefit to disallowing sub-queries.  (The
01963      * semantic issues that the standard is presumably concerned about don't
01964      * arise in Postgres, since any such sub-query will not see any updates
01965      * executed by the outer query anyway, thanks to MVCC snapshotting.)
01966      *
01967      * In addition we impose these constraints, involving features that are
01968      * not part of SQL-92:
01969      *  - No CTEs (WITH clauses).
01970      *  - No OFFSET or LIMIT clauses (this matches a SQL:2008 restriction).
01971      *  - No system columns (including whole-row references) in the tlist.
01972      *
01973      * Note that we do these checks without recursively expanding the view.
01974      * If the base relation is a view, we'll recursively deal with it later.
01975      *----------
01976      */
01977     if (viewquery->distinctClause != NIL)
01978         return gettext_noop("Views containing DISTINCT are not automatically updatable.");
01979 
01980     if (viewquery->groupClause != NIL)
01981         return gettext_noop("Views containing GROUP BY are not automatically updatable.");
01982 
01983     if (viewquery->havingQual != NULL)
01984         return gettext_noop("Views containing HAVING are not automatically updatable.");
01985 
01986     if (viewquery->setOperations != NULL)
01987         return gettext_noop("Views containing UNION, INTERSECT, or EXCEPT are not automatically updatable.");
01988 
01989     if (viewquery->cteList != NIL)
01990         return gettext_noop("Views containing WITH are not automatically updatable.");
01991 
01992     if (viewquery->limitOffset != NULL || viewquery->limitCount != NULL)
01993         return gettext_noop("Views containing LIMIT or OFFSET are not automatically updatable.");
01994 
01995     /*
01996      * For now, we also don't support security-barrier views, because of the
01997      * difficulty of keeping upper-level qual expressions away from
01998      * lower-level data.  This might get relaxed in future.
01999      */
02000     if (RelationIsSecurityView(view))
02001         return gettext_noop("Security-barrier views are not automatically updatable.");
02002 
02003     /*
02004      * The view query should select from a single base relation, which must be
02005      * a table or another view.
02006      */
02007     if (list_length(viewquery->jointree->fromlist) != 1)
02008         return gettext_noop("Views that do not select from a single table or view are not automatically updatable.");
02009 
02010     rtr = (RangeTblRef *) linitial(viewquery->jointree->fromlist);
02011     if (!IsA(rtr, RangeTblRef))
02012         return gettext_noop("Views that do not select from a single table or view are not automatically updatable.");
02013 
02014     base_rte = rt_fetch(rtr->rtindex, viewquery->rtable);
02015     if (base_rte->rtekind != RTE_RELATION ||
02016         (base_rte->relkind != RELKIND_RELATION &&
02017          base_rte->relkind != RELKIND_VIEW))
02018         return gettext_noop("Views that do not select from a single table or view are not automatically updatable.");
02019 
02020     /*
02021      * The view's targetlist entries should all be Vars referring to user
02022      * columns of the base relation, and no two should refer to the same
02023      * column.
02024      *
02025      * Note however that we should ignore resjunk entries.  This proviso is
02026      * relevant because ORDER BY is not disallowed, and we shouldn't reject a
02027      * view defined like "SELECT * FROM t ORDER BY a+b".
02028      */
02029     bms = NULL;
02030     foreach(cell, viewquery->targetList)
02031     {
02032         TargetEntry *tle = (TargetEntry *) lfirst(cell);
02033         Var        *var = (Var *) tle->expr;
02034 
02035         if (tle->resjunk)
02036             continue;
02037 
02038         if (!IsA(var, Var) ||
02039             var->varno != rtr->rtindex ||
02040             var->varlevelsup != 0)
02041             return gettext_noop("Views that return columns that are not columns of their base relation are not automatically updatable.");
02042 
02043         if (var->varattno < 0)
02044             return gettext_noop("Views that return system columns are not automatically updatable.");
02045 
02046         if (var->varattno == 0)
02047             return gettext_noop("Views that return whole-row references are not automatically updatable.");
02048 
02049         if (bms_is_member(var->varattno, bms))
02050             return gettext_noop("Views that return the same column more than once are not automatically updatable.");
02051 
02052         bms = bms_add_member(bms, var->varattno);
02053     }
02054     bms_free(bms);              /* just for cleanliness */
02055 
02056     return NULL;                /* the view is simply updatable */
02057 }
02058 
02059 
02060 /*
02061  * relation_is_updatable - test if the specified relation is updatable.
02062  *
02063  * This is used for the information_schema views, which have separate concepts
02064  * of "updatable" and "trigger updatable".  A relation is "updatable" if it
02065  * can be updated without the need for triggers (either because it has a
02066  * suitable RULE, or because it is simple enough to be automatically updated).
02067  *
02068  * A relation is "trigger updatable" if it has a suitable INSTEAD OF trigger.
02069  * The SQL standard regards this as not necessarily updatable, presumably
02070  * because there is no way of knowing what the trigger will actually do.
02071  * That's currently handled directly in the information_schema views, so
02072  * need not be considered here.
02073  *
02074  * In the case of an automatically updatable view, the base relation must
02075  * also be updatable.
02076  *
02077  * reloid is the pg_class OID to examine.  req_events is a bitmask of
02078  * rule event numbers; the relation is considered rule-updatable if it has
02079  * all the specified rules.  (We do it this way so that we can test for
02080  * UPDATE plus DELETE rules in a single call.)
02081  */
02082 bool
02083 relation_is_updatable(Oid reloid, int req_events)
02084 {
02085     Relation    rel;
02086     RuleLock   *rulelocks;
02087 
02088     rel = try_relation_open(reloid, AccessShareLock);
02089 
02090     /*
02091      * If the relation doesn't exist, say "false" rather than throwing an
02092      * error.  This is helpful since scanning an information_schema view
02093      * under MVCC rules can result in referencing rels that were just
02094      * deleted according to a SnapshotNow probe.
02095      */
02096     if (rel == NULL)
02097         return false;
02098 
02099     /* Look for unconditional DO INSTEAD rules, and note supported events */
02100     rulelocks = rel->rd_rules;
02101     if (rulelocks != NULL)
02102     {
02103         int         events = 0;
02104         int         i;
02105 
02106         for (i = 0; i < rulelocks->numLocks; i++)
02107         {
02108             if (rulelocks->rules[i]->isInstead &&
02109                 rulelocks->rules[i]->qual == NULL)
02110             {
02111                 events |= 1 << rulelocks->rules[i]->event;
02112             }
02113         }
02114 
02115         /* If we have all rules needed, say "yes" */
02116         if ((events & req_events) == req_events)
02117         {
02118             relation_close(rel, AccessShareLock);
02119             return true;
02120         }
02121     }
02122 
02123     /* Check if this is an automatically updatable view */
02124     if (rel->rd_rel->relkind == RELKIND_VIEW &&
02125         view_is_auto_updatable(rel) == NULL)
02126     {
02127         Query      *viewquery;
02128         RangeTblRef *rtr;
02129         RangeTblEntry *base_rte;
02130         Oid         baseoid;
02131 
02132         /* The base relation must also be updatable */
02133         viewquery = get_view_query(rel);
02134         rtr = (RangeTblRef *) linitial(viewquery->jointree->fromlist);
02135         base_rte = rt_fetch(rtr->rtindex, viewquery->rtable);
02136 
02137         if (base_rte->relkind == RELKIND_RELATION)
02138         {
02139             /* Tables are always updatable */
02140             relation_close(rel, AccessShareLock);
02141             return true;
02142         }
02143         else
02144         {
02145             /* Do a recursive check for any other kind of base relation */
02146             baseoid = base_rte->relid;
02147             relation_close(rel, AccessShareLock);
02148             return relation_is_updatable(baseoid, req_events);
02149         }
02150     }
02151 
02152     /* If we reach here, the relation is not updatable */
02153     relation_close(rel, AccessShareLock);
02154     return false;
02155 }
02156 
02157 
02158 /*
02159  * adjust_view_column_set - map a set of column numbers according to targetlist
02160  *
02161  * This is used with simply-updatable views to map column-permissions sets for
02162  * the view columns onto the matching columns in the underlying base relation.
02163  * The targetlist is expected to be a list of plain Vars of the underlying
02164  * relation (as per the checks above in view_is_auto_updatable).
02165  */
02166 static Bitmapset *
02167 adjust_view_column_set(Bitmapset *cols, List *targetlist)
02168 {
02169     Bitmapset  *result = NULL;
02170     Bitmapset  *tmpcols;
02171     AttrNumber  col;
02172 
02173     tmpcols = bms_copy(cols);
02174     while ((col = bms_first_member(tmpcols)) >= 0)
02175     {
02176         /* bit numbers are offset by FirstLowInvalidHeapAttributeNumber */
02177         AttrNumber  attno = col + FirstLowInvalidHeapAttributeNumber;
02178 
02179         if (attno == InvalidAttrNumber)
02180         {
02181             /*
02182              * There's a whole-row reference to the view.  For permissions
02183              * purposes, treat it as a reference to each column available from
02184              * the view.  (We should *not* convert this to a whole-row
02185              * reference to the base relation, since the view may not touch
02186              * all columns of the base relation.)
02187              */
02188             ListCell   *lc;
02189 
02190             foreach(lc, targetlist)
02191             {
02192                 TargetEntry *tle = (TargetEntry *) lfirst(lc);
02193                 Var        *var;
02194 
02195                 if (tle->resjunk)
02196                     continue;
02197                 var = (Var *) tle->expr;
02198                 Assert(IsA(var, Var));
02199                 result = bms_add_member(result,
02200                          var->varattno - FirstLowInvalidHeapAttributeNumber);
02201             }
02202         }
02203         else
02204         {
02205             /*
02206              * Views do not have system columns, so we do not expect to see
02207              * any other system attnos here.  If we do find one, the error
02208              * case will apply.
02209              */
02210             TargetEntry *tle = get_tle_by_resno(targetlist, attno);
02211 
02212             if (tle != NULL && !tle->resjunk && IsA(tle->expr, Var))
02213             {
02214                 Var        *var = (Var *) tle->expr;
02215 
02216                 result = bms_add_member(result,
02217                          var->varattno - FirstLowInvalidHeapAttributeNumber);
02218             }
02219             else
02220                 elog(ERROR, "attribute number %d not found in view targetlist",
02221                      attno);
02222         }
02223     }
02224     bms_free(tmpcols);
02225 
02226     return result;
02227 }
02228 
02229 
02230 /*
02231  * rewriteTargetView -
02232  *    Attempt to rewrite a query where the target relation is a view, so that
02233  *    the view's base relation becomes the target relation.
02234  *
02235  * Note that the base relation here may itself be a view, which may or may not
02236  * have INSTEAD OF triggers or rules to handle the update.  That is handled by
02237  * the recursion in RewriteQuery.
02238  */
02239 static Query *
02240 rewriteTargetView(Query *parsetree, Relation view)
02241 {
02242     const char *auto_update_detail;
02243     Query      *viewquery;
02244     RangeTblRef *rtr;
02245     int         base_rt_index;
02246     int         new_rt_index;
02247     RangeTblEntry *base_rte;
02248     RangeTblEntry *view_rte;
02249     RangeTblEntry *new_rte;
02250     Relation    base_rel;
02251     List       *view_targetlist;
02252     ListCell   *lc;
02253 
02254     /* The view must be simply updatable, else fail */
02255     auto_update_detail = view_is_auto_updatable(view);
02256     if (auto_update_detail)
02257     {
02258         /* messages here should match execMain.c's CheckValidResultRel */
02259         switch (parsetree->commandType)
02260         {
02261             case CMD_INSERT:
02262                 ereport(ERROR,
02263                         (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
02264                          errmsg("cannot insert into view \"%s\"",
02265                                 RelationGetRelationName(view)),
02266                          errdetail_internal("%s", _(auto_update_detail)),
02267                          errhint("To make the view insertable, provide an unconditional ON INSERT DO INSTEAD rule or an INSTEAD OF INSERT trigger.")));
02268                 break;
02269             case CMD_UPDATE:
02270                 ereport(ERROR,
02271                         (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
02272                          errmsg("cannot update view \"%s\"",
02273                                 RelationGetRelationName(view)),
02274                          errdetail_internal("%s", _(auto_update_detail)),
02275                          errhint("To make the view updatable, provide an unconditional ON UPDATE DO INSTEAD rule or an INSTEAD OF UPDATE trigger.")));
02276                 break;
02277             case CMD_DELETE:
02278                 ereport(ERROR,
02279                         (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
02280                          errmsg("cannot delete from view \"%s\"",
02281                                 RelationGetRelationName(view)),
02282                          errdetail_internal("%s", _(auto_update_detail)),
02283                          errhint("To make the view updatable, provide an unconditional ON DELETE DO INSTEAD rule or an INSTEAD OF DELETE trigger.")));
02284                 break;
02285             default:
02286                 elog(ERROR, "unrecognized CmdType: %d",
02287                      (int) parsetree->commandType);
02288                 break;
02289         }
02290     }
02291 
02292     /* Locate RTE describing the view in the outer query */
02293     view_rte = rt_fetch(parsetree->resultRelation, parsetree->rtable);
02294 
02295     /*
02296      * If we get here, view_is_auto_updatable() has verified that the view
02297      * contains a single base relation.
02298      */
02299     viewquery = get_view_query(view);
02300 
02301     Assert(list_length(viewquery->jointree->fromlist) == 1);
02302     rtr = (RangeTblRef *) linitial(viewquery->jointree->fromlist);
02303     Assert(IsA(rtr, RangeTblRef));
02304 
02305     base_rt_index = rtr->rtindex;
02306     base_rte = rt_fetch(base_rt_index, viewquery->rtable);
02307     Assert(base_rte->rtekind == RTE_RELATION);
02308 
02309     /*
02310      * Up to now, the base relation hasn't been touched at all in our query.
02311      * We need to acquire lock on it before we try to do anything with it.
02312      * (The subsequent recursive call of RewriteQuery will suppose that we
02313      * already have the right lock!)  Since it will become the query target
02314      * relation, RowExclusiveLock is always the right thing.
02315      */
02316     base_rel = heap_open(base_rte->relid, RowExclusiveLock);
02317 
02318     /*
02319      * While we have the relation open, update the RTE's relkind, just in case
02320      * it changed since this view was made (cf. AcquireRewriteLocks).
02321      */
02322     base_rte->relkind = base_rel->rd_rel->relkind;
02323 
02324     heap_close(base_rel, NoLock);
02325 
02326     /*
02327      * Create a new target RTE describing the base relation, and add it to the
02328      * outer query's rangetable.  (What's happening in the next few steps is
02329      * very much like what the planner would do to "pull up" the view into the
02330      * outer query.  Perhaps someday we should refactor things enough so that
02331      * we can share code with the planner.)
02332      */
02333     new_rte = (RangeTblEntry *) copyObject(base_rte);
02334     parsetree->rtable = lappend(parsetree->rtable, new_rte);
02335     new_rt_index = list_length(parsetree->rtable);
02336 
02337     /*
02338      * Make a copy of the view's targetlist, adjusting its Vars to reference
02339      * the new target RTE, ie make their varnos be new_rt_index instead of
02340      * base_rt_index.  There can be no Vars for other rels in the tlist, so
02341      * this is sufficient to pull up the tlist expressions for use in the
02342      * outer query.  The tlist will provide the replacement expressions used
02343      * by ReplaceVarsFromTargetList below.
02344      */
02345     view_targetlist = copyObject(viewquery->targetList);
02346 
02347     ChangeVarNodes((Node *) view_targetlist,
02348                    base_rt_index,
02349                    new_rt_index,
02350                    0);
02351 
02352     /*
02353      * Mark the new target RTE for the permissions checks that we want to
02354      * enforce against the view owner, as distinct from the query caller.  At
02355      * the relation level, require the same INSERT/UPDATE/DELETE permissions
02356      * that the query caller needs against the view.  We drop the ACL_SELECT
02357      * bit that is presumably in new_rte->requiredPerms initially.
02358      *
02359      * Note: the original view RTE remains in the query's rangetable list.
02360      * Although it will be unused in the query plan, we need it there so that
02361      * the executor still performs appropriate permissions checks for the
02362      * query caller's use of the view.
02363      */
02364     new_rte->checkAsUser = view->rd_rel->relowner;
02365     new_rte->requiredPerms = view_rte->requiredPerms;
02366 
02367     /*
02368      * Now for the per-column permissions bits.
02369      *
02370      * Initially, new_rte contains selectedCols permission check bits for all
02371      * base-rel columns referenced by the view, but since the view is a SELECT
02372      * query its modifiedCols is empty.  We set modifiedCols to include all
02373      * the columns the outer query is trying to modify, adjusting the column
02374      * numbers as needed.  But we leave selectedCols as-is, so the view owner
02375      * must have read permission for all columns used in the view definition,
02376      * even if some of them are not read by the outer query.  We could try to
02377      * limit selectedCols to only columns used in the transformed query, but
02378      * that does not correspond to what happens in ordinary SELECT usage of a
02379      * view: all referenced columns must have read permission, even if
02380      * optimization finds that some of them can be discarded during query
02381      * transformation.  The flattening we're doing here is an optional
02382      * optimization, too.  (If you are unpersuaded and want to change this,
02383      * note that applying adjust_view_column_set to view_rte->selectedCols is
02384      * clearly *not* the right answer, since that neglects base-rel columns
02385      * used in the view's WHERE quals.)
02386      *
02387      * This step needs the modified view targetlist, so we have to do things
02388      * in this order.
02389      */
02390     Assert(bms_is_empty(new_rte->modifiedCols));
02391     new_rte->modifiedCols = adjust_view_column_set(view_rte->modifiedCols,
02392                                                    view_targetlist);
02393 
02394     /*
02395      * For UPDATE/DELETE, rewriteTargetListUD will have added a wholerow junk
02396      * TLE for the view to the end of the targetlist, which we no longer need.
02397      * Remove it to avoid unnecessary work when we process the targetlist.
02398      * Note that when we recurse through rewriteQuery a new junk TLE will be
02399      * added to allow the executor to find the proper row in the new target
02400      * relation.  (So, if we failed to do this, we might have multiple junk
02401      * TLEs with the same name, which would be disastrous.)
02402      */
02403     if (parsetree->commandType != CMD_INSERT)
02404     {
02405         TargetEntry *tle = (TargetEntry *) llast(parsetree->targetList);
02406 
02407         Assert(tle->resjunk);
02408         Assert(IsA(tle->expr, Var) &&
02409                ((Var *) tle->expr)->varno == parsetree->resultRelation &&
02410                ((Var *) tle->expr)->varattno == 0);
02411         parsetree->targetList = list_delete_ptr(parsetree->targetList, tle);
02412     }
02413 
02414     /*
02415      * Now update all Vars in the outer query that reference the view to
02416      * reference the appropriate column of the base relation instead.
02417      */
02418     parsetree = (Query *)
02419         ReplaceVarsFromTargetList((Node *) parsetree,
02420                                   parsetree->resultRelation,
02421                                   0,
02422                                   view_rte,
02423                                   view_targetlist,
02424                                   REPLACEVARS_REPORT_ERROR,
02425                                   0,
02426                                   &parsetree->hasSubLinks);
02427 
02428     /*
02429      * Update all other RTI references in the query that point to the view
02430      * (for example, parsetree->resultRelation itself) to point to the new
02431      * base relation instead.  Vars will not be affected since none of them
02432      * reference parsetree->resultRelation any longer.
02433      */
02434     ChangeVarNodes((Node *) parsetree,
02435                    parsetree->resultRelation,
02436                    new_rt_index,
02437                    0);
02438     Assert(parsetree->resultRelation == new_rt_index);
02439 
02440     /*
02441      * For INSERT/UPDATE we must also update resnos in the targetlist to refer
02442      * to columns of the base relation, since those indicate the target
02443      * columns to be affected.
02444      *
02445      * Note that this destroys the resno ordering of the targetlist, but that
02446      * will be fixed when we recurse through rewriteQuery, which will invoke
02447      * rewriteTargetListIU again on the updated targetlist.
02448      */
02449     if (parsetree->commandType != CMD_DELETE)
02450     {
02451         foreach(lc, parsetree->targetList)
02452         {
02453             TargetEntry *tle = (TargetEntry *) lfirst(lc);
02454             TargetEntry *view_tle;
02455 
02456             if (tle->resjunk)
02457                 continue;
02458 
02459             view_tle = get_tle_by_resno(view_targetlist, tle->resno);
02460             if (view_tle != NULL && !view_tle->resjunk && IsA(view_tle->expr, Var))
02461                 tle->resno = ((Var *) view_tle->expr)->varattno;
02462             else
02463                 elog(ERROR, "attribute number %d not found in view targetlist",
02464                      tle->resno);
02465         }
02466     }
02467 
02468     /*
02469      * For UPDATE/DELETE, pull up any WHERE quals from the view.  We know that
02470      * any Vars in the quals must reference the one base relation, so we need
02471      * only adjust their varnos to reference the new target (just the same as
02472      * we did with the view targetlist).
02473      *
02474      * For INSERT, the view's quals can be ignored for now.  When we implement
02475      * WITH CHECK OPTION, this might be a good place to collect them.
02476      */
02477     if (parsetree->commandType != CMD_INSERT &&
02478         viewquery->jointree->quals != NULL)
02479     {
02480         Node       *viewqual = (Node *) copyObject(viewquery->jointree->quals);
02481 
02482         ChangeVarNodes(viewqual, base_rt_index, new_rt_index, 0);
02483         AddQual(parsetree, (Node *) viewqual);
02484     }
02485 
02486     return parsetree;
02487 }
02488 
02489 
02490 /*
02491  * RewriteQuery -
02492  *    rewrites the query and apply the rules again on the queries rewritten
02493  *
02494  * rewrite_events is a list of open query-rewrite actions, so we can detect
02495  * infinite recursion.
02496  */
02497 static List *
02498 RewriteQuery(Query *parsetree, List *rewrite_events)
02499 {
02500     CmdType     event = parsetree->commandType;
02501     bool        instead = false;
02502     bool        returning = false;
02503     Query      *qual_product = NULL;
02504     List       *rewritten = NIL;
02505     ListCell   *lc1;
02506 
02507     /*
02508      * First, recursively process any insert/update/delete statements in WITH
02509      * clauses.  (We have to do this first because the WITH clauses may get
02510      * copied into rule actions below.)
02511      */
02512     foreach(lc1, parsetree->cteList)
02513     {
02514         CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc1);
02515         Query      *ctequery = (Query *) cte->ctequery;
02516         List       *newstuff;
02517 
02518         Assert(IsA(ctequery, Query));
02519 
02520         if (ctequery->commandType == CMD_SELECT)
02521             continue;
02522 
02523         newstuff = RewriteQuery(ctequery, rewrite_events);
02524 
02525         /*
02526          * Currently we can only handle unconditional, single-statement DO
02527          * INSTEAD rules correctly; we have to get exactly one Query out of
02528          * the rewrite operation to stuff back into the CTE node.
02529          */
02530         if (list_length(newstuff) == 1)
02531         {
02532             /* Push the single Query back into the CTE node */
02533             ctequery = (Query *) linitial(newstuff);
02534             Assert(IsA(ctequery, Query));
02535             /* WITH queries should never be canSetTag */
02536             Assert(!ctequery->canSetTag);
02537             cte->ctequery = (Node *) ctequery;
02538         }
02539         else if (newstuff == NIL)
02540         {
02541             ereport(ERROR,
02542                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02543                      errmsg("DO INSTEAD NOTHING rules are not supported for data-modifying statements in WITH")));
02544         }
02545         else
02546         {
02547             ListCell   *lc2;
02548 
02549             /* examine queries to determine which error message to issue */
02550             foreach(lc2, newstuff)
02551             {
02552                 Query      *q = (Query *) lfirst(lc2);
02553 
02554                 if (q->querySource == QSRC_QUAL_INSTEAD_RULE)
02555                     ereport(ERROR,
02556                             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02557                              errmsg("conditional DO INSTEAD rules are not supported for data-modifying statements in WITH")));
02558                 if (q->querySource == QSRC_NON_INSTEAD_RULE)
02559                     ereport(ERROR,
02560                             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02561                              errmsg("DO ALSO rules are not supported for data-modifying statements in WITH")));
02562             }
02563 
02564             ereport(ERROR,
02565                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02566                      errmsg("multi-statement DO INSTEAD rules are not supported for data-modifying statements in WITH")));
02567         }
02568     }
02569 
02570     /*
02571      * If the statement is an insert, update, or delete, adjust its targetlist
02572      * as needed, and then fire INSERT/UPDATE/DELETE rules on it.
02573      *
02574      * SELECT rules are handled later when we have all the queries that should
02575      * get executed.  Also, utilities aren't rewritten at all (do we still
02576      * need that check?)
02577      */
02578     if (event != CMD_SELECT && event != CMD_UTILITY)
02579     {
02580         int         result_relation;
02581         RangeTblEntry *rt_entry;
02582         Relation    rt_entry_relation;
02583         List       *locks;
02584         List       *product_queries;
02585 
02586         result_relation = parsetree->resultRelation;
02587         Assert(result_relation != 0);
02588         rt_entry = rt_fetch(result_relation, parsetree->rtable);
02589         Assert(rt_entry->rtekind == RTE_RELATION);
02590 
02591         /*
02592          * We can use NoLock here since either the parser or
02593          * AcquireRewriteLocks should have locked the rel already.
02594          */
02595         rt_entry_relation = heap_open(rt_entry->relid, NoLock);
02596 
02597         /*
02598          * Rewrite the targetlist as needed for the command type.
02599          */
02600         if (event == CMD_INSERT)
02601         {
02602             RangeTblEntry *values_rte = NULL;
02603 
02604             /*
02605              * If it's an INSERT ... VALUES (...), (...), ... there will be a
02606              * single RTE for the VALUES targetlists.
02607              */
02608             if (list_length(parsetree->jointree->fromlist) == 1)
02609             {
02610                 RangeTblRef *rtr = (RangeTblRef *) linitial(parsetree->jointree->fromlist);
02611 
02612                 if (IsA(rtr, RangeTblRef))
02613                 {
02614                     RangeTblEntry *rte = rt_fetch(rtr->rtindex,
02615                                                   parsetree->rtable);
02616 
02617                     if (rte->rtekind == RTE_VALUES)
02618                         values_rte = rte;
02619                 }
02620             }
02621 
02622             if (values_rte)
02623             {
02624                 List       *attrnos;
02625 
02626                 /* Process the main targetlist ... */
02627                 rewriteTargetListIU(parsetree, rt_entry_relation, &attrnos);
02628                 /* ... and the VALUES expression lists */
02629                 rewriteValuesRTE(values_rte, rt_entry_relation, attrnos);
02630             }
02631             else
02632             {
02633                 /* Process just the main targetlist */
02634                 rewriteTargetListIU(parsetree, rt_entry_relation, NULL);
02635             }
02636         }
02637         else if (event == CMD_UPDATE)
02638         {
02639             rewriteTargetListIU(parsetree, rt_entry_relation, NULL);
02640             rewriteTargetListUD(parsetree, rt_entry, rt_entry_relation);
02641         }
02642         else if (event == CMD_DELETE)
02643         {
02644             rewriteTargetListUD(parsetree, rt_entry, rt_entry_relation);
02645         }
02646         else
02647             elog(ERROR, "unrecognized commandType: %d", (int) event);
02648 
02649         /*
02650          * Collect and apply the appropriate rules.
02651          */
02652         locks = matchLocks(event, rt_entry_relation->rd_rules,
02653                            result_relation, parsetree);
02654 
02655         product_queries = fireRules(parsetree,
02656                                     result_relation,
02657                                     event,
02658                                     locks,
02659                                     &instead,
02660                                     &returning,
02661                                     &qual_product);
02662 
02663         /*
02664          * If there were no INSTEAD rules, and the target relation is a view
02665          * without any INSTEAD OF triggers, see if the view can be
02666          * automatically updated.  If so, we perform the necessary query
02667          * transformation here and add the resulting query to the
02668          * product_queries list, so that it gets recursively rewritten if
02669          * necessary.
02670          */
02671         if (!instead && qual_product == NULL &&
02672             rt_entry_relation->rd_rel->relkind == RELKIND_VIEW &&
02673             !view_has_instead_trigger(rt_entry_relation, event))
02674         {
02675             /*
02676              * This throws an error if the view can't be automatically
02677              * updated, but that's OK since the query would fail at runtime
02678              * anyway.
02679              */
02680             parsetree = rewriteTargetView(parsetree, rt_entry_relation);
02681 
02682             /*
02683              * At this point product_queries contains any DO ALSO rule actions.
02684              * Add the rewritten query before or after those.  This must match
02685              * the handling the original query would have gotten below, if
02686              * we allowed it to be included again.
02687              */
02688             if (parsetree->commandType == CMD_INSERT)
02689                 product_queries = lcons(parsetree, product_queries);
02690             else
02691                 product_queries = lappend(product_queries, parsetree);
02692 
02693             /*
02694              * Set the "instead" flag, as if there had been an unqualified
02695              * INSTEAD, to prevent the original query from being included a
02696              * second time below.  The transformation will have rewritten any
02697              * RETURNING list, so we can also set "returning" to forestall
02698              * throwing an error below.
02699              */
02700             instead = true;
02701             returning = true;
02702         }
02703 
02704             /*
02705              * If we got any product queries, recursively rewrite them --- but
02706              * first check for recursion!
02707              */
02708             if (product_queries != NIL)
02709             {
02710                 ListCell   *n;
02711                 rewrite_event *rev;
02712 
02713                 foreach(n, rewrite_events)
02714                 {
02715                     rev = (rewrite_event *) lfirst(n);
02716                     if (rev->relation == RelationGetRelid(rt_entry_relation) &&
02717                         rev->event == event)
02718                         ereport(ERROR,
02719                                 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
02720                                  errmsg("infinite recursion detected in rules for relation \"%s\"",
02721                                RelationGetRelationName(rt_entry_relation))));
02722                 }
02723 
02724                 rev = (rewrite_event *) palloc(sizeof(rewrite_event));
02725                 rev->relation = RelationGetRelid(rt_entry_relation);
02726                 rev->event = event;
02727                 rewrite_events = lcons(rev, rewrite_events);
02728 
02729                 foreach(n, product_queries)
02730                 {
02731                     Query      *pt = (Query *) lfirst(n);
02732                     List       *newstuff;
02733 
02734                     newstuff = RewriteQuery(pt, rewrite_events);
02735                     rewritten = list_concat(rewritten, newstuff);
02736                 }
02737 
02738                 rewrite_events = list_delete_first(rewrite_events);
02739             }
02740 
02741         /*
02742          * If there is an INSTEAD, and the original query has a RETURNING, we
02743          * have to have found a RETURNING in the rule(s), else fail. (Because
02744          * DefineQueryRewrite only allows RETURNING in unconditional INSTEAD
02745          * rules, there's no need to worry whether the substituted RETURNING
02746          * will actually be executed --- it must be.)
02747          */
02748         if ((instead || qual_product != NULL) &&
02749             parsetree->returningList &&
02750             !returning)
02751         {
02752             switch (event)
02753             {
02754                 case CMD_INSERT:
02755                     ereport(ERROR,
02756                             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02757                              errmsg("cannot perform INSERT RETURNING on relation \"%s\"",
02758                                  RelationGetRelationName(rt_entry_relation)),
02759                              errhint("You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause.")));
02760                     break;
02761                 case CMD_UPDATE:
02762                     ereport(ERROR,
02763                             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02764                              errmsg("cannot perform UPDATE RETURNING on relation \"%s\"",
02765                                  RelationGetRelationName(rt_entry_relation)),
02766                              errhint("You need an unconditional ON UPDATE DO INSTEAD rule with a RETURNING clause.")));
02767                     break;
02768                 case CMD_DELETE:
02769                     ereport(ERROR,
02770                             (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02771                              errmsg("cannot perform DELETE RETURNING on relation \"%s\"",
02772                                  RelationGetRelationName(rt_entry_relation)),
02773                              errhint("You need an unconditional ON DELETE DO INSTEAD rule with a RETURNING clause.")));
02774                     break;
02775                 default:
02776                     elog(ERROR, "unrecognized commandType: %d",
02777                          (int) event);
02778                     break;
02779             }
02780         }
02781 
02782         heap_close(rt_entry_relation, NoLock);
02783     }
02784 
02785     /*
02786      * For INSERTs, the original query is done first; for UPDATE/DELETE, it is
02787      * done last.  This is needed because update and delete rule actions might
02788      * not do anything if they are invoked after the update or delete is
02789      * performed. The command counter increment between the query executions
02790      * makes the deleted (and maybe the updated) tuples disappear so the scans
02791      * for them in the rule actions cannot find them.
02792      *
02793      * If we found any unqualified INSTEAD, the original query is not done at
02794      * all, in any form.  Otherwise, we add the modified form if qualified
02795      * INSTEADs were found, else the unmodified form.
02796      */
02797     if (!instead)
02798     {
02799         if (parsetree->commandType == CMD_INSERT)
02800         {
02801             if (qual_product != NULL)
02802                 rewritten = lcons(qual_product, rewritten);
02803             else
02804                 rewritten = lcons(parsetree, rewritten);
02805         }
02806         else
02807         {
02808             if (qual_product != NULL)
02809                 rewritten = lappend(rewritten, qual_product);
02810             else
02811                 rewritten = lappend(rewritten, parsetree);
02812         }
02813     }
02814 
02815     /*
02816      * If the original query has a CTE list, and we generated more than one
02817      * non-utility result query, we have to fail because we'll have copied the
02818      * CTE list into each result query.  That would break the expectation of
02819      * single evaluation of CTEs.  This could possibly be fixed by
02820      * restructuring so that a CTE list can be shared across multiple Query
02821      * and PlannableStatement nodes.
02822      */
02823     if (parsetree->cteList != NIL)
02824     {
02825         int         qcount = 0;
02826 
02827         foreach(lc1, rewritten)
02828         {
02829             Query      *q = (Query *) lfirst(lc1);
02830 
02831             if (q->commandType != CMD_UTILITY)
02832                 qcount++;
02833         }
02834         if (qcount > 1)
02835             ereport(ERROR,
02836                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
02837                      errmsg("WITH cannot be used in a query that is rewritten by rules into multiple queries")));
02838     }
02839 
02840     return rewritten;
02841 }
02842 
02843 
02844 /*
02845  * QueryRewrite -
02846  *    Primary entry point to the query rewriter.
02847  *    Rewrite one query via query rewrite system, possibly returning 0
02848  *    or many queries.
02849  *
02850  * NOTE: the parsetree must either have come straight from the parser,
02851  * or have been scanned by AcquireRewriteLocks to acquire suitable locks.
02852  */
02853 List *
02854 QueryRewrite(Query *parsetree)
02855 {
02856     uint32      input_query_id = parsetree->queryId;
02857     List       *querylist;
02858     List       *results;
02859     ListCell   *l;
02860     CmdType     origCmdType;
02861     bool        foundOriginalQuery;
02862     Query      *lastInstead;
02863 
02864     /*
02865      * This function is only applied to top-level original queries
02866      */
02867     Assert(parsetree->querySource == QSRC_ORIGINAL);
02868     Assert(parsetree->canSetTag);
02869 
02870     /*
02871      * Step 1
02872      *
02873      * Apply all non-SELECT rules possibly getting 0 or many queries
02874      */
02875     querylist = RewriteQuery(parsetree, NIL);
02876 
02877     /*
02878      * Step 2
02879      *
02880      * Apply all the RIR rules on each query
02881      *
02882      * This is also a handy place to mark each query with the original queryId
02883      */
02884     results = NIL;
02885     foreach(l, querylist)
02886     {
02887         Query      *query = (Query *) lfirst(l);
02888 
02889         query = fireRIRrules(query, NIL, false);
02890 
02891         query->queryId = input_query_id;
02892 
02893         results = lappend(results, query);
02894     }
02895 
02896     /*
02897      * Step 3
02898      *
02899      * Determine which, if any, of the resulting queries is supposed to set
02900      * the command-result tag; and update the canSetTag fields accordingly.
02901      *
02902      * If the original query is still in the list, it sets the command tag.
02903      * Otherwise, the last INSTEAD query of the same kind as the original is
02904      * allowed to set the tag.  (Note these rules can leave us with no query
02905      * setting the tag.  The tcop code has to cope with this by setting up a
02906      * default tag based on the original un-rewritten query.)
02907      *
02908      * The Asserts verify that at most one query in the result list is marked
02909      * canSetTag.  If we aren't checking asserts, we can fall out of the loop
02910      * as soon as we find the original query.
02911      */
02912     origCmdType = parsetree->commandType;
02913     foundOriginalQuery = false;
02914     lastInstead = NULL;
02915 
02916     foreach(l, results)
02917     {
02918         Query      *query = (Query *) lfirst(l);
02919 
02920         if (query->querySource == QSRC_ORIGINAL)
02921         {
02922             Assert(query->canSetTag);
02923             Assert(!foundOriginalQuery);
02924             foundOriginalQuery = true;
02925 #ifndef USE_ASSERT_CHECKING
02926             break;
02927 #endif
02928         }
02929         else
02930         {
02931             Assert(!query->canSetTag);
02932             if (query->commandType == origCmdType &&
02933                 (query->querySource == QSRC_INSTEAD_RULE ||
02934                  query->querySource == QSRC_QUAL_INSTEAD_RULE))
02935                 lastInstead = query;
02936         }
02937     }
02938 
02939     if (!foundOriginalQuery && lastInstead != NULL)
02940         lastInstead->canSetTag = true;
02941 
02942     return results;
02943 }