@@ -3772,6 +3772,16 @@ static AfterTriggersTableData *GetAfterTriggersTableData(Oid relid,
37723772 CmdType cmdType );
37733773static TupleTableSlot * GetAfterTriggersStoreSlot (AfterTriggersTableData * table ,
37743774 TupleDesc tupdesc );
3775+ static Tuplestorestate * GetAfterTriggersTransitionTable (int event ,
3776+ TupleTableSlot * oldslot ,
3777+ TupleTableSlot * newslot ,
3778+ TransitionCaptureState * transition_capture );
3779+ static void TransitionTableAddTuple (EState * estate ,
3780+ TransitionCaptureState * transition_capture ,
3781+ ResultRelInfo * relinfo ,
3782+ TupleTableSlot * slot ,
3783+ TupleTableSlot * original_insert_tuple ,
3784+ Tuplestorestate * tuplestore );
37753785static void AfterTriggerFreeQuery (AfterTriggersQueryData * qs );
37763786static SetConstraintState SetConstraintStateCreate (int numalloc );
37773787static SetConstraintState SetConstraintStateCopy (SetConstraintState state );
@@ -5158,6 +5168,92 @@ AfterTriggerEndSubXact(bool isCommit)
51585168 }
51595169}
51605170
5171+ /*
5172+ * Get the transition table for the given event and depending on whether we are
5173+ * processing the old or the new tuple.
5174+ */
5175+ static Tuplestorestate *
5176+ GetAfterTriggersTransitionTable (int event ,
5177+ TupleTableSlot * oldslot ,
5178+ TupleTableSlot * newslot ,
5179+ TransitionCaptureState * transition_capture )
5180+ {
5181+ Tuplestorestate * tuplestore = NULL ;
5182+ bool delete_old_table = transition_capture -> tcs_delete_old_table ;
5183+ bool update_old_table = transition_capture -> tcs_update_old_table ;
5184+ bool update_new_table = transition_capture -> tcs_update_new_table ;
5185+ bool insert_new_table = transition_capture -> tcs_insert_new_table ;
5186+
5187+ /*
5188+ * For INSERT events NEW should be non-NULL, for DELETE events OLD should
5189+ * be non-NULL, whereas for UPDATE events normally both OLD and NEW are
5190+ * non-NULL. But for UPDATE events fired for capturing transition tuples
5191+ * during UPDATE partition-key row movement, OLD is NULL when the event is
5192+ * for a row being inserted, whereas NEW is NULL when the event is for a
5193+ * row being deleted.
5194+ */
5195+ Assert (!(event == TRIGGER_EVENT_DELETE && delete_old_table &&
5196+ TupIsNull (oldslot )));
5197+ Assert (!(event == TRIGGER_EVENT_INSERT && insert_new_table &&
5198+ TupIsNull (newslot )));
5199+
5200+ if (!TupIsNull (oldslot ))
5201+ {
5202+ Assert (TupIsNull (newslot ));
5203+ if (event == TRIGGER_EVENT_DELETE && delete_old_table )
5204+ tuplestore = transition_capture -> tcs_private -> old_tuplestore ;
5205+ else if (event == TRIGGER_EVENT_UPDATE && update_old_table )
5206+ tuplestore = transition_capture -> tcs_private -> old_tuplestore ;
5207+ }
5208+ else if (!TupIsNull (newslot ))
5209+ {
5210+ Assert (TupIsNull (oldslot ));
5211+ if (event == TRIGGER_EVENT_INSERT && insert_new_table )
5212+ tuplestore = transition_capture -> tcs_private -> new_tuplestore ;
5213+ else if (event == TRIGGER_EVENT_UPDATE && update_new_table )
5214+ tuplestore = transition_capture -> tcs_private -> new_tuplestore ;
5215+ }
5216+
5217+ return tuplestore ;
5218+ }
5219+
5220+ /*
5221+ * Add the given heap tuple to the given tuplestore, applying the conversion
5222+ * map if necessary.
5223+ *
5224+ * If original_insert_tuple is given, we can add that tuple without conversion.
5225+ */
5226+ static void
5227+ TransitionTableAddTuple (EState * estate ,
5228+ TransitionCaptureState * transition_capture ,
5229+ ResultRelInfo * relinfo ,
5230+ TupleTableSlot * slot ,
5231+ TupleTableSlot * original_insert_tuple ,
5232+ Tuplestorestate * tuplestore )
5233+ {
5234+ TupleConversionMap * map ;
5235+
5236+ /*
5237+ * Nothing needs to be done if we don't have a tuplestore.
5238+ */
5239+ if (tuplestore == NULL )
5240+ return ;
5241+
5242+ if (original_insert_tuple )
5243+ tuplestore_puttupleslot (tuplestore , original_insert_tuple );
5244+ else if ((map = ExecGetChildToRootMap (relinfo )) != NULL )
5245+ {
5246+ AfterTriggersTableData * table = transition_capture -> tcs_private ;
5247+ TupleTableSlot * storeslot ;
5248+
5249+ storeslot = GetAfterTriggersStoreSlot (table , map -> outdesc );
5250+ execute_attr_map_slot (map -> attrMap , slot , storeslot );
5251+ tuplestore_puttupleslot (tuplestore , storeslot );
5252+ }
5253+ else
5254+ tuplestore_puttupleslot (tuplestore , slot );
5255+ }
5256+
51615257/* ----------
51625258 * AfterTriggerEnlargeQueryState()
51635259 *
@@ -5650,7 +5746,6 @@ AfterTriggerPendingOnRel(Oid relid)
56505746 return false;
56515747}
56525748
5653-
56545749/* ----------
56555750 * AfterTriggerSaveEvent()
56565751 *
@@ -5709,68 +5804,39 @@ AfterTriggerSaveEvent(EState *estate, ResultRelInfo *relinfo,
57095804 */
57105805 if (row_trigger && transition_capture != NULL )
57115806 {
5712- TupleTableSlot * original_insert_tuple = transition_capture -> tcs_original_insert_tuple ;
5713- TupleConversionMap * map = ExecGetChildToRootMap (relinfo );
5714- bool delete_old_table = transition_capture -> tcs_delete_old_table ;
5715- bool update_old_table = transition_capture -> tcs_update_old_table ;
5716- bool update_new_table = transition_capture -> tcs_update_new_table ;
5717- bool insert_new_table = transition_capture -> tcs_insert_new_table ;
57185807
57195808 /*
5720- * For INSERT events NEW should be non-NULL, for DELETE events OLD
5721- * should be non-NULL, whereas for UPDATE events normally both OLD and
5722- * NEW are non-NULL. But for UPDATE events fired for capturing
5723- * transition tuples during UPDATE partition-key row movement, OLD is
5724- * NULL when the event is for a row being inserted, whereas NEW is
5725- * NULL when the event is for a row being deleted.
5809+ * Capture the old tuple in the appropriate transition table based on
5810+ * the event.
57265811 */
5727- Assert (!(event == TRIGGER_EVENT_DELETE && delete_old_table &&
5728- TupIsNull (oldslot )));
5729- Assert (!(event == TRIGGER_EVENT_INSERT && insert_new_table &&
5730- TupIsNull (newslot )));
5731-
5732- if (!TupIsNull (oldslot ) &&
5733- ((event == TRIGGER_EVENT_DELETE && delete_old_table ) ||
5734- (event == TRIGGER_EVENT_UPDATE && update_old_table )))
5812+ if (!TupIsNull (oldslot ))
57355813 {
57365814 Tuplestorestate * old_tuplestore ;
57375815
5738- old_tuplestore = transition_capture -> tcs_private -> old_tuplestore ;
5739-
5740- if (map != NULL )
5741- {
5742- AfterTriggersTableData * table = transition_capture -> tcs_private ;
5743- TupleTableSlot * storeslot ;
5744-
5745- storeslot = GetAfterTriggersStoreSlot (table , map -> outdesc );
5746- execute_attr_map_slot (map -> attrMap , oldslot , storeslot );
5747- tuplestore_puttupleslot (old_tuplestore , storeslot );
5748- }
5749- else
5750- tuplestore_puttupleslot (old_tuplestore , oldslot );
5816+ old_tuplestore = GetAfterTriggersTransitionTable (event ,
5817+ oldslot ,
5818+ NULL ,
5819+ transition_capture );
5820+ TransitionTableAddTuple (estate , transition_capture , relinfo ,
5821+ oldslot , NULL , old_tuplestore );
57515822 }
5752- if (!TupIsNull (newslot ) &&
5753- ((event == TRIGGER_EVENT_INSERT && insert_new_table ) ||
5754- (event == TRIGGER_EVENT_UPDATE && update_new_table )))
5823+
5824+ /*
5825+ * Capture the new tuple in the appropriate transition table based on
5826+ * the event.
5827+ */
5828+ if (!TupIsNull (newslot ))
57555829 {
57565830 Tuplestorestate * new_tuplestore ;
57575831
5758- new_tuplestore = transition_capture -> tcs_private -> new_tuplestore ;
5759-
5760- if (original_insert_tuple != NULL )
5761- tuplestore_puttupleslot (new_tuplestore ,
5762- original_insert_tuple );
5763- else if (map != NULL )
5764- {
5765- AfterTriggersTableData * table = transition_capture -> tcs_private ;
5766- TupleTableSlot * storeslot ;
5767-
5768- storeslot = GetAfterTriggersStoreSlot (table , map -> outdesc );
5769- execute_attr_map_slot (map -> attrMap , newslot , storeslot );
5770- tuplestore_puttupleslot (new_tuplestore , storeslot );
5771- }
5772- else
5773- tuplestore_puttupleslot (new_tuplestore , newslot );
5832+ new_tuplestore = GetAfterTriggersTransitionTable (event ,
5833+ NULL ,
5834+ newslot ,
5835+ transition_capture );
5836+ TransitionTableAddTuple (estate , transition_capture , relinfo ,
5837+ newslot ,
5838+ transition_capture -> tcs_original_insert_tuple ,
5839+ new_tuplestore );
57745840 }
57755841
57765842 /*
0 commit comments