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