|
24 | 24 | *values plus row-locating info for UPDATE and MERGE cases, or just the
|
25 | 25 | *row-locating info for DELETE cases.
|
26 | 26 | *
|
| 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 | + * |
27 | 35 | *MERGE runs a join between the source relation and the target
|
28 | 36 | *table; if any WHEN NOT MATCHED clauses are present, then the
|
29 | 37 | *join is an outer join. In this case, any unmatched tuples will
|
@@ -1401,18 +1409,18 @@ ExecDeleteEpilogue(ModifyTableContext *context, ResultRelInfo *resultRelInfo,
|
1401 | 1409 | *DELETE is like UPDATE, except that we delete the tuple and no
|
1402 | 1410 | *index modifications are needed.
|
1403 | 1411 | *
|
1404 |
| - *When deleting from a table, tupleid identifies the tuple to |
1405 |
| - *delete andoldtuple is NULL. When deletingfrom a view, |
1406 |
| - *oldtuple is passed to theINSTEAD OFtriggers and identifies |
1407 |
| - *what to delete, andtupleid is invalid. When deleting from a |
1408 |
| - *foreign table, tupleid isinvalid; the FDW has to figure out |
1409 |
| - *which row to delete using data from the planSlot. oldtuple is |
1410 |
| - *passed toforeign tabletriggers; it is NULL when the foreign |
1411 |
| - *table has no relevant triggers. We use tupleDeleted to indicate |
1412 |
| - *whether the tuple is actually deleted, callers can use it to |
1413 |
| - *decide whether to continue the operation. When this DELETE is a |
1414 |
| - *part of an UPDATE of partition-key, then the slot returned by |
1415 |
| - *EvalPlanQual() is passed back using output parameterepqreturnslot. |
| 1412 | + *When deleting from a table, tupleid identifies the tuple to delete and |
| 1413 | + *oldtuple is NULL. When deletingthrough a view INSTEAD OF trigger, |
| 1414 | + *oldtuple is passed to the triggers and identifies what to delete, and |
| 1415 | + *tupleid is invalid. When deleting from a foreign table, tupleid is |
| 1416 | + *invalid; the FDW has to figure out which row to delete using data from |
| 1417 | + *the planSlot. oldtuple is passed to foreign table triggers; it is |
| 1418 | + *NULL when theforeign tablehas no relevant triggers. We use |
| 1419 | + *tupleDeleted to indicate whether the tuple is actually deleted, |
| 1420 | + *callers can use it to decide whether to continue the operation. When |
| 1421 | + *this DELETE is a part of an UPDATE of partition-key, then the slot |
| 1422 | + *returned by EvalPlanQual() is passed back using output parameter |
| 1423 | + *epqreturnslot. |
1416 | 1424 | *
|
1417 | 1425 | *Returns RETURNING result if any, otherwise NULL.
|
1418 | 1426 | * ----------------------------------------------------------------
|
@@ -2244,21 +2252,22 @@ ExecCrossPartitionUpdateForeignKey(ModifyTableContext *context,
|
2244 | 2252 | *is, we don't want to get stuck in an infinite loop
|
2245 | 2253 | *which corrupts your database..
|
2246 | 2254 | *
|
2247 |
| - *When updating a table, tupleid identifies the tuple to |
2248 |
| - *update and oldtuple is NULL. When updating a view, oldtuple |
2249 |
| - *is passed to the INSTEAD OF triggers and identifies what to |
2250 |
| - *update, and tupleid is invalid. When updating a foreign table, |
2251 |
| - *tupleid is invalid; the FDW has to figure out which row to |
2252 |
| - *update using data from the planSlot. oldtuple is passed to |
2253 |
| - *foreign table triggers; it is NULL when the foreign table has |
2254 |
| - *no relevant triggers. |
| 2255 | + *When updating a table, tupleid identifies the tuple to update and |
| 2256 | + *oldtuple is NULL. When updating through a view INSTEAD OF trigger, |
| 2257 | + *oldtuple is passed to the triggers and identifies what to update, and |
| 2258 | + *tupleid is invalid. When updating a foreign table, tupleid is |
| 2259 | + *invalid; the FDW has to figure out which row to update using data from |
| 2260 | + *the planSlot. oldtuple is passed to foreign table triggers; it is |
| 2261 | + *NULL when the foreign table has no relevant triggers. |
2255 | 2262 | *
|
2256 | 2263 | *slot contains the new tuple value to be stored.
|
2257 | 2264 | *planSlot is the output of the ModifyTable's subplan; we use it
|
2258 | 2265 | *to access values from other input tables (for RETURNING),
|
2259 | 2266 | *row-ID junk columns, etc.
|
2260 | 2267 | *
|
2261 |
| - *Returns RETURNING result if any, otherwise NULL. |
| 2268 | + *Returns RETURNING result if any, otherwise NULL. On exit, if tupleid |
| 2269 | + *had identified the tuple to update, it will identify the tuple |
| 2270 | + *actually updated after EvalPlanQual. |
2262 | 2271 | * ----------------------------------------------------------------
|
2263 | 2272 | */
|
2264 | 2273 | staticTupleTableSlot*
|
@@ -3800,8 +3809,8 @@ ExecModifyTable(PlanState *pstate)
|
3800 | 3809 | * know enough here to set t_tableOid. Quite separately from
|
3801 | 3810 | * this, the FDW may fetch its own junk attrs to identify the row.
|
3802 | 3811 | *
|
3803 |
| - * Other relevant relkinds, currently limited to views, always |
3804 |
| - * have a wholerow attribute. |
| 3812 | + * Other relevant relkinds, currently limited to views having |
| 3813 | + *INSTEAD OF triggers, alwayshave a wholerow attribute. |
3805 | 3814 | */
|
3806 | 3815 | elseif (AttributeNumberIsValid(resultRelInfo->ri_RowIdAttNo))
|
3807 | 3816 | {
|
|