Skip to content

Commit 04942bf

Browse files
committed
Remove rewriteTargetListIU's expansion of view targetlists in UPDATE.
Commit 2ec993a, which added triggers on views, modified the rewriter to add dummy entries like "SET x = x" for all columns that weren't actually being updated by the user in any UPDATE directed at a view. That was needed at the time to produce a complete "NEW" row to pass to the trigger. Later it was found to cause problems for ordinary updatable views, so commit cab5dc5 restricted it to happen only for trigger-updatable views. But in the wake of commit 86dc900, we really don't need it at all. nodeModifyTable.c populates the trigger "OLD" row from the whole-row variable that is generated for the view, and then it computes the "NEW" row using that old row and the UPDATE targetlist. So there is no need for the UPDATE tlist to have dummy entries, any more than it needs them for regular tables or other types of views. (The comments for rewriteTargetListIU suggest that we must do this for correct expansion of NEW references in rules, but I now think that that was just lazy comment editing in 2ec993a. If we didn't need it for rules on views before there were triggers, we don't need it after that.) This essentially propagates 86dc900's decision that we don't need dummy column updates into the view case. Aside from making the different cases more uniform and hence possibly forestalling future bugs, it ought to save a little bit of rewriter/planner effort. Discussion: https://postgr.es/m/2181213.1619397634@sss.pgh.pa.us
1 parent 79a5928 commit 04942bf

File tree

1 file changed

+4
-38
lines changed

1 file changed

+4
-38
lines changed

src/backend/rewrite/rewriteHandler.c

+4-38
Original file line numberDiff line numberDiff line change
@@ -679,30 +679,19 @@ adjustJoinTreeList(Query *parsetree, bool removert, int rt_index)
679679
* and UPDATE, replace explicit DEFAULT specifications with column default
680680
* expressions.
681681
*
682-
* 2. For an UPDATE on a trigger-updatable view, add tlist entries for any
683-
* unassigned-to attributes, assigning them their old values. These will
684-
* later get expanded to the output values of the view. This is only needed
685-
* for trigger-updatable views, for which the view remains the result relation
686-
* of the query; without it, we would not have a complete "new tuple" to pass
687-
* to triggers. For auto-updatable views we must not do this, since it might
688-
* add assignments to non-updatable view columns. For rule-updatable views it
689-
* is unnecessary extra work, since the query will be rewritten with a
690-
* different result relation which will be processed when we recurse via
691-
* RewriteQuery.
692-
*
693-
* 3. Merge multiple entries for the same target attribute, or declare error
682+
* 2. Merge multiple entries for the same target attribute, or declare error
694683
* if we can't. Multiple entries are only allowed for INSERT/UPDATE of
695684
* portions of an array or record field, for example
696685
* UPDATE table SET foo[2] = 42, foo[4] = 43;
697686
* We can merge such operations into a single assignment op. Essentially,
698687
* the expression we want to produce in this case is like
699688
* foo = array_set_element(array_set_element(foo, 2, 42), 4, 43)
700689
*
701-
* 4. Sort the tlist into standard order: non-junk fields in order by resno,
690+
* 3. Sort the tlist into standard order: non-junk fields in order by resno,
702691
* then junk fields (these in no particular order).
703692
*
704-
* We must do items 1,2,3 before firing rewrite rules, else rewritten
705-
* references to NEW.foo will produce wrong or incomplete results. Item 4
693+
* We must do items 1 and 2 before firing rewrite rules, else rewritten
694+
* references to NEW.foo will produce wrong or incomplete results. Item 3
706695
* is not needed for rewriting, but it is helpful for the planner, and we
707696
* can do it essentially for free while handling the other items.
708697
*
@@ -984,29 +973,6 @@ rewriteTargetListIU(List *targetList,
984973
false);
985974
}
986975

987-
/*
988-
* For an UPDATE on a trigger-updatable view, provide a dummy entry
989-
* whenever there is no explicit assignment.
990-
*/
991-
if (new_tle == NULL && commandType == CMD_UPDATE &&
992-
target_relation->rd_rel->relkind == RELKIND_VIEW &&
993-
view_has_instead_trigger(target_relation, CMD_UPDATE))
994-
{
995-
Node *new_expr;
996-
997-
new_expr = (Node *) makeVar(result_rti,
998-
attrno,
999-
att_tup->atttypid,
1000-
att_tup->atttypmod,
1001-
att_tup->attcollation,
1002-
0);
1003-
1004-
new_tle = makeTargetEntry((Expr *) new_expr,
1005-
attrno,
1006-
pstrdup(NameStr(att_tup->attname)),
1007-
false);
1008-
}
1009-
1010976
if (new_tle)
1011977
new_tlist = lappend(new_tlist, new_tle);
1012978
}

0 commit comments

Comments
 (0)