]> granicus.if.org Git - postgresql/blob - src/backend/executor/nodeModifyTable.c
Fix things so that updatable views work with partitioned tables.
[postgresql] / src / backend / executor / nodeModifyTable.c
1 /*-------------------------------------------------------------------------
2  *
3  * nodeModifyTable.c
4  *        routines to handle ModifyTable nodes.
5  *
6  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        src/backend/executor/nodeModifyTable.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 /* INTERFACE ROUTINES
16  *              ExecInitModifyTable - initialize the ModifyTable node
17  *              ExecModifyTable         - retrieve the next tuple from the node
18  *              ExecEndModifyTable      - shut down the ModifyTable node
19  *              ExecReScanModifyTable - rescan the ModifyTable node
20  *
21  *       NOTES
22  *              Each ModifyTable node contains a list of one or more subplans,
23  *              much like an Append node.  There is one subplan per result relation.
24  *              The key reason for this is that in an inherited UPDATE command, each
25  *              result relation could have a different schema (more or different
26  *              columns) requiring a different plan tree to produce it.  In an
27  *              inherited DELETE, all the subplans should produce the same output
28  *              rowtype, but we might still find that different plans are appropriate
29  *              for different child relations.
30  *
31  *              If the query specifies RETURNING, then the ModifyTable returns a
32  *              RETURNING tuple after completing each row insert, update, or delete.
33  *              It must be called again to continue the operation.  Without RETURNING,
34  *              we just loop within the node until all the work is done, then
35  *              return NULL.  This avoids useless call/return overhead.
36  */
37
38 #include "postgres.h"
39
40 #include "access/htup_details.h"
41 #include "access/xact.h"
42 #include "commands/trigger.h"
43 #include "executor/executor.h"
44 #include "executor/nodeModifyTable.h"
45 #include "foreign/fdwapi.h"
46 #include "miscadmin.h"
47 #include "nodes/nodeFuncs.h"
48 #include "storage/bufmgr.h"
49 #include "storage/lmgr.h"
50 #include "utils/builtins.h"
51 #include "utils/memutils.h"
52 #include "utils/rel.h"
53 #include "utils/tqual.h"
54
55
56 static bool ExecOnConflictUpdate(ModifyTableState *mtstate,
57                                          ResultRelInfo *resultRelInfo,
58                                          ItemPointer conflictTid,
59                                          TupleTableSlot *planSlot,
60                                          TupleTableSlot *excludedSlot,
61                                          EState *estate,
62                                          bool canSetTag,
63                                          TupleTableSlot **returning);
64
65 /*
66  * Verify that the tuples to be produced by INSERT or UPDATE match the
67  * target relation's rowtype
68  *
69  * We do this to guard against stale plans.  If plan invalidation is
70  * functioning properly then we should never get a failure here, but better
71  * safe than sorry.  Note that this is called after we have obtained lock
72  * on the target rel, so the rowtype can't change underneath us.
73  *
74  * The plan output is represented by its targetlist, because that makes
75  * handling the dropped-column case easier.
76  */
77 static void
78 ExecCheckPlanOutput(Relation resultRel, List *targetList)
79 {
80         TupleDesc       resultDesc = RelationGetDescr(resultRel);
81         int                     attno = 0;
82         ListCell   *lc;
83
84         foreach(lc, targetList)
85         {
86                 TargetEntry *tle = (TargetEntry *) lfirst(lc);
87                 Form_pg_attribute attr;
88
89                 if (tle->resjunk)
90                         continue;                       /* ignore junk tlist items */
91
92                 if (attno >= resultDesc->natts)
93                         ereport(ERROR,
94                                         (errcode(ERRCODE_DATATYPE_MISMATCH),
95                                          errmsg("table row type and query-specified row type do not match"),
96                                          errdetail("Query has too many columns.")));
97                 attr = resultDesc->attrs[attno++];
98
99                 if (!attr->attisdropped)
100                 {
101                         /* Normal case: demand type match */
102                         if (exprType((Node *) tle->expr) != attr->atttypid)
103                                 ereport(ERROR,
104                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
105                                                  errmsg("table row type and query-specified row type do not match"),
106                                                  errdetail("Table has type %s at ordinal position %d, but query expects %s.",
107                                                                    format_type_be(attr->atttypid),
108                                                                    attno,
109                                                          format_type_be(exprType((Node *) tle->expr)))));
110                 }
111                 else
112                 {
113                         /*
114                          * For a dropped column, we can't check atttypid (it's likely 0).
115                          * In any case the planner has most likely inserted an INT4 null.
116                          * What we insist on is just *some* NULL constant.
117                          */
118                         if (!IsA(tle->expr, Const) ||
119                                 !((Const *) tle->expr)->constisnull)
120                                 ereport(ERROR,
121                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
122                                                  errmsg("table row type and query-specified row type do not match"),
123                                                  errdetail("Query provides a value for a dropped column at ordinal position %d.",
124                                                                    attno)));
125                 }
126         }
127         if (attno != resultDesc->natts)
128                 ereport(ERROR,
129                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
130                   errmsg("table row type and query-specified row type do not match"),
131                                  errdetail("Query has too few columns.")));
132 }
133
134 /*
135  * ExecProcessReturning --- evaluate a RETURNING list
136  *
137  * projectReturning: RETURNING projection info for current result rel
138  * tupleSlot: slot holding tuple actually inserted/updated/deleted
139  * planSlot: slot holding tuple returned by top subplan node
140  *
141  * Note: If tupleSlot is NULL, the FDW should have already provided econtext's
142  * scan tuple.
143  *
144  * Returns a slot holding the result tuple
145  */
146 static TupleTableSlot *
147 ExecProcessReturning(ResultRelInfo *resultRelInfo,
148                                          TupleTableSlot *tupleSlot,
149                                          TupleTableSlot *planSlot)
150 {
151         ProjectionInfo *projectReturning = resultRelInfo->ri_projectReturning;
152         ExprContext *econtext = projectReturning->pi_exprContext;
153
154         /*
155          * Reset per-tuple memory context to free any expression evaluation
156          * storage allocated in the previous cycle.
157          */
158         ResetExprContext(econtext);
159
160         /* Make tuple and any needed join variables available to ExecProject */
161         if (tupleSlot)
162                 econtext->ecxt_scantuple = tupleSlot;
163         else
164         {
165                 HeapTuple       tuple;
166
167                 /*
168                  * RETURNING expressions might reference the tableoid column, so
169                  * initialize t_tableOid before evaluating them.
170                  */
171                 Assert(!TupIsNull(econtext->ecxt_scantuple));
172                 tuple = ExecMaterializeSlot(econtext->ecxt_scantuple);
173                 tuple->t_tableOid = RelationGetRelid(resultRelInfo->ri_RelationDesc);
174         }
175         econtext->ecxt_outertuple = planSlot;
176
177         /* Compute the RETURNING expressions */
178         return ExecProject(projectReturning);
179 }
180
181 /*
182  * ExecCheckHeapTupleVisible -- verify heap tuple is visible
183  *
184  * It would not be consistent with guarantees of the higher isolation levels to
185  * proceed with avoiding insertion (taking speculative insertion's alternative
186  * path) on the basis of another tuple that is not visible to MVCC snapshot.
187  * Check for the need to raise a serialization failure, and do so as necessary.
188  */
189 static void
190 ExecCheckHeapTupleVisible(EState *estate,
191                                                   HeapTuple tuple,
192                                                   Buffer buffer)
193 {
194         if (!IsolationUsesXactSnapshot())
195                 return;
196
197         /*
198          * We need buffer pin and lock to call HeapTupleSatisfiesVisibility.
199          * Caller should be holding pin, but not lock.
200          */
201         LockBuffer(buffer, BUFFER_LOCK_SHARE);
202         if (!HeapTupleSatisfiesVisibility(tuple, estate->es_snapshot, buffer))
203         {
204                 /*
205                  * We should not raise a serialization failure if the conflict is
206                  * against a tuple inserted by our own transaction, even if it's not
207                  * visible to our snapshot.  (This would happen, for example, if
208                  * conflicting keys are proposed for insertion in a single command.)
209                  */
210                 if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(tuple->t_data)))
211                         ereport(ERROR,
212                                         (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
213                          errmsg("could not serialize access due to concurrent update")));
214         }
215         LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
216 }
217
218 /*
219  * ExecCheckTIDVisible -- convenience variant of ExecCheckHeapTupleVisible()
220  */
221 static void
222 ExecCheckTIDVisible(EState *estate,
223                                         ResultRelInfo *relinfo,
224                                         ItemPointer tid)
225 {
226         Relation        rel = relinfo->ri_RelationDesc;
227         Buffer          buffer;
228         HeapTupleData tuple;
229
230         /* Redundantly check isolation level */
231         if (!IsolationUsesXactSnapshot())
232                 return;
233
234         tuple.t_self = *tid;
235         if (!heap_fetch(rel, SnapshotAny, &tuple, &buffer, false, NULL))
236                 elog(ERROR, "failed to fetch conflicting tuple for ON CONFLICT");
237         ExecCheckHeapTupleVisible(estate, &tuple, buffer);
238         ReleaseBuffer(buffer);
239 }
240
241 /* ----------------------------------------------------------------
242  *              ExecInsert
243  *
244  *              For INSERT, we have to insert the tuple into the target relation
245  *              and insert appropriate tuples into the index relations.
246  *
247  *              Returns RETURNING result if any, otherwise NULL.
248  * ----------------------------------------------------------------
249  */
250 static TupleTableSlot *
251 ExecInsert(ModifyTableState *mtstate,
252                    TupleTableSlot *slot,
253                    TupleTableSlot *planSlot,
254                    List *arbiterIndexes,
255                    OnConflictAction onconflict,
256                    EState *estate,
257                    bool canSetTag)
258 {
259         HeapTuple       tuple;
260         ResultRelInfo *resultRelInfo;
261         ResultRelInfo *saved_resultRelInfo = NULL;
262         Relation        resultRelationDesc;
263         Oid                     newId;
264         List       *recheckIndexes = NIL;
265         TupleTableSlot *oldslot = slot,
266                            *result = NULL;
267
268         /*
269          * get the heap tuple out of the tuple table slot, making sure we have a
270          * writable copy
271          */
272         tuple = ExecMaterializeSlot(slot);
273
274         /*
275          * get information on the (current) result relation
276          */
277         resultRelInfo = estate->es_result_relation_info;
278
279         /* Determine the partition to heap_insert the tuple into */
280         if (mtstate->mt_partition_dispatch_info)
281         {
282                 int                     leaf_part_index;
283                 TupleConversionMap *map;
284
285                 /*
286                  * Away we go ... If we end up not finding a partition after all,
287                  * ExecFindPartition() does not return and errors out instead.
288                  * Otherwise, the returned value is to be used as an index into arrays
289                  * mt_partitions[] and mt_partition_tupconv_maps[] that will get us
290                  * the ResultRelInfo and TupleConversionMap for the partition,
291                  * respectively.
292                  */
293                 leaf_part_index = ExecFindPartition(resultRelInfo,
294                                                                                  mtstate->mt_partition_dispatch_info,
295                                                                                         slot,
296                                                                                         estate);
297                 Assert(leaf_part_index >= 0 &&
298                            leaf_part_index < mtstate->mt_num_partitions);
299
300                 /*
301                  * Save the old ResultRelInfo and switch to the one corresponding to
302                  * the selected partition.
303                  */
304                 saved_resultRelInfo = resultRelInfo;
305                 resultRelInfo = mtstate->mt_partitions + leaf_part_index;
306
307                 /* We do not yet have a way to insert into a foreign partition */
308                 if (resultRelInfo->ri_FdwRoutine)
309                         ereport(ERROR,
310                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
311                                  errmsg("cannot route inserted tuples to a foreign table")));
312
313                 /* For ExecInsertIndexTuples() to work on the partition's indexes */
314                 estate->es_result_relation_info = resultRelInfo;
315
316                 /*
317                  * We might need to convert from the parent rowtype to the partition
318                  * rowtype.
319                  */
320                 map = mtstate->mt_partition_tupconv_maps[leaf_part_index];
321                 if (map)
322                 {
323                         Relation        partrel = resultRelInfo->ri_RelationDesc;
324
325                         tuple = do_convert_tuple(tuple, map);
326
327                         /*
328                          * We must use the partition's tuple descriptor from this point
329                          * on, until we're finished dealing with the partition. Use the
330                          * dedicated slot for that.
331                          */
332                         slot = mtstate->mt_partition_tuple_slot;
333                         Assert(slot != NULL);
334                         ExecSetSlotDescriptor(slot, RelationGetDescr(partrel));
335                         ExecStoreTuple(tuple, slot, InvalidBuffer, true);
336                 }
337         }
338
339         resultRelationDesc = resultRelInfo->ri_RelationDesc;
340
341         /*
342          * If the result relation has OIDs, force the tuple's OID to zero so that
343          * heap_insert will assign a fresh OID.  Usually the OID already will be
344          * zero at this point, but there are corner cases where the plan tree can
345          * return a tuple extracted literally from some table with the same
346          * rowtype.
347          *
348          * XXX if we ever wanted to allow users to assign their own OIDs to new
349          * rows, this'd be the place to do it.  For the moment, we make a point of
350          * doing this before calling triggers, so that a user-supplied trigger
351          * could hack the OID if desired.
352          */
353         if (resultRelationDesc->rd_rel->relhasoids)
354                 HeapTupleSetOid(tuple, InvalidOid);
355
356         /*
357          * BEFORE ROW INSERT Triggers.
358          *
359          * Note: We fire BEFORE ROW TRIGGERS for every attempted insertion in an
360          * INSERT ... ON CONFLICT statement.  We cannot check for constraint
361          * violations before firing these triggers, because they can change the
362          * values to insert.  Also, they can run arbitrary user-defined code with
363          * side-effects that we can't cancel by just not inserting the tuple.
364          */
365         if (resultRelInfo->ri_TrigDesc &&
366                 resultRelInfo->ri_TrigDesc->trig_insert_before_row)
367         {
368                 slot = ExecBRInsertTriggers(estate, resultRelInfo, slot);
369
370                 if (slot == NULL)               /* "do nothing" */
371                         return NULL;
372
373                 /* trigger might have changed tuple */
374                 tuple = ExecMaterializeSlot(slot);
375         }
376
377         /* INSTEAD OF ROW INSERT Triggers */
378         if (resultRelInfo->ri_TrigDesc &&
379                 resultRelInfo->ri_TrigDesc->trig_insert_instead_row)
380         {
381                 slot = ExecIRInsertTriggers(estate, resultRelInfo, slot);
382
383                 if (slot == NULL)               /* "do nothing" */
384                         return NULL;
385
386                 /* trigger might have changed tuple */
387                 tuple = ExecMaterializeSlot(slot);
388
389                 newId = InvalidOid;
390         }
391         else if (resultRelInfo->ri_FdwRoutine)
392         {
393                 /*
394                  * insert into foreign table: let the FDW do it
395                  */
396                 slot = resultRelInfo->ri_FdwRoutine->ExecForeignInsert(estate,
397                                                                                                                            resultRelInfo,
398                                                                                                                            slot,
399                                                                                                                            planSlot);
400
401                 if (slot == NULL)               /* "do nothing" */
402                         return NULL;
403
404                 /* FDW might have changed tuple */
405                 tuple = ExecMaterializeSlot(slot);
406
407                 /*
408                  * AFTER ROW Triggers or RETURNING expressions might reference the
409                  * tableoid column, so initialize t_tableOid before evaluating them.
410                  */
411                 tuple->t_tableOid = RelationGetRelid(resultRelationDesc);
412
413                 newId = InvalidOid;
414         }
415         else
416         {
417                 /*
418                  * Constraints might reference the tableoid column, so initialize
419                  * t_tableOid before evaluating them.
420                  */
421                 tuple->t_tableOid = RelationGetRelid(resultRelationDesc);
422
423                 /*
424                  * Check any RLS INSERT WITH CHECK policies
425                  *
426                  * ExecWithCheckOptions() will skip any WCOs which are not of the kind
427                  * we are looking for at this point.
428                  */
429                 if (resultRelInfo->ri_WithCheckOptions != NIL)
430                         ExecWithCheckOptions(WCO_RLS_INSERT_CHECK,
431                                                                  resultRelInfo, slot, estate);
432
433                 /*
434                  * Check the constraints of the tuple
435                  */
436                 if (resultRelationDesc->rd_att->constr || resultRelInfo->ri_PartitionCheck)
437                         ExecConstraints(resultRelInfo, slot, oldslot, estate);
438
439                 if (onconflict != ONCONFLICT_NONE && resultRelInfo->ri_NumIndices > 0)
440                 {
441                         /* Perform a speculative insertion. */
442                         uint32          specToken;
443                         ItemPointerData conflictTid;
444                         bool            specConflict;
445
446                         /*
447                          * Do a non-conclusive check for conflicts first.
448                          *
449                          * We're not holding any locks yet, so this doesn't guarantee that
450                          * the later insert won't conflict.  But it avoids leaving behind
451                          * a lot of canceled speculative insertions, if you run a lot of
452                          * INSERT ON CONFLICT statements that do conflict.
453                          *
454                          * We loop back here if we find a conflict below, either during
455                          * the pre-check, or when we re-check after inserting the tuple
456                          * speculatively.
457                          */
458         vlock:
459                         specConflict = false;
460                         if (!ExecCheckIndexConstraints(slot, estate, &conflictTid,
461                                                                                    arbiterIndexes))
462                         {
463                                 /* committed conflict tuple found */
464                                 if (onconflict == ONCONFLICT_UPDATE)
465                                 {
466                                         /*
467                                          * In case of ON CONFLICT DO UPDATE, execute the UPDATE
468                                          * part.  Be prepared to retry if the UPDATE fails because
469                                          * of another concurrent UPDATE/DELETE to the conflict
470                                          * tuple.
471                                          */
472                                         TupleTableSlot *returning = NULL;
473
474                                         if (ExecOnConflictUpdate(mtstate, resultRelInfo,
475                                                                                          &conflictTid, planSlot, slot,
476                                                                                          estate, canSetTag, &returning))
477                                         {
478                                                 InstrCountFiltered2(&mtstate->ps, 1);
479                                                 return returning;
480                                         }
481                                         else
482                                                 goto vlock;
483                                 }
484                                 else
485                                 {
486                                         /*
487                                          * In case of ON CONFLICT DO NOTHING, do nothing. However,
488                                          * verify that the tuple is visible to the executor's MVCC
489                                          * snapshot at higher isolation levels.
490                                          */
491                                         Assert(onconflict == ONCONFLICT_NOTHING);
492                                         ExecCheckTIDVisible(estate, resultRelInfo, &conflictTid);
493                                         InstrCountFiltered2(&mtstate->ps, 1);
494                                         return NULL;
495                                 }
496                         }
497
498                         /*
499                          * Before we start insertion proper, acquire our "speculative
500                          * insertion lock".  Others can use that to wait for us to decide
501                          * if we're going to go ahead with the insertion, instead of
502                          * waiting for the whole transaction to complete.
503                          */
504                         specToken = SpeculativeInsertionLockAcquire(GetCurrentTransactionId());
505                         HeapTupleHeaderSetSpeculativeToken(tuple->t_data, specToken);
506
507                         /* insert the tuple, with the speculative token */
508                         newId = heap_insert(resultRelationDesc, tuple,
509                                                                 estate->es_output_cid,
510                                                                 HEAP_INSERT_SPECULATIVE,
511                                                                 NULL);
512
513                         /* insert index entries for tuple */
514                         recheckIndexes = ExecInsertIndexTuples(slot, &(tuple->t_self),
515                                                                                                  estate, true, &specConflict,
516                                                                                                    arbiterIndexes);
517
518                         /* adjust the tuple's state accordingly */
519                         if (!specConflict)
520                                 heap_finish_speculative(resultRelationDesc, tuple);
521                         else
522                                 heap_abort_speculative(resultRelationDesc, tuple);
523
524                         /*
525                          * Wake up anyone waiting for our decision.  They will re-check
526                          * the tuple, see that it's no longer speculative, and wait on our
527                          * XID as if this was a regularly inserted tuple all along.  Or if
528                          * we killed the tuple, they will see it's dead, and proceed as if
529                          * the tuple never existed.
530                          */
531                         SpeculativeInsertionLockRelease(GetCurrentTransactionId());
532
533                         /*
534                          * If there was a conflict, start from the beginning.  We'll do
535                          * the pre-check again, which will now find the conflicting tuple
536                          * (unless it aborts before we get there).
537                          */
538                         if (specConflict)
539                         {
540                                 list_free(recheckIndexes);
541                                 goto vlock;
542                         }
543
544                         /* Since there was no insertion conflict, we're done */
545                 }
546                 else
547                 {
548                         /*
549                          * insert the tuple normally.
550                          *
551                          * Note: heap_insert returns the tid (location) of the new tuple
552                          * in the t_self field.
553                          */
554                         newId = heap_insert(resultRelationDesc, tuple,
555                                                                 estate->es_output_cid,
556                                                                 0, NULL);
557
558                         /* insert index entries for tuple */
559                         if (resultRelInfo->ri_NumIndices > 0)
560                                 recheckIndexes = ExecInsertIndexTuples(slot, &(tuple->t_self),
561                                                                                                            estate, false, NULL,
562                                                                                                            arbiterIndexes);
563                 }
564         }
565
566         if (canSetTag)
567         {
568                 (estate->es_processed)++;
569                 estate->es_lastoid = newId;
570                 setLastTid(&(tuple->t_self));
571         }
572
573         /* AFTER ROW INSERT Triggers */
574         ExecARInsertTriggers(estate, resultRelInfo, tuple, recheckIndexes);
575
576         list_free(recheckIndexes);
577
578         /*
579          * Check any WITH CHECK OPTION constraints from parent views.  We are
580          * required to do this after testing all constraints and uniqueness
581          * violations per the SQL spec, so we do it after actually inserting the
582          * record into the heap and all indexes.
583          *
584          * ExecWithCheckOptions will elog(ERROR) if a violation is found, so the
585          * tuple will never be seen, if it violates the WITH CHECK OPTION.
586          *
587          * ExecWithCheckOptions() will skip any WCOs which are not of the kind we
588          * are looking for at this point.
589          */
590         if (resultRelInfo->ri_WithCheckOptions != NIL)
591                 ExecWithCheckOptions(WCO_VIEW_CHECK, resultRelInfo, slot, estate);
592
593         /* Process RETURNING if present */
594         if (resultRelInfo->ri_projectReturning)
595                 result = ExecProcessReturning(resultRelInfo, slot, planSlot);
596
597         if (saved_resultRelInfo)
598                 estate->es_result_relation_info = saved_resultRelInfo;
599
600         return result;
601 }
602
603 /* ----------------------------------------------------------------
604  *              ExecDelete
605  *
606  *              DELETE is like UPDATE, except that we delete the tuple and no
607  *              index modifications are needed.
608  *
609  *              When deleting from a table, tupleid identifies the tuple to
610  *              delete and oldtuple is NULL.  When deleting from a view,
611  *              oldtuple is passed to the INSTEAD OF triggers and identifies
612  *              what to delete, and tupleid is invalid.  When deleting from a
613  *              foreign table, tupleid is invalid; the FDW has to figure out
614  *              which row to delete using data from the planSlot.  oldtuple is
615  *              passed to foreign table triggers; it is NULL when the foreign
616  *              table has no relevant triggers.
617  *
618  *              Returns RETURNING result if any, otherwise NULL.
619  * ----------------------------------------------------------------
620  */
621 static TupleTableSlot *
622 ExecDelete(ItemPointer tupleid,
623                    HeapTuple oldtuple,
624                    TupleTableSlot *planSlot,
625                    EPQState *epqstate,
626                    EState *estate,
627                    bool canSetTag)
628 {
629         ResultRelInfo *resultRelInfo;
630         Relation        resultRelationDesc;
631         HTSU_Result result;
632         HeapUpdateFailureData hufd;
633         TupleTableSlot *slot = NULL;
634
635         /*
636          * get information on the (current) result relation
637          */
638         resultRelInfo = estate->es_result_relation_info;
639         resultRelationDesc = resultRelInfo->ri_RelationDesc;
640
641         /* BEFORE ROW DELETE Triggers */
642         if (resultRelInfo->ri_TrigDesc &&
643                 resultRelInfo->ri_TrigDesc->trig_delete_before_row)
644         {
645                 bool            dodelete;
646
647                 dodelete = ExecBRDeleteTriggers(estate, epqstate, resultRelInfo,
648                                                                                 tupleid, oldtuple);
649
650                 if (!dodelete)                  /* "do nothing" */
651                         return NULL;
652         }
653
654         /* INSTEAD OF ROW DELETE Triggers */
655         if (resultRelInfo->ri_TrigDesc &&
656                 resultRelInfo->ri_TrigDesc->trig_delete_instead_row)
657         {
658                 bool            dodelete;
659
660                 Assert(oldtuple != NULL);
661                 dodelete = ExecIRDeleteTriggers(estate, resultRelInfo, oldtuple);
662
663                 if (!dodelete)                  /* "do nothing" */
664                         return NULL;
665         }
666         else if (resultRelInfo->ri_FdwRoutine)
667         {
668                 HeapTuple       tuple;
669
670                 /*
671                  * delete from foreign table: let the FDW do it
672                  *
673                  * We offer the trigger tuple slot as a place to store RETURNING data,
674                  * although the FDW can return some other slot if it wants.  Set up
675                  * the slot's tupdesc so the FDW doesn't need to do that for itself.
676                  */
677                 slot = estate->es_trig_tuple_slot;
678                 if (slot->tts_tupleDescriptor != RelationGetDescr(resultRelationDesc))
679                         ExecSetSlotDescriptor(slot, RelationGetDescr(resultRelationDesc));
680
681                 slot = resultRelInfo->ri_FdwRoutine->ExecForeignDelete(estate,
682                                                                                                                            resultRelInfo,
683                                                                                                                            slot,
684                                                                                                                            planSlot);
685
686                 if (slot == NULL)               /* "do nothing" */
687                         return NULL;
688
689                 /*
690                  * RETURNING expressions might reference the tableoid column, so
691                  * initialize t_tableOid before evaluating them.
692                  */
693                 if (slot->tts_isempty)
694                         ExecStoreAllNullTuple(slot);
695                 tuple = ExecMaterializeSlot(slot);
696                 tuple->t_tableOid = RelationGetRelid(resultRelationDesc);
697         }
698         else
699         {
700                 /*
701                  * delete the tuple
702                  *
703                  * Note: if es_crosscheck_snapshot isn't InvalidSnapshot, we check
704                  * that the row to be deleted is visible to that snapshot, and throw a
705                  * can't-serialize error if not. This is a special-case behavior
706                  * needed for referential integrity updates in transaction-snapshot
707                  * mode transactions.
708                  */
709 ldelete:;
710                 result = heap_delete(resultRelationDesc, tupleid,
711                                                          estate->es_output_cid,
712                                                          estate->es_crosscheck_snapshot,
713                                                          true /* wait for commit */ ,
714                                                          &hufd);
715                 switch (result)
716                 {
717                         case HeapTupleSelfUpdated:
718
719                                 /*
720                                  * The target tuple was already updated or deleted by the
721                                  * current command, or by a later command in the current
722                                  * transaction.  The former case is possible in a join DELETE
723                                  * where multiple tuples join to the same target tuple. This
724                                  * is somewhat questionable, but Postgres has always allowed
725                                  * it: we just ignore additional deletion attempts.
726                                  *
727                                  * The latter case arises if the tuple is modified by a
728                                  * command in a BEFORE trigger, or perhaps by a command in a
729                                  * volatile function used in the query.  In such situations we
730                                  * should not ignore the deletion, but it is equally unsafe to
731                                  * proceed.  We don't want to discard the original DELETE
732                                  * while keeping the triggered actions based on its deletion;
733                                  * and it would be no better to allow the original DELETE
734                                  * while discarding updates that it triggered.  The row update
735                                  * carries some information that might be important according
736                                  * to business rules; so throwing an error is the only safe
737                                  * course.
738                                  *
739                                  * If a trigger actually intends this type of interaction, it
740                                  * can re-execute the DELETE and then return NULL to cancel
741                                  * the outer delete.
742                                  */
743                                 if (hufd.cmax != estate->es_output_cid)
744                                         ereport(ERROR,
745                                                         (errcode(ERRCODE_TRIGGERED_DATA_CHANGE_VIOLATION),
746                                                          errmsg("tuple to be updated was already modified by an operation triggered by the current command"),
747                                                          errhint("Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows.")));
748
749                                 /* Else, already deleted by self; nothing to do */
750                                 return NULL;
751
752                         case HeapTupleMayBeUpdated:
753                                 break;
754
755                         case HeapTupleUpdated:
756                                 if (IsolationUsesXactSnapshot())
757                                         ereport(ERROR,
758                                                         (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
759                                                          errmsg("could not serialize access due to concurrent update")));
760                                 if (!ItemPointerEquals(tupleid, &hufd.ctid))
761                                 {
762                                         TupleTableSlot *epqslot;
763
764                                         epqslot = EvalPlanQual(estate,
765                                                                                    epqstate,
766                                                                                    resultRelationDesc,
767                                                                                    resultRelInfo->ri_RangeTableIndex,
768                                                                                    LockTupleExclusive,
769                                                                                    &hufd.ctid,
770                                                                                    hufd.xmax);
771                                         if (!TupIsNull(epqslot))
772                                         {
773                                                 *tupleid = hufd.ctid;
774                                                 goto ldelete;
775                                         }
776                                 }
777                                 /* tuple already deleted; nothing to do */
778                                 return NULL;
779
780                         default:
781                                 elog(ERROR, "unrecognized heap_delete status: %u", result);
782                                 return NULL;
783                 }
784
785                 /*
786                  * Note: Normally one would think that we have to delete index tuples
787                  * associated with the heap tuple now...
788                  *
789                  * ... but in POSTGRES, we have no need to do this because VACUUM will
790                  * take care of it later.  We can't delete index tuples immediately
791                  * anyway, since the tuple is still visible to other transactions.
792                  */
793         }
794
795         if (canSetTag)
796                 (estate->es_processed)++;
797
798         /* AFTER ROW DELETE Triggers */
799         ExecARDeleteTriggers(estate, resultRelInfo, tupleid, oldtuple);
800
801         /* Process RETURNING if present */
802         if (resultRelInfo->ri_projectReturning)
803         {
804                 /*
805                  * We have to put the target tuple into a slot, which means first we
806                  * gotta fetch it.  We can use the trigger tuple slot.
807                  */
808                 TupleTableSlot *rslot;
809                 HeapTupleData deltuple;
810                 Buffer          delbuffer;
811
812                 if (resultRelInfo->ri_FdwRoutine)
813                 {
814                         /* FDW must have provided a slot containing the deleted row */
815                         Assert(!TupIsNull(slot));
816                         delbuffer = InvalidBuffer;
817                 }
818                 else
819                 {
820                         slot = estate->es_trig_tuple_slot;
821                         if (oldtuple != NULL)
822                         {
823                                 deltuple = *oldtuple;
824                                 delbuffer = InvalidBuffer;
825                         }
826                         else
827                         {
828                                 deltuple.t_self = *tupleid;
829                                 if (!heap_fetch(resultRelationDesc, SnapshotAny,
830                                                                 &deltuple, &delbuffer, false, NULL))
831                                         elog(ERROR, "failed to fetch deleted tuple for DELETE RETURNING");
832                         }
833
834                         if (slot->tts_tupleDescriptor != RelationGetDescr(resultRelationDesc))
835                                 ExecSetSlotDescriptor(slot, RelationGetDescr(resultRelationDesc));
836                         ExecStoreTuple(&deltuple, slot, InvalidBuffer, false);
837                 }
838
839                 rslot = ExecProcessReturning(resultRelInfo, slot, planSlot);
840
841                 /*
842                  * Before releasing the target tuple again, make sure rslot has a
843                  * local copy of any pass-by-reference values.
844                  */
845                 ExecMaterializeSlot(rslot);
846
847                 ExecClearTuple(slot);
848                 if (BufferIsValid(delbuffer))
849                         ReleaseBuffer(delbuffer);
850
851                 return rslot;
852         }
853
854         return NULL;
855 }
856
857 /* ----------------------------------------------------------------
858  *              ExecUpdate
859  *
860  *              note: we can't run UPDATE queries with transactions
861  *              off because UPDATEs are actually INSERTs and our
862  *              scan will mistakenly loop forever, updating the tuple
863  *              it just inserted..  This should be fixed but until it
864  *              is, we don't want to get stuck in an infinite loop
865  *              which corrupts your database..
866  *
867  *              When updating a table, tupleid identifies the tuple to
868  *              update and oldtuple is NULL.  When updating a view, oldtuple
869  *              is passed to the INSTEAD OF triggers and identifies what to
870  *              update, and tupleid is invalid.  When updating a foreign table,
871  *              tupleid is invalid; the FDW has to figure out which row to
872  *              update using data from the planSlot.  oldtuple is passed to
873  *              foreign table triggers; it is NULL when the foreign table has
874  *              no relevant triggers.
875  *
876  *              Returns RETURNING result if any, otherwise NULL.
877  * ----------------------------------------------------------------
878  */
879 static TupleTableSlot *
880 ExecUpdate(ItemPointer tupleid,
881                    HeapTuple oldtuple,
882                    TupleTableSlot *slot,
883                    TupleTableSlot *planSlot,
884                    EPQState *epqstate,
885                    EState *estate,
886                    bool canSetTag)
887 {
888         HeapTuple       tuple;
889         ResultRelInfo *resultRelInfo;
890         Relation        resultRelationDesc;
891         HTSU_Result result;
892         HeapUpdateFailureData hufd;
893         List       *recheckIndexes = NIL;
894
895         /*
896          * abort the operation if not running transactions
897          */
898         if (IsBootstrapProcessingMode())
899                 elog(ERROR, "cannot UPDATE during bootstrap");
900
901         /*
902          * get the heap tuple out of the tuple table slot, making sure we have a
903          * writable copy
904          */
905         tuple = ExecMaterializeSlot(slot);
906
907         /*
908          * get information on the (current) result relation
909          */
910         resultRelInfo = estate->es_result_relation_info;
911         resultRelationDesc = resultRelInfo->ri_RelationDesc;
912
913         /* BEFORE ROW UPDATE Triggers */
914         if (resultRelInfo->ri_TrigDesc &&
915                 resultRelInfo->ri_TrigDesc->trig_update_before_row)
916         {
917                 slot = ExecBRUpdateTriggers(estate, epqstate, resultRelInfo,
918                                                                         tupleid, oldtuple, slot);
919
920                 if (slot == NULL)               /* "do nothing" */
921                         return NULL;
922
923                 /* trigger might have changed tuple */
924                 tuple = ExecMaterializeSlot(slot);
925         }
926
927         /* INSTEAD OF ROW UPDATE Triggers */
928         if (resultRelInfo->ri_TrigDesc &&
929                 resultRelInfo->ri_TrigDesc->trig_update_instead_row)
930         {
931                 slot = ExecIRUpdateTriggers(estate, resultRelInfo,
932                                                                         oldtuple, slot);
933
934                 if (slot == NULL)               /* "do nothing" */
935                         return NULL;
936
937                 /* trigger might have changed tuple */
938                 tuple = ExecMaterializeSlot(slot);
939         }
940         else if (resultRelInfo->ri_FdwRoutine)
941         {
942                 /*
943                  * update in foreign table: let the FDW do it
944                  */
945                 slot = resultRelInfo->ri_FdwRoutine->ExecForeignUpdate(estate,
946                                                                                                                            resultRelInfo,
947                                                                                                                            slot,
948                                                                                                                            planSlot);
949
950                 if (slot == NULL)               /* "do nothing" */
951                         return NULL;
952
953                 /* FDW might have changed tuple */
954                 tuple = ExecMaterializeSlot(slot);
955
956                 /*
957                  * AFTER ROW Triggers or RETURNING expressions might reference the
958                  * tableoid column, so initialize t_tableOid before evaluating them.
959                  */
960                 tuple->t_tableOid = RelationGetRelid(resultRelationDesc);
961         }
962         else
963         {
964                 LockTupleMode lockmode;
965
966                 /*
967                  * Constraints might reference the tableoid column, so initialize
968                  * t_tableOid before evaluating them.
969                  */
970                 tuple->t_tableOid = RelationGetRelid(resultRelationDesc);
971
972                 /*
973                  * Check any RLS UPDATE WITH CHECK policies
974                  *
975                  * If we generate a new candidate tuple after EvalPlanQual testing, we
976                  * must loop back here and recheck any RLS policies and constraints.
977                  * (We don't need to redo triggers, however.  If there are any BEFORE
978                  * triggers then trigger.c will have done heap_lock_tuple to lock the
979                  * correct tuple, so there's no need to do them again.)
980                  *
981                  * ExecWithCheckOptions() will skip any WCOs which are not of the kind
982                  * we are looking for at this point.
983                  */
984 lreplace:;
985                 if (resultRelInfo->ri_WithCheckOptions != NIL)
986                         ExecWithCheckOptions(WCO_RLS_UPDATE_CHECK,
987                                                                  resultRelInfo, slot, estate);
988
989                 /*
990                  * Check the constraints of the tuple.  Note that we pass the same
991                  * slot for the orig_slot argument, because unlike ExecInsert(), no
992                  * tuple-routing is performed here, hence the slot remains unchanged.
993                  */
994                 if (resultRelationDesc->rd_att->constr || resultRelInfo->ri_PartitionCheck)
995                         ExecConstraints(resultRelInfo, slot, slot, estate);
996
997                 /*
998                  * replace the heap tuple
999                  *
1000                  * Note: if es_crosscheck_snapshot isn't InvalidSnapshot, we check
1001                  * that the row to be updated is visible to that snapshot, and throw a
1002                  * can't-serialize error if not. This is a special-case behavior
1003                  * needed for referential integrity updates in transaction-snapshot
1004                  * mode transactions.
1005                  */
1006                 result = heap_update(resultRelationDesc, tupleid, tuple,
1007                                                          estate->es_output_cid,
1008                                                          estate->es_crosscheck_snapshot,
1009                                                          true /* wait for commit */ ,
1010                                                          &hufd, &lockmode);
1011                 switch (result)
1012                 {
1013                         case HeapTupleSelfUpdated:
1014
1015                                 /*
1016                                  * The target tuple was already updated or deleted by the
1017                                  * current command, or by a later command in the current
1018                                  * transaction.  The former case is possible in a join UPDATE
1019                                  * where multiple tuples join to the same target tuple. This
1020                                  * is pretty questionable, but Postgres has always allowed it:
1021                                  * we just execute the first update action and ignore
1022                                  * additional update attempts.
1023                                  *
1024                                  * The latter case arises if the tuple is modified by a
1025                                  * command in a BEFORE trigger, or perhaps by a command in a
1026                                  * volatile function used in the query.  In such situations we
1027                                  * should not ignore the update, but it is equally unsafe to
1028                                  * proceed.  We don't want to discard the original UPDATE
1029                                  * while keeping the triggered actions based on it; and we
1030                                  * have no principled way to merge this update with the
1031                                  * previous ones.  So throwing an error is the only safe
1032                                  * course.
1033                                  *
1034                                  * If a trigger actually intends this type of interaction, it
1035                                  * can re-execute the UPDATE (assuming it can figure out how)
1036                                  * and then return NULL to cancel the outer update.
1037                                  */
1038                                 if (hufd.cmax != estate->es_output_cid)
1039                                         ereport(ERROR,
1040                                                         (errcode(ERRCODE_TRIGGERED_DATA_CHANGE_VIOLATION),
1041                                                          errmsg("tuple to be updated was already modified by an operation triggered by the current command"),
1042                                                          errhint("Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows.")));
1043
1044                                 /* Else, already updated by self; nothing to do */
1045                                 return NULL;
1046
1047                         case HeapTupleMayBeUpdated:
1048                                 break;
1049
1050                         case HeapTupleUpdated:
1051                                 if (IsolationUsesXactSnapshot())
1052                                         ereport(ERROR,
1053                                                         (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
1054                                                          errmsg("could not serialize access due to concurrent update")));
1055                                 if (!ItemPointerEquals(tupleid, &hufd.ctid))
1056                                 {
1057                                         TupleTableSlot *epqslot;
1058
1059                                         epqslot = EvalPlanQual(estate,
1060                                                                                    epqstate,
1061                                                                                    resultRelationDesc,
1062                                                                                    resultRelInfo->ri_RangeTableIndex,
1063                                                                                    lockmode,
1064                                                                                    &hufd.ctid,
1065                                                                                    hufd.xmax);
1066                                         if (!TupIsNull(epqslot))
1067                                         {
1068                                                 *tupleid = hufd.ctid;
1069                                                 slot = ExecFilterJunk(resultRelInfo->ri_junkFilter, epqslot);
1070                                                 tuple = ExecMaterializeSlot(slot);
1071                                                 goto lreplace;
1072                                         }
1073                                 }
1074                                 /* tuple already deleted; nothing to do */
1075                                 return NULL;
1076
1077                         default:
1078                                 elog(ERROR, "unrecognized heap_update status: %u", result);
1079                                 return NULL;
1080                 }
1081
1082                 /*
1083                  * Note: instead of having to update the old index tuples associated
1084                  * with the heap tuple, all we do is form and insert new index tuples.
1085                  * This is because UPDATEs are actually DELETEs and INSERTs, and index
1086                  * tuple deletion is done later by VACUUM (see notes in ExecDelete).
1087                  * All we do here is insert new index tuples.  -cim 9/27/89
1088                  */
1089
1090                 /*
1091                  * insert index entries for tuple
1092                  *
1093                  * Note: heap_update returns the tid (location) of the new tuple in
1094                  * the t_self field.
1095                  *
1096                  * If it's a HOT update, we mustn't insert new index entries.
1097                  */
1098                 if (resultRelInfo->ri_NumIndices > 0 && !HeapTupleIsHeapOnly(tuple))
1099                         recheckIndexes = ExecInsertIndexTuples(slot, &(tuple->t_self),
1100                                                                                                    estate, false, NULL, NIL);
1101         }
1102
1103         if (canSetTag)
1104                 (estate->es_processed)++;
1105
1106         /* AFTER ROW UPDATE Triggers */
1107         ExecARUpdateTriggers(estate, resultRelInfo, tupleid, oldtuple, tuple,
1108                                                  recheckIndexes);
1109
1110         list_free(recheckIndexes);
1111
1112         /*
1113          * Check any WITH CHECK OPTION constraints from parent views.  We are
1114          * required to do this after testing all constraints and uniqueness
1115          * violations per the SQL spec, so we do it after actually updating the
1116          * record in the heap and all indexes.
1117          *
1118          * ExecWithCheckOptions() will skip any WCOs which are not of the kind we
1119          * are looking for at this point.
1120          */
1121         if (resultRelInfo->ri_WithCheckOptions != NIL)
1122                 ExecWithCheckOptions(WCO_VIEW_CHECK, resultRelInfo, slot, estate);
1123
1124         /* Process RETURNING if present */
1125         if (resultRelInfo->ri_projectReturning)
1126                 return ExecProcessReturning(resultRelInfo, slot, planSlot);
1127
1128         return NULL;
1129 }
1130
1131 /*
1132  * ExecOnConflictUpdate --- execute UPDATE of INSERT ON CONFLICT DO UPDATE
1133  *
1134  * Try to lock tuple for update as part of speculative insertion.  If
1135  * a qual originating from ON CONFLICT DO UPDATE is satisfied, update
1136  * (but still lock row, even though it may not satisfy estate's
1137  * snapshot).
1138  *
1139  * Returns true if if we're done (with or without an update), or false if
1140  * the caller must retry the INSERT from scratch.
1141  */
1142 static bool
1143 ExecOnConflictUpdate(ModifyTableState *mtstate,
1144                                          ResultRelInfo *resultRelInfo,
1145                                          ItemPointer conflictTid,
1146                                          TupleTableSlot *planSlot,
1147                                          TupleTableSlot *excludedSlot,
1148                                          EState *estate,
1149                                          bool canSetTag,
1150                                          TupleTableSlot **returning)
1151 {
1152         ExprContext *econtext = mtstate->ps.ps_ExprContext;
1153         Relation        relation = resultRelInfo->ri_RelationDesc;
1154         List       *onConflictSetWhere = resultRelInfo->ri_onConflictSetWhere;
1155         HeapTupleData tuple;
1156         HeapUpdateFailureData hufd;
1157         LockTupleMode lockmode;
1158         HTSU_Result test;
1159         Buffer          buffer;
1160
1161         /* Determine lock mode to use */
1162         lockmode = ExecUpdateLockMode(estate, resultRelInfo);
1163
1164         /*
1165          * Lock tuple for update.  Don't follow updates when tuple cannot be
1166          * locked without doing so.  A row locking conflict here means our
1167          * previous conclusion that the tuple is conclusively committed is not
1168          * true anymore.
1169          */
1170         tuple.t_self = *conflictTid;
1171         test = heap_lock_tuple(relation, &tuple, estate->es_output_cid,
1172                                                    lockmode, LockWaitBlock, false, &buffer,
1173                                                    &hufd);
1174         switch (test)
1175         {
1176                 case HeapTupleMayBeUpdated:
1177                         /* success! */
1178                         break;
1179
1180                 case HeapTupleInvisible:
1181
1182                         /*
1183                          * This can occur when a just inserted tuple is updated again in
1184                          * the same command. E.g. because multiple rows with the same
1185                          * conflicting key values are inserted.
1186                          *
1187                          * This is somewhat similar to the ExecUpdate()
1188                          * HeapTupleSelfUpdated case.  We do not want to proceed because
1189                          * it would lead to the same row being updated a second time in
1190                          * some unspecified order, and in contrast to plain UPDATEs
1191                          * there's no historical behavior to break.
1192                          *
1193                          * It is the user's responsibility to prevent this situation from
1194                          * occurring.  These problems are why SQL-2003 similarly specifies
1195                          * that for SQL MERGE, an exception must be raised in the event of
1196                          * an attempt to update the same row twice.
1197                          */
1198                         if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(tuple.t_data)))
1199                                 ereport(ERROR,
1200                                                 (errcode(ERRCODE_CARDINALITY_VIOLATION),
1201                                                  errmsg("ON CONFLICT DO UPDATE command cannot affect row a second time"),
1202                                                  errhint("Ensure that no rows proposed for insertion within the same command have duplicate constrained values.")));
1203
1204                         /* This shouldn't happen */
1205                         elog(ERROR, "attempted to lock invisible tuple");
1206
1207                 case HeapTupleSelfUpdated:
1208
1209                         /*
1210                          * This state should never be reached. As a dirty snapshot is used
1211                          * to find conflicting tuples, speculative insertion wouldn't have
1212                          * seen this row to conflict with.
1213                          */
1214                         elog(ERROR, "unexpected self-updated tuple");
1215
1216                 case HeapTupleUpdated:
1217                         if (IsolationUsesXactSnapshot())
1218                                 ereport(ERROR,
1219                                                 (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
1220                                                  errmsg("could not serialize access due to concurrent update")));
1221
1222                         /*
1223                          * Tell caller to try again from the very start.
1224                          *
1225                          * It does not make sense to use the usual EvalPlanQual() style
1226                          * loop here, as the new version of the row might not conflict
1227                          * anymore, or the conflicting tuple has actually been deleted.
1228                          */
1229                         ReleaseBuffer(buffer);
1230                         return false;
1231
1232                 default:
1233                         elog(ERROR, "unrecognized heap_lock_tuple status: %u", test);
1234         }
1235
1236         /*
1237          * Success, the tuple is locked.
1238          *
1239          * Reset per-tuple memory context to free any expression evaluation
1240          * storage allocated in the previous cycle.
1241          */
1242         ResetExprContext(econtext);
1243
1244         /*
1245          * Verify that the tuple is visible to our MVCC snapshot if the current
1246          * isolation level mandates that.
1247          *
1248          * It's not sufficient to rely on the check within ExecUpdate() as e.g.
1249          * CONFLICT ... WHERE clause may prevent us from reaching that.
1250          *
1251          * This means we only ever continue when a new command in the current
1252          * transaction could see the row, even though in READ COMMITTED mode the
1253          * tuple will not be visible according to the current statement's
1254          * snapshot.  This is in line with the way UPDATE deals with newer tuple
1255          * versions.
1256          */
1257         ExecCheckHeapTupleVisible(estate, &tuple, buffer);
1258
1259         /* Store target's existing tuple in the state's dedicated slot */
1260         ExecStoreTuple(&tuple, mtstate->mt_existing, buffer, false);
1261
1262         /*
1263          * Make tuple and any needed join variables available to ExecQual and
1264          * ExecProject.  The EXCLUDED tuple is installed in ecxt_innertuple, while
1265          * the target's existing tuple is installed in the scantuple.  EXCLUDED
1266          * has been made to reference INNER_VAR in setrefs.c, but there is no
1267          * other redirection.
1268          */
1269         econtext->ecxt_scantuple = mtstate->mt_existing;
1270         econtext->ecxt_innertuple = excludedSlot;
1271         econtext->ecxt_outertuple = NULL;
1272
1273         if (!ExecQual(onConflictSetWhere, econtext, false))
1274         {
1275                 ReleaseBuffer(buffer);
1276                 InstrCountFiltered1(&mtstate->ps, 1);
1277                 return true;                    /* done with the tuple */
1278         }
1279
1280         if (resultRelInfo->ri_WithCheckOptions != NIL)
1281         {
1282                 /*
1283                  * Check target's existing tuple against UPDATE-applicable USING
1284                  * security barrier quals (if any), enforced here as RLS checks/WCOs.
1285                  *
1286                  * The rewriter creates UPDATE RLS checks/WCOs for UPDATE security
1287                  * quals, and stores them as WCOs of "kind" WCO_RLS_CONFLICT_CHECK,
1288                  * but that's almost the extent of its special handling for ON
1289                  * CONFLICT DO UPDATE.
1290                  *
1291                  * The rewriter will also have associated UPDATE applicable straight
1292                  * RLS checks/WCOs for the benefit of the ExecUpdate() call that
1293                  * follows.  INSERTs and UPDATEs naturally have mutually exclusive WCO
1294                  * kinds, so there is no danger of spurious over-enforcement in the
1295                  * INSERT or UPDATE path.
1296                  */
1297                 ExecWithCheckOptions(WCO_RLS_CONFLICT_CHECK, resultRelInfo,
1298                                                          mtstate->mt_existing,
1299                                                          mtstate->ps.state);
1300         }
1301
1302         /* Project the new tuple version */
1303         ExecProject(resultRelInfo->ri_onConflictSetProj);
1304
1305         /*
1306          * Note that it is possible that the target tuple has been modified in
1307          * this session, after the above heap_lock_tuple. We choose to not error
1308          * out in that case, in line with ExecUpdate's treatment of similar cases.
1309          * This can happen if an UPDATE is triggered from within ExecQual(),
1310          * ExecWithCheckOptions() or ExecProject() above, e.g. by selecting from a
1311          * wCTE in the ON CONFLICT's SET.
1312          */
1313
1314         /* Execute UPDATE with projection */
1315         *returning = ExecUpdate(&tuple.t_self, NULL,
1316                                                         mtstate->mt_conflproj, planSlot,
1317                                                         &mtstate->mt_epqstate, mtstate->ps.state,
1318                                                         canSetTag);
1319
1320         ReleaseBuffer(buffer);
1321         return true;
1322 }
1323
1324
1325 /*
1326  * Process BEFORE EACH STATEMENT triggers
1327  */
1328 static void
1329 fireBSTriggers(ModifyTableState *node)
1330 {
1331         switch (node->operation)
1332         {
1333                 case CMD_INSERT:
1334                         ExecBSInsertTriggers(node->ps.state, node->resultRelInfo);
1335                         if (node->mt_onconflict == ONCONFLICT_UPDATE)
1336                                 ExecBSUpdateTriggers(node->ps.state,
1337                                                                          node->resultRelInfo);
1338                         break;
1339                 case CMD_UPDATE:
1340                         ExecBSUpdateTriggers(node->ps.state, node->resultRelInfo);
1341                         break;
1342                 case CMD_DELETE:
1343                         ExecBSDeleteTriggers(node->ps.state, node->resultRelInfo);
1344                         break;
1345                 default:
1346                         elog(ERROR, "unknown operation");
1347                         break;
1348         }
1349 }
1350
1351 /*
1352  * Process AFTER EACH STATEMENT triggers
1353  */
1354 static void
1355 fireASTriggers(ModifyTableState *node)
1356 {
1357         switch (node->operation)
1358         {
1359                 case CMD_INSERT:
1360                         if (node->mt_onconflict == ONCONFLICT_UPDATE)
1361                                 ExecASUpdateTriggers(node->ps.state,
1362                                                                          node->resultRelInfo);
1363                         ExecASInsertTriggers(node->ps.state, node->resultRelInfo);
1364                         break;
1365                 case CMD_UPDATE:
1366                         ExecASUpdateTriggers(node->ps.state, node->resultRelInfo);
1367                         break;
1368                 case CMD_DELETE:
1369                         ExecASDeleteTriggers(node->ps.state, node->resultRelInfo);
1370                         break;
1371                 default:
1372                         elog(ERROR, "unknown operation");
1373                         break;
1374         }
1375 }
1376
1377
1378 /* ----------------------------------------------------------------
1379  *         ExecModifyTable
1380  *
1381  *              Perform table modifications as required, and return RETURNING results
1382  *              if needed.
1383  * ----------------------------------------------------------------
1384  */
1385 TupleTableSlot *
1386 ExecModifyTable(ModifyTableState *node)
1387 {
1388         EState     *estate = node->ps.state;
1389         CmdType         operation = node->operation;
1390         ResultRelInfo *saved_resultRelInfo;
1391         ResultRelInfo *resultRelInfo;
1392         PlanState  *subplanstate;
1393         JunkFilter *junkfilter;
1394         TupleTableSlot *slot;
1395         TupleTableSlot *planSlot;
1396         ItemPointer tupleid = NULL;
1397         ItemPointerData tuple_ctid;
1398         HeapTupleData oldtupdata;
1399         HeapTuple       oldtuple;
1400
1401         /*
1402          * This should NOT get called during EvalPlanQual; we should have passed a
1403          * subplan tree to EvalPlanQual, instead.  Use a runtime test not just
1404          * Assert because this condition is easy to miss in testing.  (Note:
1405          * although ModifyTable should not get executed within an EvalPlanQual
1406          * operation, we do have to allow it to be initialized and shut down in
1407          * case it is within a CTE subplan.  Hence this test must be here, not in
1408          * ExecInitModifyTable.)
1409          */
1410         if (estate->es_epqTuple != NULL)
1411                 elog(ERROR, "ModifyTable should not be called during EvalPlanQual");
1412
1413         /*
1414          * If we've already completed processing, don't try to do more.  We need
1415          * this test because ExecPostprocessPlan might call us an extra time, and
1416          * our subplan's nodes aren't necessarily robust against being called
1417          * extra times.
1418          */
1419         if (node->mt_done)
1420                 return NULL;
1421
1422         /*
1423          * On first call, fire BEFORE STATEMENT triggers before proceeding.
1424          */
1425         if (node->fireBSTriggers)
1426         {
1427                 fireBSTriggers(node);
1428                 node->fireBSTriggers = false;
1429         }
1430
1431         /* Preload local variables */
1432         resultRelInfo = node->resultRelInfo + node->mt_whichplan;
1433         subplanstate = node->mt_plans[node->mt_whichplan];
1434         junkfilter = resultRelInfo->ri_junkFilter;
1435
1436         /*
1437          * es_result_relation_info must point to the currently active result
1438          * relation while we are within this ModifyTable node.  Even though
1439          * ModifyTable nodes can't be nested statically, they can be nested
1440          * dynamically (since our subplan could include a reference to a modifying
1441          * CTE).  So we have to save and restore the caller's value.
1442          */
1443         saved_resultRelInfo = estate->es_result_relation_info;
1444
1445         estate->es_result_relation_info = resultRelInfo;
1446
1447         /*
1448          * Fetch rows from subplan(s), and execute the required table modification
1449          * for each row.
1450          */
1451         for (;;)
1452         {
1453                 /*
1454                  * Reset the per-output-tuple exprcontext.  This is needed because
1455                  * triggers expect to use that context as workspace.  It's a bit ugly
1456                  * to do this below the top level of the plan, however.  We might need
1457                  * to rethink this later.
1458                  */
1459                 ResetPerTupleExprContext(estate);
1460
1461                 planSlot = ExecProcNode(subplanstate);
1462
1463                 if (TupIsNull(planSlot))
1464                 {
1465                         /* advance to next subplan if any */
1466                         node->mt_whichplan++;
1467                         if (node->mt_whichplan < node->mt_nplans)
1468                         {
1469                                 resultRelInfo++;
1470                                 subplanstate = node->mt_plans[node->mt_whichplan];
1471                                 junkfilter = resultRelInfo->ri_junkFilter;
1472                                 estate->es_result_relation_info = resultRelInfo;
1473                                 EvalPlanQualSetPlan(&node->mt_epqstate, subplanstate->plan,
1474                                                                         node->mt_arowmarks[node->mt_whichplan]);
1475                                 continue;
1476                         }
1477                         else
1478                                 break;
1479                 }
1480
1481                 /*
1482                  * If resultRelInfo->ri_usesFdwDirectModify is true, all we need to do
1483                  * here is compute the RETURNING expressions.
1484                  */
1485                 if (resultRelInfo->ri_usesFdwDirectModify)
1486                 {
1487                         Assert(resultRelInfo->ri_projectReturning);
1488
1489                         /*
1490                          * A scan slot containing the data that was actually inserted,
1491                          * updated or deleted has already been made available to
1492                          * ExecProcessReturning by IterateDirectModify, so no need to
1493                          * provide it here.
1494                          */
1495                         slot = ExecProcessReturning(resultRelInfo, NULL, planSlot);
1496
1497                         estate->es_result_relation_info = saved_resultRelInfo;
1498                         return slot;
1499                 }
1500
1501                 EvalPlanQualSetSlot(&node->mt_epqstate, planSlot);
1502                 slot = planSlot;
1503
1504                 oldtuple = NULL;
1505                 if (junkfilter != NULL)
1506                 {
1507                         /*
1508                          * extract the 'ctid' or 'wholerow' junk attribute.
1509                          */
1510                         if (operation == CMD_UPDATE || operation == CMD_DELETE)
1511                         {
1512                                 char            relkind;
1513                                 Datum           datum;
1514                                 bool            isNull;
1515
1516                                 relkind = resultRelInfo->ri_RelationDesc->rd_rel->relkind;
1517                                 if (relkind == RELKIND_RELATION || relkind == RELKIND_MATVIEW)
1518                                 {
1519                                         datum = ExecGetJunkAttribute(slot,
1520                                                                                                  junkfilter->jf_junkAttNo,
1521                                                                                                  &isNull);
1522                                         /* shouldn't ever get a null result... */
1523                                         if (isNull)
1524                                                 elog(ERROR, "ctid is NULL");
1525
1526                                         tupleid = (ItemPointer) DatumGetPointer(datum);
1527                                         tuple_ctid = *tupleid;          /* be sure we don't free
1528                                                                                                  * ctid!! */
1529                                         tupleid = &tuple_ctid;
1530                                 }
1531
1532                                 /*
1533                                  * Use the wholerow attribute, when available, to reconstruct
1534                                  * the old relation tuple.
1535                                  *
1536                                  * Foreign table updates have a wholerow attribute when the
1537                                  * relation has an AFTER ROW trigger.  Note that the wholerow
1538                                  * attribute does not carry system columns.  Foreign table
1539                                  * triggers miss seeing those, except that we know enough here
1540                                  * to set t_tableOid.  Quite separately from this, the FDW may
1541                                  * fetch its own junk attrs to identify the row.
1542                                  *
1543                                  * Other relevant relkinds, currently limited to views, always
1544                                  * have a wholerow attribute.
1545                                  */
1546                                 else if (AttributeNumberIsValid(junkfilter->jf_junkAttNo))
1547                                 {
1548                                         datum = ExecGetJunkAttribute(slot,
1549                                                                                                  junkfilter->jf_junkAttNo,
1550                                                                                                  &isNull);
1551                                         /* shouldn't ever get a null result... */
1552                                         if (isNull)
1553                                                 elog(ERROR, "wholerow is NULL");
1554
1555                                         oldtupdata.t_data = DatumGetHeapTupleHeader(datum);
1556                                         oldtupdata.t_len =
1557                                                 HeapTupleHeaderGetDatumLength(oldtupdata.t_data);
1558                                         ItemPointerSetInvalid(&(oldtupdata.t_self));
1559                                         /* Historically, view triggers see invalid t_tableOid. */
1560                                         oldtupdata.t_tableOid =
1561                                                 (relkind == RELKIND_VIEW) ? InvalidOid :
1562                                                 RelationGetRelid(resultRelInfo->ri_RelationDesc);
1563
1564                                         oldtuple = &oldtupdata;
1565                                 }
1566                                 else
1567                                         Assert(relkind == RELKIND_FOREIGN_TABLE);
1568                         }
1569
1570                         /*
1571                          * apply the junkfilter if needed.
1572                          */
1573                         if (operation != CMD_DELETE)
1574                                 slot = ExecFilterJunk(junkfilter, slot);
1575                 }
1576
1577                 switch (operation)
1578                 {
1579                         case CMD_INSERT:
1580                                 slot = ExecInsert(node, slot, planSlot,
1581                                                                 node->mt_arbiterindexes, node->mt_onconflict,
1582                                                                   estate, node->canSetTag);
1583                                 break;
1584                         case CMD_UPDATE:
1585                                 slot = ExecUpdate(tupleid, oldtuple, slot, planSlot,
1586                                                                 &node->mt_epqstate, estate, node->canSetTag);
1587                                 break;
1588                         case CMD_DELETE:
1589                                 slot = ExecDelete(tupleid, oldtuple, planSlot,
1590                                                                 &node->mt_epqstate, estate, node->canSetTag);
1591                                 break;
1592                         default:
1593                                 elog(ERROR, "unknown operation");
1594                                 break;
1595                 }
1596
1597                 /*
1598                  * If we got a RETURNING result, return it to caller.  We'll continue
1599                  * the work on next call.
1600                  */
1601                 if (slot)
1602                 {
1603                         estate->es_result_relation_info = saved_resultRelInfo;
1604                         return slot;
1605                 }
1606         }
1607
1608         /* Restore es_result_relation_info before exiting */
1609         estate->es_result_relation_info = saved_resultRelInfo;
1610
1611         /*
1612          * We're done, but fire AFTER STATEMENT triggers before exiting.
1613          */
1614         fireASTriggers(node);
1615
1616         node->mt_done = true;
1617
1618         return NULL;
1619 }
1620
1621 /* ----------------------------------------------------------------
1622  *              ExecInitModifyTable
1623  * ----------------------------------------------------------------
1624  */
1625 ModifyTableState *
1626 ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
1627 {
1628         ModifyTableState *mtstate;
1629         CmdType         operation = node->operation;
1630         int                     nplans = list_length(node->plans);
1631         ResultRelInfo *saved_resultRelInfo;
1632         ResultRelInfo *resultRelInfo;
1633         TupleDesc       tupDesc;
1634         Plan       *subplan;
1635         ListCell   *l;
1636         int                     i;
1637         Relation        rel;
1638
1639         /* check for unsupported flags */
1640         Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
1641
1642         /*
1643          * create state structure
1644          */
1645         mtstate = makeNode(ModifyTableState);
1646         mtstate->ps.plan = (Plan *) node;
1647         mtstate->ps.state = estate;
1648         mtstate->ps.targetlist = NIL;           /* not actually used */
1649
1650         mtstate->operation = operation;
1651         mtstate->canSetTag = node->canSetTag;
1652         mtstate->mt_done = false;
1653
1654         mtstate->mt_plans = (PlanState **) palloc0(sizeof(PlanState *) * nplans);
1655         mtstate->resultRelInfo = estate->es_result_relations + node->resultRelIndex;
1656         mtstate->mt_arowmarks = (List **) palloc0(sizeof(List *) * nplans);
1657         mtstate->mt_nplans = nplans;
1658         mtstate->mt_onconflict = node->onConflictAction;
1659         mtstate->mt_arbiterindexes = node->arbiterIndexes;
1660
1661         /* set up epqstate with dummy subplan data for the moment */
1662         EvalPlanQualInit(&mtstate->mt_epqstate, estate, NULL, NIL, node->epqParam);
1663         mtstate->fireBSTriggers = true;
1664
1665         /*
1666          * call ExecInitNode on each of the plans to be executed and save the
1667          * results into the array "mt_plans".  This is also a convenient place to
1668          * verify that the proposed target relations are valid and open their
1669          * indexes for insertion of new index entries.  Note we *must* set
1670          * estate->es_result_relation_info correctly while we initialize each
1671          * sub-plan; ExecContextForcesOids depends on that!
1672          */
1673         saved_resultRelInfo = estate->es_result_relation_info;
1674
1675         resultRelInfo = mtstate->resultRelInfo;
1676         i = 0;
1677         foreach(l, node->plans)
1678         {
1679                 subplan = (Plan *) lfirst(l);
1680
1681                 /* Initialize the usesFdwDirectModify flag */
1682                 resultRelInfo->ri_usesFdwDirectModify = bms_is_member(i,
1683                                                                                                  node->fdwDirectModifyPlans);
1684
1685                 /*
1686                  * Verify result relation is a valid target for the current operation
1687                  */
1688                 CheckValidResultRel(resultRelInfo->ri_RelationDesc, operation);
1689
1690                 /*
1691                  * If there are indices on the result relation, open them and save
1692                  * descriptors in the result relation info, so that we can add new
1693                  * index entries for the tuples we add/update.  We need not do this
1694                  * for a DELETE, however, since deletion doesn't affect indexes. Also,
1695                  * inside an EvalPlanQual operation, the indexes might be open
1696                  * already, since we share the resultrel state with the original
1697                  * query.
1698                  */
1699                 if (resultRelInfo->ri_RelationDesc->rd_rel->relhasindex &&
1700                         operation != CMD_DELETE &&
1701                         resultRelInfo->ri_IndexRelationDescs == NULL)
1702                         ExecOpenIndices(resultRelInfo, mtstate->mt_onconflict != ONCONFLICT_NONE);
1703
1704                 /* Now init the plan for this result rel */
1705                 estate->es_result_relation_info = resultRelInfo;
1706                 mtstate->mt_plans[i] = ExecInitNode(subplan, estate, eflags);
1707
1708                 /* Also let FDWs init themselves for foreign-table result rels */
1709                 if (!resultRelInfo->ri_usesFdwDirectModify &&
1710                         resultRelInfo->ri_FdwRoutine != NULL &&
1711                         resultRelInfo->ri_FdwRoutine->BeginForeignModify != NULL)
1712                 {
1713                         List       *fdw_private = (List *) list_nth(node->fdwPrivLists, i);
1714
1715                         resultRelInfo->ri_FdwRoutine->BeginForeignModify(mtstate,
1716                                                                                                                          resultRelInfo,
1717                                                                                                                          fdw_private,
1718                                                                                                                          i,
1719                                                                                                                          eflags);
1720                 }
1721
1722                 resultRelInfo++;
1723                 i++;
1724         }
1725
1726         estate->es_result_relation_info = saved_resultRelInfo;
1727
1728         /* Build state for INSERT tuple routing */
1729         rel = mtstate->resultRelInfo->ri_RelationDesc;
1730         if (operation == CMD_INSERT &&
1731                 rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
1732         {
1733                 PartitionDispatch *partition_dispatch_info;
1734                 ResultRelInfo *partitions;
1735                 TupleConversionMap **partition_tupconv_maps;
1736                 TupleTableSlot *partition_tuple_slot;
1737                 int                     num_parted,
1738                                         num_partitions;
1739
1740                 ExecSetupPartitionTupleRouting(rel,
1741                                                                            &partition_dispatch_info,
1742                                                                            &partitions,
1743                                                                            &partition_tupconv_maps,
1744                                                                            &partition_tuple_slot,
1745                                                                            &num_parted, &num_partitions);
1746                 mtstate->mt_partition_dispatch_info = partition_dispatch_info;
1747                 mtstate->mt_num_dispatch = num_parted;
1748                 mtstate->mt_partitions = partitions;
1749                 mtstate->mt_num_partitions = num_partitions;
1750                 mtstate->mt_partition_tupconv_maps = partition_tupconv_maps;
1751                 mtstate->mt_partition_tuple_slot = partition_tuple_slot;
1752         }
1753
1754         /*
1755          * Initialize any WITH CHECK OPTION constraints if needed.
1756          */
1757         resultRelInfo = mtstate->resultRelInfo;
1758         i = 0;
1759         foreach(l, node->withCheckOptionLists)
1760         {
1761                 List       *wcoList = (List *) lfirst(l);
1762                 List       *wcoExprs = NIL;
1763                 ListCell   *ll;
1764
1765                 foreach(ll, wcoList)
1766                 {
1767                         WithCheckOption *wco = (WithCheckOption *) lfirst(ll);
1768                         ExprState  *wcoExpr = ExecInitExpr((Expr *) wco->qual,
1769                                                                                            mtstate->mt_plans[i]);
1770
1771                         wcoExprs = lappend(wcoExprs, wcoExpr);
1772                 }
1773
1774                 resultRelInfo->ri_WithCheckOptions = wcoList;
1775                 resultRelInfo->ri_WithCheckOptionExprs = wcoExprs;
1776                 resultRelInfo++;
1777                 i++;
1778         }
1779
1780         /*
1781          * Build WITH CHECK OPTION constraints for each leaf partition rel.
1782          * Note that we didn't build the withCheckOptionList for each partition
1783          * within the planner, but simple translation of the varattnos for each
1784          * partition will suffice.  This only occurs for the INSERT case;
1785          * UPDATE/DELETE cases are handled above.
1786          */
1787         if (node->withCheckOptionLists != NIL && mtstate->mt_num_partitions > 0)
1788         {
1789                 List            *wcoList;
1790
1791                 Assert(operation == CMD_INSERT);
1792                 resultRelInfo = mtstate->mt_partitions;
1793                 wcoList = linitial(node->withCheckOptionLists);
1794                 for (i = 0; i < mtstate->mt_num_partitions; i++)
1795                 {
1796                         Relation        partrel = resultRelInfo->ri_RelationDesc;
1797                         List       *mapped_wcoList;
1798                         List       *wcoExprs = NIL;
1799                         ListCell   *ll;
1800
1801                         /* varno = node->nominalRelation */
1802                         mapped_wcoList = map_partition_varattnos(wcoList,
1803                                                                                                          node->nominalRelation,
1804                                                                                                          partrel, rel);
1805                         foreach(ll, mapped_wcoList)
1806                         {
1807                                 WithCheckOption *wco = (WithCheckOption *) lfirst(ll);
1808                                 ExprState  *wcoExpr = ExecInitExpr((Expr *) wco->qual,
1809                                                                                            mtstate->mt_plans[i]);
1810
1811                                 wcoExprs = lappend(wcoExprs, wcoExpr);
1812                         }
1813
1814                         resultRelInfo->ri_WithCheckOptions = mapped_wcoList;
1815                         resultRelInfo->ri_WithCheckOptionExprs = wcoExprs;
1816                         resultRelInfo++;
1817                 }
1818         }
1819
1820         /*
1821          * Initialize RETURNING projections if needed.
1822          */
1823         if (node->returningLists)
1824         {
1825                 TupleTableSlot *slot;
1826                 ExprContext *econtext;
1827                 List       *returningList;
1828
1829                 /*
1830                  * Initialize result tuple slot and assign its rowtype using the first
1831                  * RETURNING list.  We assume the rest will look the same.
1832                  */
1833                 tupDesc = ExecTypeFromTL((List *) linitial(node->returningLists),
1834                                                                  false);
1835
1836                 /* Set up a slot for the output of the RETURNING projection(s) */
1837                 ExecInitResultTupleSlot(estate, &mtstate->ps);
1838                 ExecAssignResultType(&mtstate->ps, tupDesc);
1839                 slot = mtstate->ps.ps_ResultTupleSlot;
1840
1841                 /* Need an econtext too */
1842                 econtext = CreateExprContext(estate);
1843                 mtstate->ps.ps_ExprContext = econtext;
1844
1845                 /*
1846                  * Build a projection for each result rel.
1847                  */
1848                 resultRelInfo = mtstate->resultRelInfo;
1849                 foreach(l, node->returningLists)
1850                 {
1851                         List       *rlist = (List *) lfirst(l);
1852                         List       *rliststate;
1853
1854                         rliststate = (List *) ExecInitExpr((Expr *) rlist, &mtstate->ps);
1855                         resultRelInfo->ri_projectReturning =
1856                                 ExecBuildProjectionInfo(rliststate, econtext, slot,
1857                                                                          resultRelInfo->ri_RelationDesc->rd_att);
1858                         resultRelInfo++;
1859                 }
1860
1861                 /*
1862                  * Build a projection for each leaf partition rel.  Note that we
1863                  * didn't build the returningList for each partition within the
1864                  * planner, but simple translation of the varattnos for each partition
1865                  * will suffice.  This only occurs for the INSERT case; UPDATE/DELETE
1866                  * are handled above.
1867                  */
1868                 resultRelInfo = mtstate->mt_partitions;
1869                 returningList = linitial(node->returningLists);
1870                 for (i = 0; i < mtstate->mt_num_partitions; i++)
1871                 {
1872                         Relation        partrel = resultRelInfo->ri_RelationDesc;
1873                         List       *rlist,
1874                                            *rliststate;
1875
1876                         /* varno = node->nominalRelation */
1877                         rlist = map_partition_varattnos(returningList,
1878                                                                                         node->nominalRelation,
1879                                                                                         partrel, rel);
1880                         rliststate = (List *) ExecInitExpr((Expr *) rlist, &mtstate->ps);
1881                         resultRelInfo->ri_projectReturning =
1882                                 ExecBuildProjectionInfo(rliststate, econtext, slot,
1883                                                                          resultRelInfo->ri_RelationDesc->rd_att);
1884                         resultRelInfo++;
1885                 }
1886         }
1887         else
1888         {
1889                 /*
1890                  * We still must construct a dummy result tuple type, because InitPlan
1891                  * expects one (maybe should change that?).
1892                  */
1893                 tupDesc = ExecTypeFromTL(NIL, false);
1894                 ExecInitResultTupleSlot(estate, &mtstate->ps);
1895                 ExecAssignResultType(&mtstate->ps, tupDesc);
1896
1897                 mtstate->ps.ps_ExprContext = NULL;
1898         }
1899
1900         /*
1901          * If needed, Initialize target list, projection and qual for ON CONFLICT
1902          * DO UPDATE.
1903          */
1904         resultRelInfo = mtstate->resultRelInfo;
1905         if (node->onConflictAction == ONCONFLICT_UPDATE)
1906         {
1907                 ExprContext *econtext;
1908                 ExprState  *setexpr;
1909                 TupleDesc       tupDesc;
1910
1911                 /* insert may only have one plan, inheritance is not expanded */
1912                 Assert(nplans == 1);
1913
1914                 /* already exists if created by RETURNING processing above */
1915                 if (mtstate->ps.ps_ExprContext == NULL)
1916                         ExecAssignExprContext(estate, &mtstate->ps);
1917
1918                 econtext = mtstate->ps.ps_ExprContext;
1919
1920                 /* initialize slot for the existing tuple */
1921                 mtstate->mt_existing = ExecInitExtraTupleSlot(mtstate->ps.state);
1922                 ExecSetSlotDescriptor(mtstate->mt_existing,
1923                                                           resultRelInfo->ri_RelationDesc->rd_att);
1924
1925                 /* carried forward solely for the benefit of explain */
1926                 mtstate->mt_excludedtlist = node->exclRelTlist;
1927
1928                 /* create target slot for UPDATE SET projection */
1929                 tupDesc = ExecTypeFromTL((List *) node->onConflictSet,
1930                                                  resultRelInfo->ri_RelationDesc->rd_rel->relhasoids);
1931                 mtstate->mt_conflproj = ExecInitExtraTupleSlot(mtstate->ps.state);
1932                 ExecSetSlotDescriptor(mtstate->mt_conflproj, tupDesc);
1933
1934                 /* build UPDATE SET expression and projection state */
1935                 setexpr = ExecInitExpr((Expr *) node->onConflictSet, &mtstate->ps);
1936                 resultRelInfo->ri_onConflictSetProj =
1937                         ExecBuildProjectionInfo((List *) setexpr, econtext,
1938                                                                         mtstate->mt_conflproj,
1939                                                                         resultRelInfo->ri_RelationDesc->rd_att);
1940
1941                 /* build DO UPDATE WHERE clause expression */
1942                 if (node->onConflictWhere)
1943                 {
1944                         ExprState  *qualexpr;
1945
1946                         qualexpr = ExecInitExpr((Expr *) node->onConflictWhere,
1947                                                                         &mtstate->ps);
1948
1949                         resultRelInfo->ri_onConflictSetWhere = (List *) qualexpr;
1950                 }
1951         }
1952
1953         /*
1954          * If we have any secondary relations in an UPDATE or DELETE, they need to
1955          * be treated like non-locked relations in SELECT FOR UPDATE, ie, the
1956          * EvalPlanQual mechanism needs to be told about them.  Locate the
1957          * relevant ExecRowMarks.
1958          */
1959         foreach(l, node->rowMarks)
1960         {
1961                 PlanRowMark *rc = (PlanRowMark *) lfirst(l);
1962                 ExecRowMark *erm;
1963
1964                 Assert(IsA(rc, PlanRowMark));
1965
1966                 /* ignore "parent" rowmarks; they are irrelevant at runtime */
1967                 if (rc->isParent)
1968                         continue;
1969
1970                 /* find ExecRowMark (same for all subplans) */
1971                 erm = ExecFindRowMark(estate, rc->rti, false);
1972
1973                 /* build ExecAuxRowMark for each subplan */
1974                 for (i = 0; i < nplans; i++)
1975                 {
1976                         ExecAuxRowMark *aerm;
1977
1978                         subplan = mtstate->mt_plans[i]->plan;
1979                         aerm = ExecBuildAuxRowMark(erm, subplan->targetlist);
1980                         mtstate->mt_arowmarks[i] = lappend(mtstate->mt_arowmarks[i], aerm);
1981                 }
1982         }
1983
1984         /* select first subplan */
1985         mtstate->mt_whichplan = 0;
1986         subplan = (Plan *) linitial(node->plans);
1987         EvalPlanQualSetPlan(&mtstate->mt_epqstate, subplan,
1988                                                 mtstate->mt_arowmarks[0]);
1989
1990         /*
1991          * Initialize the junk filter(s) if needed.  INSERT queries need a filter
1992          * if there are any junk attrs in the tlist.  UPDATE and DELETE always
1993          * need a filter, since there's always a junk 'ctid' or 'wholerow'
1994          * attribute present --- no need to look first.
1995          *
1996          * If there are multiple result relations, each one needs its own junk
1997          * filter.  Note multiple rels are only possible for UPDATE/DELETE, so we
1998          * can't be fooled by some needing a filter and some not.
1999          *
2000          * This section of code is also a convenient place to verify that the
2001          * output of an INSERT or UPDATE matches the target table(s).
2002          */
2003         {
2004                 bool            junk_filter_needed = false;
2005
2006                 switch (operation)
2007                 {
2008                         case CMD_INSERT:
2009                                 foreach(l, subplan->targetlist)
2010                                 {
2011                                         TargetEntry *tle = (TargetEntry *) lfirst(l);
2012
2013                                         if (tle->resjunk)
2014                                         {
2015                                                 junk_filter_needed = true;
2016                                                 break;
2017                                         }
2018                                 }
2019                                 break;
2020                         case CMD_UPDATE:
2021                         case CMD_DELETE:
2022                                 junk_filter_needed = true;
2023                                 break;
2024                         default:
2025                                 elog(ERROR, "unknown operation");
2026                                 break;
2027                 }
2028
2029                 if (junk_filter_needed)
2030                 {
2031                         resultRelInfo = mtstate->resultRelInfo;
2032                         for (i = 0; i < nplans; i++)
2033                         {
2034                                 JunkFilter *j;
2035
2036                                 subplan = mtstate->mt_plans[i]->plan;
2037                                 if (operation == CMD_INSERT || operation == CMD_UPDATE)
2038                                         ExecCheckPlanOutput(resultRelInfo->ri_RelationDesc,
2039                                                                                 subplan->targetlist);
2040
2041                                 j = ExecInitJunkFilter(subplan->targetlist,
2042                                                         resultRelInfo->ri_RelationDesc->rd_att->tdhasoid,
2043                                                                            ExecInitExtraTupleSlot(estate));
2044
2045                                 if (operation == CMD_UPDATE || operation == CMD_DELETE)
2046                                 {
2047                                         /* For UPDATE/DELETE, find the appropriate junk attr now */
2048                                         char            relkind;
2049
2050                                         relkind = resultRelInfo->ri_RelationDesc->rd_rel->relkind;
2051                                         if (relkind == RELKIND_RELATION ||
2052                                                 relkind == RELKIND_MATVIEW ||
2053                                                 relkind == RELKIND_PARTITIONED_TABLE)
2054                                         {
2055                                                 j->jf_junkAttNo = ExecFindJunkAttribute(j, "ctid");
2056                                                 if (!AttributeNumberIsValid(j->jf_junkAttNo))
2057                                                         elog(ERROR, "could not find junk ctid column");
2058                                         }
2059                                         else if (relkind == RELKIND_FOREIGN_TABLE)
2060                                         {
2061                                                 /*
2062                                                  * When there is an AFTER trigger, there should be a
2063                                                  * wholerow attribute.
2064                                                  */
2065                                                 j->jf_junkAttNo = ExecFindJunkAttribute(j, "wholerow");
2066                                         }
2067                                         else
2068                                         {
2069                                                 j->jf_junkAttNo = ExecFindJunkAttribute(j, "wholerow");
2070                                                 if (!AttributeNumberIsValid(j->jf_junkAttNo))
2071                                                         elog(ERROR, "could not find junk wholerow column");
2072                                         }
2073                                 }
2074
2075                                 resultRelInfo->ri_junkFilter = j;
2076                                 resultRelInfo++;
2077                         }
2078                 }
2079                 else
2080                 {
2081                         if (operation == CMD_INSERT)
2082                                 ExecCheckPlanOutput(mtstate->resultRelInfo->ri_RelationDesc,
2083                                                                         subplan->targetlist);
2084                 }
2085         }
2086
2087         /*
2088          * Set up a tuple table slot for use for trigger output tuples. In a plan
2089          * containing multiple ModifyTable nodes, all can share one such slot, so
2090          * we keep it in the estate.
2091          */
2092         if (estate->es_trig_tuple_slot == NULL)
2093                 estate->es_trig_tuple_slot = ExecInitExtraTupleSlot(estate);
2094
2095         /*
2096          * Lastly, if this is not the primary (canSetTag) ModifyTable node, add it
2097          * to estate->es_auxmodifytables so that it will be run to completion by
2098          * ExecPostprocessPlan.  (It'd actually work fine to add the primary
2099          * ModifyTable node too, but there's no need.)  Note the use of lcons not
2100          * lappend: we need later-initialized ModifyTable nodes to be shut down
2101          * before earlier ones.  This ensures that we don't throw away RETURNING
2102          * rows that need to be seen by a later CTE subplan.
2103          */
2104         if (!mtstate->canSetTag)
2105                 estate->es_auxmodifytables = lcons(mtstate,
2106                                                                                    estate->es_auxmodifytables);
2107
2108         return mtstate;
2109 }
2110
2111 /* ----------------------------------------------------------------
2112  *              ExecEndModifyTable
2113  *
2114  *              Shuts down the plan.
2115  *
2116  *              Returns nothing of interest.
2117  * ----------------------------------------------------------------
2118  */
2119 void
2120 ExecEndModifyTable(ModifyTableState *node)
2121 {
2122         int                     i;
2123
2124         /*
2125          * Allow any FDWs to shut down
2126          */
2127         for (i = 0; i < node->mt_nplans; i++)
2128         {
2129                 ResultRelInfo *resultRelInfo = node->resultRelInfo + i;
2130
2131                 if (!resultRelInfo->ri_usesFdwDirectModify &&
2132                         resultRelInfo->ri_FdwRoutine != NULL &&
2133                         resultRelInfo->ri_FdwRoutine->EndForeignModify != NULL)
2134                         resultRelInfo->ri_FdwRoutine->EndForeignModify(node->ps.state,
2135                                                                                                                    resultRelInfo);
2136         }
2137
2138         /*
2139          * Close all the partitioned tables, leaf partitions, and their indices
2140          *
2141          * Remember node->mt_partition_dispatch_info[0] corresponds to the root
2142          * partitioned table, which we must not try to close, because it is the
2143          * main target table of the query that will be closed by ExecEndPlan().
2144          * Also, tupslot is NULL for the root partitioned table.
2145          */
2146         for (i = 1; i < node->mt_num_dispatch; i++)
2147         {
2148                 PartitionDispatch pd = node->mt_partition_dispatch_info[i];
2149
2150                 heap_close(pd->reldesc, NoLock);
2151                 ExecDropSingleTupleTableSlot(pd->tupslot);
2152         }
2153         for (i = 0; i < node->mt_num_partitions; i++)
2154         {
2155                 ResultRelInfo *resultRelInfo = node->mt_partitions + i;
2156
2157                 ExecCloseIndices(resultRelInfo);
2158                 heap_close(resultRelInfo->ri_RelationDesc, NoLock);
2159         }
2160
2161         /* Release the standalone partition tuple descriptor, if any */
2162         if (node->mt_partition_tuple_slot)
2163                 ExecDropSingleTupleTableSlot(node->mt_partition_tuple_slot);
2164
2165         /*
2166          * Free the exprcontext
2167          */
2168         ExecFreeExprContext(&node->ps);
2169
2170         /*
2171          * clean out the tuple table
2172          */
2173         ExecClearTuple(node->ps.ps_ResultTupleSlot);
2174
2175         /*
2176          * Terminate EPQ execution if active
2177          */
2178         EvalPlanQualEnd(&node->mt_epqstate);
2179
2180         /*
2181          * shut down subplans
2182          */
2183         for (i = 0; i < node->mt_nplans; i++)
2184                 ExecEndNode(node->mt_plans[i]);
2185 }
2186
2187 void
2188 ExecReScanModifyTable(ModifyTableState *node)
2189 {
2190         /*
2191          * Currently, we don't need to support rescan on ModifyTable nodes. The
2192          * semantics of that would be a bit debatable anyway.
2193          */
2194         elog(ERROR, "ExecReScanModifyTable is not implemented");
2195 }