postgres.git / summary / log / commit / refs

commit    fea47de3016ac8bc29bce10382220a457d2ef57f
Author:   Noah Misch <noah@leadboat.com>
Date:     Fri Jun 28 02:21:05 2024 +0000
First released in: 17.0, 12.20, 13.16, 14.13, 15.8, 16.4

    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


src/backend/executor/nodeModifyTable.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index e64b355eecb..8c0f3126058 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -28,6 +28,14 @@ * rowtype, but we might still find that different plans are appropriate * for different child relations. * + * The relation to modify can be an ordinary table, a view having an + * INSTEAD OF trigger, or a foreign table. Earlier processing already + * pointed ModifyTable to the underlying relations of any automatically + * updatable view not using an INSTEAD OF trigger, so code here can + * assume it won't have one as a modification target. This node does + * process ri_WithCheckOptions, which may have expressions from those + * automatically updatable views. + * * If the query specifies RETURNING, then the ModifyTable returns a * RETURNING tuple after completing each row insert, update, or delete. * It must be called again to continue the operation. Without RETURNING, @@ -729,8 +737,8 @@ ExecInsert(ModifyTableState *mtstate, * index modifications are needed. * * When deleting from a table, tupleid identifies the tuple to - * delete and oldtuple is NULL. When deleting from a view, - * oldtuple is passed to the INSTEAD OF triggers and identifies + * delete and oldtuple is NULL. When deleting through a view + * INSTEAD OF trigger, oldtuple is passed to the triggers and identifies * what to delete, and tupleid is invalid. When deleting from a * foreign table, tupleid is invalid; the FDW has to figure out * which row to delete using data from the planSlot. oldtuple is @@ -1095,15 +1103,17 @@ ldelete:; * which corrupts your database.. * * When updating a table, tupleid identifies the tuple to - * update and oldtuple is NULL. When updating a view, oldtuple - * is passed to the INSTEAD OF triggers and identifies what to + * update and oldtuple is NULL. When updating through a view INSTEAD OF + * trigger, oldtuple is passed to the triggers and identifies what to * update, and tupleid is invalid. When updating a foreign table, * tupleid is invalid; the FDW has to figure out which row to * update using data from the planSlot. oldtuple is passed to * foreign table triggers; it is NULL when the foreign table has * no relevant triggers. * - * Returns RETURNING result if any, otherwise NULL. + * Returns RETURNING result if any, otherwise NULL. On exit, if tupleid + * had identified the tuple to update, it will identify the tuple + * actually updated after EvalPlanQual. * ---------------------------------------------------------------- */ static TupleTableSlot * @@ -2255,8 +2265,8 @@ ExecModifyTable(PlanState *pstate) * to set t_tableOid. Quite separately from this, the FDW may * fetch its own junk attrs to identify the row. * - * Other relevant relkinds, currently limited to views, always - * have a wholerow attribute. + * Other relevant relkinds, currently limited to views having + * INSTEAD OF triggers, always have a wholerow attribute. */ else if (AttributeNumberIsValid(junkfilter->jf_junkAttNo)) { [parent: 796d191028bb]