Skip to content

Commit f054443

Browse files
committed
Expand comments and add an assertion in nodeModifyTable.c.
Most comments concern RELKIND_VIEW. One addresses the ExecUpdate() "tupleid" parameter. A later commit will rely on these facts, but they hold already. Back-patch to v12 (all supported versions), the plan for that commit. Reviewed (in an earlier version) by Robert Haas. Discussion: https://postgr.es/m/20240512232923.aa.nmisch@google.com
1 parent 3c6becd commit f054443

File tree

1 file changed

+32
-23
lines changed

1 file changed

+32
-23
lines changed

src/backend/executor/nodeModifyTable.c

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@
2424
* values plus row-locating info for UPDATE and MERGE cases, or just the
2525
* row-locating info for DELETE cases.
2626
*
27+
* The relation to modify can be an ordinary table, a view having an
28+
* INSTEAD OF trigger, or a foreign table. Earlier processing already
29+
* pointed ModifyTable to the underlying relations of any automatically
30+
* updatable view not using an INSTEAD OF trigger, so code here can
31+
* assume it won't have one as a modification target. This node does
32+
* process ri_WithCheckOptions, which may have expressions from those
33+
* automatically updatable views.
34+
*
2735
* MERGE runs a join between the source relation and the target
2836
* table; if any WHEN NOT MATCHED clauses are present, then the
2937
* join is an outer join. In this case, any unmatched tuples will
@@ -1380,18 +1388,18 @@ ExecDeleteEpilogue(ModifyTableContext *context, ResultRelInfo *resultRelInfo,
13801388
* DELETE is like UPDATE, except that we delete the tuple and no
13811389
* index modifications are needed.
13821390
*
1383-
* When deleting from a table, tupleid identifies the tuple to
1384-
* delete and oldtuple is NULL. When deleting from a view,
1385-
* oldtuple is passed to the INSTEAD OF triggers and identifies
1386-
* what to delete, and tupleid is invalid. When deleting from a
1387-
* foreign table, tupleid is invalid; the FDW has to figure out
1388-
* which row to delete using data from the planSlot. oldtuple is
1389-
* passed to foreign table triggers; it is NULL when the foreign
1390-
* table has no relevant triggers. We use tupleDeleted to indicate
1391-
* whether the tuple is actually deleted, callers can use it to
1392-
* decide whether to continue the operation. When this DELETE is a
1393-
* part of an UPDATE of partition-key, then the slot returned by
1394-
* EvalPlanQual() is passed back using output parameter epqreturnslot.
1391+
* When deleting from a table, tupleid identifies the tuple to delete and
1392+
* oldtuple is NULL. When deleting through a view INSTEAD OF trigger,
1393+
* oldtuple is passed to the triggers and identifies what to delete, and
1394+
* tupleid is invalid. When deleting from a foreign table, tupleid is
1395+
* invalid; the FDW has to figure out which row to delete using data from
1396+
* the planSlot. oldtuple is passed to foreign table triggers; it is
1397+
* NULL when the foreign table has no relevant triggers. We use
1398+
* tupleDeleted to indicate whether the tuple is actually deleted,
1399+
* callers can use it to decide whether to continue the operation. When
1400+
* this DELETE is a part of an UPDATE of partition-key, then the slot
1401+
* returned by EvalPlanQual() is passed back using output parameter
1402+
* epqreturnslot.
13951403
*
13961404
* Returns RETURNING result if any, otherwise NULL.
13971405
* ----------------------------------------------------------------
@@ -2225,21 +2233,22 @@ ExecCrossPartitionUpdateForeignKey(ModifyTableContext *context,
22252233
* is, we don't want to get stuck in an infinite loop
22262234
* which corrupts your database..
22272235
*
2228-
* When updating a table, tupleid identifies the tuple to
2229-
* update and oldtuple is NULL. When updating a view, oldtuple
2230-
* is passed to the INSTEAD OF triggers and identifies what to
2231-
* update, and tupleid is invalid. When updating a foreign table,
2232-
* tupleid is invalid; the FDW has to figure out which row to
2233-
* update using data from the planSlot. oldtuple is passed to
2234-
* foreign table triggers; it is NULL when the foreign table has
2235-
* no relevant triggers.
2236+
* When updating a table, tupleid identifies the tuple to update and
2237+
* oldtuple is NULL. When updating through a view INSTEAD OF trigger,
2238+
* oldtuple is passed to the triggers and identifies what to update, and
2239+
* tupleid is invalid. When updating a foreign table, tupleid is
2240+
* invalid; the FDW has to figure out which row to update using data from
2241+
* the planSlot. oldtuple is passed to foreign table triggers; it is
2242+
* NULL when the foreign table has no relevant triggers.
22362243
*
22372244
* slot contains the new tuple value to be stored.
22382245
* planSlot is the output of the ModifyTable's subplan; we use it
22392246
* to access values from other input tables (for RETURNING),
22402247
* row-ID junk columns, etc.
22412248
*
2242-
* Returns RETURNING result if any, otherwise NULL.
2249+
* Returns RETURNING result if any, otherwise NULL. On exit, if tupleid
2250+
* had identified the tuple to update, it will identify the tuple
2251+
* actually updated after EvalPlanQual.
22432252
* ----------------------------------------------------------------
22442253
*/
22452254
static TupleTableSlot *
@@ -3781,8 +3790,8 @@ ExecModifyTable(PlanState *pstate)
37813790
* know enough here to set t_tableOid. Quite separately from
37823791
* this, the FDW may fetch its own junk attrs to identify the row.
37833792
*
3784-
* Other relevant relkinds, currently limited to views, always
3785-
* have a wholerow attribute.
3793+
* Other relevant relkinds, currently limited to views having
3794+
* INSTEAD OF triggers, always have a wholerow attribute.
37863795
*/
37873796
else if (AttributeNumberIsValid(resultRelInfo->ri_RowIdAttNo))
37883797
{

0 commit comments

Comments
 (0)