1 /*-------------------------------------------------------------------------
4 * Primary module of query rewriter.
6 * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
10 * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.110 2002/09/18 21:35:22 tgl Exp $
12 *-------------------------------------------------------------------------
16 #include "access/heapam.h"
17 #include "catalog/pg_operator.h"
18 #include "catalog/pg_type.h"
19 #include "miscadmin.h"
20 #include "nodes/makefuncs.h"
21 #include "optimizer/clauses.h"
22 #include "optimizer/prep.h"
23 #include "optimizer/var.h"
24 #include "parser/analyze.h"
25 #include "parser/parse_coerce.h"
26 #include "parser/parse_expr.h"
27 #include "parser/parse_oper.h"
28 #include "parser/parse_type.h"
29 #include "parser/parsetree.h"
30 #include "rewrite/rewriteHandler.h"
31 #include "rewrite/rewriteManip.h"
32 #include "utils/builtins.h"
33 #include "utils/lsyscache.h"
36 static Query *rewriteRuleAction(Query *parsetree,
41 static List *adjustJoinTreeList(Query *parsetree, bool removert, int rt_index);
42 static void rewriteTargetList(Query *parsetree, Relation target_relation);
43 static TargetEntry *process_matched_tle(TargetEntry *src_tle,
44 TargetEntry *prior_tle);
45 static void markQueryForUpdate(Query *qry, bool skipOldNew);
46 static List *matchLocks(CmdType event, RuleLock *rulelocks,
47 int varno, Query *parsetree);
48 static Query *fireRIRrules(Query *parsetree);
53 * Rewrite the rule action with appropriate qualifiers (taken from
54 * the triggering query).
57 rewriteRuleAction(Query *parsetree,
67 Query **sub_action_ptr;
70 * Make modifiable copies of rule action and qual (what we're passed
71 * are the stored versions in the relcache; don't touch 'em!).
73 rule_action = (Query *) copyObject(rule_action);
74 rule_qual = (Node *) copyObject(rule_qual);
76 current_varno = rt_index;
77 rt_length = length(parsetree->rtable);
78 new_varno = PRS2_NEW_VARNO + rt_length;
81 * Adjust rule action and qual to offset its varnos, so that we can
82 * merge its rtable with the main parsetree's rtable.
84 * If the rule action is an INSERT...SELECT, the OLD/NEW rtable entries
85 * will be in the SELECT part, and we have to modify that rather than
86 * the top-level INSERT (kluge!).
88 sub_action = getInsertSelectQuery(rule_action, &sub_action_ptr);
90 OffsetVarNodes((Node *) sub_action, rt_length, 0);
91 OffsetVarNodes(rule_qual, rt_length, 0);
92 /* but references to *OLD* should point at original rt_index */
93 ChangeVarNodes((Node *) sub_action,
94 PRS2_OLD_VARNO + rt_length, rt_index, 0);
95 ChangeVarNodes(rule_qual,
96 PRS2_OLD_VARNO + rt_length, rt_index, 0);
99 * Generate expanded rtable consisting of main parsetree's rtable plus
100 * rule action's rtable; this becomes the complete rtable for the rule
101 * action. Some of the entries may be unused after we finish
102 * rewriting, but if we tried to clean those out we'd have a much
103 * harder job to adjust RT indexes in the query's Vars. It's OK to
104 * have unused RT entries, since planner will ignore them.
106 * NOTE: because planner will destructively alter rtable, we must ensure
107 * that rule action's rtable is separate and shares no substructure
108 * with the main rtable. Hence do a deep copy here.
110 sub_action->rtable = nconc((List *) copyObject(parsetree->rtable),
114 * Each rule action's jointree should be the main parsetree's jointree
115 * plus that rule's jointree, but usually *without* the original
116 * rtindex that we're replacing (if present, which it won't be for
117 * INSERT). Note that if the rule action refers to OLD, its jointree
118 * will add a reference to rt_index. If the rule action doesn't refer
119 * to OLD, but either the rule_qual or the user query quals do, then
120 * we need to keep the original rtindex in the jointree to provide
121 * data for the quals. We don't want the original rtindex to be
122 * joined twice, however, so avoid keeping it if the rule action
125 * As above, the action's jointree must not share substructure with the
128 if (sub_action->jointree != NULL)
133 keeporig = (!rangeTableEntry_used((Node *) sub_action->jointree,
135 (rangeTableEntry_used(rule_qual, rt_index, 0) ||
136 rangeTableEntry_used(parsetree->jointree->quals, rt_index, 0));
137 newjointree = adjustJoinTreeList(parsetree, !keeporig, rt_index);
138 sub_action->jointree->fromlist =
139 nconc(newjointree, sub_action->jointree->fromlist);
143 * We copy the qualifications of the parsetree to the action and vice
144 * versa. So force hasSubLinks if one of them has it. If this is not
145 * right, the flag will get cleared later, but we mustn't risk having
146 * it not set when it needs to be. (XXX this should probably be
147 * handled by AddQual and friends, not here...)
149 if (parsetree->hasSubLinks)
150 sub_action->hasSubLinks = TRUE;
151 else if (sub_action->hasSubLinks)
152 parsetree->hasSubLinks = TRUE;
155 * Event Qualification forces copying of parsetree and splitting into
156 * two queries one w/rule_qual, one w/NOT rule_qual. Also add user
157 * query qual onto rule action
159 AddQual(sub_action, rule_qual);
161 AddQual(sub_action, parsetree->jointree->quals);
164 * Rewrite new.attribute w/ right hand side of target-list entry for
165 * appropriate field name in insert/update.
167 * KLUGE ALERT: since ResolveNew returns a mutated copy, we can't just
168 * apply it to sub_action; we have to remember to update the sublink
169 * inside rule_action, too.
171 if (event == CMD_INSERT || event == CMD_UPDATE)
173 sub_action = (Query *) ResolveNew((Node *) sub_action,
176 parsetree->targetList,
180 *sub_action_ptr = sub_action;
182 rule_action = sub_action;
189 * Copy the query's jointree list, and optionally attempt to remove any
190 * occurrence of the given rt_index as a top-level join item (we do not look
191 * for it within join items; this is OK because we are only expecting to find
192 * it as an UPDATE or DELETE target relation, which will be at the top level
193 * of the join). Returns modified jointree list --- this is a separate copy
194 * sharing no nodes with the original.
197 adjustJoinTreeList(Query *parsetree, bool removert, int rt_index)
199 List *newjointree = copyObject(parsetree->jointree->fromlist);
204 foreach(jjt, newjointree)
206 RangeTblRef *rtr = lfirst(jjt);
208 if (IsA(rtr, RangeTblRef) &&rtr->rtindex == rt_index)
210 newjointree = lremove(rtr, newjointree);
220 * rewriteTargetList - rewrite INSERT/UPDATE targetlist into standard form
222 * This has the following responsibilities:
224 * 1. For an INSERT, add tlist entries to compute default values for any
225 * attributes that have defaults and are not assigned to in the given tlist.
226 * (We do not insert anything for default-less attributes, however. The
227 * planner will later insert NULLs for them, but there's no reason to slow
228 * down rewriter processing with extra tlist nodes.)
230 * 2. Merge multiple entries for the same target attribute, or declare error
231 * if we can't. Presently, multiple entries are only allowed for UPDATE of
232 * an array field, for example "UPDATE table SET foo[2] = 42, foo[4] = 43".
233 * We can merge such operations into a single assignment op. Essentially,
234 * the expression we want to produce in this case is like
235 * foo = array_set(array_set(foo, 2, 42), 4, 43)
237 * 3. Sort the tlist into standard order: non-junk fields in order by resno,
238 * then junk fields (these in no particular order).
240 * We must do items 1 and 2 before firing rewrite rules, else rewritten
241 * references to NEW.foo will produce wrong or incomplete results. Item 3
242 * is not needed for rewriting, but will be needed by the planner, and we
243 * can do it essentially for free while handling items 1 and 2.
246 rewriteTargetList(Query *parsetree, Relation target_relation)
248 CmdType commandType = parsetree->commandType;
249 List *tlist = parsetree->targetList;
250 List *new_tlist = NIL;
256 * Scan the tuple description in the relation's relcache entry to make
257 * sure we have all the user attributes in the right order.
259 numattrs = RelationGetNumberOfAttributes(target_relation);
261 for (attrno = 1; attrno <= numattrs; attrno++)
263 Form_pg_attribute att_tup = target_relation->rd_att->attrs[attrno - 1];
264 TargetEntry *new_tle = NULL;
266 /* We can ignore deleted attributes */
267 if (att_tup->attisdropped)
271 * Look for targetlist entries matching this attr. We match by
272 * resno, but the resname should match too.
274 * Junk attributes are not candidates to be matched.
278 TargetEntry *old_tle = (TargetEntry *) lfirst(temp);
279 Resdom *resdom = old_tle->resdom;
281 if (!resdom->resjunk && resdom->resno == attrno)
283 Assert(strcmp(resdom->resname,
284 NameStr(att_tup->attname)) == 0);
285 new_tle = process_matched_tle(old_tle, new_tle);
286 /* keep scanning to detect multiple assignments to attr */
290 if (new_tle == NULL && commandType == CMD_INSERT)
293 * Didn't find a matching tlist entry; if it's an INSERT, look
294 * for a default value, and add a tlist entry computing the
295 * default if we find one.
299 new_expr = build_column_default(target_relation, attrno);
302 new_tle = makeTargetEntry(makeResdom(attrno,
305 pstrdup(NameStr(att_tup->attname)),
311 new_tlist = lappend(new_tlist, new_tle);
315 * Copy all resjunk tlist entries to the end of the new tlist, and
316 * assign them resnos above the last real resno.
318 * Typical junk entries include ORDER BY or GROUP BY expressions (are
319 * these actually possible in an INSERT or UPDATE?), system attribute
324 TargetEntry *old_tle = (TargetEntry *) lfirst(temp);
325 Resdom *resdom = old_tle->resdom;
329 /* Get the resno right, but don't copy unnecessarily */
330 if (resdom->resno != attrno)
332 resdom = (Resdom *) copyObject((Node *) resdom);
333 resdom->resno = attrno;
334 old_tle = makeTargetEntry(resdom, old_tle->expr);
336 new_tlist = lappend(new_tlist, old_tle);
341 /* Let's just make sure we processed all the non-junk items */
342 if (resdom->resno < 1 || resdom->resno > numattrs)
343 elog(ERROR, "rewriteTargetList: bogus resno %d in targetlist",
348 parsetree->targetList = new_tlist;
353 * Convert a matched TLE from the original tlist into a correct new TLE.
355 * This routine detects and handles multiple assignments to the same target
359 process_matched_tle(TargetEntry *src_tle,
360 TargetEntry *prior_tle)
362 Resdom *resdom = src_tle->resdom;
366 if (prior_tle == NULL)
369 * Normal case where this is the first assignment to the
376 * Multiple assignments to same attribute. Allow only if all are
377 * array-assign operators with same bottom array object.
379 if (src_tle->expr == NULL || !IsA(src_tle->expr, ArrayRef) ||
380 ((ArrayRef *) src_tle->expr)->refassgnexpr == NULL ||
381 prior_tle->expr == NULL || !IsA(prior_tle->expr, ArrayRef) ||
382 ((ArrayRef *) prior_tle->expr)->refassgnexpr == NULL ||
383 ((ArrayRef *) src_tle->expr)->refrestype !=
384 ((ArrayRef *) prior_tle->expr)->refrestype)
385 elog(ERROR, "Multiple assignments to same attribute \"%s\"",
389 * Prior TLE could be a nest of ArrayRefs if we do this more than
392 priorbottom = ((ArrayRef *) prior_tle->expr)->refexpr;
393 while (priorbottom != NULL && IsA(priorbottom, ArrayRef) &&
394 ((ArrayRef *) priorbottom)->refassgnexpr != NULL)
395 priorbottom = ((ArrayRef *) priorbottom)->refexpr;
396 if (!equal(priorbottom, ((ArrayRef *) src_tle->expr)->refexpr))
397 elog(ERROR, "Multiple assignments to same attribute \"%s\"",
401 * Looks OK to nest 'em.
403 newexpr = makeNode(ArrayRef);
404 memcpy(newexpr, src_tle->expr, sizeof(ArrayRef));
405 newexpr->refexpr = prior_tle->expr;
407 return makeTargetEntry(resdom, (Node *) newexpr);
412 * Make an expression tree for the default value for a column.
414 * If there is no default, return a NULL instead.
417 build_column_default(Relation rel, int attrno)
419 TupleDesc rd_att = rel->rd_att;
420 Form_pg_attribute att_tup = rd_att->attrs[attrno - 1];
421 Oid atttype = att_tup->atttypid;
422 int32 atttypmod = att_tup->atttypmod;
427 * Scan to see if relation has a default for this column.
429 if (rd_att->constr && rd_att->constr->num_defval > 0)
431 AttrDefault *defval = rd_att->constr->defval;
432 int ndef = rd_att->constr->num_defval;
436 if (attrno == defval[ndef].adnum)
439 * Found it, convert string representation to node tree.
441 expr = stringToNode(defval[ndef].adbin);
450 * No per-column default, so look for a default for the type
453 if (att_tup->attisset)
456 * Set attributes are represented as OIDs no matter what the
457 * set element type is, and the element type's default is
462 expr = get_typdefault(atttype);
466 return NULL; /* No default anywhere */
469 * Make sure the value is coerced to the target column type (might not
470 * be right type yet if it's not a constant!) This should match the
471 * parser's processing of non-defaulted expressions --- see
472 * updateTargetListEntry().
474 exprtype = exprType(expr);
476 expr = coerce_to_target_type(expr, exprtype,
479 COERCE_IMPLICIT_CAST);
481 * This really shouldn't fail; should have checked the default's
482 * type when it was created ...
485 elog(ERROR, "Column \"%s\" is of type %s"
486 " but default expression is of type %s"
487 "\n\tYou will need to rewrite or cast the expression",
488 NameStr(att_tup->attname),
489 format_type_be(atttype),
490 format_type_be(exprtype));
498 * match the list of locks and returns the matching rules
501 matchLocks(CmdType event,
506 List *real_locks = NIL;
510 Assert(rulelocks != NULL); /* we get called iff there is some lock */
511 Assert(parsetree != NULL);
513 if (parsetree->commandType != CMD_SELECT)
515 if (parsetree->resultRelation != varno)
519 nlocks = rulelocks->numLocks;
521 for (i = 0; i < nlocks; i++)
523 RewriteRule *oneLock = rulelocks->rules[i];
525 if (oneLock->event == event)
527 if (parsetree->commandType != CMD_SELECT ||
528 (oneLock->attrno == -1 ?
529 rangeTableEntry_used((Node *) parsetree, varno, 0) :
530 attribute_used((Node *) parsetree,
531 varno, oneLock->attrno, 0)))
532 real_locks = lappend(real_locks, oneLock);
541 ApplyRetrieveRule(Query *parsetree,
552 if (length(rule->actions) != 1)
553 elog(ERROR, "ApplyRetrieveRule: expected just one rule action");
554 if (rule->qual != NULL)
555 elog(ERROR, "ApplyRetrieveRule: can't handle qualified ON SELECT rule");
557 elog(ERROR, "ApplyRetrieveRule: can't handle per-attribute ON SELECT rule");
560 * Make a modifiable copy of the view query, and recursively expand
561 * any view references inside it.
563 rule_action = copyObject(lfirst(rule->actions));
565 rule_action = fireRIRrules(rule_action);
568 * VIEWs are really easy --- just plug the view query in as a
569 * subselect, replacing the relation's original RTE.
571 rte = rt_fetch(rt_index, parsetree->rtable);
573 rte->rtekind = RTE_SUBQUERY;
574 rte->relid = InvalidOid;
575 rte->subquery = rule_action;
576 rte->inh = false; /* must not be set for a subquery */
579 * We move the view's permission check data down to its rangetable.
580 * The checks will actually be done against the *OLD* entry therein.
582 subrte = rt_fetch(PRS2_OLD_VARNO, rule_action->rtable);
583 Assert(subrte->relid == relation->rd_id);
584 subrte->checkForRead = rte->checkForRead;
585 subrte->checkForWrite = rte->checkForWrite;
586 subrte->checkAsUser = rte->checkAsUser;
588 rte->checkForRead = false; /* no permission check on subquery itself */
589 rte->checkForWrite = false;
590 rte->checkAsUser = InvalidOid;
593 * FOR UPDATE of view?
595 if (intMember(rt_index, parsetree->rowMarks))
598 * Remove the view from the list of rels that will actually be
599 * marked FOR UPDATE by the executor. It will still be access-
600 * checked for write access, though.
602 parsetree->rowMarks = lremovei(rt_index, parsetree->rowMarks);
605 * Set up the view's referenced tables as if FOR UPDATE.
607 markQueryForUpdate(rule_action, true);
614 * Recursively mark all relations used by a view as FOR UPDATE.
616 * This may generate an invalid query, eg if some sub-query uses an
617 * aggregate. We leave it to the planner to detect that.
619 * NB: this must agree with the parser's transformForUpdate() routine.
622 markQueryForUpdate(Query *qry, bool skipOldNew)
627 foreach(l, qry->rtable)
629 RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
633 /* Ignore OLD and NEW entries if we are at top level of view */
635 (rti == PRS2_OLD_VARNO || rti == PRS2_NEW_VARNO))
638 if (rte->rtekind == RTE_RELATION)
640 if (!intMember(rti, qry->rowMarks))
641 qry->rowMarks = lappendi(qry->rowMarks, rti);
642 rte->checkForWrite = true;
644 else if (rte->rtekind == RTE_SUBQUERY)
646 /* FOR UPDATE of subquery is propagated to subquery's rels */
647 markQueryForUpdate(rte->subquery, false);
655 * Apply fireRIRrules() to each SubLink (subselect in expression) found
658 * NOTE: although this has the form of a walker, we cheat and modify the
659 * SubLink nodes in-place. It is caller's responsibility to ensure that
660 * no unwanted side-effects occur!
662 * This is unlike most of the other routines that recurse into subselects,
663 * because we must take control at the SubLink node in order to replace
664 * the SubLink's subselect link with the possibly-rewritten subquery.
667 fireRIRonSubLink(Node *node, void *context)
671 if (IsA(node, SubLink))
673 SubLink *sub = (SubLink *) node;
675 /* Do what we came for */
676 sub->subselect = (Node *) fireRIRrules((Query *) (sub->subselect));
677 /* Fall through to process lefthand args of SubLink */
681 * Do NOT recurse into Query nodes, because fireRIRrules already
682 * processed subselects of subselects for us.
684 return expression_tree_walker(node, fireRIRonSubLink,
691 * Apply all RIR rules on each rangetable entry in a query
694 fireRIRrules(Query *parsetree)
699 * don't try to convert this into a foreach loop, because rtable list
700 * can get changed each time through...
703 while (rt_index < length(parsetree->rtable))
717 rte = rt_fetch(rt_index, parsetree->rtable);
720 * A subquery RTE can't have associated rules, so there's nothing
721 * to do to this level of the query, but we must recurse into the
722 * subquery to expand any rule references in it.
724 if (rte->rtekind == RTE_SUBQUERY)
726 rte->subquery = fireRIRrules(rte->subquery);
731 * Joins and other non-relation RTEs can be ignored completely.
733 if (rte->rtekind != RTE_RELATION)
737 * If the table is not referenced in the query, then we ignore it.
738 * This prevents infinite expansion loop due to new rtable entries
739 * inserted by expansion of a rule. A table is referenced if it is
740 * part of the join set (a source table), or is referenced by any
741 * Var nodes, or is the result table.
743 relIsUsed = rangeTableEntry_used((Node *) parsetree, rt_index, 0);
745 if (!relIsUsed && rt_index != parsetree->resultRelation)
749 * This may well be the first access to the relation during the
750 * current statement (it will be, if this Query was extracted from
751 * a rule or somehow got here other than via the parser).
752 * Therefore, grab the appropriate lock type for the relation, and
753 * do not release it until end of transaction. This protects the
754 * rewriter and planner against schema changes mid-query.
756 * If the relation is the query's result relation, then
757 * RewriteQuery() already got the right lock on it, so we need no
758 * additional lock. Otherwise, check to see if the relation is
759 * accessed FOR UPDATE or not.
761 if (rt_index == parsetree->resultRelation)
763 else if (intMember(rt_index, parsetree->rowMarks))
764 lockmode = RowShareLock;
766 lockmode = AccessShareLock;
768 rel = heap_open(rte->relid, lockmode);
771 * Collect the RIR rules that we must apply
773 rules = rel->rd_rules;
776 heap_close(rel, NoLock);
780 for (i = 0; i < rules->numLocks; i++)
782 rule = rules->rules[i];
783 if (rule->event != CMD_SELECT)
786 if (rule->attrno > 0)
788 /* per-attr rule; do we need it? */
789 if (!attribute_used((Node *) parsetree, rt_index,
794 locks = lappend(locks, rule);
804 parsetree = ApplyRetrieveRule(parsetree,
812 heap_close(rel, NoLock);
816 * Recurse into sublink subqueries, too. But we already did the ones
819 if (parsetree->hasSubLinks)
820 query_tree_walker(parsetree, fireRIRonSubLink, NULL,
821 QTW_IGNORE_SUBQUERIES);
824 * If the query was marked having aggregates, check if this is still
825 * true after rewriting. Ditto for sublinks. Note there should be no
826 * aggs in the qual at this point. (Does this code still do anything
827 * useful? The view-becomes-subselect-in-FROM approach doesn't look
828 * like it could remove aggs or sublinks...)
830 if (parsetree->hasAggs)
832 parsetree->hasAggs = checkExprHasAggs((Node *) parsetree);
833 if (parsetree->hasAggs)
834 if (checkExprHasAggs((Node *) parsetree->jointree))
835 elog(ERROR, "fireRIRrules: failed to remove aggs from qual");
837 if (parsetree->hasSubLinks)
838 parsetree->hasSubLinks = checkExprHasSubLink((Node *) parsetree);
845 * idea is to fire regular rules first, then qualified instead
846 * rules and unqualified instead rules last. Any lemming is counted for.
849 orderRules(List *locks)
852 List *instead_rules = NIL;
853 List *instead_qualified = NIL;
858 RewriteRule *rule_lock = (RewriteRule *) lfirst(i);
860 if (rule_lock->isInstead)
862 if (rule_lock->qual == NULL)
863 instead_rules = lappend(instead_rules, rule_lock);
865 instead_qualified = lappend(instead_qualified, rule_lock);
868 regular = lappend(regular, rule_lock);
870 return nconc(nconc(regular, instead_qualified), instead_rules);
875 * Modify the given query by adding 'AND NOT rule_qual' to its qualification.
876 * This is used to generate suitable "else clauses" for conditional INSTEAD
879 * The rule_qual may contain references to OLD or NEW. OLD references are
880 * replaced by references to the specified rt_index (the relation that the
881 * rule applies to). NEW references are only possible for INSERT and UPDATE
882 * queries on the relation itself, and so they should be replaced by copies
883 * of the related entries in the query's own targetlist.
886 CopyAndAddQual(Query *parsetree,
891 Query *new_tree = (Query *) copyObject(parsetree);
892 Node *new_qual = (Node *) copyObject(rule_qual);
894 /* Fix references to OLD */
895 ChangeVarNodes(new_qual, PRS2_OLD_VARNO, rt_index, 0);
896 /* Fix references to NEW */
897 if (event == CMD_INSERT || event == CMD_UPDATE)
898 new_qual = ResolveNew(new_qual,
901 parsetree->targetList,
904 /* And attach the fixed qual */
905 AddNotQual(new_tree, new_qual);
914 * Iterate through rule locks applying rules.
915 * All rules create their own parsetrees. Instead rules
916 * with rule qualification save the original parsetree
917 * and add their negated qualification to it. Real instead
918 * rules finally throw away the original parsetree.
920 * remember: reality is for dead birds -- glass
924 fireRules(Query *parsetree,
929 List **qual_products)
934 /* choose rule to fire from list of rules */
938 locks = orderRules(locks); /* real instead rules last */
942 RewriteRule *rule_lock = (RewriteRule *) lfirst(i);
947 /* multiple rule action time */
948 *instead_flag = rule_lock->isInstead;
949 event_qual = rule_lock->qual;
950 actions = rule_lock->actions;
952 if (event_qual != NULL && *instead_flag)
957 * If there are instead rules with qualifications, the
958 * original query is still performed. But all the negated rule
959 * qualifications of the instead rules are added so it does
960 * its actions only in cases where the rule quals of all
961 * instead rules are false. Think of it as the default action
962 * in a case. We save this in *qual_products so
963 * deepRewriteQuery() can add it to the query list after we
964 * mangled it up enough.
966 if (*qual_products == NIL)
967 qual_product = parsetree;
969 qual_product = (Query *) lfirst(*qual_products);
971 qual_product = CopyAndAddQual(qual_product,
976 *qual_products = makeList1(qual_product);
981 Query *rule_action = lfirst(r);
983 if (rule_action->commandType == CMD_NOTHING)
986 rule_action = rewriteRuleAction(parsetree, rule_action,
987 event_qual, rt_index, event);
989 results = lappend(results, rule_action);
993 * If this was an unqualified instead rule, throw away an
994 * eventually saved 'default' parsetree
996 if (event_qual == NULL && *instead_flag)
997 *qual_products = NIL;
1005 RewriteQuery(Query *parsetree, bool *instead_flag, List **qual_products)
1008 List *product_queries = NIL;
1009 int result_relation;
1010 RangeTblEntry *rt_entry;
1011 Relation rt_entry_relation;
1012 RuleLock *rt_entry_locks;
1014 Assert(parsetree != NULL);
1016 event = parsetree->commandType;
1019 * SELECT rules are handled later when we have all the queries that
1020 * should get executed
1022 if (event == CMD_SELECT)
1026 * Utilities aren't rewritten at all - why is this here?
1028 if (event == CMD_UTILITY)
1032 * the statement is an update, insert or delete - fire rules on it.
1034 result_relation = parsetree->resultRelation;
1035 Assert(result_relation != 0);
1036 rt_entry = rt_fetch(result_relation, parsetree->rtable);
1037 Assert(rt_entry->rtekind == RTE_RELATION);
1040 * This may well be the first access to the result relation during the
1041 * current statement (it will be, if this Query was extracted from a
1042 * rule or somehow got here other than via the parser). Therefore,
1043 * grab the appropriate lock type for a result relation, and do not
1044 * release it until end of transaction. This protects the rewriter
1045 * and planner against schema changes mid-query.
1047 rt_entry_relation = heap_open(rt_entry->relid, RowExclusiveLock);
1050 * If it's an INSERT or UPDATE, rewrite the targetlist into standard
1051 * form. This will be needed by the planner anyway, and doing it now
1052 * ensures that any references to NEW.field will behave sanely.
1054 if (event == CMD_INSERT || event == CMD_UPDATE)
1055 rewriteTargetList(parsetree, rt_entry_relation);
1058 * Collect and apply the appropriate rules.
1060 rt_entry_locks = rt_entry_relation->rd_rules;
1062 if (rt_entry_locks != NULL)
1064 List *locks = matchLocks(event, rt_entry_locks,
1065 result_relation, parsetree);
1067 product_queries = fireRules(parsetree,
1075 heap_close(rt_entry_relation, NoLock); /* keep lock! */
1077 return product_queries;
1082 * to avoid infinite recursion, we restrict the number of times a query
1083 * can be rewritten. Detecting cycles is left for the reader as an exercise.
1085 #ifndef REWRITE_INVOKE_MAX
1086 #define REWRITE_INVOKE_MAX 10
1089 static int numQueryRewriteInvoked = 0;
1092 * deepRewriteQuery -
1093 * rewrites the query and apply the rules again on the queries rewritten
1096 deepRewriteQuery(Query *parsetree)
1099 List *rewritten = NIL;
1102 List *qual_products = NIL;
1104 if (++numQueryRewriteInvoked > REWRITE_INVOKE_MAX)
1106 elog(ERROR, "query rewritten %d times, may contain cycles",
1107 numQueryRewriteInvoked - 1);
1111 result = RewriteQuery(parsetree, &instead, &qual_products);
1115 Query *pt = lfirst(n);
1118 newstuff = deepRewriteQuery(pt);
1119 if (newstuff != NIL)
1120 rewritten = nconc(rewritten, newstuff);
1124 * For INSERTs, the original query is done first; for UPDATE/DELETE,
1125 * it is done last. This is needed because update and delete rule
1126 * actions might not do anything if they are invoked after the update
1127 * or delete is performed. The command counter increment between the
1128 * query execution makes the deleted (and maybe the updated) tuples
1129 * disappear so the scans for them in the rule actions cannot find
1132 if (parsetree->commandType == CMD_INSERT)
1135 * qual_products are the original query with the negated rule
1136 * qualification of an INSTEAD rule
1138 if (qual_products != NIL)
1139 rewritten = nconc(qual_products, rewritten);
1142 * Add the unmodified original query, if no INSTEAD rule was seen.
1145 rewritten = lcons(parsetree, rewritten);
1150 * qual_products are the original query with the negated rule
1151 * qualification of an INSTEAD rule
1153 if (qual_products != NIL)
1154 rewritten = nconc(rewritten, qual_products);
1157 * Add the unmodified original query, if no INSTEAD rule was seen.
1160 rewritten = lappend(rewritten, parsetree);
1172 QueryRewriteOne(Query *parsetree)
1174 numQueryRewriteInvoked = 0;
1177 * take a deep breath and apply all the rewrite rules - ay
1179 return deepRewriteQuery(parsetree);
1185 * Primary entry point to the query rewriter.
1186 * Rewrite one query via query rewrite system, possibly returning 0
1189 * NOTE: The code in QueryRewrite was formerly in pg_parse_and_plan(), and was
1190 * moved here so that it would be invoked during EXPLAIN.
1193 QueryRewrite(Query *parsetree)
1196 List *results = NIL;
1202 * Apply all non-SELECT rules possibly getting 0 or many queries
1204 querylist = QueryRewriteOne(parsetree);
1209 * Apply all the RIR rules on each query
1211 foreach(l, querylist)
1213 Query *query = (Query *) lfirst(l);
1215 query = fireRIRrules(query);
1218 * If the query target was rewritten as a view, complain.
1220 if (query->resultRelation)
1222 RangeTblEntry *rte = rt_fetch(query->resultRelation,
1225 if (rte->rtekind == RTE_SUBQUERY)
1227 switch (query->commandType)
1230 elog(ERROR, "Cannot insert into a view"
1231 "\n\tYou need an unconditional ON INSERT DO INSTEAD rule");
1234 elog(ERROR, "Cannot update a view"
1235 "\n\tYou need an unconditional ON UPDATE DO INSTEAD rule");
1238 elog(ERROR, "Cannot delete from a view"
1239 "\n\tYou need an unconditional ON DELETE DO INSTEAD rule");
1242 elog(ERROR, "QueryRewrite: unexpected commandType %d",
1243 (int) query->commandType);
1249 results = lappend(results, query);