@@ -3772,6 +3772,16 @@ static AfterTriggersTableData *GetAfterTriggersTableData(Oid relid,
3772
3772
CmdType cmdType );
3773
3773
static TupleTableSlot * GetAfterTriggersStoreSlot (AfterTriggersTableData * table ,
3774
3774
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 );
3775
3785
static void AfterTriggerFreeQuery (AfterTriggersQueryData * qs );
3776
3786
static SetConstraintState SetConstraintStateCreate (int numalloc );
3777
3787
static SetConstraintState SetConstraintStateCopy (SetConstraintState state );
@@ -5158,6 +5168,92 @@ AfterTriggerEndSubXact(bool isCommit)
5158
5168
}
5159
5169
}
5160
5170
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
+
5161
5257
/* ----------
5162
5258
* AfterTriggerEnlargeQueryState()
5163
5259
*
@@ -5650,7 +5746,6 @@ AfterTriggerPendingOnRel(Oid relid)
5650
5746
return false;
5651
5747
}
5652
5748
5653
-
5654
5749
/* ----------
5655
5750
* AfterTriggerSaveEvent()
5656
5751
*
@@ -5709,68 +5804,39 @@ AfterTriggerSaveEvent(EState *estate, ResultRelInfo *relinfo,
5709
5804
*/
5710
5805
if (row_trigger && transition_capture != NULL )
5711
5806
{
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 ;
5718
5807
5719
5808
/*
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.
5726
5811
*/
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 ))
5735
5813
{
5736
5814
Tuplestorestate * old_tuplestore ;
5737
5815
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 );
5751
5822
}
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 ))
5755
5829
{
5756
5830
Tuplestorestate * new_tuplestore ;
5757
5831
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 );
5774
5840
}
5775
5841
5776
5842
/*