Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Expand comments and add an assertion in nodeModifyTable.c.
authorNoah Misch <noah@leadboat.com>
Fri, 28 Jun 2024 02:21:05 +0000 (19:21 -0700)
committerNoah Misch <noah@leadboat.com>
Fri, 28 Jun 2024 02:21:11 +0000 (19:21 -0700)
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

index fd0789e9ba2fafc719ea83740e8eda187522e5d4..1006f450258482339e0561055476f5b00f465a05 100644 (file)
  *     values plus row-locating info for UPDATE cases, or just the
  *     row-locating info for DELETE cases.
  *
+ *     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,
@@ -1158,8 +1166,8 @@ ExecBatchInsert(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
@@ -1710,8 +1718,8 @@ ExecCrossPartitionUpdate(ModifyTableState *mtstate,
  *     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
@@ -1723,7 +1731,9 @@ ExecCrossPartitionUpdate(ModifyTableState *mtstate,
  *     to access values from other input tables (for RETURNING),
  *     row-ID junk columns, etc.
  *
- *     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 *
@@ -2650,8 +2660,8 @@ ExecModifyTable(PlanState *pstate)
             * know enough here 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(resultRelInfo->ri_RowIdAttNo))
            {