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