Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * rewriteHandler.c
4 : * Primary module of query rewriter.
5 : *
6 : * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 : * Portions Copyright (c) 1994, Regents of the University of California
8 : *
9 : * IDENTIFICATION
10 : * src/backend/rewrite/rewriteHandler.c
11 : *
12 : * NOTES
13 : * Some of the terms used in this file are of historic nature: "retrieve"
14 : * was the PostQUEL keyword for what today is SELECT. "RIR" stands for
15 : * "Retrieve-Instead-Retrieve", that is an ON SELECT DO INSTEAD SELECT rule
16 : * (which has to be unconditional and where only one rule can exist on each
17 : * relation).
18 : *
19 : *-------------------------------------------------------------------------
20 : */
21 : #include "postgres.h"
22 :
23 : #include "access/relation.h"
24 : #include "access/sysattr.h"
25 : #include "access/table.h"
26 : #include "catalog/dependency.h"
27 : #include "commands/trigger.h"
28 : #include "executor/executor.h"
29 : #include "foreign/fdwapi.h"
30 : #include "miscadmin.h"
31 : #include "nodes/makefuncs.h"
32 : #include "nodes/nodeFuncs.h"
33 : #include "optimizer/optimizer.h"
34 : #include "parser/analyze.h"
35 : #include "parser/parse_coerce.h"
36 : #include "parser/parse_relation.h"
37 : #include "parser/parsetree.h"
38 : #include "rewrite/rewriteDefine.h"
39 : #include "rewrite/rewriteHandler.h"
40 : #include "rewrite/rewriteManip.h"
41 : #include "rewrite/rewriteSearchCycle.h"
42 : #include "rewrite/rowsecurity.h"
43 : #include "tcop/tcopprot.h"
44 : #include "utils/builtins.h"
45 : #include "utils/lsyscache.h"
46 : #include "utils/rel.h"
47 :
48 :
49 : /* We use a list of these to detect recursion in RewriteQuery */
50 : typedef struct rewrite_event
51 : {
52 : Oid relation; /* OID of relation having rules */
53 : CmdType event; /* type of rule being fired */
54 : } rewrite_event;
55 :
56 : typedef struct acquireLocksOnSubLinks_context
57 : {
58 : bool for_execute; /* AcquireRewriteLocks' forExecute param */
59 : } acquireLocksOnSubLinks_context;
60 :
61 : typedef struct fireRIRonSubLink_context
62 : {
63 : List *activeRIRs;
64 : bool hasRowSecurity;
65 : } fireRIRonSubLink_context;
66 :
67 : static bool acquireLocksOnSubLinks(Node *node,
68 : acquireLocksOnSubLinks_context *context);
69 : static Query *rewriteRuleAction(Query *parsetree,
70 : Query *rule_action,
71 : Node *rule_qual,
72 : int rt_index,
73 : CmdType event,
74 : bool *returning_flag);
75 : static List *adjustJoinTreeList(Query *parsetree, bool removert, int rt_index);
76 : static List *rewriteTargetListIU(List *targetList,
77 : CmdType commandType,
78 : OverridingKind override,
79 : Relation target_relation,
80 : RangeTblEntry *values_rte,
81 : int values_rte_index,
82 : Bitmapset **unused_values_attrnos);
83 : static TargetEntry *process_matched_tle(TargetEntry *src_tle,
84 : TargetEntry *prior_tle,
85 : const char *attrName);
86 : static Node *get_assignment_input(Node *node);
87 : static Bitmapset *findDefaultOnlyColumns(RangeTblEntry *rte);
88 : static bool rewriteValuesRTE(Query *parsetree, RangeTblEntry *rte, int rti,
89 : Relation target_relation,
90 : Bitmapset *unused_cols);
91 : static void rewriteValuesRTEToNulls(Query *parsetree, RangeTblEntry *rte);
92 : static void markQueryForLocking(Query *qry, Node *jtnode,
93 : LockClauseStrength strength, LockWaitPolicy waitPolicy,
94 : bool pushedDown);
95 : static List *matchLocks(CmdType event, Relation relation,
96 : int varno, Query *parsetree, bool *hasUpdate);
97 : static Query *fireRIRrules(Query *parsetree, List *activeRIRs);
98 : static Bitmapset *adjust_view_column_set(Bitmapset *cols, List *targetlist);
99 : static Node *expand_generated_columns_internal(Node *node, Relation rel, int rt_index,
100 : RangeTblEntry *rte, int result_relation);
101 :
102 :
103 : /*
104 : * AcquireRewriteLocks -
105 : * Acquire suitable locks on all the relations mentioned in the Query.
106 : * These locks will ensure that the relation schemas don't change under us
107 : * while we are rewriting, planning, and executing the query.
108 : *
109 : * Caution: this may modify the querytree, therefore caller should usually
110 : * have done a copyObject() to make a writable copy of the querytree in the
111 : * current memory context.
112 : *
113 : * forExecute indicates that the query is about to be executed. If so,
114 : * we'll acquire the lock modes specified in the RTE rellockmode fields.
115 : * If forExecute is false, AccessShareLock is acquired on all relations.
116 : * This case is suitable for ruleutils.c, for example, where we only need
117 : * schema stability and we don't intend to actually modify any relations.
118 : *
119 : * forUpdatePushedDown indicates that a pushed-down FOR [KEY] UPDATE/SHARE
120 : * applies to the current subquery, requiring all rels to be opened with at
121 : * least RowShareLock. This should always be false at the top of the
122 : * recursion. When it is true, we adjust RTE rellockmode fields to reflect
123 : * the higher lock level. This flag is ignored if forExecute is false.
124 : *
125 : * A secondary purpose of this routine is to fix up JOIN RTE references to
126 : * dropped columns (see details below). Such RTEs are modified in-place.
127 : *
128 : * This processing can, and for efficiency's sake should, be skipped when the
129 : * querytree has just been built by the parser: parse analysis already got
130 : * all the same locks we'd get here, and the parser will have omitted dropped
131 : * columns from JOINs to begin with. But we must do this whenever we are
132 : * dealing with a querytree produced earlier than the current command.
133 : *
134 : * About JOINs and dropped columns: although the parser never includes an
135 : * already-dropped column in a JOIN RTE's alias var list, it is possible for
136 : * such a list in a stored rule to include references to dropped columns.
137 : * (If the column is not explicitly referenced anywhere else in the query,
138 : * the dependency mechanism won't consider it used by the rule and so won't
139 : * prevent the column drop.) To support get_rte_attribute_is_dropped(), we
140 : * replace join alias vars that reference dropped columns with null pointers.
141 : *
142 : * (In PostgreSQL 8.0, we did not do this processing but instead had
143 : * get_rte_attribute_is_dropped() recurse to detect dropped columns in joins.
144 : * That approach had horrible performance unfortunately; in particular
145 : * construction of a nested join was O(N^2) in the nesting depth.)
146 : */
147 : void
148 38194 : AcquireRewriteLocks(Query *parsetree,
149 : bool forExecute,
150 : bool forUpdatePushedDown)
151 : {
152 : ListCell *l;
153 : int rt_index;
154 : acquireLocksOnSubLinks_context context;
155 :
156 38194 : context.for_execute = forExecute;
157 :
158 : /*
159 : * First, process RTEs of the current query level.
160 : */
161 38194 : rt_index = 0;
162 110938 : foreach(l, parsetree->rtable)
163 : {
164 72744 : RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
165 : Relation rel;
166 : LOCKMODE lockmode;
167 : List *newaliasvars;
168 : Index curinputvarno;
169 : RangeTblEntry *curinputrte;
170 : ListCell *ll;
171 :
172 72744 : ++rt_index;
173 72744 : switch (rte->rtekind)
174 : {
175 43086 : case RTE_RELATION:
176 :
177 : /*
178 : * Grab the appropriate lock type for the relation, and do not
179 : * release it until end of transaction. This protects the
180 : * rewriter, planner, and executor against schema changes
181 : * mid-query.
182 : *
183 : * If forExecute is false, ignore rellockmode and just use
184 : * AccessShareLock.
185 : */
186 43086 : if (!forExecute)
187 9404 : lockmode = AccessShareLock;
188 33682 : else if (forUpdatePushedDown)
189 : {
190 : /* Upgrade RTE's lock mode to reflect pushed-down lock */
191 96 : if (rte->rellockmode == AccessShareLock)
192 96 : rte->rellockmode = RowShareLock;
193 96 : lockmode = rte->rellockmode;
194 : }
195 : else
196 33586 : lockmode = rte->rellockmode;
197 :
198 43086 : rel = table_open(rte->relid, lockmode);
199 :
200 : /*
201 : * While we have the relation open, update the RTE's relkind,
202 : * just in case it changed since this rule was made.
203 : */
204 43086 : rte->relkind = rel->rd_rel->relkind;
205 :
206 43086 : table_close(rel, NoLock);
207 43086 : break;
208 :
209 16378 : case RTE_JOIN:
210 :
211 : /*
212 : * Scan the join's alias var list to see if any columns have
213 : * been dropped, and if so replace those Vars with null
214 : * pointers.
215 : *
216 : * Since a join has only two inputs, we can expect to see
217 : * multiple references to the same input RTE; optimize away
218 : * multiple fetches.
219 : */
220 16378 : newaliasvars = NIL;
221 16378 : curinputvarno = 0;
222 16378 : curinputrte = NULL;
223 660962 : foreach(ll, rte->joinaliasvars)
224 : {
225 644584 : Var *aliasitem = (Var *) lfirst(ll);
226 644584 : Var *aliasvar = aliasitem;
227 :
228 : /* Look through any implicit coercion */
229 644584 : aliasvar = (Var *) strip_implicit_coercions((Node *) aliasvar);
230 :
231 : /*
232 : * If the list item isn't a simple Var, then it must
233 : * represent a merged column, ie a USING column, and so it
234 : * couldn't possibly be dropped, since it's referenced in
235 : * the join clause. (Conceivably it could also be a null
236 : * pointer already? But that's OK too.)
237 : */
238 644584 : if (aliasvar && IsA(aliasvar, Var))
239 : {
240 : /*
241 : * The elements of an alias list have to refer to
242 : * earlier RTEs of the same rtable, because that's the
243 : * order the planner builds things in. So we already
244 : * processed the referenced RTE, and so it's safe to
245 : * use get_rte_attribute_is_dropped on it. (This might
246 : * not hold after rewriting or planning, but it's OK
247 : * to assume here.)
248 : */
249 : Assert(aliasvar->varlevelsup == 0);
250 644410 : if (aliasvar->varno != curinputvarno)
251 : {
252 42770 : curinputvarno = aliasvar->varno;
253 42770 : if (curinputvarno >= rt_index)
254 0 : elog(ERROR, "unexpected varno %d in JOIN RTE %d",
255 : curinputvarno, rt_index);
256 42770 : curinputrte = rt_fetch(curinputvarno,
257 : parsetree->rtable);
258 : }
259 644410 : if (get_rte_attribute_is_dropped(curinputrte,
260 644410 : aliasvar->varattno))
261 : {
262 : /* Replace the join alias item with a NULL */
263 6 : aliasitem = NULL;
264 : }
265 : }
266 644584 : newaliasvars = lappend(newaliasvars, aliasitem);
267 : }
268 16378 : rte->joinaliasvars = newaliasvars;
269 16378 : break;
270 :
271 2626 : case RTE_SUBQUERY:
272 :
273 : /*
274 : * The subquery RTE itself is all right, but we have to
275 : * recurse to process the represented subquery.
276 : */
277 2626 : AcquireRewriteLocks(rte->subquery,
278 : forExecute,
279 5252 : (forUpdatePushedDown ||
280 2626 : get_parse_rowmark(parsetree, rt_index) != NULL));
281 2626 : break;
282 :
283 10654 : default:
284 : /* ignore other types of RTEs */
285 10654 : break;
286 : }
287 : }
288 :
289 : /* Recurse into subqueries in WITH */
290 38448 : foreach(l, parsetree->cteList)
291 : {
292 254 : CommonTableExpr *cte = (CommonTableExpr *) lfirst(l);
293 :
294 254 : AcquireRewriteLocks((Query *) cte->ctequery, forExecute, false);
295 : }
296 :
297 : /*
298 : * Recurse into sublink subqueries, too. But we already did the ones in
299 : * the rtable and cteList.
300 : */
301 38194 : if (parsetree->hasSubLinks)
302 1926 : query_tree_walker(parsetree, acquireLocksOnSubLinks, &context,
303 : QTW_IGNORE_RC_SUBQUERIES);
304 38194 : }
305 :
306 : /*
307 : * Walker to find sublink subqueries for AcquireRewriteLocks
308 : */
309 : static bool
310 141434 : acquireLocksOnSubLinks(Node *node, acquireLocksOnSubLinks_context *context)
311 : {
312 141434 : if (node == NULL)
313 34264 : return false;
314 107170 : if (IsA(node, SubLink))
315 : {
316 4180 : SubLink *sub = (SubLink *) node;
317 :
318 : /* Do what we came for */
319 4180 : AcquireRewriteLocks((Query *) sub->subselect,
320 4180 : context->for_execute,
321 : false);
322 : /* Fall through to process lefthand args of SubLink */
323 : }
324 :
325 : /*
326 : * Do NOT recurse into Query nodes, because AcquireRewriteLocks already
327 : * processed subselects of subselects for us.
328 : */
329 107170 : return expression_tree_walker(node, acquireLocksOnSubLinks, context);
330 : }
331 :
332 :
333 : /*
334 : * rewriteRuleAction -
335 : * Rewrite the rule action with appropriate qualifiers (taken from
336 : * the triggering query).
337 : *
338 : * Input arguments:
339 : * parsetree - original query
340 : * rule_action - one action (query) of a rule
341 : * rule_qual - WHERE condition of rule, or NULL if unconditional
342 : * rt_index - RT index of result relation in original query
343 : * event - type of rule event
344 : * Output arguments:
345 : * *returning_flag - set true if we rewrite RETURNING clause in rule_action
346 : * (must be initialized to false)
347 : * Return value:
348 : * rewritten form of rule_action
349 : */
350 : static Query *
351 1380 : rewriteRuleAction(Query *parsetree,
352 : Query *rule_action,
353 : Node *rule_qual,
354 : int rt_index,
355 : CmdType event,
356 : bool *returning_flag)
357 : {
358 : int current_varno,
359 : new_varno;
360 : int rt_length;
361 : Query *sub_action;
362 : Query **sub_action_ptr;
363 : acquireLocksOnSubLinks_context context;
364 : ListCell *lc;
365 :
366 1380 : context.for_execute = true;
367 :
368 : /*
369 : * Make modifiable copies of rule action and qual (what we're passed are
370 : * the stored versions in the relcache; don't touch 'em!).
371 : */
372 1380 : rule_action = copyObject(rule_action);
373 1380 : rule_qual = copyObject(rule_qual);
374 :
375 : /*
376 : * Acquire necessary locks and fix any deleted JOIN RTE entries.
377 : */
378 1380 : AcquireRewriteLocks(rule_action, true, false);
379 1380 : (void) acquireLocksOnSubLinks(rule_qual, &context);
380 :
381 1380 : current_varno = rt_index;
382 1380 : rt_length = list_length(parsetree->rtable);
383 1380 : new_varno = PRS2_NEW_VARNO + rt_length;
384 :
385 : /*
386 : * Adjust rule action and qual to offset its varnos, so that we can merge
387 : * its rtable with the main parsetree's rtable.
388 : *
389 : * If the rule action is an INSERT...SELECT, the OLD/NEW rtable entries
390 : * will be in the SELECT part, and we have to modify that rather than the
391 : * top-level INSERT (kluge!).
392 : */
393 1380 : sub_action = getInsertSelectQuery(rule_action, &sub_action_ptr);
394 :
395 1380 : OffsetVarNodes((Node *) sub_action, rt_length, 0);
396 1380 : OffsetVarNodes(rule_qual, rt_length, 0);
397 : /* but references to OLD should point at original rt_index */
398 1380 : ChangeVarNodes((Node *) sub_action,
399 : PRS2_OLD_VARNO + rt_length, rt_index, 0);
400 1380 : ChangeVarNodes(rule_qual,
401 : PRS2_OLD_VARNO + rt_length, rt_index, 0);
402 :
403 : /*
404 : * Mark any subquery RTEs in the rule action as LATERAL if they contain
405 : * Vars referring to the current query level (references to NEW/OLD).
406 : * Those really are lateral references, but we've historically not
407 : * required users to mark such subqueries with LATERAL explicitly. But
408 : * the planner will complain if such Vars exist in a non-LATERAL subquery,
409 : * so we have to fix things up here.
410 : */
411 5460 : foreach(lc, sub_action->rtable)
412 : {
413 4080 : RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc);
414 :
415 4092 : if (rte->rtekind == RTE_SUBQUERY && !rte->lateral &&
416 12 : contain_vars_of_level((Node *) rte->subquery, 1))
417 12 : rte->lateral = true;
418 : }
419 :
420 : /*
421 : * Generate expanded rtable consisting of main parsetree's rtable plus
422 : * rule action's rtable; this becomes the complete rtable for the rule
423 : * action. Some of the entries may be unused after we finish rewriting,
424 : * but we leave them all in place to avoid having to adjust the query's
425 : * varnos. RT entries that are not referenced in the completed jointree
426 : * will be ignored by the planner, so they do not affect query semantics.
427 : *
428 : * Also merge RTEPermissionInfo lists to ensure that all permissions are
429 : * checked correctly.
430 : *
431 : * If the rule is INSTEAD, then the original query won't be executed at
432 : * all, and so its rteperminfos must be preserved so that the executor
433 : * will do the correct permissions checks on the relations referenced in
434 : * it. This allows us to check that the caller has, say, insert-permission
435 : * on a view, when the view is not semantically referenced at all in the
436 : * resulting query.
437 : *
438 : * When a rule is not INSTEAD, the permissions checks done using the
439 : * copied entries will be redundant with those done during execution of
440 : * the original query, but we don't bother to treat that case differently.
441 : *
442 : * NOTE: because planner will destructively alter rtable and rteperminfos,
443 : * we must ensure that rule action's lists are separate and shares no
444 : * substructure with the main query's lists. Hence do a deep copy here
445 : * for both.
446 : */
447 : {
448 1380 : List *rtable_tail = sub_action->rtable;
449 1380 : List *perminfos_tail = sub_action->rteperminfos;
450 :
451 : /*
452 : * RewriteQuery relies on the fact that RT entries from the original
453 : * query appear at the start of the expanded rtable, so we put the
454 : * action's original table at the end of the list.
455 : */
456 1380 : sub_action->rtable = copyObject(parsetree->rtable);
457 1380 : sub_action->rteperminfos = copyObject(parsetree->rteperminfos);
458 1380 : CombineRangeTables(&sub_action->rtable, &sub_action->rteperminfos,
459 : rtable_tail, perminfos_tail);
460 : }
461 :
462 : /*
463 : * There could have been some SubLinks in parsetree's rtable, in which
464 : * case we'd better mark the sub_action correctly.
465 : */
466 1380 : if (parsetree->hasSubLinks && !sub_action->hasSubLinks)
467 : {
468 66 : foreach(lc, parsetree->rtable)
469 : {
470 48 : RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc);
471 :
472 48 : switch (rte->rtekind)
473 : {
474 42 : case RTE_RELATION:
475 42 : sub_action->hasSubLinks =
476 42 : checkExprHasSubLink((Node *) rte->tablesample);
477 42 : break;
478 0 : case RTE_FUNCTION:
479 0 : sub_action->hasSubLinks =
480 0 : checkExprHasSubLink((Node *) rte->functions);
481 0 : break;
482 0 : case RTE_TABLEFUNC:
483 0 : sub_action->hasSubLinks =
484 0 : checkExprHasSubLink((Node *) rte->tablefunc);
485 0 : break;
486 0 : case RTE_VALUES:
487 0 : sub_action->hasSubLinks =
488 0 : checkExprHasSubLink((Node *) rte->values_lists);
489 0 : break;
490 6 : default:
491 : /* other RTE types don't contain bare expressions */
492 6 : break;
493 : }
494 48 : sub_action->hasSubLinks |=
495 48 : checkExprHasSubLink((Node *) rte->securityQuals);
496 48 : if (sub_action->hasSubLinks)
497 6 : break; /* no need to keep scanning rtable */
498 : }
499 : }
500 :
501 : /*
502 : * Also, we might have absorbed some RTEs with RLS conditions into the
503 : * sub_action. If so, mark it as hasRowSecurity, whether or not those
504 : * RTEs will be referenced after we finish rewriting. (Note: currently
505 : * this is a no-op because RLS conditions aren't added till later, but it
506 : * seems like good future-proofing to do this anyway.)
507 : */
508 1380 : sub_action->hasRowSecurity |= parsetree->hasRowSecurity;
509 :
510 : /*
511 : * Each rule action's jointree should be the main parsetree's jointree
512 : * plus that rule's jointree, but usually *without* the original rtindex
513 : * that we're replacing (if present, which it won't be for INSERT). Note
514 : * that if the rule action refers to OLD, its jointree will add a
515 : * reference to rt_index. If the rule action doesn't refer to OLD, but
516 : * either the rule_qual or the user query quals do, then we need to keep
517 : * the original rtindex in the jointree to provide data for the quals. We
518 : * don't want the original rtindex to be joined twice, however, so avoid
519 : * keeping it if the rule action mentions it.
520 : *
521 : * As above, the action's jointree must not share substructure with the
522 : * main parsetree's.
523 : */
524 1380 : if (sub_action->commandType != CMD_UTILITY)
525 : {
526 : bool keeporig;
527 : List *newjointree;
528 :
529 : Assert(sub_action->jointree != NULL);
530 1350 : keeporig = (!rangeTableEntry_used((Node *) sub_action->jointree,
531 3150 : rt_index, 0)) &&
532 1800 : (rangeTableEntry_used(rule_qual, rt_index, 0) ||
533 900 : rangeTableEntry_used(parsetree->jointree->quals, rt_index, 0));
534 1350 : newjointree = adjustJoinTreeList(parsetree, !keeporig, rt_index);
535 1350 : if (newjointree != NIL)
536 : {
537 : /*
538 : * If sub_action is a setop, manipulating its jointree will do no
539 : * good at all, because the jointree is dummy. (Perhaps someday
540 : * we could push the joining and quals down to the member
541 : * statements of the setop?)
542 : */
543 276 : if (sub_action->setOperations != NULL)
544 0 : ereport(ERROR,
545 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
546 : errmsg("conditional UNION/INTERSECT/EXCEPT statements are not implemented")));
547 :
548 552 : sub_action->jointree->fromlist =
549 276 : list_concat(newjointree, sub_action->jointree->fromlist);
550 :
551 : /*
552 : * There could have been some SubLinks in newjointree, in which
553 : * case we'd better mark the sub_action correctly.
554 : */
555 276 : if (parsetree->hasSubLinks && !sub_action->hasSubLinks)
556 6 : sub_action->hasSubLinks =
557 6 : checkExprHasSubLink((Node *) newjointree);
558 : }
559 : }
560 :
561 : /*
562 : * If the original query has any CTEs, copy them into the rule action. But
563 : * we don't need them for a utility action.
564 : */
565 1380 : if (parsetree->cteList != NIL && sub_action->commandType != CMD_UTILITY)
566 : {
567 : /*
568 : * Annoying implementation restriction: because CTEs are identified by
569 : * name within a cteList, we can't merge a CTE from the original query
570 : * if it has the same name as any CTE in the rule action.
571 : *
572 : * This could possibly be fixed by using some sort of internally
573 : * generated ID, instead of names, to link CTE RTEs to their CTEs.
574 : * However, decompiling the results would be quite confusing; note the
575 : * merge of hasRecursive flags below, which could change the apparent
576 : * semantics of such redundantly-named CTEs.
577 : */
578 60 : foreach(lc, parsetree->cteList)
579 : {
580 30 : CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
581 : ListCell *lc2;
582 :
583 30 : foreach(lc2, sub_action->cteList)
584 : {
585 0 : CommonTableExpr *cte2 = (CommonTableExpr *) lfirst(lc2);
586 :
587 0 : if (strcmp(cte->ctename, cte2->ctename) == 0)
588 0 : ereport(ERROR,
589 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
590 : errmsg("WITH query name \"%s\" appears in both a rule action and the query being rewritten",
591 : cte->ctename)));
592 : }
593 : }
594 :
595 : /* OK, it's safe to combine the CTE lists */
596 30 : sub_action->cteList = list_concat(sub_action->cteList,
597 30 : copyObject(parsetree->cteList));
598 : /* ... and don't forget about the associated flags */
599 30 : sub_action->hasRecursive |= parsetree->hasRecursive;
600 30 : sub_action->hasModifyingCTE |= parsetree->hasModifyingCTE;
601 :
602 : /*
603 : * If rule_action is different from sub_action (i.e., the rule action
604 : * is an INSERT...SELECT), then we might have just added some
605 : * data-modifying CTEs that are not at the top query level. This is
606 : * disallowed by the parser and we mustn't generate such trees here
607 : * either, so throw an error.
608 : *
609 : * Conceivably such cases could be supported by attaching the original
610 : * query's CTEs to rule_action not sub_action. But to do that, we'd
611 : * have to increment ctelevelsup in RTEs and SubLinks copied from the
612 : * original query. For now, it doesn't seem worth the trouble.
613 : */
614 30 : if (sub_action->hasModifyingCTE && rule_action != sub_action)
615 6 : ereport(ERROR,
616 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
617 : errmsg("INSERT ... SELECT rule actions are not supported for queries having data-modifying statements in WITH")));
618 : }
619 :
620 : /*
621 : * Event Qualification forces copying of parsetree and splitting into two
622 : * queries one w/rule_qual, one w/NOT rule_qual. Also add user query qual
623 : * onto rule action
624 : */
625 1374 : AddQual(sub_action, rule_qual);
626 :
627 1374 : AddQual(sub_action, parsetree->jointree->quals);
628 :
629 : /*
630 : * Rewrite new.attribute with right hand side of target-list entry for
631 : * appropriate field name in insert/update.
632 : *
633 : * KLUGE ALERT: since ReplaceVarsFromTargetList returns a mutated copy, we
634 : * can't just apply it to sub_action; we have to remember to update the
635 : * sublink inside rule_action, too.
636 : */
637 1374 : if ((event == CMD_INSERT || event == CMD_UPDATE) &&
638 1194 : sub_action->commandType != CMD_UTILITY)
639 : {
640 : sub_action = (Query *)
641 2328 : ReplaceVarsFromTargetList((Node *) sub_action,
642 : new_varno,
643 : 0,
644 1164 : rt_fetch(new_varno, sub_action->rtable),
645 : parsetree->targetList,
646 : sub_action->resultRelation,
647 : (event == CMD_UPDATE) ?
648 : REPLACEVARS_CHANGE_VARNO :
649 : REPLACEVARS_SUBSTITUTE_NULL,
650 : current_varno,
651 : NULL);
652 1164 : if (sub_action_ptr)
653 54 : *sub_action_ptr = sub_action;
654 : else
655 1110 : rule_action = sub_action;
656 : }
657 :
658 : /*
659 : * If rule_action has a RETURNING clause, then either throw it away if the
660 : * triggering query has no RETURNING clause, or rewrite it to emit what
661 : * the triggering query's RETURNING clause asks for. Throw an error if
662 : * more than one rule has a RETURNING clause.
663 : */
664 1374 : if (!parsetree->returningList)
665 1224 : rule_action->returningList = NIL;
666 150 : else if (rule_action->returningList)
667 : {
668 138 : if (*returning_flag)
669 0 : ereport(ERROR,
670 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
671 : errmsg("cannot have RETURNING lists in multiple rules")));
672 138 : *returning_flag = true;
673 138 : rule_action->returningList = (List *)
674 138 : ReplaceVarsFromTargetList((Node *) parsetree->returningList,
675 : parsetree->resultRelation,
676 : 0,
677 138 : rt_fetch(parsetree->resultRelation,
678 : parsetree->rtable),
679 : rule_action->returningList,
680 : rule_action->resultRelation,
681 : REPLACEVARS_REPORT_ERROR,
682 : 0,
683 : &rule_action->hasSubLinks);
684 :
685 : /* use triggering query's aliases for OLD and NEW in RETURNING list */
686 138 : rule_action->returningOldAlias = parsetree->returningOldAlias;
687 138 : rule_action->returningNewAlias = parsetree->returningNewAlias;
688 :
689 : /*
690 : * There could have been some SubLinks in parsetree's returningList,
691 : * in which case we'd better mark the rule_action correctly.
692 : */
693 138 : if (parsetree->hasSubLinks && !rule_action->hasSubLinks)
694 0 : rule_action->hasSubLinks =
695 0 : checkExprHasSubLink((Node *) rule_action->returningList);
696 : }
697 :
698 1374 : return rule_action;
699 : }
700 :
701 : /*
702 : * Copy the query's jointree list, and optionally attempt to remove any
703 : * occurrence of the given rt_index as a top-level join item (we do not look
704 : * for it within join items; this is OK because we are only expecting to find
705 : * it as an UPDATE or DELETE target relation, which will be at the top level
706 : * of the join). Returns modified jointree list --- this is a separate copy
707 : * sharing no nodes with the original.
708 : */
709 : static List *
710 1350 : adjustJoinTreeList(Query *parsetree, bool removert, int rt_index)
711 : {
712 1350 : List *newjointree = copyObject(parsetree->jointree->fromlist);
713 : ListCell *l;
714 :
715 1350 : if (removert)
716 : {
717 1590 : foreach(l, newjointree)
718 : {
719 744 : RangeTblRef *rtr = lfirst(l);
720 :
721 744 : if (IsA(rtr, RangeTblRef) &&
722 744 : rtr->rtindex == rt_index)
723 : {
724 504 : newjointree = foreach_delete_current(newjointree, l);
725 504 : break;
726 : }
727 : }
728 : }
729 1350 : return newjointree;
730 : }
731 :
732 :
733 : /*
734 : * rewriteTargetListIU - rewrite INSERT/UPDATE targetlist into standard form
735 : *
736 : * This has the following responsibilities:
737 : *
738 : * 1. For an INSERT, add tlist entries to compute default values for any
739 : * attributes that have defaults and are not assigned to in the given tlist.
740 : * (We do not insert anything for default-less attributes, however. The
741 : * planner will later insert NULLs for them, but there's no reason to slow
742 : * down rewriter processing with extra tlist nodes.) Also, for both INSERT
743 : * and UPDATE, replace explicit DEFAULT specifications with column default
744 : * expressions.
745 : *
746 : * 2. Merge multiple entries for the same target attribute, or declare error
747 : * if we can't. Multiple entries are only allowed for INSERT/UPDATE of
748 : * portions of an array or record field, for example
749 : * UPDATE table SET foo[2] = 42, foo[4] = 43;
750 : * We can merge such operations into a single assignment op. Essentially,
751 : * the expression we want to produce in this case is like
752 : * foo = array_set_element(array_set_element(foo, 2, 42), 4, 43)
753 : *
754 : * 3. Sort the tlist into standard order: non-junk fields in order by resno,
755 : * then junk fields (these in no particular order).
756 : *
757 : * We must do items 1 and 2 before firing rewrite rules, else rewritten
758 : * references to NEW.foo will produce wrong or incomplete results. Item 3
759 : * is not needed for rewriting, but it is helpful for the planner, and we
760 : * can do it essentially for free while handling the other items.
761 : *
762 : * If values_rte is non-NULL (i.e., we are doing a multi-row INSERT using
763 : * values from a VALUES RTE), we populate *unused_values_attrnos with the
764 : * attribute numbers of any unused columns from the VALUES RTE. This can
765 : * happen for identity and generated columns whose targetlist entries are
766 : * replaced with generated expressions (if INSERT ... OVERRIDING USER VALUE is
767 : * used, or all the values to be inserted are DEFAULT). This information is
768 : * required by rewriteValuesRTE() to handle any DEFAULT items in the unused
769 : * columns. The caller must have initialized *unused_values_attrnos to NULL.
770 : */
771 : static List *
772 93646 : rewriteTargetListIU(List *targetList,
773 : CmdType commandType,
774 : OverridingKind override,
775 : Relation target_relation,
776 : RangeTblEntry *values_rte,
777 : int values_rte_index,
778 : Bitmapset **unused_values_attrnos)
779 : {
780 : TargetEntry **new_tles;
781 93646 : List *new_tlist = NIL;
782 93646 : List *junk_tlist = NIL;
783 : Form_pg_attribute att_tup;
784 : int attrno,
785 : next_junk_attrno,
786 : numattrs;
787 : ListCell *temp;
788 93646 : Bitmapset *default_only_cols = NULL;
789 :
790 : /*
791 : * We process the normal (non-junk) attributes by scanning the input tlist
792 : * once and transferring TLEs into an array, then scanning the array to
793 : * build an output tlist. This avoids O(N^2) behavior for large numbers
794 : * of attributes.
795 : *
796 : * Junk attributes are tossed into a separate list during the same tlist
797 : * scan, then appended to the reconstructed tlist.
798 : */
799 93646 : numattrs = RelationGetNumberOfAttributes(target_relation);
800 93646 : new_tles = (TargetEntry **) palloc0(numattrs * sizeof(TargetEntry *));
801 93646 : next_junk_attrno = numattrs + 1;
802 :
803 259924 : foreach(temp, targetList)
804 : {
805 166296 : TargetEntry *old_tle = (TargetEntry *) lfirst(temp);
806 :
807 166296 : if (!old_tle->resjunk)
808 : {
809 : /* Normal attr: stash it into new_tles[] */
810 166164 : attrno = old_tle->resno;
811 166164 : if (attrno < 1 || attrno > numattrs)
812 0 : elog(ERROR, "bogus resno %d in targetlist", attrno);
813 166164 : att_tup = TupleDescAttr(target_relation->rd_att, attrno - 1);
814 :
815 : /* We can (and must) ignore deleted attributes */
816 166164 : if (att_tup->attisdropped)
817 0 : continue;
818 :
819 : /* Merge with any prior assignment to same attribute */
820 166146 : new_tles[attrno - 1] =
821 166164 : process_matched_tle(old_tle,
822 166164 : new_tles[attrno - 1],
823 166164 : NameStr(att_tup->attname));
824 : }
825 : else
826 : {
827 : /*
828 : * Copy all resjunk tlist entries to junk_tlist, and assign them
829 : * resnos above the last real resno.
830 : *
831 : * Typical junk entries include ORDER BY or GROUP BY expressions
832 : * (are these actually possible in an INSERT or UPDATE?), system
833 : * attribute references, etc.
834 : */
835 :
836 : /* Get the resno right, but don't copy unnecessarily */
837 132 : if (old_tle->resno != next_junk_attrno)
838 : {
839 0 : old_tle = flatCopyTargetEntry(old_tle);
840 0 : old_tle->resno = next_junk_attrno;
841 : }
842 132 : junk_tlist = lappend(junk_tlist, old_tle);
843 132 : next_junk_attrno++;
844 : }
845 : }
846 :
847 403964 : for (attrno = 1; attrno <= numattrs; attrno++)
848 : {
849 310534 : TargetEntry *new_tle = new_tles[attrno - 1];
850 : bool apply_default;
851 :
852 310534 : att_tup = TupleDescAttr(target_relation->rd_att, attrno - 1);
853 :
854 : /* We can (and must) ignore deleted attributes */
855 310534 : if (att_tup->attisdropped)
856 950 : continue;
857 :
858 : /*
859 : * Handle the two cases where we need to insert a default expression:
860 : * it's an INSERT and there's no tlist entry for the column, or the
861 : * tlist entry is a DEFAULT placeholder node.
862 : */
863 475338 : apply_default = ((new_tle == NULL && commandType == CMD_INSERT) ||
864 165754 : (new_tle && new_tle->expr && IsA(new_tle->expr, SetToDefault)));
865 :
866 309584 : if (commandType == CMD_INSERT)
867 : {
868 169128 : int values_attrno = 0;
869 :
870 : /* Source attribute number for values that come from a VALUES RTE */
871 169128 : if (values_rte && new_tle && IsA(new_tle->expr, Var))
872 : {
873 8658 : Var *var = (Var *) new_tle->expr;
874 :
875 8658 : if (var->varno == values_rte_index)
876 8658 : values_attrno = var->varattno;
877 : }
878 :
879 : /*
880 : * Can only insert DEFAULT into GENERATED ALWAYS identity columns,
881 : * unless either OVERRIDING USER VALUE or OVERRIDING SYSTEM VALUE
882 : * is specified.
883 : */
884 169128 : if (att_tup->attidentity == ATTRIBUTE_IDENTITY_ALWAYS && !apply_default)
885 : {
886 140 : if (override == OVERRIDING_USER_VALUE)
887 42 : apply_default = true;
888 98 : else if (override != OVERRIDING_SYSTEM_VALUE)
889 : {
890 : /*
891 : * If this column's values come from a VALUES RTE, test
892 : * whether it contains only SetToDefault items. Since the
893 : * VALUES list might be quite large, we arrange to only
894 : * scan it once.
895 : */
896 50 : if (values_attrno != 0)
897 : {
898 26 : if (default_only_cols == NULL)
899 26 : default_only_cols = findDefaultOnlyColumns(values_rte);
900 :
901 26 : if (bms_is_member(values_attrno, default_only_cols))
902 8 : apply_default = true;
903 : }
904 :
905 50 : if (!apply_default)
906 42 : ereport(ERROR,
907 : (errcode(ERRCODE_GENERATED_ALWAYS),
908 : errmsg("cannot insert a non-DEFAULT value into column \"%s\"",
909 : NameStr(att_tup->attname)),
910 : errdetail("Column \"%s\" is an identity column defined as GENERATED ALWAYS.",
911 : NameStr(att_tup->attname)),
912 : errhint("Use OVERRIDING SYSTEM VALUE to override.")));
913 : }
914 : }
915 :
916 : /*
917 : * Although inserting into a GENERATED BY DEFAULT identity column
918 : * is allowed, apply the default if OVERRIDING USER VALUE is
919 : * specified.
920 : */
921 169086 : if (att_tup->attidentity == ATTRIBUTE_IDENTITY_BY_DEFAULT &&
922 : override == OVERRIDING_USER_VALUE)
923 18 : apply_default = true;
924 :
925 : /*
926 : * Can only insert DEFAULT into generated columns. (The
927 : * OVERRIDING clause does not apply to generated columns, so we
928 : * don't consider it here.)
929 : */
930 169086 : if (att_tup->attgenerated && !apply_default)
931 : {
932 : /*
933 : * If this column's values come from a VALUES RTE, test
934 : * whether it contains only SetToDefault items, as above.
935 : */
936 170 : if (values_attrno != 0)
937 : {
938 116 : if (default_only_cols == NULL)
939 116 : default_only_cols = findDefaultOnlyColumns(values_rte);
940 :
941 116 : if (bms_is_member(values_attrno, default_only_cols))
942 32 : apply_default = true;
943 : }
944 :
945 170 : if (!apply_default)
946 138 : ereport(ERROR,
947 : (errcode(ERRCODE_GENERATED_ALWAYS),
948 : errmsg("cannot insert a non-DEFAULT value into column \"%s\"",
949 : NameStr(att_tup->attname)),
950 : errdetail("Column \"%s\" is a generated column.",
951 : NameStr(att_tup->attname))));
952 : }
953 :
954 : /*
955 : * For an INSERT from a VALUES RTE, return the attribute numbers
956 : * of any VALUES columns that will no longer be used (due to the
957 : * targetlist entry being replaced by a default expression).
958 : */
959 168948 : if (values_attrno != 0 && apply_default && unused_values_attrnos)
960 64 : *unused_values_attrnos = bms_add_member(*unused_values_attrnos,
961 : values_attrno);
962 : }
963 :
964 : /*
965 : * Updates to identity and generated columns follow the same rules as
966 : * above, except that UPDATE doesn't admit OVERRIDING clauses. Also,
967 : * the source can't be a VALUES RTE, so we needn't consider that.
968 : */
969 309404 : if (commandType == CMD_UPDATE)
970 : {
971 140456 : if (att_tup->attidentity == ATTRIBUTE_IDENTITY_ALWAYS &&
972 12 : new_tle && !apply_default)
973 6 : ereport(ERROR,
974 : (errcode(ERRCODE_GENERATED_ALWAYS),
975 : errmsg("column \"%s\" can only be updated to DEFAULT",
976 : NameStr(att_tup->attname)),
977 : errdetail("Column \"%s\" is an identity column defined as GENERATED ALWAYS.",
978 : NameStr(att_tup->attname))));
979 :
980 140450 : if (att_tup->attgenerated && new_tle && !apply_default)
981 12 : ereport(ERROR,
982 : (errcode(ERRCODE_GENERATED_ALWAYS),
983 : errmsg("column \"%s\" can only be updated to DEFAULT",
984 : NameStr(att_tup->attname)),
985 : errdetail("Column \"%s\" is a generated column.",
986 : NameStr(att_tup->attname))));
987 : }
988 :
989 309386 : if (att_tup->attgenerated)
990 : {
991 : /*
992 : * virtual generated column stores a null value; stored generated
993 : * column will be fixed in executor
994 : */
995 1570 : new_tle = NULL;
996 : }
997 307816 : else if (apply_default)
998 : {
999 : Node *new_expr;
1000 :
1001 25472 : new_expr = build_column_default(target_relation, attrno);
1002 :
1003 : /*
1004 : * If there is no default (ie, default is effectively NULL), we
1005 : * can omit the tlist entry in the INSERT case, since the planner
1006 : * can insert a NULL for itself, and there's no point in spending
1007 : * any more rewriter cycles on the entry. But in the UPDATE case
1008 : * we've got to explicitly set the column to NULL.
1009 : */
1010 25472 : if (!new_expr)
1011 : {
1012 18854 : if (commandType == CMD_INSERT)
1013 18834 : new_tle = NULL;
1014 : else
1015 20 : new_expr = coerce_null_to_domain(att_tup->atttypid,
1016 : att_tup->atttypmod,
1017 : att_tup->attcollation,
1018 20 : att_tup->attlen,
1019 20 : att_tup->attbyval);
1020 : }
1021 :
1022 25472 : if (new_expr)
1023 6638 : new_tle = makeTargetEntry((Expr *) new_expr,
1024 : attrno,
1025 6638 : pstrdup(NameStr(att_tup->attname)),
1026 : false);
1027 : }
1028 :
1029 309386 : if (new_tle)
1030 171412 : new_tlist = lappend(new_tlist, new_tle);
1031 : }
1032 :
1033 93430 : pfree(new_tles);
1034 :
1035 93430 : return list_concat(new_tlist, junk_tlist);
1036 : }
1037 :
1038 :
1039 : /*
1040 : * Convert a matched TLE from the original tlist into a correct new TLE.
1041 : *
1042 : * This routine detects and handles multiple assignments to the same target
1043 : * attribute. (The attribute name is needed only for error messages.)
1044 : */
1045 : static TargetEntry *
1046 166164 : process_matched_tle(TargetEntry *src_tle,
1047 : TargetEntry *prior_tle,
1048 : const char *attrName)
1049 : {
1050 : TargetEntry *result;
1051 166164 : CoerceToDomain *coerce_expr = NULL;
1052 : Node *src_expr;
1053 : Node *prior_expr;
1054 : Node *src_input;
1055 : Node *prior_input;
1056 : Node *priorbottom;
1057 : Node *newexpr;
1058 :
1059 166164 : if (prior_tle == NULL)
1060 : {
1061 : /*
1062 : * Normal case where this is the first assignment to the attribute.
1063 : */
1064 165826 : return src_tle;
1065 : }
1066 :
1067 : /*----------
1068 : * Multiple assignments to same attribute. Allow only if all are
1069 : * FieldStore or SubscriptingRef assignment operations. This is a bit
1070 : * tricky because what we may actually be looking at is a nest of
1071 : * such nodes; consider
1072 : * UPDATE tab SET col.fld1.subfld1 = x, col.fld2.subfld2 = y
1073 : * The two expressions produced by the parser will look like
1074 : * FieldStore(col, fld1, FieldStore(placeholder, subfld1, x))
1075 : * FieldStore(col, fld2, FieldStore(placeholder, subfld2, y))
1076 : * However, we can ignore the substructure and just consider the top
1077 : * FieldStore or SubscriptingRef from each assignment, because it works to
1078 : * combine these as
1079 : * FieldStore(FieldStore(col, fld1,
1080 : * FieldStore(placeholder, subfld1, x)),
1081 : * fld2, FieldStore(placeholder, subfld2, y))
1082 : * Note the leftmost expression goes on the inside so that the
1083 : * assignments appear to occur left-to-right.
1084 : *
1085 : * For FieldStore, instead of nesting we can generate a single
1086 : * FieldStore with multiple target fields. We must nest when
1087 : * SubscriptingRefs are involved though.
1088 : *
1089 : * As a further complication, the destination column might be a domain,
1090 : * resulting in each assignment containing a CoerceToDomain node over a
1091 : * FieldStore or SubscriptingRef. These should have matching target
1092 : * domains, so we strip them and reconstitute a single CoerceToDomain over
1093 : * the combined FieldStore/SubscriptingRef nodes. (Notice that this has
1094 : * the result that the domain's checks are applied only after we do all
1095 : * the field or element updates, not after each one. This is desirable.)
1096 : *----------
1097 : */
1098 338 : src_expr = (Node *) src_tle->expr;
1099 338 : prior_expr = (Node *) prior_tle->expr;
1100 :
1101 338 : if (src_expr && IsA(src_expr, CoerceToDomain) &&
1102 162 : prior_expr && IsA(prior_expr, CoerceToDomain) &&
1103 162 : ((CoerceToDomain *) src_expr)->resulttype ==
1104 162 : ((CoerceToDomain *) prior_expr)->resulttype)
1105 : {
1106 : /* we assume without checking that resulttypmod/resultcollid match */
1107 162 : coerce_expr = (CoerceToDomain *) src_expr;
1108 162 : src_expr = (Node *) ((CoerceToDomain *) src_expr)->arg;
1109 162 : prior_expr = (Node *) ((CoerceToDomain *) prior_expr)->arg;
1110 : }
1111 :
1112 338 : src_input = get_assignment_input(src_expr);
1113 338 : prior_input = get_assignment_input(prior_expr);
1114 338 : if (src_input == NULL ||
1115 320 : prior_input == NULL ||
1116 320 : exprType(src_expr) != exprType(prior_expr))
1117 18 : ereport(ERROR,
1118 : (errcode(ERRCODE_SYNTAX_ERROR),
1119 : errmsg("multiple assignments to same column \"%s\"",
1120 : attrName)));
1121 :
1122 : /*
1123 : * Prior TLE could be a nest of assignments if we do this more than once.
1124 : */
1125 320 : priorbottom = prior_input;
1126 : for (;;)
1127 42 : {
1128 362 : Node *newbottom = get_assignment_input(priorbottom);
1129 :
1130 362 : if (newbottom == NULL)
1131 320 : break; /* found the original Var reference */
1132 42 : priorbottom = newbottom;
1133 : }
1134 320 : if (!equal(priorbottom, src_input))
1135 0 : ereport(ERROR,
1136 : (errcode(ERRCODE_SYNTAX_ERROR),
1137 : errmsg("multiple assignments to same column \"%s\"",
1138 : attrName)));
1139 :
1140 : /*
1141 : * Looks OK to nest 'em.
1142 : */
1143 320 : if (IsA(src_expr, FieldStore))
1144 : {
1145 126 : FieldStore *fstore = makeNode(FieldStore);
1146 :
1147 126 : if (IsA(prior_expr, FieldStore))
1148 : {
1149 : /* combine the two */
1150 126 : memcpy(fstore, prior_expr, sizeof(FieldStore));
1151 126 : fstore->newvals =
1152 126 : list_concat_copy(((FieldStore *) prior_expr)->newvals,
1153 126 : ((FieldStore *) src_expr)->newvals);
1154 126 : fstore->fieldnums =
1155 126 : list_concat_copy(((FieldStore *) prior_expr)->fieldnums,
1156 126 : ((FieldStore *) src_expr)->fieldnums);
1157 : }
1158 : else
1159 : {
1160 : /* general case, just nest 'em */
1161 0 : memcpy(fstore, src_expr, sizeof(FieldStore));
1162 0 : fstore->arg = (Expr *) prior_expr;
1163 : }
1164 126 : newexpr = (Node *) fstore;
1165 : }
1166 194 : else if (IsA(src_expr, SubscriptingRef))
1167 : {
1168 194 : SubscriptingRef *sbsref = makeNode(SubscriptingRef);
1169 :
1170 194 : memcpy(sbsref, src_expr, sizeof(SubscriptingRef));
1171 194 : sbsref->refexpr = (Expr *) prior_expr;
1172 194 : newexpr = (Node *) sbsref;
1173 : }
1174 : else
1175 : {
1176 0 : elog(ERROR, "cannot happen");
1177 : newexpr = NULL;
1178 : }
1179 :
1180 320 : if (coerce_expr)
1181 : {
1182 : /* put back the CoerceToDomain */
1183 162 : CoerceToDomain *newcoerce = makeNode(CoerceToDomain);
1184 :
1185 162 : memcpy(newcoerce, coerce_expr, sizeof(CoerceToDomain));
1186 162 : newcoerce->arg = (Expr *) newexpr;
1187 162 : newexpr = (Node *) newcoerce;
1188 : }
1189 :
1190 320 : result = flatCopyTargetEntry(src_tle);
1191 320 : result->expr = (Expr *) newexpr;
1192 320 : return result;
1193 : }
1194 :
1195 : /*
1196 : * If node is an assignment node, return its input; else return NULL
1197 : */
1198 : static Node *
1199 1038 : get_assignment_input(Node *node)
1200 : {
1201 1038 : if (node == NULL)
1202 0 : return NULL;
1203 1038 : if (IsA(node, FieldStore))
1204 : {
1205 252 : FieldStore *fstore = (FieldStore *) node;
1206 :
1207 252 : return (Node *) fstore->arg;
1208 : }
1209 786 : else if (IsA(node, SubscriptingRef))
1210 : {
1211 430 : SubscriptingRef *sbsref = (SubscriptingRef *) node;
1212 :
1213 430 : if (sbsref->refassgnexpr == NULL)
1214 0 : return NULL;
1215 :
1216 430 : return (Node *) sbsref->refexpr;
1217 : }
1218 :
1219 356 : return NULL;
1220 : }
1221 :
1222 : /*
1223 : * Make an expression tree for the default value for a column.
1224 : *
1225 : * If there is no default, return a NULL instead.
1226 : */
1227 : Node *
1228 188730 : build_column_default(Relation rel, int attrno)
1229 : {
1230 188730 : TupleDesc rd_att = rel->rd_att;
1231 188730 : Form_pg_attribute att_tup = TupleDescAttr(rd_att, attrno - 1);
1232 188730 : Oid atttype = att_tup->atttypid;
1233 188730 : int32 atttypmod = att_tup->atttypmod;
1234 188730 : Node *expr = NULL;
1235 : Oid exprtype;
1236 :
1237 188730 : if (att_tup->attidentity)
1238 : {
1239 460 : NextValueExpr *nve = makeNode(NextValueExpr);
1240 :
1241 460 : nve->seqid = getIdentitySequence(rel, attrno, false);
1242 460 : nve->typeId = att_tup->atttypid;
1243 :
1244 460 : return (Node *) nve;
1245 : }
1246 :
1247 : /*
1248 : * If relation has a default for this column, fetch that expression.
1249 : */
1250 188270 : if (att_tup->atthasdef)
1251 : {
1252 150736 : expr = TupleDescGetDefault(rd_att, attrno);
1253 150736 : if (expr == NULL)
1254 0 : elog(ERROR, "default expression not found for attribute %d of relation \"%s\"",
1255 : attrno, RelationGetRelationName(rel));
1256 : }
1257 :
1258 : /*
1259 : * No per-column default, so look for a default for the type itself. But
1260 : * not for generated columns.
1261 : */
1262 188270 : if (expr == NULL && !att_tup->attgenerated)
1263 37534 : expr = get_typdefault(atttype);
1264 :
1265 188270 : if (expr == NULL)
1266 37304 : return NULL; /* No default anywhere */
1267 :
1268 : /*
1269 : * Make sure the value is coerced to the target column type; this will
1270 : * generally be true already, but there seem to be some corner cases
1271 : * involving domain defaults where it might not be true. This should match
1272 : * the parser's processing of non-defaulted expressions --- see
1273 : * transformAssignedExpr().
1274 : */
1275 150966 : exprtype = exprType(expr);
1276 :
1277 150966 : expr = coerce_to_target_type(NULL, /* no UNKNOWN params here */
1278 : expr, exprtype,
1279 : atttype, atttypmod,
1280 : COERCION_ASSIGNMENT,
1281 : COERCE_IMPLICIT_CAST,
1282 : -1);
1283 150966 : if (expr == NULL)
1284 0 : ereport(ERROR,
1285 : (errcode(ERRCODE_DATATYPE_MISMATCH),
1286 : errmsg("column \"%s\" is of type %s"
1287 : " but default expression is of type %s",
1288 : NameStr(att_tup->attname),
1289 : format_type_be(atttype),
1290 : format_type_be(exprtype)),
1291 : errhint("You will need to rewrite or cast the expression.")));
1292 :
1293 150966 : return expr;
1294 : }
1295 :
1296 :
1297 : /* Does VALUES RTE contain any SetToDefault items? */
1298 : static bool
1299 4776 : searchForDefault(RangeTblEntry *rte)
1300 : {
1301 : ListCell *lc;
1302 :
1303 19552 : foreach(lc, rte->values_lists)
1304 : {
1305 15080 : List *sublist = (List *) lfirst(lc);
1306 : ListCell *lc2;
1307 :
1308 43746 : foreach(lc2, sublist)
1309 : {
1310 28970 : Node *col = (Node *) lfirst(lc2);
1311 :
1312 28970 : if (IsA(col, SetToDefault))
1313 304 : return true;
1314 : }
1315 : }
1316 4472 : return false;
1317 : }
1318 :
1319 :
1320 : /*
1321 : * Search a VALUES RTE for columns that contain only SetToDefault items,
1322 : * returning a Bitmapset containing the attribute numbers of any such columns.
1323 : */
1324 : static Bitmapset *
1325 142 : findDefaultOnlyColumns(RangeTblEntry *rte)
1326 : {
1327 142 : Bitmapset *default_only_cols = NULL;
1328 : ListCell *lc;
1329 :
1330 258 : foreach(lc, rte->values_lists)
1331 : {
1332 218 : List *sublist = (List *) lfirst(lc);
1333 : ListCell *lc2;
1334 : int i;
1335 :
1336 218 : if (default_only_cols == NULL)
1337 : {
1338 : /* Populate the initial result bitmap from the first row */
1339 142 : i = 0;
1340 434 : foreach(lc2, sublist)
1341 : {
1342 292 : Node *col = (Node *) lfirst(lc2);
1343 :
1344 292 : i++;
1345 292 : if (IsA(col, SetToDefault))
1346 72 : default_only_cols = bms_add_member(default_only_cols, i);
1347 : }
1348 : }
1349 : else
1350 : {
1351 : /* Update the result bitmap from this next row */
1352 76 : i = 0;
1353 242 : foreach(lc2, sublist)
1354 : {
1355 166 : Node *col = (Node *) lfirst(lc2);
1356 :
1357 166 : i++;
1358 166 : if (!IsA(col, SetToDefault))
1359 118 : default_only_cols = bms_del_member(default_only_cols, i);
1360 : }
1361 : }
1362 :
1363 : /*
1364 : * If no column in the rows read so far contains only DEFAULT items,
1365 : * we are done.
1366 : */
1367 218 : if (bms_is_empty(default_only_cols))
1368 102 : break;
1369 : }
1370 :
1371 142 : return default_only_cols;
1372 : }
1373 :
1374 :
1375 : /*
1376 : * When processing INSERT ... VALUES with a VALUES RTE (ie, multiple VALUES
1377 : * lists), we have to replace any DEFAULT items in the VALUES lists with
1378 : * the appropriate default expressions. The other aspects of targetlist
1379 : * rewriting need be applied only to the query's targetlist proper.
1380 : *
1381 : * For an auto-updatable view, each DEFAULT item in the VALUES list is
1382 : * replaced with the default from the view, if it has one. Otherwise it is
1383 : * left untouched so that the underlying base relation's default can be
1384 : * applied instead (when we later recurse to here after rewriting the query
1385 : * to refer to the base relation instead of the view).
1386 : *
1387 : * For other types of relation, including rule- and trigger-updatable views,
1388 : * all DEFAULT items are replaced, and if the target relation doesn't have a
1389 : * default, the value is explicitly set to NULL.
1390 : *
1391 : * Also, if a DEFAULT item is found in a column mentioned in unused_cols,
1392 : * it is explicitly set to NULL. This happens for columns in the VALUES RTE
1393 : * whose corresponding targetlist entries have already been replaced with the
1394 : * relation's default expressions, so that any values in those columns of the
1395 : * VALUES RTE are no longer used. This can happen for identity and generated
1396 : * columns (if INSERT ... OVERRIDING USER VALUE is used, or all the values to
1397 : * be inserted are DEFAULT). In principle we could replace all entries in
1398 : * such a column with NULL, whether DEFAULT or not; but it doesn't seem worth
1399 : * the trouble.
1400 : *
1401 : * Note that we may have subscripted or field assignment targetlist entries,
1402 : * as well as more complex expressions from already-replaced DEFAULT items if
1403 : * we have recursed to here for an auto-updatable view. However, it ought to
1404 : * be impossible for such entries to have DEFAULTs assigned to them, except
1405 : * for unused columns, as described above --- we should only have to replace
1406 : * DEFAULT items for targetlist entries that contain simple Vars referencing
1407 : * the VALUES RTE, or which are no longer referred to by the targetlist.
1408 : *
1409 : * Returns true if all DEFAULT items were replaced, and false if some were
1410 : * left untouched.
1411 : */
1412 : static bool
1413 4776 : rewriteValuesRTE(Query *parsetree, RangeTblEntry *rte, int rti,
1414 : Relation target_relation,
1415 : Bitmapset *unused_cols)
1416 : {
1417 : List *newValues;
1418 : ListCell *lc;
1419 : bool isAutoUpdatableView;
1420 : bool allReplaced;
1421 : int numattrs;
1422 : int *attrnos;
1423 :
1424 : /* Steps below are not sensible for non-INSERT queries */
1425 : Assert(parsetree->commandType == CMD_INSERT);
1426 : Assert(rte->rtekind == RTE_VALUES);
1427 :
1428 : /*
1429 : * Rebuilding all the lists is a pretty expensive proposition in a big
1430 : * VALUES list, and it's a waste of time if there aren't any DEFAULT
1431 : * placeholders. So first scan to see if there are any.
1432 : */
1433 4776 : if (!searchForDefault(rte))
1434 4472 : return true; /* nothing to do */
1435 :
1436 : /*
1437 : * Scan the targetlist for entries referring to the VALUES RTE, and note
1438 : * the target attributes. As noted above, we should only need to do this
1439 : * for targetlist entries containing simple Vars --- nothing else in the
1440 : * VALUES RTE should contain DEFAULT items (except possibly for unused
1441 : * columns), and we complain if such a thing does occur.
1442 : */
1443 304 : numattrs = list_length(linitial(rte->values_lists));
1444 304 : attrnos = (int *) palloc0(numattrs * sizeof(int));
1445 :
1446 1230 : foreach(lc, parsetree->targetList)
1447 : {
1448 926 : TargetEntry *tle = (TargetEntry *) lfirst(lc);
1449 :
1450 926 : if (IsA(tle->expr, Var))
1451 : {
1452 792 : Var *var = (Var *) tle->expr;
1453 :
1454 792 : if (var->varno == rti)
1455 : {
1456 792 : int attrno = var->varattno;
1457 :
1458 : Assert(attrno >= 1 && attrno <= numattrs);
1459 792 : attrnos[attrno - 1] = tle->resno;
1460 : }
1461 : }
1462 : }
1463 :
1464 : /*
1465 : * Check if the target relation is an auto-updatable view, in which case
1466 : * unresolved defaults will be left untouched rather than being set to
1467 : * NULL.
1468 : */
1469 304 : isAutoUpdatableView = false;
1470 304 : if (target_relation->rd_rel->relkind == RELKIND_VIEW &&
1471 114 : !view_has_instead_trigger(target_relation, CMD_INSERT, NIL))
1472 : {
1473 : List *locks;
1474 : bool hasUpdate;
1475 : bool found;
1476 : ListCell *l;
1477 :
1478 : /* Look for an unconditional DO INSTEAD rule */
1479 102 : locks = matchLocks(CMD_INSERT, target_relation,
1480 : parsetree->resultRelation, parsetree, &hasUpdate);
1481 :
1482 102 : found = false;
1483 126 : foreach(l, locks)
1484 : {
1485 36 : RewriteRule *rule_lock = (RewriteRule *) lfirst(l);
1486 :
1487 36 : if (rule_lock->isInstead &&
1488 12 : rule_lock->qual == NULL)
1489 : {
1490 12 : found = true;
1491 12 : break;
1492 : }
1493 : }
1494 :
1495 : /*
1496 : * If we didn't find an unconditional DO INSTEAD rule, assume that the
1497 : * view is auto-updatable. If it isn't, rewriteTargetView() will
1498 : * throw an error.
1499 : */
1500 102 : if (!found)
1501 90 : isAutoUpdatableView = true;
1502 : }
1503 :
1504 304 : newValues = NIL;
1505 304 : allReplaced = true;
1506 930 : foreach(lc, rte->values_lists)
1507 : {
1508 626 : List *sublist = (List *) lfirst(lc);
1509 626 : List *newList = NIL;
1510 : ListCell *lc2;
1511 : int i;
1512 :
1513 : Assert(list_length(sublist) == numattrs);
1514 :
1515 626 : i = 0;
1516 2494 : foreach(lc2, sublist)
1517 : {
1518 1868 : Node *col = (Node *) lfirst(lc2);
1519 1868 : int attrno = attrnos[i++];
1520 :
1521 1868 : if (IsA(col, SetToDefault))
1522 : {
1523 : Form_pg_attribute att_tup;
1524 : Node *new_expr;
1525 :
1526 : /*
1527 : * If this column isn't used, just replace the DEFAULT with
1528 : * NULL (attrno will be 0 in this case because the targetlist
1529 : * entry will have been replaced by the default expression).
1530 : */
1531 870 : if (bms_is_member(i, unused_cols))
1532 110 : {
1533 110 : SetToDefault *def = (SetToDefault *) col;
1534 :
1535 110 : newList = lappend(newList,
1536 110 : makeNullConst(def->typeId,
1537 : def->typeMod,
1538 : def->collation));
1539 110 : continue;
1540 : }
1541 :
1542 760 : if (attrno == 0)
1543 0 : elog(ERROR, "cannot set value in column %d to DEFAULT", i);
1544 : Assert(attrno > 0 && attrno <= target_relation->rd_att->natts);
1545 760 : att_tup = TupleDescAttr(target_relation->rd_att, attrno - 1);
1546 :
1547 760 : if (!att_tup->attisdropped)
1548 760 : new_expr = build_column_default(target_relation, attrno);
1549 : else
1550 0 : new_expr = NULL; /* force a NULL if dropped */
1551 :
1552 : /*
1553 : * If there is no default (ie, default is effectively NULL),
1554 : * we've got to explicitly set the column to NULL, unless the
1555 : * target relation is an auto-updatable view.
1556 : */
1557 760 : if (!new_expr)
1558 : {
1559 358 : if (isAutoUpdatableView)
1560 : {
1561 : /* Leave the value untouched */
1562 150 : newList = lappend(newList, col);
1563 150 : allReplaced = false;
1564 150 : continue;
1565 : }
1566 :
1567 208 : new_expr = coerce_null_to_domain(att_tup->atttypid,
1568 : att_tup->atttypmod,
1569 : att_tup->attcollation,
1570 208 : att_tup->attlen,
1571 208 : att_tup->attbyval);
1572 : }
1573 610 : newList = lappend(newList, new_expr);
1574 : }
1575 : else
1576 998 : newList = lappend(newList, col);
1577 : }
1578 626 : newValues = lappend(newValues, newList);
1579 : }
1580 304 : rte->values_lists = newValues;
1581 :
1582 304 : pfree(attrnos);
1583 :
1584 304 : return allReplaced;
1585 : }
1586 :
1587 : /*
1588 : * Mop up any remaining DEFAULT items in the given VALUES RTE by
1589 : * replacing them with NULL constants.
1590 : *
1591 : * This is used for the product queries generated by DO ALSO rules attached to
1592 : * an auto-updatable view. The action can't depend on the "target relation"
1593 : * since the product query might not have one (it needn't be an INSERT).
1594 : * Essentially, such queries are treated as being attached to a rule-updatable
1595 : * view.
1596 : */
1597 : static void
1598 24 : rewriteValuesRTEToNulls(Query *parsetree, RangeTblEntry *rte)
1599 : {
1600 : List *newValues;
1601 : ListCell *lc;
1602 :
1603 24 : newValues = NIL;
1604 72 : foreach(lc, rte->values_lists)
1605 : {
1606 48 : List *sublist = (List *) lfirst(lc);
1607 48 : List *newList = NIL;
1608 : ListCell *lc2;
1609 :
1610 204 : foreach(lc2, sublist)
1611 : {
1612 156 : Node *col = (Node *) lfirst(lc2);
1613 :
1614 156 : if (IsA(col, SetToDefault))
1615 : {
1616 66 : SetToDefault *def = (SetToDefault *) col;
1617 :
1618 66 : newList = lappend(newList, makeNullConst(def->typeId,
1619 : def->typeMod,
1620 : def->collation));
1621 : }
1622 : else
1623 90 : newList = lappend(newList, col);
1624 : }
1625 48 : newValues = lappend(newValues, newList);
1626 : }
1627 24 : rte->values_lists = newValues;
1628 24 : }
1629 :
1630 :
1631 : /*
1632 : * matchLocks -
1633 : * match a relation's list of locks and returns the matching rules
1634 : */
1635 : static List *
1636 96314 : matchLocks(CmdType event,
1637 : Relation relation,
1638 : int varno,
1639 : Query *parsetree,
1640 : bool *hasUpdate)
1641 : {
1642 96314 : RuleLock *rulelocks = relation->rd_rules;
1643 96314 : List *matching_locks = NIL;
1644 : int nlocks;
1645 : int i;
1646 :
1647 96314 : if (rulelocks == NULL)
1648 90624 : return NIL;
1649 :
1650 5690 : if (parsetree->commandType != CMD_SELECT)
1651 : {
1652 5690 : if (parsetree->resultRelation != varno)
1653 0 : return NIL;
1654 : }
1655 :
1656 5690 : nlocks = rulelocks->numLocks;
1657 :
1658 13000 : for (i = 0; i < nlocks; i++)
1659 : {
1660 7328 : RewriteRule *oneLock = rulelocks->rules[i];
1661 :
1662 7328 : if (oneLock->event == CMD_UPDATE)
1663 660 : *hasUpdate = true;
1664 :
1665 : /*
1666 : * Suppress ON INSERT/UPDATE/DELETE rules that are disabled or
1667 : * configured to not fire during the current session's replication
1668 : * role. ON SELECT rules will always be applied in order to keep views
1669 : * working even in LOCAL or REPLICA role.
1670 : */
1671 7328 : if (oneLock->event != CMD_SELECT)
1672 : {
1673 2730 : if (SessionReplicationRole == SESSION_REPLICATION_ROLE_REPLICA)
1674 : {
1675 12 : if (oneLock->enabled == RULE_FIRES_ON_ORIGIN ||
1676 6 : oneLock->enabled == RULE_DISABLED)
1677 6 : continue;
1678 : }
1679 : else /* ORIGIN or LOCAL ROLE */
1680 : {
1681 2718 : if (oneLock->enabled == RULE_FIRES_ON_REPLICA ||
1682 2712 : oneLock->enabled == RULE_DISABLED)
1683 30 : continue;
1684 : }
1685 :
1686 : /* Non-SELECT rules are not supported for MERGE */
1687 2694 : if (parsetree->commandType == CMD_MERGE)
1688 18 : ereport(ERROR,
1689 : errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1690 : errmsg("cannot execute MERGE on relation \"%s\"",
1691 : RelationGetRelationName(relation)),
1692 : errdetail("MERGE is not supported for relations with rules."));
1693 : }
1694 :
1695 7274 : if (oneLock->event == event)
1696 : {
1697 1572 : if (parsetree->commandType != CMD_SELECT ||
1698 0 : rangeTableEntry_used((Node *) parsetree, varno, 0))
1699 1572 : matching_locks = lappend(matching_locks, oneLock);
1700 : }
1701 : }
1702 :
1703 5672 : return matching_locks;
1704 : }
1705 :
1706 :
1707 : /*
1708 : * ApplyRetrieveRule - expand an ON SELECT rule
1709 : */
1710 : static Query *
1711 15514 : ApplyRetrieveRule(Query *parsetree,
1712 : RewriteRule *rule,
1713 : int rt_index,
1714 : Relation relation,
1715 : List *activeRIRs)
1716 : {
1717 : Query *rule_action;
1718 : RangeTblEntry *rte;
1719 : RowMarkClause *rc;
1720 : int numCols;
1721 :
1722 15514 : if (list_length(rule->actions) != 1)
1723 0 : elog(ERROR, "expected just one rule action");
1724 15514 : if (rule->qual != NULL)
1725 0 : elog(ERROR, "cannot handle qualified ON SELECT rule");
1726 :
1727 : /* Check if the expansion of non-system views are restricted */
1728 15514 : if (unlikely((restrict_nonsystem_relation_kind & RESTRICT_RELKIND_VIEW) != 0 &&
1729 : RelationGetRelid(relation) >= FirstNormalObjectId))
1730 6 : ereport(ERROR,
1731 : (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1732 : errmsg("access to non-system view \"%s\" is restricted",
1733 : RelationGetRelationName(relation))));
1734 :
1735 15508 : if (rt_index == parsetree->resultRelation)
1736 : {
1737 : /*
1738 : * We have a view as the result relation of the query, and it wasn't
1739 : * rewritten by any rule. This case is supported if there is an
1740 : * INSTEAD OF trigger that will trap attempts to insert/update/delete
1741 : * view rows. The executor will check that; for the moment just plow
1742 : * ahead. We have two cases:
1743 : *
1744 : * For INSERT, we needn't do anything. The unmodified RTE will serve
1745 : * fine as the result relation.
1746 : *
1747 : * For UPDATE/DELETE/MERGE, we need to expand the view so as to have
1748 : * source data for the operation. But we also need an unmodified RTE
1749 : * to serve as the target. So, copy the RTE and add the copy to the
1750 : * rangetable. Note that the copy does not get added to the jointree.
1751 : * Also note that there's a hack in fireRIRrules to avoid calling this
1752 : * function again when it arrives at the copied RTE.
1753 : */
1754 408 : if (parsetree->commandType == CMD_INSERT)
1755 120 : return parsetree;
1756 288 : else if (parsetree->commandType == CMD_UPDATE ||
1757 132 : parsetree->commandType == CMD_DELETE ||
1758 78 : parsetree->commandType == CMD_MERGE)
1759 288 : {
1760 : RangeTblEntry *newrte;
1761 : Var *var;
1762 : TargetEntry *tle;
1763 :
1764 288 : rte = rt_fetch(rt_index, parsetree->rtable);
1765 288 : newrte = copyObject(rte);
1766 288 : parsetree->rtable = lappend(parsetree->rtable, newrte);
1767 288 : parsetree->resultRelation = list_length(parsetree->rtable);
1768 : /* parsetree->mergeTargetRelation unchanged (use expanded view) */
1769 :
1770 : /*
1771 : * For the most part, Vars referencing the view should remain as
1772 : * they are, meaning that they implicitly represent OLD values.
1773 : * But in the RETURNING list if any, we want such Vars to
1774 : * represent NEW values, so change them to reference the new RTE.
1775 : *
1776 : * Since ChangeVarNodes scribbles on the tree in-place, copy the
1777 : * RETURNING list first for safety.
1778 : */
1779 288 : parsetree->returningList = copyObject(parsetree->returningList);
1780 288 : ChangeVarNodes((Node *) parsetree->returningList, rt_index,
1781 : parsetree->resultRelation, 0);
1782 :
1783 : /*
1784 : * To allow the executor to compute the original view row to pass
1785 : * to the INSTEAD OF trigger, we add a resjunk whole-row Var
1786 : * referencing the original RTE. This will later get expanded
1787 : * into a RowExpr computing all the OLD values of the view row.
1788 : */
1789 288 : var = makeWholeRowVar(rte, rt_index, 0, false);
1790 288 : tle = makeTargetEntry((Expr *) var,
1791 288 : list_length(parsetree->targetList) + 1,
1792 : pstrdup("wholerow"),
1793 : true);
1794 :
1795 288 : parsetree->targetList = lappend(parsetree->targetList, tle);
1796 :
1797 : /* Now, continue with expanding the original view RTE */
1798 : }
1799 : else
1800 0 : elog(ERROR, "unrecognized commandType: %d",
1801 : (int) parsetree->commandType);
1802 : }
1803 :
1804 : /*
1805 : * Check if there's a FOR [KEY] UPDATE/SHARE clause applying to this view.
1806 : *
1807 : * Note: we needn't explicitly consider any such clauses appearing in
1808 : * ancestor query levels; their effects have already been pushed down to
1809 : * here by markQueryForLocking, and will be reflected in "rc".
1810 : */
1811 15388 : rc = get_parse_rowmark(parsetree, rt_index);
1812 :
1813 : /*
1814 : * Make a modifiable copy of the view query, and acquire needed locks on
1815 : * the relations it mentions. Force at least RowShareLock for all such
1816 : * rels if there's a FOR [KEY] UPDATE/SHARE clause affecting this view.
1817 : */
1818 15388 : rule_action = copyObject(linitial(rule->actions));
1819 :
1820 15388 : AcquireRewriteLocks(rule_action, true, (rc != NULL));
1821 :
1822 : /*
1823 : * If FOR [KEY] UPDATE/SHARE of view, mark all the contained tables as
1824 : * implicit FOR [KEY] UPDATE/SHARE, the same as the parser would have done
1825 : * if the view's subquery had been written out explicitly.
1826 : */
1827 15388 : if (rc != NULL)
1828 96 : markQueryForLocking(rule_action, (Node *) rule_action->jointree,
1829 : rc->strength, rc->waitPolicy, true);
1830 :
1831 : /*
1832 : * Recursively expand any view references inside the view.
1833 : */
1834 15388 : rule_action = fireRIRrules(rule_action, activeRIRs);
1835 :
1836 : /*
1837 : * Make sure the query is marked as having row security if the view query
1838 : * does.
1839 : */
1840 15358 : parsetree->hasRowSecurity |= rule_action->hasRowSecurity;
1841 :
1842 : /*
1843 : * Now, plug the view query in as a subselect, converting the relation's
1844 : * original RTE to a subquery RTE.
1845 : */
1846 15358 : rte = rt_fetch(rt_index, parsetree->rtable);
1847 :
1848 15358 : rte->rtekind = RTE_SUBQUERY;
1849 15358 : rte->subquery = rule_action;
1850 15358 : rte->security_barrier = RelationIsSecurityView(relation);
1851 :
1852 : /*
1853 : * Clear fields that should not be set in a subquery RTE. Note that we
1854 : * leave the relid, relkind, rellockmode, and perminfoindex fields set, so
1855 : * that the view relation can be appropriately locked before execution and
1856 : * its permissions checked.
1857 : */
1858 15358 : rte->tablesample = NULL;
1859 15358 : rte->inh = false; /* must not be set for a subquery */
1860 :
1861 : /*
1862 : * Since we allow CREATE OR REPLACE VIEW to add columns to a view, the
1863 : * rule_action might emit more columns than we expected when the current
1864 : * query was parsed. Various places expect rte->eref->colnames to be
1865 : * consistent with the non-junk output columns of the subquery, so patch
1866 : * things up if necessary by adding some dummy column names.
1867 : */
1868 15358 : numCols = ExecCleanTargetListLength(rule_action->targetList);
1869 15376 : while (list_length(rte->eref->colnames) < numCols)
1870 : {
1871 18 : rte->eref->colnames = lappend(rte->eref->colnames,
1872 18 : makeString(pstrdup("?column?")));
1873 : }
1874 :
1875 15358 : return parsetree;
1876 : }
1877 :
1878 : /*
1879 : * Recursively mark all relations used by a view as FOR [KEY] UPDATE/SHARE.
1880 : *
1881 : * This may generate an invalid query, eg if some sub-query uses an
1882 : * aggregate. We leave it to the planner to detect that.
1883 : *
1884 : * NB: this must agree with the parser's transformLockingClause() routine.
1885 : * However, we used to have to avoid marking a view's OLD and NEW rels for
1886 : * updating, which motivated scanning the jointree to determine which rels
1887 : * are used. Possibly that could now be simplified into just scanning the
1888 : * rangetable as the parser does.
1889 : */
1890 : static void
1891 192 : markQueryForLocking(Query *qry, Node *jtnode,
1892 : LockClauseStrength strength, LockWaitPolicy waitPolicy,
1893 : bool pushedDown)
1894 : {
1895 192 : if (jtnode == NULL)
1896 0 : return;
1897 192 : if (IsA(jtnode, RangeTblRef))
1898 : {
1899 96 : int rti = ((RangeTblRef *) jtnode)->rtindex;
1900 96 : RangeTblEntry *rte = rt_fetch(rti, qry->rtable);
1901 :
1902 96 : if (rte->rtekind == RTE_RELATION)
1903 : {
1904 : RTEPermissionInfo *perminfo;
1905 :
1906 96 : applyLockingClause(qry, rti, strength, waitPolicy, pushedDown);
1907 :
1908 96 : perminfo = getRTEPermissionInfo(qry->rteperminfos, rte);
1909 96 : perminfo->requiredPerms |= ACL_SELECT_FOR_UPDATE;
1910 : }
1911 0 : else if (rte->rtekind == RTE_SUBQUERY)
1912 : {
1913 0 : applyLockingClause(qry, rti, strength, waitPolicy, pushedDown);
1914 : /* FOR UPDATE/SHARE of subquery is propagated to subquery's rels */
1915 0 : markQueryForLocking(rte->subquery, (Node *) rte->subquery->jointree,
1916 : strength, waitPolicy, true);
1917 : }
1918 : /* other RTE types are unaffected by FOR UPDATE */
1919 : }
1920 96 : else if (IsA(jtnode, FromExpr))
1921 : {
1922 96 : FromExpr *f = (FromExpr *) jtnode;
1923 : ListCell *l;
1924 :
1925 192 : foreach(l, f->fromlist)
1926 96 : markQueryForLocking(qry, lfirst(l), strength, waitPolicy, pushedDown);
1927 : }
1928 0 : else if (IsA(jtnode, JoinExpr))
1929 : {
1930 0 : JoinExpr *j = (JoinExpr *) jtnode;
1931 :
1932 0 : markQueryForLocking(qry, j->larg, strength, waitPolicy, pushedDown);
1933 0 : markQueryForLocking(qry, j->rarg, strength, waitPolicy, pushedDown);
1934 : }
1935 : else
1936 0 : elog(ERROR, "unrecognized node type: %d",
1937 : (int) nodeTag(jtnode));
1938 : }
1939 :
1940 :
1941 : /*
1942 : * fireRIRonSubLink -
1943 : * Apply fireRIRrules() to each SubLink (subselect in expression) found
1944 : * in the given tree.
1945 : *
1946 : * NOTE: although this has the form of a walker, we cheat and modify the
1947 : * SubLink nodes in-place. It is caller's responsibility to ensure that
1948 : * no unwanted side-effects occur!
1949 : *
1950 : * This is unlike most of the other routines that recurse into subselects,
1951 : * because we must take control at the SubLink node in order to replace
1952 : * the SubLink's subselect link with the possibly-rewritten subquery.
1953 : */
1954 : static bool
1955 2903730 : fireRIRonSubLink(Node *node, fireRIRonSubLink_context *context)
1956 : {
1957 2903730 : if (node == NULL)
1958 568446 : return false;
1959 2335284 : if (IsA(node, SubLink))
1960 : {
1961 49382 : SubLink *sub = (SubLink *) node;
1962 :
1963 : /* Do what we came for */
1964 49382 : sub->subselect = (Node *) fireRIRrules((Query *) sub->subselect,
1965 : context->activeRIRs);
1966 :
1967 : /*
1968 : * Remember if any of the sublinks have row security.
1969 : */
1970 49310 : context->hasRowSecurity |= ((Query *) sub->subselect)->hasRowSecurity;
1971 :
1972 : /* Fall through to process lefthand args of SubLink */
1973 : }
1974 :
1975 : /*
1976 : * Do NOT recurse into Query nodes, because fireRIRrules already processed
1977 : * subselects of subselects for us.
1978 : */
1979 2335212 : return expression_tree_walker(node, fireRIRonSubLink, context);
1980 : }
1981 :
1982 :
1983 : /*
1984 : * fireRIRrules -
1985 : * Apply all RIR rules on each rangetable entry in the given query
1986 : *
1987 : * activeRIRs is a list of the OIDs of views we're already processing RIR
1988 : * rules for, used to detect/reject recursion.
1989 : */
1990 : static Query *
1991 566042 : fireRIRrules(Query *parsetree, List *activeRIRs)
1992 : {
1993 566042 : int origResultRelation = parsetree->resultRelation;
1994 : int rt_index;
1995 : ListCell *lc;
1996 :
1997 : /*
1998 : * Expand SEARCH and CYCLE clauses in CTEs.
1999 : *
2000 : * This is just a convenient place to do this, since we are already
2001 : * looking at each Query.
2002 : */
2003 570080 : foreach(lc, parsetree->cteList)
2004 : {
2005 4044 : CommonTableExpr *cte = lfirst_node(CommonTableExpr, lc);
2006 :
2007 4044 : if (cte->search_clause || cte->cycle_clause)
2008 : {
2009 144 : cte = rewriteSearchAndCycle(cte);
2010 138 : lfirst(lc) = cte;
2011 : }
2012 : }
2013 :
2014 : /*
2015 : * don't try to convert this into a foreach loop, because rtable list can
2016 : * get changed each time through...
2017 : */
2018 566036 : rt_index = 0;
2019 1252542 : while (rt_index < list_length(parsetree->rtable))
2020 : {
2021 : RangeTblEntry *rte;
2022 : Relation rel;
2023 : List *locks;
2024 : RuleLock *rules;
2025 : RewriteRule *rule;
2026 : int i;
2027 :
2028 686542 : ++rt_index;
2029 :
2030 686542 : rte = rt_fetch(rt_index, parsetree->rtable);
2031 :
2032 : /*
2033 : * A subquery RTE can't have associated rules, so there's nothing to
2034 : * do to this level of the query, but we must recurse into the
2035 : * subquery to expand any rule references in it.
2036 : */
2037 686542 : if (rte->rtekind == RTE_SUBQUERY)
2038 : {
2039 46622 : rte->subquery = fireRIRrules(rte->subquery, activeRIRs);
2040 :
2041 : /*
2042 : * While we are here, make sure the query is marked as having row
2043 : * security if any of its subqueries do.
2044 : */
2045 46622 : parsetree->hasRowSecurity |= rte->subquery->hasRowSecurity;
2046 :
2047 46622 : continue;
2048 : }
2049 :
2050 : /*
2051 : * Joins and other non-relation RTEs can be ignored completely.
2052 : */
2053 639920 : if (rte->rtekind != RTE_RELATION)
2054 161172 : continue;
2055 :
2056 : /*
2057 : * Always ignore RIR rules for materialized views referenced in
2058 : * queries. (This does not prevent refreshing MVs, since they aren't
2059 : * referenced in their own query definitions.)
2060 : *
2061 : * Note: in the future we might want to allow MVs to be conditionally
2062 : * expanded as if they were regular views, if they are not scannable.
2063 : * In that case this test would need to be postponed till after we've
2064 : * opened the rel, so that we could check its state.
2065 : */
2066 478748 : if (rte->relkind == RELKIND_MATVIEW)
2067 464 : continue;
2068 :
2069 : /*
2070 : * In INSERT ... ON CONFLICT, ignore the EXCLUDED pseudo-relation;
2071 : * even if it points to a view, we needn't expand it, and should not
2072 : * because we want the RTE to remain of RTE_RELATION type. Otherwise,
2073 : * it would get changed to RTE_SUBQUERY type, which is an
2074 : * untested/unsupported situation.
2075 : */
2076 478284 : if (parsetree->onConflict &&
2077 3540 : rt_index == parsetree->onConflict->exclRelIndex)
2078 1270 : continue;
2079 :
2080 : /*
2081 : * If the table is not referenced in the query, then we ignore it.
2082 : * This prevents infinite expansion loop due to new rtable entries
2083 : * inserted by expansion of a rule. A table is referenced if it is
2084 : * part of the join set (a source table), or is referenced by any Var
2085 : * nodes, or is the result table.
2086 : */
2087 477014 : if (rt_index != parsetree->resultRelation &&
2088 384908 : !rangeTableEntry_used((Node *) parsetree, rt_index, 0))
2089 7208 : continue;
2090 :
2091 : /*
2092 : * Also, if this is a new result relation introduced by
2093 : * ApplyRetrieveRule, we don't want to do anything more with it.
2094 : */
2095 469806 : if (rt_index == parsetree->resultRelation &&
2096 : rt_index != origResultRelation)
2097 288 : continue;
2098 :
2099 : /*
2100 : * We can use NoLock here since either the parser or
2101 : * AcquireRewriteLocks should have locked the rel already.
2102 : */
2103 469518 : rel = table_open(rte->relid, NoLock);
2104 :
2105 : /*
2106 : * Collect the RIR rules that we must apply
2107 : */
2108 469518 : rules = rel->rd_rules;
2109 469518 : if (rules != NULL)
2110 : {
2111 16820 : locks = NIL;
2112 36808 : for (i = 0; i < rules->numLocks; i++)
2113 : {
2114 19988 : rule = rules->rules[i];
2115 19988 : if (rule->event != CMD_SELECT)
2116 4474 : continue;
2117 :
2118 15514 : locks = lappend(locks, rule);
2119 : }
2120 :
2121 : /*
2122 : * If we found any, apply them --- but first check for recursion!
2123 : */
2124 16820 : if (locks != NIL)
2125 : {
2126 : ListCell *l;
2127 :
2128 15514 : if (list_member_oid(activeRIRs, RelationGetRelid(rel)))
2129 0 : ereport(ERROR,
2130 : (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2131 : errmsg("infinite recursion detected in rules for relation \"%s\"",
2132 : RelationGetRelationName(rel))));
2133 15514 : activeRIRs = lappend_oid(activeRIRs, RelationGetRelid(rel));
2134 :
2135 30992 : foreach(l, locks)
2136 : {
2137 15514 : rule = lfirst(l);
2138 :
2139 15514 : parsetree = ApplyRetrieveRule(parsetree,
2140 : rule,
2141 : rt_index,
2142 : rel,
2143 : activeRIRs);
2144 : }
2145 :
2146 15478 : activeRIRs = list_delete_last(activeRIRs);
2147 : }
2148 : }
2149 :
2150 469482 : table_close(rel, NoLock);
2151 : }
2152 :
2153 : /* Recurse into subqueries in WITH */
2154 570038 : foreach(lc, parsetree->cteList)
2155 : {
2156 4038 : CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
2157 :
2158 4038 : cte->ctequery = (Node *)
2159 4038 : fireRIRrules((Query *) cte->ctequery, activeRIRs);
2160 :
2161 : /*
2162 : * While we are here, make sure the query is marked as having row
2163 : * security if any of its CTEs do.
2164 : */
2165 4038 : parsetree->hasRowSecurity |= ((Query *) cte->ctequery)->hasRowSecurity;
2166 : }
2167 :
2168 : /*
2169 : * Recurse into sublink subqueries, too. But we already did the ones in
2170 : * the rtable and cteList.
2171 : */
2172 566000 : if (parsetree->hasSubLinks)
2173 : {
2174 : fireRIRonSubLink_context context;
2175 :
2176 39124 : context.activeRIRs = activeRIRs;
2177 39124 : context.hasRowSecurity = false;
2178 :
2179 39124 : query_tree_walker(parsetree, fireRIRonSubLink, &context,
2180 : QTW_IGNORE_RC_SUBQUERIES);
2181 :
2182 : /*
2183 : * Make sure the query is marked as having row security if any of its
2184 : * sublinks do.
2185 : */
2186 39124 : parsetree->hasRowSecurity |= context.hasRowSecurity;
2187 : }
2188 :
2189 : /*
2190 : * Apply any row-level security policies. We do this last because it
2191 : * requires special recursion detection if the new quals have sublink
2192 : * subqueries, and if we did it in the loop above query_tree_walker would
2193 : * then recurse into those quals a second time.
2194 : */
2195 566000 : rt_index = 0;
2196 1252332 : foreach(lc, parsetree->rtable)
2197 : {
2198 686506 : RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc);
2199 : Relation rel;
2200 : List *securityQuals;
2201 : List *withCheckOptions;
2202 : bool hasRowSecurity;
2203 : bool hasSubLinks;
2204 :
2205 686506 : ++rt_index;
2206 :
2207 : /* Only normal relations can have RLS policies */
2208 686506 : if (rte->rtekind != RTE_RELATION ||
2209 463354 : (rte->relkind != RELKIND_RELATION &&
2210 26042 : rte->relkind != RELKIND_PARTITIONED_TABLE))
2211 231846 : continue;
2212 :
2213 454660 : rel = table_open(rte->relid, NoLock);
2214 :
2215 : /*
2216 : * Fetch any new security quals that must be applied to this RTE.
2217 : */
2218 454660 : get_row_security_policies(parsetree, rte, rt_index,
2219 : &securityQuals, &withCheckOptions,
2220 : &hasRowSecurity, &hasSubLinks);
2221 :
2222 454600 : if (securityQuals != NIL || withCheckOptions != NIL)
2223 : {
2224 2754 : if (hasSubLinks)
2225 : {
2226 : acquireLocksOnSubLinks_context context;
2227 : fireRIRonSubLink_context fire_context;
2228 :
2229 : /*
2230 : * Recursively process the new quals, checking for infinite
2231 : * recursion.
2232 : */
2233 684 : if (list_member_oid(activeRIRs, RelationGetRelid(rel)))
2234 42 : ereport(ERROR,
2235 : (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2236 : errmsg("infinite recursion detected in policy for relation \"%s\"",
2237 : RelationGetRelationName(rel))));
2238 :
2239 642 : activeRIRs = lappend_oid(activeRIRs, RelationGetRelid(rel));
2240 :
2241 : /*
2242 : * get_row_security_policies just passed back securityQuals
2243 : * and/or withCheckOptions, and there were SubLinks, make sure
2244 : * we lock any relations which are referenced.
2245 : *
2246 : * These locks would normally be acquired by the parser, but
2247 : * securityQuals and withCheckOptions are added post-parsing.
2248 : */
2249 642 : context.for_execute = true;
2250 642 : (void) acquireLocksOnSubLinks((Node *) securityQuals, &context);
2251 642 : (void) acquireLocksOnSubLinks((Node *) withCheckOptions,
2252 : &context);
2253 :
2254 : /*
2255 : * Now that we have the locks on anything added by
2256 : * get_row_security_policies, fire any RIR rules for them.
2257 : */
2258 642 : fire_context.activeRIRs = activeRIRs;
2259 642 : fire_context.hasRowSecurity = false;
2260 :
2261 642 : expression_tree_walker((Node *) securityQuals,
2262 : fireRIRonSubLink, &fire_context);
2263 :
2264 576 : expression_tree_walker((Node *) withCheckOptions,
2265 : fireRIRonSubLink, &fire_context);
2266 :
2267 : /*
2268 : * We can ignore the value of fire_context.hasRowSecurity
2269 : * since we only reach this code in cases where hasRowSecurity
2270 : * is already true.
2271 : */
2272 : Assert(hasRowSecurity);
2273 :
2274 570 : activeRIRs = list_delete_last(activeRIRs);
2275 : }
2276 :
2277 : /*
2278 : * Add the new security barrier quals to the start of the RTE's
2279 : * list so that they get applied before any existing barrier quals
2280 : * (which would have come from a security-barrier view, and should
2281 : * get lower priority than RLS conditions on the table itself).
2282 : */
2283 5280 : rte->securityQuals = list_concat(securityQuals,
2284 2640 : rte->securityQuals);
2285 :
2286 2640 : parsetree->withCheckOptions = list_concat(withCheckOptions,
2287 2640 : parsetree->withCheckOptions);
2288 : }
2289 :
2290 : /*
2291 : * Make sure the query is marked correctly if row-level security
2292 : * applies, or if the new quals had sublinks.
2293 : */
2294 454486 : if (hasRowSecurity)
2295 3242 : parsetree->hasRowSecurity = true;
2296 454486 : if (hasSubLinks)
2297 570 : parsetree->hasSubLinks = true;
2298 :
2299 454486 : table_close(rel, NoLock);
2300 : }
2301 :
2302 565826 : return parsetree;
2303 : }
2304 :
2305 :
2306 : /*
2307 : * Modify the given query by adding 'AND rule_qual IS NOT TRUE' to its
2308 : * qualification. This is used to generate suitable "else clauses" for
2309 : * conditional INSTEAD rules. (Unfortunately we must use "x IS NOT TRUE",
2310 : * not just "NOT x" which the planner is much smarter about, else we will
2311 : * do the wrong thing when the qual evaluates to NULL.)
2312 : *
2313 : * The rule_qual may contain references to OLD or NEW. OLD references are
2314 : * replaced by references to the specified rt_index (the relation that the
2315 : * rule applies to). NEW references are only possible for INSERT and UPDATE
2316 : * queries on the relation itself, and so they should be replaced by copies
2317 : * of the related entries in the query's own targetlist.
2318 : */
2319 : static Query *
2320 444 : CopyAndAddInvertedQual(Query *parsetree,
2321 : Node *rule_qual,
2322 : int rt_index,
2323 : CmdType event)
2324 : {
2325 : /* Don't scribble on the passed qual (it's in the relcache!) */
2326 444 : Node *new_qual = copyObject(rule_qual);
2327 : acquireLocksOnSubLinks_context context;
2328 :
2329 444 : context.for_execute = true;
2330 :
2331 : /*
2332 : * In case there are subqueries in the qual, acquire necessary locks and
2333 : * fix any deleted JOIN RTE entries. (This is somewhat redundant with
2334 : * rewriteRuleAction, but not entirely ... consider restructuring so that
2335 : * we only need to process the qual this way once.)
2336 : */
2337 444 : (void) acquireLocksOnSubLinks(new_qual, &context);
2338 :
2339 : /* Fix references to OLD */
2340 444 : ChangeVarNodes(new_qual, PRS2_OLD_VARNO, rt_index, 0);
2341 : /* Fix references to NEW */
2342 444 : if (event == CMD_INSERT || event == CMD_UPDATE)
2343 864 : new_qual = ReplaceVarsFromTargetList(new_qual,
2344 : PRS2_NEW_VARNO,
2345 : 0,
2346 432 : rt_fetch(rt_index,
2347 : parsetree->rtable),
2348 : parsetree->targetList,
2349 : parsetree->resultRelation,
2350 : (event == CMD_UPDATE) ?
2351 : REPLACEVARS_CHANGE_VARNO :
2352 : REPLACEVARS_SUBSTITUTE_NULL,
2353 : rt_index,
2354 : &parsetree->hasSubLinks);
2355 : /* And attach the fixed qual */
2356 444 : AddInvertedQual(parsetree, new_qual);
2357 :
2358 444 : return parsetree;
2359 : }
2360 :
2361 :
2362 : /*
2363 : * fireRules -
2364 : * Iterate through rule locks applying rules.
2365 : *
2366 : * Input arguments:
2367 : * parsetree - original query
2368 : * rt_index - RT index of result relation in original query
2369 : * event - type of rule event
2370 : * locks - list of rules to fire
2371 : * Output arguments:
2372 : * *instead_flag - set true if any unqualified INSTEAD rule is found
2373 : * (must be initialized to false)
2374 : * *returning_flag - set true if we rewrite RETURNING clause in any rule
2375 : * (must be initialized to false)
2376 : * *qual_product - filled with modified original query if any qualified
2377 : * INSTEAD rule is found (must be initialized to NULL)
2378 : * Return value:
2379 : * list of rule actions adjusted for use with this query
2380 : *
2381 : * Qualified INSTEAD rules generate their action with the qualification
2382 : * condition added. They also generate a modified version of the original
2383 : * query with the negated qualification added, so that it will run only for
2384 : * rows that the qualified action doesn't act on. (If there are multiple
2385 : * qualified INSTEAD rules, we AND all the negated quals onto a single
2386 : * modified original query.) We won't execute the original, unmodified
2387 : * query if we find either qualified or unqualified INSTEAD rules. If
2388 : * we find both, the modified original query is discarded too.
2389 : */
2390 : static List *
2391 96194 : fireRules(Query *parsetree,
2392 : int rt_index,
2393 : CmdType event,
2394 : List *locks,
2395 : bool *instead_flag,
2396 : bool *returning_flag,
2397 : Query **qual_product)
2398 : {
2399 96194 : List *results = NIL;
2400 : ListCell *l;
2401 :
2402 97724 : foreach(l, locks)
2403 : {
2404 1536 : RewriteRule *rule_lock = (RewriteRule *) lfirst(l);
2405 1536 : Node *event_qual = rule_lock->qual;
2406 1536 : List *actions = rule_lock->actions;
2407 : QuerySource qsrc;
2408 : ListCell *r;
2409 :
2410 : /* Determine correct QuerySource value for actions */
2411 1536 : if (rule_lock->isInstead)
2412 : {
2413 1152 : if (event_qual != NULL)
2414 450 : qsrc = QSRC_QUAL_INSTEAD_RULE;
2415 : else
2416 : {
2417 702 : qsrc = QSRC_INSTEAD_RULE;
2418 702 : *instead_flag = true; /* report unqualified INSTEAD */
2419 : }
2420 : }
2421 : else
2422 384 : qsrc = QSRC_NON_INSTEAD_RULE;
2423 :
2424 1536 : if (qsrc == QSRC_QUAL_INSTEAD_RULE)
2425 : {
2426 : /*
2427 : * If there are INSTEAD rules with qualifications, the original
2428 : * query is still performed. But all the negated rule
2429 : * qualifications of the INSTEAD rules are added so it does its
2430 : * actions only in cases where the rule quals of all INSTEAD rules
2431 : * are false. Think of it as the default action in a case. We save
2432 : * this in *qual_product so RewriteQuery() can add it to the query
2433 : * list after we mangled it up enough.
2434 : *
2435 : * If we have already found an unqualified INSTEAD rule, then
2436 : * *qual_product won't be used, so don't bother building it.
2437 : */
2438 450 : if (!*instead_flag)
2439 : {
2440 444 : if (*qual_product == NULL)
2441 360 : *qual_product = copyObject(parsetree);
2442 444 : *qual_product = CopyAndAddInvertedQual(*qual_product,
2443 : event_qual,
2444 : rt_index,
2445 : event);
2446 : }
2447 : }
2448 :
2449 : /* Now process the rule's actions and add them to the result list */
2450 3120 : foreach(r, actions)
2451 : {
2452 1590 : Query *rule_action = lfirst(r);
2453 :
2454 1590 : if (rule_action->commandType == CMD_NOTHING)
2455 210 : continue;
2456 :
2457 1380 : rule_action = rewriteRuleAction(parsetree, rule_action,
2458 : event_qual, rt_index, event,
2459 : returning_flag);
2460 :
2461 1374 : rule_action->querySource = qsrc;
2462 1374 : rule_action->canSetTag = false; /* might change later */
2463 :
2464 1374 : results = lappend(results, rule_action);
2465 : }
2466 : }
2467 :
2468 96188 : return results;
2469 : }
2470 :
2471 :
2472 : /*
2473 : * get_view_query - get the Query from a view's _RETURN rule.
2474 : *
2475 : * Caller should have verified that the relation is a view, and therefore
2476 : * we should find an ON SELECT action.
2477 : *
2478 : * Note that the pointer returned is into the relcache and therefore must
2479 : * be treated as read-only to the caller and not modified or scribbled on.
2480 : */
2481 : Query *
2482 5894 : get_view_query(Relation view)
2483 : {
2484 : int i;
2485 :
2486 : Assert(view->rd_rel->relkind == RELKIND_VIEW);
2487 :
2488 5894 : for (i = 0; i < view->rd_rules->numLocks; i++)
2489 : {
2490 5894 : RewriteRule *rule = view->rd_rules->rules[i];
2491 :
2492 5894 : if (rule->event == CMD_SELECT)
2493 : {
2494 : /* A _RETURN rule should have only one action */
2495 5894 : if (list_length(rule->actions) != 1)
2496 0 : elog(ERROR, "invalid _RETURN rule action specification");
2497 :
2498 5894 : return (Query *) linitial(rule->actions);
2499 : }
2500 : }
2501 :
2502 0 : elog(ERROR, "failed to find _RETURN rule for view");
2503 : return NULL; /* keep compiler quiet */
2504 : }
2505 :
2506 :
2507 : /*
2508 : * view_has_instead_trigger - does view have an INSTEAD OF trigger for event?
2509 : *
2510 : * If it does, we don't want to treat it as auto-updatable. This test can't
2511 : * be folded into view_query_is_auto_updatable because it's not an error
2512 : * condition.
2513 : *
2514 : * For MERGE, this will return true if there is an INSTEAD OF trigger for
2515 : * every action in mergeActionList, and false if there are any actions that
2516 : * lack an INSTEAD OF trigger. If there are no data-modifying MERGE actions
2517 : * (only DO NOTHING actions), true is returned so that the view is treated
2518 : * as trigger-updatable, rather than erroring out if it's not auto-updatable.
2519 : */
2520 : bool
2521 5492 : view_has_instead_trigger(Relation view, CmdType event, List *mergeActionList)
2522 : {
2523 5492 : TriggerDesc *trigDesc = view->trigdesc;
2524 :
2525 5492 : switch (event)
2526 : {
2527 1770 : case CMD_INSERT:
2528 1770 : if (trigDesc && trigDesc->trig_insert_instead_row)
2529 264 : return true;
2530 1506 : break;
2531 2060 : case CMD_UPDATE:
2532 2060 : if (trigDesc && trigDesc->trig_update_instead_row)
2533 318 : return true;
2534 1742 : break;
2535 612 : case CMD_DELETE:
2536 612 : if (trigDesc && trigDesc->trig_delete_instead_row)
2537 108 : return true;
2538 504 : break;
2539 1050 : case CMD_MERGE:
2540 1482 : foreach_node(MergeAction, action, mergeActionList)
2541 : {
2542 1170 : switch (action->commandType)
2543 : {
2544 204 : case CMD_INSERT:
2545 204 : if (!trigDesc || !trigDesc->trig_insert_instead_row)
2546 894 : return false;
2547 84 : break;
2548 744 : case CMD_UPDATE:
2549 744 : if (!trigDesc || !trigDesc->trig_update_instead_row)
2550 636 : return false;
2551 108 : break;
2552 162 : case CMD_DELETE:
2553 162 : if (!trigDesc || !trigDesc->trig_delete_instead_row)
2554 138 : return false;
2555 24 : break;
2556 60 : case CMD_NOTHING:
2557 : /* No trigger required */
2558 60 : break;
2559 0 : default:
2560 0 : elog(ERROR, "unrecognized commandType: %d", action->commandType);
2561 : break;
2562 : }
2563 : }
2564 156 : return true; /* no actions without an INSTEAD OF trigger */
2565 0 : default:
2566 0 : elog(ERROR, "unrecognized CmdType: %d", (int) event);
2567 : break;
2568 : }
2569 3752 : return false;
2570 : }
2571 :
2572 :
2573 : /*
2574 : * view_col_is_auto_updatable - test whether the specified column of a view
2575 : * is auto-updatable. Returns NULL (if the column can be updated) or a message
2576 : * string giving the reason that it cannot be.
2577 : *
2578 : * The returned string has not been translated; if it is shown as an error
2579 : * message, the caller should apply _() to translate it.
2580 : *
2581 : * Note that the checks performed here are local to this view. We do not check
2582 : * whether the referenced column of the underlying base relation is updatable.
2583 : */
2584 : static const char *
2585 14388 : view_col_is_auto_updatable(RangeTblRef *rtr, TargetEntry *tle)
2586 : {
2587 14388 : Var *var = (Var *) tle->expr;
2588 :
2589 : /*
2590 : * For now, the only updatable columns we support are those that are Vars
2591 : * referring to user columns of the underlying base relation.
2592 : *
2593 : * The view targetlist may contain resjunk columns (e.g., a view defined
2594 : * like "SELECT * FROM t ORDER BY a+b" is auto-updatable) but such columns
2595 : * are not auto-updatable, and in fact should never appear in the outer
2596 : * query's targetlist.
2597 : */
2598 14388 : if (tle->resjunk)
2599 180 : return gettext_noop("Junk view columns are not updatable.");
2600 :
2601 14208 : if (!IsA(var, Var) ||
2602 12786 : var->varno != rtr->rtindex ||
2603 12786 : var->varlevelsup != 0)
2604 1422 : return gettext_noop("View columns that are not columns of their base relation are not updatable.");
2605 :
2606 12786 : if (var->varattno < 0)
2607 402 : return gettext_noop("View columns that refer to system columns are not updatable.");
2608 :
2609 12384 : if (var->varattno == 0)
2610 0 : return gettext_noop("View columns that return whole-row references are not updatable.");
2611 :
2612 12384 : return NULL; /* the view column is updatable */
2613 : }
2614 :
2615 :
2616 : /*
2617 : * view_query_is_auto_updatable - test whether the specified view definition
2618 : * represents an auto-updatable view. Returns NULL (if the view can be updated)
2619 : * or a message string giving the reason that it cannot be.
2620 :
2621 : * The returned string has not been translated; if it is shown as an error
2622 : * message, the caller should apply _() to translate it.
2623 : *
2624 : * If check_cols is true, the view is required to have at least one updatable
2625 : * column (necessary for INSERT/UPDATE). Otherwise the view's columns are not
2626 : * checked for updatability. See also view_cols_are_auto_updatable.
2627 : *
2628 : * Note that the checks performed here are only based on the view definition.
2629 : * We do not check whether any base relations referred to by the view are
2630 : * updatable.
2631 : */
2632 : const char *
2633 5668 : view_query_is_auto_updatable(Query *viewquery, bool check_cols)
2634 : {
2635 : RangeTblRef *rtr;
2636 : RangeTblEntry *base_rte;
2637 :
2638 : /*----------
2639 : * Check if the view is simply updatable. According to SQL-92 this means:
2640 : * - No DISTINCT clause.
2641 : * - Each TLE is a column reference, and each column appears at most once.
2642 : * - FROM contains exactly one base relation.
2643 : * - No GROUP BY or HAVING clauses.
2644 : * - No set operations (UNION, INTERSECT or EXCEPT).
2645 : * - No sub-queries in the WHERE clause that reference the target table.
2646 : *
2647 : * We ignore that last restriction since it would be complex to enforce
2648 : * and there isn't any actual benefit to disallowing sub-queries. (The
2649 : * semantic issues that the standard is presumably concerned about don't
2650 : * arise in Postgres, since any such sub-query will not see any updates
2651 : * executed by the outer query anyway, thanks to MVCC snapshotting.)
2652 : *
2653 : * We also relax the second restriction by supporting part of SQL:1999
2654 : * feature T111, which allows for a mix of updatable and non-updatable
2655 : * columns, provided that an INSERT or UPDATE doesn't attempt to assign to
2656 : * a non-updatable column.
2657 : *
2658 : * In addition we impose these constraints, involving features that are
2659 : * not part of SQL-92:
2660 : * - No CTEs (WITH clauses).
2661 : * - No OFFSET or LIMIT clauses (this matches a SQL:2008 restriction).
2662 : * - No system columns (including whole-row references) in the tlist.
2663 : * - No window functions in the tlist.
2664 : * - No set-returning functions in the tlist.
2665 : *
2666 : * Note that we do these checks without recursively expanding the view.
2667 : * If the base relation is a view, we'll recursively deal with it later.
2668 : *----------
2669 : */
2670 5668 : if (viewquery->distinctClause != NIL)
2671 72 : return gettext_noop("Views containing DISTINCT are not automatically updatable.");
2672 :
2673 5596 : if (viewquery->groupClause != NIL || viewquery->groupingSets)
2674 36 : return gettext_noop("Views containing GROUP BY are not automatically updatable.");
2675 :
2676 5560 : if (viewquery->havingQual != NULL)
2677 30 : return gettext_noop("Views containing HAVING are not automatically updatable.");
2678 :
2679 5530 : if (viewquery->setOperations != NULL)
2680 36 : return gettext_noop("Views containing UNION, INTERSECT, or EXCEPT are not automatically updatable.");
2681 :
2682 5494 : if (viewquery->cteList != NIL)
2683 36 : return gettext_noop("Views containing WITH are not automatically updatable.");
2684 :
2685 5458 : if (viewquery->limitOffset != NULL || viewquery->limitCount != NULL)
2686 576 : return gettext_noop("Views containing LIMIT or OFFSET are not automatically updatable.");
2687 :
2688 : /*
2689 : * We must not allow window functions or set returning functions in the
2690 : * targetlist. Otherwise we might end up inserting them into the quals of
2691 : * the main query. We must also check for aggregates in the targetlist in
2692 : * case they appear without a GROUP BY.
2693 : *
2694 : * These restrictions ensure that each row of the view corresponds to a
2695 : * unique row in the underlying base relation.
2696 : */
2697 4882 : if (viewquery->hasAggs)
2698 30 : return gettext_noop("Views that return aggregate functions are not automatically updatable.");
2699 :
2700 4852 : if (viewquery->hasWindowFuncs)
2701 36 : return gettext_noop("Views that return window functions are not automatically updatable.");
2702 :
2703 4816 : if (viewquery->hasTargetSRFs)
2704 42 : return gettext_noop("Views that return set-returning functions are not automatically updatable.");
2705 :
2706 : /*
2707 : * The view query should select from a single base relation, which must be
2708 : * a table or another view.
2709 : */
2710 4774 : if (list_length(viewquery->jointree->fromlist) != 1)
2711 66 : return gettext_noop("Views that do not select from a single table or view are not automatically updatable.");
2712 :
2713 4708 : rtr = (RangeTblRef *) linitial(viewquery->jointree->fromlist);
2714 4708 : if (!IsA(rtr, RangeTblRef))
2715 0 : return gettext_noop("Views that do not select from a single table or view are not automatically updatable.");
2716 :
2717 4708 : base_rte = rt_fetch(rtr->rtindex, viewquery->rtable);
2718 4708 : if (base_rte->rtekind != RTE_RELATION ||
2719 4594 : (base_rte->relkind != RELKIND_RELATION &&
2720 1802 : base_rte->relkind != RELKIND_FOREIGN_TABLE &&
2721 1780 : base_rte->relkind != RELKIND_VIEW &&
2722 256 : base_rte->relkind != RELKIND_PARTITIONED_TABLE))
2723 156 : return gettext_noop("Views that do not select from a single table or view are not automatically updatable.");
2724 :
2725 4552 : if (base_rte->tablesample)
2726 6 : return gettext_noop("Views containing TABLESAMPLE are not automatically updatable.");
2727 :
2728 : /*
2729 : * Check that the view has at least one updatable column. This is required
2730 : * for INSERT/UPDATE but not for DELETE.
2731 : */
2732 4546 : if (check_cols)
2733 : {
2734 : ListCell *cell;
2735 : bool found;
2736 :
2737 3112 : found = false;
2738 3298 : foreach(cell, viewquery->targetList)
2739 : {
2740 3298 : TargetEntry *tle = (TargetEntry *) lfirst(cell);
2741 :
2742 3298 : if (view_col_is_auto_updatable(rtr, tle) == NULL)
2743 : {
2744 3112 : found = true;
2745 3112 : break;
2746 : }
2747 : }
2748 :
2749 3112 : if (!found)
2750 0 : return gettext_noop("Views that have no updatable columns are not automatically updatable.");
2751 : }
2752 :
2753 4546 : return NULL; /* the view is updatable */
2754 : }
2755 :
2756 :
2757 : /*
2758 : * view_cols_are_auto_updatable - test whether all of the required columns of
2759 : * an auto-updatable view are actually updatable. Returns NULL (if all the
2760 : * required columns can be updated) or a message string giving the reason that
2761 : * they cannot be.
2762 : *
2763 : * The returned string has not been translated; if it is shown as an error
2764 : * message, the caller should apply _() to translate it.
2765 : *
2766 : * This should be used for INSERT/UPDATE to ensure that we don't attempt to
2767 : * assign to any non-updatable columns.
2768 : *
2769 : * Additionally it may be used to retrieve the set of updatable columns in the
2770 : * view, or if one or more of the required columns is not updatable, the name
2771 : * of the first offending non-updatable column.
2772 : *
2773 : * The caller must have already verified that this is an auto-updatable view
2774 : * using view_query_is_auto_updatable.
2775 : *
2776 : * Note that the checks performed here are only based on the view definition.
2777 : * We do not check whether the referenced columns of the base relation are
2778 : * updatable.
2779 : */
2780 : static const char *
2781 4010 : view_cols_are_auto_updatable(Query *viewquery,
2782 : Bitmapset *required_cols,
2783 : Bitmapset **updatable_cols,
2784 : char **non_updatable_col)
2785 : {
2786 : RangeTblRef *rtr;
2787 : AttrNumber col;
2788 : ListCell *cell;
2789 :
2790 : /*
2791 : * The caller should have verified that this view is auto-updatable and so
2792 : * there should be a single base relation.
2793 : */
2794 : Assert(list_length(viewquery->jointree->fromlist) == 1);
2795 4010 : rtr = linitial_node(RangeTblRef, viewquery->jointree->fromlist);
2796 :
2797 : /* Initialize the optional return values */
2798 4010 : if (updatable_cols != NULL)
2799 1050 : *updatable_cols = NULL;
2800 4010 : if (non_updatable_col != NULL)
2801 2960 : *non_updatable_col = NULL;
2802 :
2803 : /* Test each view column for updatability */
2804 4010 : col = -FirstLowInvalidHeapAttributeNumber;
2805 14980 : foreach(cell, viewquery->targetList)
2806 : {
2807 11090 : TargetEntry *tle = (TargetEntry *) lfirst(cell);
2808 : const char *col_update_detail;
2809 :
2810 11090 : col++;
2811 11090 : col_update_detail = view_col_is_auto_updatable(rtr, tle);
2812 :
2813 11090 : if (col_update_detail == NULL)
2814 : {
2815 : /* The column is updatable */
2816 9272 : if (updatable_cols != NULL)
2817 2136 : *updatable_cols = bms_add_member(*updatable_cols, col);
2818 : }
2819 1818 : else if (bms_is_member(col, required_cols))
2820 : {
2821 : /* The required column is not updatable */
2822 120 : if (non_updatable_col != NULL)
2823 120 : *non_updatable_col = tle->resname;
2824 120 : return col_update_detail;
2825 : }
2826 : }
2827 :
2828 3890 : return NULL; /* all the required view columns are updatable */
2829 : }
2830 :
2831 :
2832 : /*
2833 : * relation_is_updatable - determine which update events the specified
2834 : * relation supports.
2835 : *
2836 : * Note that views may contain a mix of updatable and non-updatable columns.
2837 : * For a view to support INSERT/UPDATE it must have at least one updatable
2838 : * column, but there is no such restriction for DELETE. If include_cols is
2839 : * non-NULL, then only the specified columns are considered when testing for
2840 : * updatability.
2841 : *
2842 : * Unlike the preceding functions, this does recurse to look at a view's
2843 : * base relations, so it needs to detect recursion. To do that, we pass
2844 : * a list of currently-considered outer relations. External callers need
2845 : * only pass NIL.
2846 : *
2847 : * This is used for the information_schema views, which have separate concepts
2848 : * of "updatable" and "trigger updatable". A relation is "updatable" if it
2849 : * can be updated without the need for triggers (either because it has a
2850 : * suitable RULE, or because it is simple enough to be automatically updated).
2851 : * A relation is "trigger updatable" if it has a suitable INSTEAD OF trigger.
2852 : * The SQL standard regards this as not necessarily updatable, presumably
2853 : * because there is no way of knowing what the trigger will actually do.
2854 : * The information_schema views therefore call this function with
2855 : * include_triggers = false. However, other callers might only care whether
2856 : * data-modifying SQL will work, so they can pass include_triggers = true
2857 : * to have trigger updatability included in the result.
2858 : *
2859 : * The return value is a bitmask of rule event numbers indicating which of
2860 : * the INSERT, UPDATE and DELETE operations are supported. (We do it this way
2861 : * so that we can test for UPDATE plus DELETE support in a single call.)
2862 : */
2863 : int
2864 2112 : relation_is_updatable(Oid reloid,
2865 : List *outer_reloids,
2866 : bool include_triggers,
2867 : Bitmapset *include_cols)
2868 : {
2869 2112 : int events = 0;
2870 : Relation rel;
2871 : RuleLock *rulelocks;
2872 :
2873 : #define ALL_EVENTS ((1 << CMD_INSERT) | (1 << CMD_UPDATE) | (1 << CMD_DELETE))
2874 :
2875 : /* Since this function recurses, it could be driven to stack overflow */
2876 2112 : check_stack_depth();
2877 :
2878 2112 : rel = try_relation_open(reloid, AccessShareLock);
2879 :
2880 : /*
2881 : * If the relation doesn't exist, return zero rather than throwing an
2882 : * error. This is helpful since scanning an information_schema view under
2883 : * MVCC rules can result in referencing rels that have actually been
2884 : * deleted already.
2885 : */
2886 2112 : if (rel == NULL)
2887 0 : return 0;
2888 :
2889 : /* If we detect a recursive view, report that it is not updatable */
2890 2112 : if (list_member_oid(outer_reloids, RelationGetRelid(rel)))
2891 : {
2892 0 : relation_close(rel, AccessShareLock);
2893 0 : return 0;
2894 : }
2895 :
2896 : /* If the relation is a table, it is always updatable */
2897 2112 : if (rel->rd_rel->relkind == RELKIND_RELATION ||
2898 2112 : rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
2899 : {
2900 18 : relation_close(rel, AccessShareLock);
2901 18 : return ALL_EVENTS;
2902 : }
2903 :
2904 : /* Look for unconditional DO INSTEAD rules, and note supported events */
2905 2094 : rulelocks = rel->rd_rules;
2906 2094 : if (rulelocks != NULL)
2907 : {
2908 : int i;
2909 :
2910 4560 : for (i = 0; i < rulelocks->numLocks; i++)
2911 : {
2912 2466 : if (rulelocks->rules[i]->isInstead &&
2913 2454 : rulelocks->rules[i]->qual == NULL)
2914 : {
2915 2454 : events |= ((1 << rulelocks->rules[i]->event) & ALL_EVENTS);
2916 : }
2917 : }
2918 :
2919 : /* If we have rules for all events, we're done */
2920 2094 : if (events == ALL_EVENTS)
2921 : {
2922 60 : relation_close(rel, AccessShareLock);
2923 60 : return events;
2924 : }
2925 : }
2926 :
2927 : /* Similarly look for INSTEAD OF triggers, if they are to be included */
2928 2034 : if (include_triggers)
2929 : {
2930 0 : TriggerDesc *trigDesc = rel->trigdesc;
2931 :
2932 0 : if (trigDesc)
2933 : {
2934 0 : if (trigDesc->trig_insert_instead_row)
2935 0 : events |= (1 << CMD_INSERT);
2936 0 : if (trigDesc->trig_update_instead_row)
2937 0 : events |= (1 << CMD_UPDATE);
2938 0 : if (trigDesc->trig_delete_instead_row)
2939 0 : events |= (1 << CMD_DELETE);
2940 :
2941 : /* If we have triggers for all events, we're done */
2942 0 : if (events == ALL_EVENTS)
2943 : {
2944 0 : relation_close(rel, AccessShareLock);
2945 0 : return events;
2946 : }
2947 : }
2948 : }
2949 :
2950 : /* If this is a foreign table, check which update events it supports */
2951 2034 : if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
2952 : {
2953 0 : FdwRoutine *fdwroutine = GetFdwRoutineForRelation(rel, false);
2954 :
2955 0 : if (fdwroutine->IsForeignRelUpdatable != NULL)
2956 0 : events |= fdwroutine->IsForeignRelUpdatable(rel);
2957 : else
2958 : {
2959 : /* Assume presence of executor functions is sufficient */
2960 0 : if (fdwroutine->ExecForeignInsert != NULL)
2961 0 : events |= (1 << CMD_INSERT);
2962 0 : if (fdwroutine->ExecForeignUpdate != NULL)
2963 0 : events |= (1 << CMD_UPDATE);
2964 0 : if (fdwroutine->ExecForeignDelete != NULL)
2965 0 : events |= (1 << CMD_DELETE);
2966 : }
2967 :
2968 0 : relation_close(rel, AccessShareLock);
2969 0 : return events;
2970 : }
2971 :
2972 : /* Check if this is an automatically updatable view */
2973 2034 : if (rel->rd_rel->relkind == RELKIND_VIEW)
2974 : {
2975 2034 : Query *viewquery = get_view_query(rel);
2976 :
2977 2034 : if (view_query_is_auto_updatable(viewquery, false) == NULL)
2978 : {
2979 : Bitmapset *updatable_cols;
2980 : int auto_events;
2981 : RangeTblRef *rtr;
2982 : RangeTblEntry *base_rte;
2983 : Oid baseoid;
2984 :
2985 : /*
2986 : * Determine which of the view's columns are updatable. If there
2987 : * are none within the set of columns we are looking at, then the
2988 : * view doesn't support INSERT/UPDATE, but it may still support
2989 : * DELETE.
2990 : */
2991 1050 : view_cols_are_auto_updatable(viewquery, NULL,
2992 : &updatable_cols, NULL);
2993 :
2994 1050 : if (include_cols != NULL)
2995 576 : updatable_cols = bms_int_members(updatable_cols, include_cols);
2996 :
2997 1050 : if (bms_is_empty(updatable_cols))
2998 150 : auto_events = (1 << CMD_DELETE); /* May support DELETE */
2999 : else
3000 900 : auto_events = ALL_EVENTS; /* May support all events */
3001 :
3002 : /*
3003 : * The base relation must also support these update commands.
3004 : * Tables are always updatable, but for any other kind of base
3005 : * relation we must do a recursive check limited to the columns
3006 : * referenced by the locally updatable columns in this view.
3007 : */
3008 1050 : rtr = (RangeTblRef *) linitial(viewquery->jointree->fromlist);
3009 1050 : base_rte = rt_fetch(rtr->rtindex, viewquery->rtable);
3010 : Assert(base_rte->rtekind == RTE_RELATION);
3011 :
3012 1050 : if (base_rte->relkind != RELKIND_RELATION &&
3013 582 : base_rte->relkind != RELKIND_PARTITIONED_TABLE)
3014 : {
3015 552 : baseoid = base_rte->relid;
3016 552 : outer_reloids = lappend_oid(outer_reloids,
3017 : RelationGetRelid(rel));
3018 552 : include_cols = adjust_view_column_set(updatable_cols,
3019 : viewquery->targetList);
3020 552 : auto_events &= relation_is_updatable(baseoid,
3021 : outer_reloids,
3022 : include_triggers,
3023 : include_cols);
3024 552 : outer_reloids = list_delete_last(outer_reloids);
3025 : }
3026 1050 : events |= auto_events;
3027 : }
3028 : }
3029 :
3030 : /* If we reach here, the relation may support some update commands */
3031 2034 : relation_close(rel, AccessShareLock);
3032 2034 : return events;
3033 : }
3034 :
3035 :
3036 : /*
3037 : * adjust_view_column_set - map a set of column numbers according to targetlist
3038 : *
3039 : * This is used with simply-updatable views to map column-permissions sets for
3040 : * the view columns onto the matching columns in the underlying base relation.
3041 : * Relevant entries in the targetlist must be plain Vars of the underlying
3042 : * relation (as per the checks above in view_query_is_auto_updatable).
3043 : */
3044 : static Bitmapset *
3045 6988 : adjust_view_column_set(Bitmapset *cols, List *targetlist)
3046 : {
3047 6988 : Bitmapset *result = NULL;
3048 : int col;
3049 :
3050 6988 : col = -1;
3051 12106 : while ((col = bms_next_member(cols, col)) >= 0)
3052 : {
3053 : /* bit numbers are offset by FirstLowInvalidHeapAttributeNumber */
3054 5118 : AttrNumber attno = col + FirstLowInvalidHeapAttributeNumber;
3055 :
3056 5118 : if (attno == InvalidAttrNumber)
3057 : {
3058 : /*
3059 : * There's a whole-row reference to the view. For permissions
3060 : * purposes, treat it as a reference to each column available from
3061 : * the view. (We should *not* convert this to a whole-row
3062 : * reference to the base relation, since the view may not touch
3063 : * all columns of the base relation.)
3064 : */
3065 : ListCell *lc;
3066 :
3067 0 : foreach(lc, targetlist)
3068 : {
3069 0 : TargetEntry *tle = lfirst_node(TargetEntry, lc);
3070 : Var *var;
3071 :
3072 0 : if (tle->resjunk)
3073 0 : continue;
3074 0 : var = castNode(Var, tle->expr);
3075 0 : result = bms_add_member(result,
3076 0 : var->varattno - FirstLowInvalidHeapAttributeNumber);
3077 : }
3078 : }
3079 : else
3080 : {
3081 : /*
3082 : * Views do not have system columns, so we do not expect to see
3083 : * any other system attnos here. If we do find one, the error
3084 : * case will apply.
3085 : */
3086 5118 : TargetEntry *tle = get_tle_by_resno(targetlist, attno);
3087 :
3088 5118 : if (tle != NULL && !tle->resjunk && IsA(tle->expr, Var))
3089 5118 : {
3090 5118 : Var *var = (Var *) tle->expr;
3091 :
3092 5118 : result = bms_add_member(result,
3093 5118 : var->varattno - FirstLowInvalidHeapAttributeNumber);
3094 : }
3095 : else
3096 0 : elog(ERROR, "attribute number %d not found in view targetlist",
3097 : attno);
3098 : }
3099 : }
3100 :
3101 6988 : return result;
3102 : }
3103 :
3104 :
3105 : /*
3106 : * error_view_not_updatable -
3107 : * Report an error due to an attempt to update a non-updatable view.
3108 : *
3109 : * Generally this is expected to be called from the rewriter, with suitable
3110 : * error detail explaining why the view is not updatable. Note, however, that
3111 : * the executor also performs a just-in-case check that the target view is
3112 : * updatable. That check is expected to never fail, but if it does, it will
3113 : * call this function with NULL error detail --- see CheckValidResultRel().
3114 : *
3115 : * Note: for MERGE, at least one of the actions in mergeActionList is expected
3116 : * to lack a suitable INSTEAD OF trigger --- see view_has_instead_trigger().
3117 : */
3118 : void
3119 156 : error_view_not_updatable(Relation view,
3120 : CmdType command,
3121 : List *mergeActionList,
3122 : const char *detail)
3123 : {
3124 156 : TriggerDesc *trigDesc = view->trigdesc;
3125 :
3126 156 : switch (command)
3127 : {
3128 24 : case CMD_INSERT:
3129 24 : ereport(ERROR,
3130 : errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
3131 : errmsg("cannot insert into view \"%s\"",
3132 : RelationGetRelationName(view)),
3133 : detail ? errdetail_internal("%s", _(detail)) : 0,
3134 : errhint("To enable inserting into the view, provide an INSTEAD OF INSERT trigger or an unconditional ON INSERT DO INSTEAD rule."));
3135 : break;
3136 54 : case CMD_UPDATE:
3137 54 : ereport(ERROR,
3138 : errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
3139 : errmsg("cannot update view \"%s\"",
3140 : RelationGetRelationName(view)),
3141 : detail ? errdetail_internal("%s", _(detail)) : 0,
3142 : errhint("To enable updating the view, provide an INSTEAD OF UPDATE trigger or an unconditional ON UPDATE DO INSTEAD rule."));
3143 : break;
3144 48 : case CMD_DELETE:
3145 48 : ereport(ERROR,
3146 : errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
3147 : errmsg("cannot delete from view \"%s\"",
3148 : RelationGetRelationName(view)),
3149 : detail ? errdetail_internal("%s", _(detail)) : 0,
3150 : errhint("To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an unconditional ON DELETE DO INSTEAD rule."));
3151 : break;
3152 30 : case CMD_MERGE:
3153 :
3154 : /*
3155 : * Note that the error hints here differ from above, since MERGE
3156 : * doesn't support rules.
3157 : */
3158 36 : foreach_node(MergeAction, action, mergeActionList)
3159 : {
3160 36 : switch (action->commandType)
3161 : {
3162 12 : case CMD_INSERT:
3163 12 : if (!trigDesc || !trigDesc->trig_insert_instead_row)
3164 12 : ereport(ERROR,
3165 : errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
3166 : errmsg("cannot insert into view \"%s\"",
3167 : RelationGetRelationName(view)),
3168 : detail ? errdetail_internal("%s", _(detail)) : 0,
3169 : errhint("To enable inserting into the view using MERGE, provide an INSTEAD OF INSERT trigger."));
3170 0 : break;
3171 12 : case CMD_UPDATE:
3172 12 : if (!trigDesc || !trigDesc->trig_update_instead_row)
3173 6 : ereport(ERROR,
3174 : errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
3175 : errmsg("cannot update view \"%s\"",
3176 : RelationGetRelationName(view)),
3177 : detail ? errdetail_internal("%s", _(detail)) : 0,
3178 : errhint("To enable updating the view using MERGE, provide an INSTEAD OF UPDATE trigger."));
3179 6 : break;
3180 12 : case CMD_DELETE:
3181 12 : if (!trigDesc || !trigDesc->trig_delete_instead_row)
3182 12 : ereport(ERROR,
3183 : errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
3184 : errmsg("cannot delete from view \"%s\"",
3185 : RelationGetRelationName(view)),
3186 : detail ? errdetail_internal("%s", _(detail)) : 0,
3187 : errhint("To enable deleting from the view using MERGE, provide an INSTEAD OF DELETE trigger."));
3188 0 : break;
3189 0 : case CMD_NOTHING:
3190 0 : break;
3191 0 : default:
3192 0 : elog(ERROR, "unrecognized commandType: %d", action->commandType);
3193 : break;
3194 : }
3195 : }
3196 0 : break;
3197 0 : default:
3198 0 : elog(ERROR, "unrecognized CmdType: %d", (int) command);
3199 : break;
3200 : }
3201 0 : }
3202 :
3203 :
3204 : /*
3205 : * rewriteTargetView -
3206 : * Attempt to rewrite a query where the target relation is a view, so that
3207 : * the view's base relation becomes the target relation.
3208 : *
3209 : * Note that the base relation here may itself be a view, which may or may not
3210 : * have INSTEAD OF triggers or rules to handle the update. That is handled by
3211 : * the recursion in RewriteQuery.
3212 : */
3213 : static Query *
3214 3488 : rewriteTargetView(Query *parsetree, Relation view)
3215 : {
3216 : Query *viewquery;
3217 : bool insert_or_update;
3218 : const char *auto_update_detail;
3219 : RangeTblRef *rtr;
3220 : int base_rt_index;
3221 : int new_rt_index;
3222 : RangeTblEntry *base_rte;
3223 : RangeTblEntry *view_rte;
3224 : RangeTblEntry *new_rte;
3225 : RTEPermissionInfo *base_perminfo;
3226 : RTEPermissionInfo *view_perminfo;
3227 : RTEPermissionInfo *new_perminfo;
3228 : Relation base_rel;
3229 : List *view_targetlist;
3230 : ListCell *lc;
3231 :
3232 : /*
3233 : * Get the Query from the view's ON SELECT rule. We're going to munge the
3234 : * Query to change the view's base relation into the target relation,
3235 : * along with various other changes along the way, so we need to make a
3236 : * copy of it (get_view_query() returns a pointer into the relcache, so we
3237 : * have to treat it as read-only).
3238 : */
3239 3488 : viewquery = copyObject(get_view_query(view));
3240 :
3241 : /* Locate RTE and perminfo describing the view in the outer query */
3242 3488 : view_rte = rt_fetch(parsetree->resultRelation, parsetree->rtable);
3243 3488 : view_perminfo = getRTEPermissionInfo(parsetree->rteperminfos, view_rte);
3244 :
3245 : /*
3246 : * Are we doing INSERT/UPDATE, or MERGE containing INSERT/UPDATE? If so,
3247 : * various additional checks on the view columns need to be applied, and
3248 : * any view CHECK OPTIONs need to be enforced.
3249 : */
3250 3488 : insert_or_update =
3251 5776 : (parsetree->commandType == CMD_INSERT ||
3252 2288 : parsetree->commandType == CMD_UPDATE);
3253 :
3254 3488 : if (parsetree->commandType == CMD_MERGE)
3255 : {
3256 1926 : foreach_node(MergeAction, action, parsetree->mergeActionList)
3257 : {
3258 942 : if (action->commandType == CMD_INSERT ||
3259 834 : action->commandType == CMD_UPDATE)
3260 : {
3261 804 : insert_or_update = true;
3262 804 : break;
3263 : }
3264 : }
3265 : }
3266 :
3267 : /* Check if the expansion of non-system views are restricted */
3268 3488 : if (unlikely((restrict_nonsystem_relation_kind & RESTRICT_RELKIND_VIEW) != 0 &&
3269 : RelationGetRelid(view) >= FirstNormalObjectId))
3270 6 : ereport(ERROR,
3271 : (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
3272 : errmsg("access to non-system view \"%s\" is restricted",
3273 : RelationGetRelationName(view))));
3274 :
3275 : /*
3276 : * The view must be updatable, else fail.
3277 : *
3278 : * If we are doing INSERT/UPDATE (or MERGE containing INSERT/UPDATE), we
3279 : * also check that there is at least one updatable column.
3280 : */
3281 : auto_update_detail =
3282 3482 : view_query_is_auto_updatable(viewquery, insert_or_update);
3283 :
3284 3482 : if (auto_update_detail)
3285 138 : error_view_not_updatable(view,
3286 : parsetree->commandType,
3287 : parsetree->mergeActionList,
3288 : auto_update_detail);
3289 :
3290 : /*
3291 : * For INSERT/UPDATE (or MERGE containing INSERT/UPDATE) the modified
3292 : * columns must all be updatable.
3293 : */
3294 3344 : if (insert_or_update)
3295 : {
3296 : Bitmapset *modified_cols;
3297 : char *non_updatable_col;
3298 :
3299 : /*
3300 : * Compute the set of modified columns as those listed in the result
3301 : * RTE's insertedCols and/or updatedCols sets plus those that are
3302 : * targets of the query's targetlist(s). We must consider the query's
3303 : * targetlist because rewriteTargetListIU may have added additional
3304 : * targetlist entries for view defaults, and these must also be
3305 : * updatable. But rewriteTargetListIU can also remove entries if they
3306 : * are DEFAULT markers and the column's default is NULL, so
3307 : * considering only the targetlist would also be wrong.
3308 : */
3309 2960 : modified_cols = bms_union(view_perminfo->insertedCols,
3310 2960 : view_perminfo->updatedCols);
3311 :
3312 6242 : foreach(lc, parsetree->targetList)
3313 : {
3314 3282 : TargetEntry *tle = (TargetEntry *) lfirst(lc);
3315 :
3316 3282 : if (!tle->resjunk)
3317 3282 : modified_cols = bms_add_member(modified_cols,
3318 3282 : tle->resno - FirstLowInvalidHeapAttributeNumber);
3319 : }
3320 :
3321 2960 : if (parsetree->onConflict)
3322 : {
3323 336 : foreach(lc, parsetree->onConflict->onConflictSet)
3324 : {
3325 156 : TargetEntry *tle = (TargetEntry *) lfirst(lc);
3326 :
3327 156 : if (!tle->resjunk)
3328 156 : modified_cols = bms_add_member(modified_cols,
3329 156 : tle->resno - FirstLowInvalidHeapAttributeNumber);
3330 : }
3331 : }
3332 :
3333 6898 : foreach_node(MergeAction, action, parsetree->mergeActionList)
3334 : {
3335 978 : if (action->commandType == CMD_INSERT ||
3336 768 : action->commandType == CMD_UPDATE)
3337 : {
3338 2946 : foreach_node(TargetEntry, tle, action->targetList)
3339 : {
3340 1134 : if (!tle->resjunk)
3341 1134 : modified_cols = bms_add_member(modified_cols,
3342 1134 : tle->resno - FirstLowInvalidHeapAttributeNumber);
3343 : }
3344 : }
3345 : }
3346 :
3347 2960 : auto_update_detail = view_cols_are_auto_updatable(viewquery,
3348 : modified_cols,
3349 : NULL,
3350 : &non_updatable_col);
3351 2960 : if (auto_update_detail)
3352 : {
3353 : /*
3354 : * This is a different error, caused by an attempt to update a
3355 : * non-updatable column in an otherwise updatable view.
3356 : */
3357 120 : switch (parsetree->commandType)
3358 : {
3359 72 : case CMD_INSERT:
3360 72 : ereport(ERROR,
3361 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3362 : errmsg("cannot insert into column \"%s\" of view \"%s\"",
3363 : non_updatable_col,
3364 : RelationGetRelationName(view)),
3365 : errdetail_internal("%s", _(auto_update_detail))));
3366 : break;
3367 42 : case CMD_UPDATE:
3368 42 : ereport(ERROR,
3369 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3370 : errmsg("cannot update column \"%s\" of view \"%s\"",
3371 : non_updatable_col,
3372 : RelationGetRelationName(view)),
3373 : errdetail_internal("%s", _(auto_update_detail))));
3374 : break;
3375 6 : case CMD_MERGE:
3376 6 : ereport(ERROR,
3377 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3378 : errmsg("cannot merge into column \"%s\" of view \"%s\"",
3379 : non_updatable_col,
3380 : RelationGetRelationName(view)),
3381 : errdetail_internal("%s", _(auto_update_detail))));
3382 : break;
3383 0 : default:
3384 0 : elog(ERROR, "unrecognized CmdType: %d",
3385 : (int) parsetree->commandType);
3386 : break;
3387 : }
3388 : }
3389 : }
3390 :
3391 : /*
3392 : * For MERGE, there must not be any INSTEAD OF triggers on an otherwise
3393 : * updatable view. The caller already checked that there isn't a full set
3394 : * of INSTEAD OF triggers, so this is to guard against having a partial
3395 : * set (mixing auto-update and trigger-update actions in a single command
3396 : * isn't supported).
3397 : */
3398 3224 : if (parsetree->commandType == CMD_MERGE)
3399 : {
3400 2748 : foreach_node(MergeAction, action, parsetree->mergeActionList)
3401 : {
3402 2088 : if (action->commandType != CMD_NOTHING &&
3403 1044 : view_has_instead_trigger(view, action->commandType, NIL))
3404 6 : ereport(ERROR,
3405 : errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3406 : errmsg("cannot merge into view \"%s\"",
3407 : RelationGetRelationName(view)),
3408 : errdetail("MERGE is not supported for views with INSTEAD OF triggers for some actions but not all."),
3409 : errhint("To enable merging into the view, either provide a full set of INSTEAD OF triggers or drop the existing INSTEAD OF triggers."));
3410 : }
3411 : }
3412 :
3413 : /*
3414 : * If we get here, view_query_is_auto_updatable() has verified that the
3415 : * view contains a single base relation.
3416 : */
3417 : Assert(list_length(viewquery->jointree->fromlist) == 1);
3418 3218 : rtr = linitial_node(RangeTblRef, viewquery->jointree->fromlist);
3419 :
3420 3218 : base_rt_index = rtr->rtindex;
3421 3218 : base_rte = rt_fetch(base_rt_index, viewquery->rtable);
3422 : Assert(base_rte->rtekind == RTE_RELATION);
3423 3218 : base_perminfo = getRTEPermissionInfo(viewquery->rteperminfos, base_rte);
3424 :
3425 : /*
3426 : * Up to now, the base relation hasn't been touched at all in our query.
3427 : * We need to acquire lock on it before we try to do anything with it.
3428 : * (The subsequent recursive call of RewriteQuery will suppose that we
3429 : * already have the right lock!) Since it will become the query target
3430 : * relation, RowExclusiveLock is always the right thing.
3431 : */
3432 3218 : base_rel = table_open(base_rte->relid, RowExclusiveLock);
3433 :
3434 : /*
3435 : * While we have the relation open, update the RTE's relkind, just in case
3436 : * it changed since this view was made (cf. AcquireRewriteLocks).
3437 : */
3438 3218 : base_rte->relkind = base_rel->rd_rel->relkind;
3439 :
3440 : /*
3441 : * If the view query contains any sublink subqueries then we need to also
3442 : * acquire locks on any relations they refer to. We know that there won't
3443 : * be any subqueries in the range table or CTEs, so we can skip those, as
3444 : * in AcquireRewriteLocks.
3445 : */
3446 3218 : if (viewquery->hasSubLinks)
3447 : {
3448 : acquireLocksOnSubLinks_context context;
3449 :
3450 258 : context.for_execute = true;
3451 258 : query_tree_walker(viewquery, acquireLocksOnSubLinks, &context,
3452 : QTW_IGNORE_RC_SUBQUERIES);
3453 : }
3454 :
3455 : /*
3456 : * Create a new target RTE describing the base relation, and add it to the
3457 : * outer query's rangetable. (What's happening in the next few steps is
3458 : * very much like what the planner would do to "pull up" the view into the
3459 : * outer query. Perhaps someday we should refactor things enough so that
3460 : * we can share code with the planner.)
3461 : *
3462 : * Be sure to set rellockmode to the correct thing for the target table.
3463 : * Since we copied the whole viewquery above, we can just scribble on
3464 : * base_rte instead of copying it.
3465 : */
3466 3218 : new_rte = base_rte;
3467 3218 : new_rte->rellockmode = RowExclusiveLock;
3468 :
3469 3218 : parsetree->rtable = lappend(parsetree->rtable, new_rte);
3470 3218 : new_rt_index = list_length(parsetree->rtable);
3471 :
3472 : /*
3473 : * INSERTs never inherit. For UPDATE/DELETE/MERGE, we use the view
3474 : * query's inheritance flag for the base relation.
3475 : */
3476 3218 : if (parsetree->commandType == CMD_INSERT)
3477 1104 : new_rte->inh = false;
3478 :
3479 : /*
3480 : * Adjust the view's targetlist Vars to reference the new target RTE, ie
3481 : * make their varnos be new_rt_index instead of base_rt_index. There can
3482 : * be no Vars for other rels in the tlist, so this is sufficient to pull
3483 : * up the tlist expressions for use in the outer query. The tlist will
3484 : * provide the replacement expressions used by ReplaceVarsFromTargetList
3485 : * below.
3486 : */
3487 3218 : view_targetlist = viewquery->targetList;
3488 :
3489 3218 : ChangeVarNodes((Node *) view_targetlist,
3490 : base_rt_index,
3491 : new_rt_index,
3492 : 0);
3493 :
3494 : /*
3495 : * If the view has "security_invoker" set, mark the new target relation
3496 : * for the permissions checks that we want to enforce against the query
3497 : * caller. Otherwise we want to enforce them against the view owner.
3498 : *
3499 : * At the relation level, require the same INSERT/UPDATE/DELETE
3500 : * permissions that the query caller needs against the view. We drop the
3501 : * ACL_SELECT bit that is presumably in new_perminfo->requiredPerms
3502 : * initially.
3503 : *
3504 : * Note: the original view's RTEPermissionInfo remains in the query's
3505 : * rteperminfos so that the executor still performs appropriate
3506 : * permissions checks for the query caller's use of the view.
3507 : *
3508 : * Disregard the perminfo in viewquery->rteperminfos that the base_rte
3509 : * would currently be pointing at, because we'd like it to point now to a
3510 : * new one that will be filled below. Must set perminfoindex to 0 to not
3511 : * trip over the Assert in addRTEPermissionInfo().
3512 : */
3513 3218 : new_rte->perminfoindex = 0;
3514 3218 : new_perminfo = addRTEPermissionInfo(&parsetree->rteperminfos, new_rte);
3515 3218 : if (RelationHasSecurityInvoker(view))
3516 486 : new_perminfo->checkAsUser = InvalidOid;
3517 : else
3518 2732 : new_perminfo->checkAsUser = view->rd_rel->relowner;
3519 3218 : new_perminfo->requiredPerms = view_perminfo->requiredPerms;
3520 :
3521 : /*
3522 : * Now for the per-column permissions bits.
3523 : *
3524 : * Initially, new_perminfo (base_perminfo) contains selectedCols
3525 : * permission check bits for all base-rel columns referenced by the view,
3526 : * but since the view is a SELECT query its insertedCols/updatedCols is
3527 : * empty. We set insertedCols and updatedCols to include all the columns
3528 : * the outer query is trying to modify, adjusting the column numbers as
3529 : * needed. But we leave selectedCols as-is, so the view owner must have
3530 : * read permission for all columns used in the view definition, even if
3531 : * some of them are not read by the outer query. We could try to limit
3532 : * selectedCols to only columns used in the transformed query, but that
3533 : * does not correspond to what happens in ordinary SELECT usage of a view:
3534 : * all referenced columns must have read permission, even if optimization
3535 : * finds that some of them can be discarded during query transformation.
3536 : * The flattening we're doing here is an optional optimization, too. (If
3537 : * you are unpersuaded and want to change this, note that applying
3538 : * adjust_view_column_set to view_perminfo->selectedCols is clearly *not*
3539 : * the right answer, since that neglects base-rel columns used in the
3540 : * view's WHERE quals.)
3541 : *
3542 : * This step needs the modified view targetlist, so we have to do things
3543 : * in this order.
3544 : */
3545 : Assert(bms_is_empty(new_perminfo->insertedCols) &&
3546 : bms_is_empty(new_perminfo->updatedCols));
3547 :
3548 3218 : new_perminfo->selectedCols = base_perminfo->selectedCols;
3549 :
3550 3218 : new_perminfo->insertedCols =
3551 3218 : adjust_view_column_set(view_perminfo->insertedCols, view_targetlist);
3552 :
3553 3218 : new_perminfo->updatedCols =
3554 3218 : adjust_view_column_set(view_perminfo->updatedCols, view_targetlist);
3555 :
3556 : /*
3557 : * Move any security barrier quals from the view RTE onto the new target
3558 : * RTE. Any such quals should now apply to the new target RTE and will
3559 : * not reference the original view RTE in the rewritten query.
3560 : */
3561 3218 : new_rte->securityQuals = view_rte->securityQuals;
3562 3218 : view_rte->securityQuals = NIL;
3563 :
3564 : /*
3565 : * Now update all Vars in the outer query that reference the view to
3566 : * reference the appropriate column of the base relation instead.
3567 : */
3568 : parsetree = (Query *)
3569 3218 : ReplaceVarsFromTargetList((Node *) parsetree,
3570 : parsetree->resultRelation,
3571 : 0,
3572 : view_rte,
3573 : view_targetlist,
3574 : new_rt_index,
3575 : REPLACEVARS_REPORT_ERROR,
3576 : 0,
3577 : NULL);
3578 :
3579 : /*
3580 : * Update all other RTI references in the query that point to the view
3581 : * (for example, parsetree->resultRelation itself) to point to the new
3582 : * base relation instead. Vars will not be affected since none of them
3583 : * reference parsetree->resultRelation any longer.
3584 : */
3585 3218 : ChangeVarNodes((Node *) parsetree,
3586 : parsetree->resultRelation,
3587 : new_rt_index,
3588 : 0);
3589 : Assert(parsetree->resultRelation == new_rt_index);
3590 :
3591 : /*
3592 : * For INSERT/UPDATE we must also update resnos in the targetlist to refer
3593 : * to columns of the base relation, since those indicate the target
3594 : * columns to be affected. Similarly, for MERGE we must update the resnos
3595 : * in the merge action targetlists of any INSERT/UPDATE actions.
3596 : *
3597 : * Note that this destroys the resno ordering of the targetlists, but that
3598 : * will be fixed when we recurse through RewriteQuery, which will invoke
3599 : * rewriteTargetListIU again on the updated targetlists.
3600 : */
3601 3218 : if (parsetree->commandType != CMD_DELETE)
3602 : {
3603 5972 : foreach(lc, parsetree->targetList)
3604 : {
3605 3054 : TargetEntry *tle = (TargetEntry *) lfirst(lc);
3606 : TargetEntry *view_tle;
3607 :
3608 3054 : if (tle->resjunk)
3609 0 : continue;
3610 :
3611 3054 : view_tle = get_tle_by_resno(view_targetlist, tle->resno);
3612 3054 : if (view_tle != NULL && !view_tle->resjunk && IsA(view_tle->expr, Var))
3613 3054 : tle->resno = ((Var *) view_tle->expr)->varattno;
3614 : else
3615 0 : elog(ERROR, "attribute number %d not found in view targetlist",
3616 : tle->resno);
3617 : }
3618 :
3619 6874 : foreach_node(MergeAction, action, parsetree->mergeActionList)
3620 : {
3621 1038 : if (action->commandType == CMD_INSERT ||
3622 840 : action->commandType == CMD_UPDATE)
3623 : {
3624 2856 : foreach_node(TargetEntry, tle, action->targetList)
3625 : {
3626 : TargetEntry *view_tle;
3627 :
3628 1092 : if (tle->resjunk)
3629 0 : continue;
3630 :
3631 1092 : view_tle = get_tle_by_resno(view_targetlist, tle->resno);
3632 1092 : if (view_tle != NULL && !view_tle->resjunk && IsA(view_tle->expr, Var))
3633 1092 : tle->resno = ((Var *) view_tle->expr)->varattno;
3634 : else
3635 0 : elog(ERROR, "attribute number %d not found in view targetlist",
3636 : tle->resno);
3637 : }
3638 : }
3639 : }
3640 : }
3641 :
3642 : /*
3643 : * For INSERT .. ON CONFLICT .. DO UPDATE, we must also update assorted
3644 : * stuff in the onConflict data structure.
3645 : */
3646 3218 : if (parsetree->onConflict &&
3647 168 : parsetree->onConflict->action == ONCONFLICT_UPDATE)
3648 : {
3649 : Index old_exclRelIndex,
3650 : new_exclRelIndex;
3651 : ParseNamespaceItem *new_exclNSItem;
3652 : RangeTblEntry *new_exclRte;
3653 : List *tmp_tlist;
3654 :
3655 : /*
3656 : * Like the INSERT/UPDATE code above, update the resnos in the
3657 : * auxiliary UPDATE targetlist to refer to columns of the base
3658 : * relation.
3659 : */
3660 288 : foreach(lc, parsetree->onConflict->onConflictSet)
3661 : {
3662 144 : TargetEntry *tle = (TargetEntry *) lfirst(lc);
3663 : TargetEntry *view_tle;
3664 :
3665 144 : if (tle->resjunk)
3666 0 : continue;
3667 :
3668 144 : view_tle = get_tle_by_resno(view_targetlist, tle->resno);
3669 144 : if (view_tle != NULL && !view_tle->resjunk && IsA(view_tle->expr, Var))
3670 144 : tle->resno = ((Var *) view_tle->expr)->varattno;
3671 : else
3672 0 : elog(ERROR, "attribute number %d not found in view targetlist",
3673 : tle->resno);
3674 : }
3675 :
3676 : /*
3677 : * Also, create a new RTE for the EXCLUDED pseudo-relation, using the
3678 : * query's new base rel (which may well have a different column list
3679 : * from the view, hence we need a new column alias list). This should
3680 : * match transformOnConflictClause. In particular, note that the
3681 : * relkind is set to composite to signal that we're not dealing with
3682 : * an actual relation.
3683 : */
3684 144 : old_exclRelIndex = parsetree->onConflict->exclRelIndex;
3685 :
3686 144 : new_exclNSItem = addRangeTableEntryForRelation(make_parsestate(NULL),
3687 : base_rel,
3688 : RowExclusiveLock,
3689 : makeAlias("excluded", NIL),
3690 : false, false);
3691 144 : new_exclRte = new_exclNSItem->p_rte;
3692 144 : new_exclRte->relkind = RELKIND_COMPOSITE_TYPE;
3693 : /* Ignore the RTEPermissionInfo that would've been added. */
3694 144 : new_exclRte->perminfoindex = 0;
3695 :
3696 144 : parsetree->rtable = lappend(parsetree->rtable, new_exclRte);
3697 288 : new_exclRelIndex = parsetree->onConflict->exclRelIndex =
3698 144 : list_length(parsetree->rtable);
3699 :
3700 : /*
3701 : * Replace the targetlist for the EXCLUDED pseudo-relation with a new
3702 : * one, representing the columns from the new base relation.
3703 : */
3704 288 : parsetree->onConflict->exclRelTlist =
3705 144 : BuildOnConflictExcludedTargetlist(base_rel, new_exclRelIndex);
3706 :
3707 : /*
3708 : * Update all Vars in the ON CONFLICT clause that refer to the old
3709 : * EXCLUDED pseudo-relation. We want to use the column mappings
3710 : * defined in the view targetlist, but we need the outputs to refer to
3711 : * the new EXCLUDED pseudo-relation rather than the new target RTE.
3712 : * Also notice that "EXCLUDED.*" will be expanded using the view's
3713 : * rowtype, which seems correct.
3714 : */
3715 144 : tmp_tlist = copyObject(view_targetlist);
3716 :
3717 144 : ChangeVarNodes((Node *) tmp_tlist, new_rt_index,
3718 : new_exclRelIndex, 0);
3719 :
3720 144 : parsetree->onConflict = (OnConflictExpr *)
3721 144 : ReplaceVarsFromTargetList((Node *) parsetree->onConflict,
3722 : old_exclRelIndex,
3723 : 0,
3724 : view_rte,
3725 : tmp_tlist,
3726 : new_rt_index,
3727 : REPLACEVARS_REPORT_ERROR,
3728 : 0,
3729 : &parsetree->hasSubLinks);
3730 : }
3731 :
3732 : /*
3733 : * For UPDATE/DELETE/MERGE, pull up any WHERE quals from the view. We
3734 : * know that any Vars in the quals must reference the one base relation,
3735 : * so we need only adjust their varnos to reference the new target (just
3736 : * the same as we did with the view targetlist).
3737 : *
3738 : * If it's a security-barrier view, its WHERE quals must be applied before
3739 : * quals from the outer query, so we attach them to the RTE as security
3740 : * barrier quals rather than adding them to the main WHERE clause.
3741 : *
3742 : * For INSERT, the view's quals can be ignored in the main query.
3743 : */
3744 3218 : if (parsetree->commandType != CMD_INSERT &&
3745 2114 : viewquery->jointree->quals != NULL)
3746 : {
3747 758 : Node *viewqual = (Node *) viewquery->jointree->quals;
3748 :
3749 : /*
3750 : * Even though we copied viewquery already at the top of this
3751 : * function, we must duplicate the viewqual again here, because we may
3752 : * need to use the quals again below for a WithCheckOption clause.
3753 : */
3754 758 : viewqual = copyObject(viewqual);
3755 :
3756 758 : ChangeVarNodes(viewqual, base_rt_index, new_rt_index, 0);
3757 :
3758 758 : if (RelationIsSecurityView(view))
3759 : {
3760 : /*
3761 : * The view's quals go in front of existing barrier quals: those
3762 : * would have come from an outer level of security-barrier view,
3763 : * and so must get evaluated later.
3764 : *
3765 : * Note: the parsetree has been mutated, so the new_rte pointer is
3766 : * stale and needs to be re-computed.
3767 : */
3768 234 : new_rte = rt_fetch(new_rt_index, parsetree->rtable);
3769 234 : new_rte->securityQuals = lcons(viewqual, new_rte->securityQuals);
3770 :
3771 : /*
3772 : * Do not set parsetree->hasRowSecurity, because these aren't RLS
3773 : * conditions (they aren't affected by enabling/disabling RLS).
3774 : */
3775 :
3776 : /*
3777 : * Make sure that the query is marked correctly if the added qual
3778 : * has sublinks.
3779 : */
3780 234 : if (!parsetree->hasSubLinks)
3781 210 : parsetree->hasSubLinks = checkExprHasSubLink(viewqual);
3782 : }
3783 : else
3784 524 : AddQual(parsetree, (Node *) viewqual);
3785 : }
3786 :
3787 : /*
3788 : * For INSERT/UPDATE (or MERGE containing INSERT/UPDATE), if the view has
3789 : * the WITH CHECK OPTION, or any parent view specified WITH CASCADED CHECK
3790 : * OPTION, add the quals from the view to the query's withCheckOptions
3791 : * list.
3792 : */
3793 3218 : if (insert_or_update)
3794 : {
3795 2834 : bool has_wco = RelationHasCheckOption(view);
3796 2834 : bool cascaded = RelationHasCascadedCheckOption(view);
3797 :
3798 : /*
3799 : * If the parent view has a cascaded check option, treat this view as
3800 : * if it also had a cascaded check option.
3801 : *
3802 : * New WithCheckOptions are added to the start of the list, so if
3803 : * there is a cascaded check option, it will be the first item in the
3804 : * list.
3805 : */
3806 2834 : if (parsetree->withCheckOptions != NIL)
3807 : {
3808 114 : WithCheckOption *parent_wco =
3809 114 : (WithCheckOption *) linitial(parsetree->withCheckOptions);
3810 :
3811 114 : if (parent_wco->cascaded)
3812 : {
3813 90 : has_wco = true;
3814 90 : cascaded = true;
3815 : }
3816 : }
3817 :
3818 : /*
3819 : * Add the new WithCheckOption to the start of the list, so that
3820 : * checks on inner views are run before checks on outer views, as
3821 : * required by the SQL standard.
3822 : *
3823 : * If the new check is CASCADED, we need to add it even if this view
3824 : * has no quals, since there may be quals on child views. A LOCAL
3825 : * check can be omitted if this view has no quals.
3826 : */
3827 2834 : if (has_wco && (cascaded || viewquery->jointree->quals != NULL))
3828 : {
3829 : WithCheckOption *wco;
3830 :
3831 656 : wco = makeNode(WithCheckOption);
3832 656 : wco->kind = WCO_VIEW_CHECK;
3833 656 : wco->relname = pstrdup(RelationGetRelationName(view));
3834 656 : wco->polname = NULL;
3835 656 : wco->qual = NULL;
3836 656 : wco->cascaded = cascaded;
3837 :
3838 656 : parsetree->withCheckOptions = lcons(wco,
3839 : parsetree->withCheckOptions);
3840 :
3841 656 : if (viewquery->jointree->quals != NULL)
3842 : {
3843 596 : wco->qual = (Node *) viewquery->jointree->quals;
3844 596 : ChangeVarNodes(wco->qual, base_rt_index, new_rt_index, 0);
3845 :
3846 : /*
3847 : * For INSERT, make sure that the query is marked correctly if
3848 : * the added qual has sublinks. This can be skipped for
3849 : * UPDATE/MERGE, since the same qual will have already been
3850 : * added above, and the check will already have been done.
3851 : */
3852 596 : if (!parsetree->hasSubLinks &&
3853 500 : parsetree->commandType == CMD_INSERT)
3854 312 : parsetree->hasSubLinks = checkExprHasSubLink(wco->qual);
3855 : }
3856 : }
3857 : }
3858 :
3859 3218 : table_close(base_rel, NoLock);
3860 :
3861 3218 : return parsetree;
3862 : }
3863 :
3864 :
3865 : /*
3866 : * RewriteQuery -
3867 : * rewrites the query and apply the rules again on the queries rewritten
3868 : *
3869 : * rewrite_events is a list of open query-rewrite actions, so we can detect
3870 : * infinite recursion.
3871 : *
3872 : * orig_rt_length is the length of the originating query's rtable, for product
3873 : * queries created by fireRules(), and 0 otherwise. This is used to skip any
3874 : * already-processed VALUES RTEs from the original query.
3875 : */
3876 : static List *
3877 455456 : RewriteQuery(Query *parsetree, List *rewrite_events, int orig_rt_length)
3878 : {
3879 455456 : CmdType event = parsetree->commandType;
3880 455456 : bool instead = false;
3881 455456 : bool returning = false;
3882 455456 : bool updatableview = false;
3883 455456 : Query *qual_product = NULL;
3884 455456 : List *rewritten = NIL;
3885 : ListCell *lc1;
3886 :
3887 : /*
3888 : * First, recursively process any insert/update/delete/merge statements in
3889 : * WITH clauses. (We have to do this first because the WITH clauses may
3890 : * get copied into rule actions below.)
3891 : */
3892 459014 : foreach(lc1, parsetree->cteList)
3893 : {
3894 3588 : CommonTableExpr *cte = lfirst_node(CommonTableExpr, lc1);
3895 3588 : Query *ctequery = castNode(Query, cte->ctequery);
3896 : List *newstuff;
3897 :
3898 3588 : if (ctequery->commandType == CMD_SELECT)
3899 3240 : continue;
3900 :
3901 348 : newstuff = RewriteQuery(ctequery, rewrite_events, 0);
3902 :
3903 : /*
3904 : * Currently we can only handle unconditional, single-statement DO
3905 : * INSTEAD rules correctly; we have to get exactly one non-utility
3906 : * Query out of the rewrite operation to stuff back into the CTE node.
3907 : */
3908 348 : if (list_length(newstuff) == 1)
3909 : {
3910 : /* Must check it's not a utility command */
3911 324 : ctequery = linitial_node(Query, newstuff);
3912 324 : if (!(ctequery->commandType == CMD_SELECT ||
3913 324 : ctequery->commandType == CMD_UPDATE ||
3914 240 : ctequery->commandType == CMD_INSERT ||
3915 84 : ctequery->commandType == CMD_DELETE ||
3916 30 : ctequery->commandType == CMD_MERGE))
3917 : {
3918 : /*
3919 : * Currently it could only be NOTIFY; this error message will
3920 : * need work if we ever allow other utility commands in rules.
3921 : */
3922 6 : ereport(ERROR,
3923 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3924 : errmsg("DO INSTEAD NOTIFY rules are not supported for data-modifying statements in WITH")));
3925 : }
3926 : /* WITH queries should never be canSetTag */
3927 : Assert(!ctequery->canSetTag);
3928 : /* Push the single Query back into the CTE node */
3929 318 : cte->ctequery = (Node *) ctequery;
3930 : }
3931 24 : else if (newstuff == NIL)
3932 : {
3933 6 : ereport(ERROR,
3934 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3935 : errmsg("DO INSTEAD NOTHING rules are not supported for data-modifying statements in WITH")));
3936 : }
3937 : else
3938 : {
3939 : ListCell *lc2;
3940 :
3941 : /* examine queries to determine which error message to issue */
3942 42 : foreach(lc2, newstuff)
3943 : {
3944 36 : Query *q = (Query *) lfirst(lc2);
3945 :
3946 36 : if (q->querySource == QSRC_QUAL_INSTEAD_RULE)
3947 6 : ereport(ERROR,
3948 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3949 : errmsg("conditional DO INSTEAD rules are not supported for data-modifying statements in WITH")));
3950 30 : if (q->querySource == QSRC_NON_INSTEAD_RULE)
3951 6 : ereport(ERROR,
3952 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3953 : errmsg("DO ALSO rules are not supported for data-modifying statements in WITH")));
3954 : }
3955 :
3956 6 : ereport(ERROR,
3957 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3958 : errmsg("multi-statement DO INSTEAD rules are not supported for data-modifying statements in WITH")));
3959 : }
3960 : }
3961 :
3962 : /*
3963 : * If the statement is an insert, update, delete, or merge, adjust its
3964 : * targetlist as needed, and then fire INSERT/UPDATE/DELETE rules on it.
3965 : *
3966 : * SELECT rules are handled later when we have all the queries that should
3967 : * get executed. Also, utilities aren't rewritten at all (do we still
3968 : * need that check?)
3969 : */
3970 455426 : if (event != CMD_SELECT && event != CMD_UTILITY)
3971 : {
3972 : int result_relation;
3973 : RangeTblEntry *rt_entry;
3974 : Relation rt_entry_relation;
3975 : List *locks;
3976 : int product_orig_rt_length;
3977 : List *product_queries;
3978 96428 : bool hasUpdate = false;
3979 96428 : int values_rte_index = 0;
3980 96428 : bool defaults_remaining = false;
3981 :
3982 96428 : result_relation = parsetree->resultRelation;
3983 : Assert(result_relation != 0);
3984 96428 : rt_entry = rt_fetch(result_relation, parsetree->rtable);
3985 : Assert(rt_entry->rtekind == RTE_RELATION);
3986 :
3987 : /*
3988 : * We can use NoLock here since either the parser or
3989 : * AcquireRewriteLocks should have locked the rel already.
3990 : */
3991 96428 : rt_entry_relation = table_open(rt_entry->relid, NoLock);
3992 :
3993 : /*
3994 : * Rewrite the targetlist as needed for the command type.
3995 : */
3996 96428 : if (event == CMD_INSERT)
3997 : {
3998 : ListCell *lc2;
3999 74210 : RangeTblEntry *values_rte = NULL;
4000 :
4001 : /*
4002 : * Test if it's a multi-row INSERT ... VALUES (...), (...), ... by
4003 : * looking for a VALUES RTE in the fromlist. For product queries,
4004 : * we must ignore any already-processed VALUES RTEs from the
4005 : * original query. These appear at the start of the rangetable.
4006 : */
4007 86580 : foreach(lc2, parsetree->jointree->fromlist)
4008 : {
4009 12370 : RangeTblRef *rtr = (RangeTblRef *) lfirst(lc2);
4010 :
4011 12370 : if (IsA(rtr, RangeTblRef) && rtr->rtindex > orig_rt_length)
4012 : {
4013 12046 : RangeTblEntry *rte = rt_fetch(rtr->rtindex,
4014 : parsetree->rtable);
4015 :
4016 12046 : if (rte->rtekind == RTE_VALUES)
4017 : {
4018 : /* should not find more than one VALUES RTE */
4019 4878 : if (values_rte != NULL)
4020 0 : elog(ERROR, "more than one VALUES RTE found");
4021 :
4022 4878 : values_rte = rte;
4023 4878 : values_rte_index = rtr->rtindex;
4024 : }
4025 : }
4026 : }
4027 :
4028 74210 : if (values_rte)
4029 : {
4030 4878 : Bitmapset *unused_values_attrnos = NULL;
4031 :
4032 : /* Process the main targetlist ... */
4033 4878 : parsetree->targetList = rewriteTargetListIU(parsetree->targetList,
4034 : parsetree->commandType,
4035 : parsetree->override,
4036 : rt_entry_relation,
4037 : values_rte,
4038 : values_rte_index,
4039 : &unused_values_attrnos);
4040 : /* ... and the VALUES expression lists */
4041 4776 : if (!rewriteValuesRTE(parsetree, values_rte, values_rte_index,
4042 : rt_entry_relation,
4043 : unused_values_attrnos))
4044 78 : defaults_remaining = true;
4045 : }
4046 : else
4047 : {
4048 : /* Process just the main targetlist */
4049 69254 : parsetree->targetList =
4050 69332 : rewriteTargetListIU(parsetree->targetList,
4051 : parsetree->commandType,
4052 : parsetree->override,
4053 : rt_entry_relation,
4054 : NULL, 0, NULL);
4055 : }
4056 :
4057 74030 : if (parsetree->onConflict &&
4058 2006 : parsetree->onConflict->action == ONCONFLICT_UPDATE)
4059 : {
4060 1432 : parsetree->onConflict->onConflictSet =
4061 1432 : rewriteTargetListIU(parsetree->onConflict->onConflictSet,
4062 : CMD_UPDATE,
4063 : parsetree->override,
4064 : rt_entry_relation,
4065 : NULL, 0, NULL);
4066 : }
4067 : }
4068 22218 : else if (event == CMD_UPDATE)
4069 : {
4070 : Assert(parsetree->override == OVERRIDING_NOT_SET);
4071 14652 : parsetree->targetList =
4072 14682 : rewriteTargetListIU(parsetree->targetList,
4073 : parsetree->commandType,
4074 : parsetree->override,
4075 : rt_entry_relation,
4076 : NULL, 0, NULL);
4077 : }
4078 7536 : else if (event == CMD_MERGE)
4079 : {
4080 : Assert(parsetree->override == OVERRIDING_NOT_SET);
4081 :
4082 : /*
4083 : * Rewrite each action targetlist separately
4084 : */
4085 6828 : foreach(lc1, parsetree->mergeActionList)
4086 : {
4087 4038 : MergeAction *action = (MergeAction *) lfirst(lc1);
4088 :
4089 4038 : switch (action->commandType)
4090 : {
4091 716 : case CMD_NOTHING:
4092 : case CMD_DELETE: /* Nothing to do here */
4093 716 : break;
4094 3322 : case CMD_UPDATE:
4095 : case CMD_INSERT:
4096 :
4097 : /*
4098 : * MERGE actions do not permit multi-row INSERTs, so
4099 : * there is no VALUES RTE to deal with here.
4100 : */
4101 3316 : action->targetList =
4102 3322 : rewriteTargetListIU(action->targetList,
4103 : action->commandType,
4104 : action->override,
4105 : rt_entry_relation,
4106 : NULL, 0, NULL);
4107 3316 : break;
4108 0 : default:
4109 0 : elog(ERROR, "unrecognized commandType: %d", action->commandType);
4110 : break;
4111 : }
4112 : }
4113 : }
4114 4740 : else if (event == CMD_DELETE)
4115 : {
4116 : /* Nothing to do here */
4117 : }
4118 : else
4119 0 : elog(ERROR, "unrecognized commandType: %d", (int) event);
4120 :
4121 : /*
4122 : * Collect and apply the appropriate rules.
4123 : */
4124 96212 : locks = matchLocks(event, rt_entry_relation,
4125 : result_relation, parsetree, &hasUpdate);
4126 :
4127 96194 : product_orig_rt_length = list_length(parsetree->rtable);
4128 96194 : product_queries = fireRules(parsetree,
4129 : result_relation,
4130 : event,
4131 : locks,
4132 : &instead,
4133 : &returning,
4134 : &qual_product);
4135 :
4136 : /*
4137 : * If we have a VALUES RTE with any remaining untouched DEFAULT items,
4138 : * and we got any product queries, finalize the VALUES RTE for each
4139 : * product query (replacing the remaining DEFAULT items with NULLs).
4140 : * We don't do this for the original query, because we know that it
4141 : * must be an auto-insert on a view, and so should use the base
4142 : * relation's defaults for any remaining DEFAULT items.
4143 : */
4144 96188 : if (defaults_remaining && product_queries != NIL)
4145 : {
4146 : ListCell *n;
4147 :
4148 : /*
4149 : * Each product query has its own copy of the VALUES RTE at the
4150 : * same index in the rangetable, so we must finalize each one.
4151 : *
4152 : * Note that if the product query is an INSERT ... SELECT, then
4153 : * the VALUES RTE will be at the same index in the SELECT part of
4154 : * the product query rather than the top-level product query
4155 : * itself.
4156 : */
4157 48 : foreach(n, product_queries)
4158 : {
4159 24 : Query *pt = (Query *) lfirst(n);
4160 : RangeTblEntry *values_rte;
4161 :
4162 24 : if (pt->commandType == CMD_INSERT &&
4163 48 : pt->jointree && IsA(pt->jointree, FromExpr) &&
4164 24 : list_length(pt->jointree->fromlist) == 1)
4165 : {
4166 24 : Node *jtnode = (Node *) linitial(pt->jointree->fromlist);
4167 :
4168 24 : if (IsA(jtnode, RangeTblRef))
4169 : {
4170 24 : int rtindex = ((RangeTblRef *) jtnode)->rtindex;
4171 24 : RangeTblEntry *src_rte = rt_fetch(rtindex, pt->rtable);
4172 :
4173 24 : if (src_rte->rtekind == RTE_SUBQUERY &&
4174 6 : src_rte->subquery &&
4175 6 : IsA(src_rte->subquery, Query) &&
4176 6 : src_rte->subquery->commandType == CMD_SELECT)
4177 6 : pt = src_rte->subquery;
4178 : }
4179 : }
4180 :
4181 24 : values_rte = rt_fetch(values_rte_index, pt->rtable);
4182 24 : if (values_rte->rtekind != RTE_VALUES)
4183 0 : elog(ERROR, "failed to find VALUES RTE in product query");
4184 :
4185 24 : rewriteValuesRTEToNulls(pt, values_rte);
4186 : }
4187 : }
4188 :
4189 : /*
4190 : * If there was no unqualified INSTEAD rule, and the target relation
4191 : * is a view without any INSTEAD OF triggers, see if the view can be
4192 : * automatically updated. If so, we perform the necessary query
4193 : * transformation here and add the resulting query to the
4194 : * product_queries list, so that it gets recursively rewritten if
4195 : * necessary. For MERGE, the view must be automatically updatable if
4196 : * any of the merge actions lack a corresponding INSTEAD OF trigger.
4197 : *
4198 : * If the view cannot be automatically updated, we throw an error here
4199 : * which is OK since the query would fail at runtime anyway. Throwing
4200 : * the error here is preferable to the executor check since we have
4201 : * more detailed information available about why the view isn't
4202 : * updatable.
4203 : */
4204 96188 : if (!instead &&
4205 95498 : rt_entry_relation->rd_rel->relkind == RELKIND_VIEW &&
4206 3914 : !view_has_instead_trigger(rt_entry_relation, event,
4207 : parsetree->mergeActionList))
4208 : {
4209 : /*
4210 : * If there were any qualified INSTEAD rules, don't allow the view
4211 : * to be automatically updated (an unqualified INSTEAD rule or
4212 : * INSTEAD OF trigger is required).
4213 : */
4214 3506 : if (qual_product != NULL)
4215 18 : error_view_not_updatable(rt_entry_relation,
4216 : parsetree->commandType,
4217 : parsetree->mergeActionList,
4218 : gettext_noop("Views with conditional DO INSTEAD rules are not automatically updatable."));
4219 :
4220 : /*
4221 : * Attempt to rewrite the query to automatically update the view.
4222 : * This throws an error if the view can't be automatically
4223 : * updated.
4224 : */
4225 3488 : parsetree = rewriteTargetView(parsetree, rt_entry_relation);
4226 :
4227 : /*
4228 : * At this point product_queries contains any DO ALSO rule
4229 : * actions. Add the rewritten query before or after those. This
4230 : * must match the handling the original query would have gotten
4231 : * below, if we allowed it to be included again.
4232 : */
4233 3218 : if (parsetree->commandType == CMD_INSERT)
4234 1104 : product_queries = lcons(parsetree, product_queries);
4235 : else
4236 2114 : product_queries = lappend(product_queries, parsetree);
4237 :
4238 : /*
4239 : * Set the "instead" flag, as if there had been an unqualified
4240 : * INSTEAD, to prevent the original query from being included a
4241 : * second time below. The transformation will have rewritten any
4242 : * RETURNING list, so we can also set "returning" to forestall
4243 : * throwing an error below.
4244 : */
4245 3218 : instead = true;
4246 3218 : returning = true;
4247 3218 : updatableview = true;
4248 : }
4249 :
4250 : /*
4251 : * If we got any product queries, recursively rewrite them --- but
4252 : * first check for recursion!
4253 : */
4254 95900 : if (product_queries != NIL)
4255 : {
4256 : ListCell *n;
4257 : rewrite_event *rev;
4258 :
4259 5282 : foreach(n, rewrite_events)
4260 : {
4261 942 : rev = (rewrite_event *) lfirst(n);
4262 942 : if (rev->relation == RelationGetRelid(rt_entry_relation) &&
4263 0 : rev->event == event)
4264 0 : ereport(ERROR,
4265 : (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
4266 : errmsg("infinite recursion detected in rules for relation \"%s\"",
4267 : RelationGetRelationName(rt_entry_relation))));
4268 : }
4269 :
4270 4340 : rev = (rewrite_event *) palloc(sizeof(rewrite_event));
4271 4340 : rev->relation = RelationGetRelid(rt_entry_relation);
4272 4340 : rev->event = event;
4273 4340 : rewrite_events = lappend(rewrite_events, rev);
4274 :
4275 8770 : foreach(n, product_queries)
4276 : {
4277 4574 : Query *pt = (Query *) lfirst(n);
4278 : List *newstuff;
4279 :
4280 : /*
4281 : * For an updatable view, pt might be the rewritten version of
4282 : * the original query, in which case we pass on orig_rt_length
4283 : * to finish processing any VALUES RTE it contained.
4284 : *
4285 : * Otherwise, we have a product query created by fireRules().
4286 : * Any VALUES RTEs from the original query have been fully
4287 : * processed, and must be skipped when we recurse.
4288 : */
4289 4574 : newstuff = RewriteQuery(pt, rewrite_events,
4290 : pt == parsetree ?
4291 : orig_rt_length :
4292 : product_orig_rt_length);
4293 4430 : rewritten = list_concat(rewritten, newstuff);
4294 : }
4295 :
4296 4196 : rewrite_events = list_delete_last(rewrite_events);
4297 : }
4298 :
4299 : /*
4300 : * If there is an INSTEAD, and the original query has a RETURNING, we
4301 : * have to have found a RETURNING in the rule(s), else fail. (Because
4302 : * DefineQueryRewrite only allows RETURNING in unconditional INSTEAD
4303 : * rules, there's no need to worry whether the substituted RETURNING
4304 : * will actually be executed --- it must be.)
4305 : */
4306 95756 : if ((instead || qual_product != NULL) &&
4307 4076 : parsetree->returningList &&
4308 366 : !returning)
4309 : {
4310 6 : switch (event)
4311 : {
4312 6 : case CMD_INSERT:
4313 6 : ereport(ERROR,
4314 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4315 : errmsg("cannot perform INSERT RETURNING on relation \"%s\"",
4316 : RelationGetRelationName(rt_entry_relation)),
4317 : errhint("You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause.")));
4318 : break;
4319 0 : case CMD_UPDATE:
4320 0 : ereport(ERROR,
4321 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4322 : errmsg("cannot perform UPDATE RETURNING on relation \"%s\"",
4323 : RelationGetRelationName(rt_entry_relation)),
4324 : errhint("You need an unconditional ON UPDATE DO INSTEAD rule with a RETURNING clause.")));
4325 : break;
4326 0 : case CMD_DELETE:
4327 0 : ereport(ERROR,
4328 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4329 : errmsg("cannot perform DELETE RETURNING on relation \"%s\"",
4330 : RelationGetRelationName(rt_entry_relation)),
4331 : errhint("You need an unconditional ON DELETE DO INSTEAD rule with a RETURNING clause.")));
4332 : break;
4333 0 : default:
4334 0 : elog(ERROR, "unrecognized commandType: %d",
4335 : (int) event);
4336 : break;
4337 : }
4338 : }
4339 :
4340 : /*
4341 : * Updatable views are supported by ON CONFLICT, so don't prevent that
4342 : * case from proceeding
4343 : */
4344 95750 : if (parsetree->onConflict &&
4345 1814 : (product_queries != NIL || hasUpdate) &&
4346 180 : !updatableview)
4347 12 : ereport(ERROR,
4348 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4349 : errmsg("INSERT with ON CONFLICT clause cannot be used with table that has INSERT or UPDATE rules")));
4350 :
4351 95738 : table_close(rt_entry_relation, NoLock);
4352 : }
4353 :
4354 : /*
4355 : * For INSERTs, the original query is done first; for UPDATE/DELETE, it is
4356 : * done last. This is needed because update and delete rule actions might
4357 : * not do anything if they are invoked after the update or delete is
4358 : * performed. The command counter increment between the query executions
4359 : * makes the deleted (and maybe the updated) tuples disappear so the scans
4360 : * for them in the rule actions cannot find them.
4361 : *
4362 : * If we found any unqualified INSTEAD, the original query is not done at
4363 : * all, in any form. Otherwise, we add the modified form if qualified
4364 : * INSTEADs were found, else the unmodified form.
4365 : */
4366 454736 : if (!instead)
4367 : {
4368 450990 : if (parsetree->commandType == CMD_INSERT)
4369 : {
4370 72440 : if (qual_product != NULL)
4371 294 : rewritten = lcons(qual_product, rewritten);
4372 : else
4373 72146 : rewritten = lcons(parsetree, rewritten);
4374 : }
4375 : else
4376 : {
4377 378550 : if (qual_product != NULL)
4378 18 : rewritten = lappend(rewritten, qual_product);
4379 : else
4380 378532 : rewritten = lappend(rewritten, parsetree);
4381 : }
4382 : }
4383 :
4384 : /*
4385 : * If the original query has a CTE list, and we generated more than one
4386 : * non-utility result query, we have to fail because we'll have copied the
4387 : * CTE list into each result query. That would break the expectation of
4388 : * single evaluation of CTEs. This could possibly be fixed by
4389 : * restructuring so that a CTE list can be shared across multiple Query
4390 : * and PlannableStatement nodes.
4391 : */
4392 454736 : if (parsetree->cteList != NIL)
4393 : {
4394 2464 : int qcount = 0;
4395 :
4396 4928 : foreach(lc1, rewritten)
4397 : {
4398 2464 : Query *q = (Query *) lfirst(lc1);
4399 :
4400 2464 : if (q->commandType != CMD_UTILITY)
4401 2464 : qcount++;
4402 : }
4403 2464 : if (qcount > 1)
4404 0 : ereport(ERROR,
4405 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4406 : errmsg("WITH cannot be used in a query that is rewritten by rules into multiple queries")));
4407 : }
4408 :
4409 454736 : return rewritten;
4410 : }
4411 :
4412 :
4413 : /*
4414 : * Expand virtual generated columns
4415 : *
4416 : * If the table contains virtual generated columns, build a target list
4417 : * containing the expanded expressions and use ReplaceVarsFromTargetList() to
4418 : * do the replacements.
4419 : *
4420 : * Vars matching rt_index at the current query level are replaced by the
4421 : * virtual generated column expressions from rel, if there are any.
4422 : *
4423 : * The caller must also provide rte, the RTE describing the target relation,
4424 : * in order to handle any whole-row Vars referencing the target, and
4425 : * result_relation, the index of the result relation, if this is part of an
4426 : * INSERT/UPDATE/DELETE/MERGE query.
4427 : */
4428 : static Node *
4429 260 : expand_generated_columns_internal(Node *node, Relation rel, int rt_index,
4430 : RangeTblEntry *rte, int result_relation)
4431 : {
4432 : TupleDesc tupdesc;
4433 :
4434 260 : tupdesc = RelationGetDescr(rel);
4435 260 : if (tupdesc->constr && tupdesc->constr->has_generated_virtual)
4436 : {
4437 260 : List *tlist = NIL;
4438 :
4439 922 : for (int i = 0; i < tupdesc->natts; i++)
4440 : {
4441 662 : Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
4442 :
4443 662 : if (attr->attgenerated == ATTRIBUTE_GENERATED_VIRTUAL)
4444 : {
4445 : Node *defexpr;
4446 : TargetEntry *te;
4447 :
4448 278 : defexpr = build_generation_expression(rel, i + 1);
4449 278 : ChangeVarNodes(defexpr, 1, rt_index, 0);
4450 :
4451 278 : te = makeTargetEntry((Expr *) defexpr, i + 1, 0, false);
4452 278 : tlist = lappend(tlist, te);
4453 : }
4454 : }
4455 :
4456 : Assert(list_length(tlist) > 0);
4457 :
4458 260 : node = ReplaceVarsFromTargetList(node, rt_index, 0, rte, tlist,
4459 : result_relation,
4460 : REPLACEVARS_CHANGE_VARNO, rt_index,
4461 : NULL);
4462 : }
4463 :
4464 260 : return node;
4465 : }
4466 :
4467 : /*
4468 : * Expand virtual generated columns in an expression
4469 : *
4470 : * This is for expressions that are not part of a query, such as default
4471 : * expressions or index predicates. The rt_index is usually 1.
4472 : */
4473 : Node *
4474 4874 : expand_generated_columns_in_expr(Node *node, Relation rel, int rt_index)
4475 : {
4476 4874 : TupleDesc tupdesc = RelationGetDescr(rel);
4477 :
4478 4874 : if (tupdesc->constr && tupdesc->constr->has_generated_virtual)
4479 : {
4480 : RangeTblEntry *rte;
4481 :
4482 260 : rte = makeNode(RangeTblEntry);
4483 : /* eref needs to be set, but the actual name doesn't matter */
4484 260 : rte->eref = makeAlias(RelationGetRelationName(rel), NIL);
4485 260 : rte->rtekind = RTE_RELATION;
4486 260 : rte->relid = RelationGetRelid(rel);
4487 :
4488 260 : node = expand_generated_columns_internal(node, rel, rt_index, rte, 0);
4489 : }
4490 :
4491 4874 : return node;
4492 : }
4493 :
4494 : /*
4495 : * Build the generation expression for the virtual generated column.
4496 : *
4497 : * Error out if there is no generation expression found for the given column.
4498 : */
4499 : Node *
4500 1766 : build_generation_expression(Relation rel, int attrno)
4501 : {
4502 1766 : TupleDesc rd_att = RelationGetDescr(rel);
4503 1766 : Form_pg_attribute att_tup = TupleDescAttr(rd_att, attrno - 1);
4504 : Node *defexpr;
4505 : Oid attcollid;
4506 :
4507 : Assert(rd_att->constr && rd_att->constr->has_generated_virtual);
4508 : Assert(att_tup->attgenerated == ATTRIBUTE_GENERATED_VIRTUAL);
4509 :
4510 1766 : defexpr = build_column_default(rel, attrno);
4511 1766 : if (defexpr == NULL)
4512 0 : elog(ERROR, "no generation expression found for column number %d of table \"%s\"",
4513 : attrno, RelationGetRelationName(rel));
4514 :
4515 : /*
4516 : * If the column definition has a collation and it is different from the
4517 : * collation of the generation expression, put a COLLATE clause around the
4518 : * expression.
4519 : */
4520 1766 : attcollid = att_tup->attcollation;
4521 1766 : if (attcollid && attcollid != exprCollation(defexpr))
4522 : {
4523 12 : CollateExpr *ce = makeNode(CollateExpr);
4524 :
4525 12 : ce->arg = (Expr *) defexpr;
4526 12 : ce->collOid = attcollid;
4527 12 : ce->location = -1;
4528 :
4529 12 : defexpr = (Node *) ce;
4530 : }
4531 :
4532 1766 : return defexpr;
4533 : }
4534 :
4535 :
4536 : /*
4537 : * QueryRewrite -
4538 : * Primary entry point to the query rewriter.
4539 : * Rewrite one query via query rewrite system, possibly returning 0
4540 : * or many queries.
4541 : *
4542 : * NOTE: the parsetree must either have come straight from the parser,
4543 : * or have been scanned by AcquireRewriteLocks to acquire suitable locks.
4544 : */
4545 : List *
4546 450534 : QueryRewrite(Query *parsetree)
4547 : {
4548 450534 : int64 input_query_id = parsetree->queryId;
4549 : List *querylist;
4550 : List *results;
4551 : ListCell *l;
4552 : CmdType origCmdType;
4553 : bool foundOriginalQuery;
4554 : Query *lastInstead;
4555 :
4556 : /*
4557 : * This function is only applied to top-level original queries
4558 : */
4559 : Assert(parsetree->querySource == QSRC_ORIGINAL);
4560 : Assert(parsetree->canSetTag);
4561 :
4562 : /*
4563 : * Step 1
4564 : *
4565 : * Apply all non-SELECT rules possibly getting 0 or many queries
4566 : */
4567 450534 : querylist = RewriteQuery(parsetree, NIL, 0);
4568 :
4569 : /*
4570 : * Step 2
4571 : *
4572 : * Apply all the RIR rules on each query
4573 : *
4574 : * This is also a handy place to mark each query with the original queryId
4575 : */
4576 449958 : results = NIL;
4577 900456 : foreach(l, querylist)
4578 : {
4579 450612 : Query *query = (Query *) lfirst(l);
4580 :
4581 450612 : query = fireRIRrules(query, NIL);
4582 :
4583 450498 : query->queryId = input_query_id;
4584 :
4585 450498 : results = lappend(results, query);
4586 : }
4587 :
4588 : /*
4589 : * Step 3
4590 : *
4591 : * Determine which, if any, of the resulting queries is supposed to set
4592 : * the command-result tag; and update the canSetTag fields accordingly.
4593 : *
4594 : * If the original query is still in the list, it sets the command tag.
4595 : * Otherwise, the last INSTEAD query of the same kind as the original is
4596 : * allowed to set the tag. (Note these rules can leave us with no query
4597 : * setting the tag. The tcop code has to cope with this by setting up a
4598 : * default tag based on the original un-rewritten query.)
4599 : *
4600 : * The Asserts verify that at most one query in the result list is marked
4601 : * canSetTag. If we aren't checking asserts, we can fall out of the loop
4602 : * as soon as we find the original query.
4603 : */
4604 449844 : origCmdType = parsetree->commandType;
4605 449844 : foundOriginalQuery = false;
4606 449844 : lastInstead = NULL;
4607 :
4608 450684 : foreach(l, results)
4609 : {
4610 450042 : Query *query = (Query *) lfirst(l);
4611 :
4612 450042 : if (query->querySource == QSRC_ORIGINAL)
4613 : {
4614 : Assert(query->canSetTag);
4615 : Assert(!foundOriginalQuery);
4616 449202 : foundOriginalQuery = true;
4617 : #ifndef USE_ASSERT_CHECKING
4618 449202 : break;
4619 : #endif
4620 : }
4621 : else
4622 : {
4623 : Assert(!query->canSetTag);
4624 840 : if (query->commandType == origCmdType &&
4625 624 : (query->querySource == QSRC_INSTEAD_RULE ||
4626 108 : query->querySource == QSRC_QUAL_INSTEAD_RULE))
4627 564 : lastInstead = query;
4628 : }
4629 : }
4630 :
4631 449844 : if (!foundOriginalQuery && lastInstead != NULL)
4632 540 : lastInstead->canSetTag = true;
4633 :
4634 449844 : return results;
4635 : }
|