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