Skip to content

Commit 6973533

Browse files
committed
Revise child-to-root tuple conversion map management.
Store the tuple conversion map to convert a tuple from a child table's format to the root format in a new ri_ChildToRootMap field in ResultRelInfo. It is initialized if transition tuple capture for FOR STATEMENT triggers or INSERT tuple routing on a partitioned table is needed. Previously, ModifyTable kept the maps in the per-subplan ModifyTableState->mt_per_subplan_tupconv_maps array, or when tuple routing was used, in ResultRelInfo->ri_Partitioninfo->pi_PartitionToRootMap. The new field replaces both of those. Now that the child-to-root tuple conversion map is always available in ResultRelInfo (when needed), remove the TransitionCaptureState.tcs_map field. The callers of Exec*Trigger() functions no longer need to set or save it, which is much less confusing and bug-prone. Also, as a future optimization, this will allow us to delay creating the map for a given result relation until the relation is actually processed during execution. Author: Amit Langote Discussion: https://www.postgresql.org/message-id/CA%2BHiwqHtCWLdK-LO%3DNEsvOdHx%2B7yv4mE_zYK0i3BH7dXb-wxog%40mail.gmail.com
1 parent f49b85d commit 6973533

File tree

8 files changed

+84
-215
lines changed

8 files changed

+84
-215
lines changed

src/backend/commands/copy.c

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3106,31 +3106,14 @@ CopyFrom(CopyState cstate)
31063106

31073107
/*
31083108
* If we're capturing transition tuples, we might need to convert
3109-
* from the partition rowtype to root rowtype.
3109+
* from the partition rowtype to root rowtype. But if there are no
3110+
* BEFORE triggers on the partition that could change the tuple,
3111+
* we can just remember the original unconverted tuple to avoid a
3112+
* needless round trip conversion.
31103113
*/
31113114
if (cstate->transition_capture != NULL)
3112-
{
3113-
if (has_before_insert_row_trig)
3114-
{
3115-
/*
3116-
* If there are any BEFORE triggers on the partition,
3117-
* we'll have to be ready to convert their result back to
3118-
* tuplestore format.
3119-
*/
3120-
cstate->transition_capture->tcs_original_insert_tuple = NULL;
3121-
cstate->transition_capture->tcs_map =
3122-
resultRelInfo->ri_PartitionInfo->pi_PartitionToRootMap;
3123-
}
3124-
else
3125-
{
3126-
/*
3127-
* Otherwise, just remember the original unconverted
3128-
* tuple, to avoid a needless round trip conversion.
3129-
*/
3130-
cstate->transition_capture->tcs_original_insert_tuple = myslot;
3131-
cstate->transition_capture->tcs_map = NULL;
3132-
}
3133-
}
3115+
cstate->transition_capture->tcs_original_insert_tuple =
3116+
!has_before_insert_row_trig ? myslot : NULL;
31343117

31353118
/*
31363119
* We might need to convert from the root rowtype to the partition

src/backend/commands/trigger.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "commands/defrem.h"
3636
#include "commands/trigger.h"
3737
#include "executor/executor.h"
38+
#include "executor/execPartition.h"
3839
#include "miscadmin.h"
3940
#include "nodes/bitmapset.h"
4041
#include "nodes/makefuncs.h"
@@ -4292,9 +4293,10 @@ GetAfterTriggersTableData(Oid relid, CmdType cmdType)
42924293
* If there are no triggers in 'trigdesc' that request relevant transition
42934294
* tables, then return NULL.
42944295
*
4295-
* The resulting object can be passed to the ExecAR* functions. The caller
4296-
* should set tcs_map or tcs_original_insert_tuple as appropriate when dealing
4297-
* with child tables.
4296+
* The resulting object can be passed to the ExecAR* functions. When
4297+
* dealing with child tables, the caller can set tcs_original_insert_tuple
4298+
* to avoid having to reconstruct the original tuple in the root table's
4299+
* format.
42984300
*
42994301
* Note that we copy the flags from a parent table into this struct (rather
43004302
* than subsequently using the relation's TriggerDesc directly) so that we can
@@ -5389,7 +5391,7 @@ AfterTriggerSaveEvent(EState *estate, ResultRelInfo *relinfo,
53895391
if (row_trigger && transition_capture != NULL)
53905392
{
53915393
TupleTableSlot *original_insert_tuple = transition_capture->tcs_original_insert_tuple;
5392-
TupleConversionMap *map = transition_capture->tcs_map;
5394+
TupleConversionMap *map = relinfo->ri_ChildToRootMap;
53935395
bool delete_old_table = transition_capture->tcs_delete_old_table;
53945396
bool update_old_table = transition_capture->tcs_update_old_table;
53955397
bool update_new_table = transition_capture->tcs_update_new_table;

src/backend/executor/execMain.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,6 +1244,7 @@ InitResultRelInfo(ResultRelInfo *resultRelInfo,
12441244
resultRelInfo->ri_TrigNewSlot = NULL;
12451245
resultRelInfo->ri_PartitionRoot = partition_root;
12461246
resultRelInfo->ri_PartitionInfo = NULL; /* may be set later */
1247+
resultRelInfo->ri_ChildToRootMap = NULL;
12471248
resultRelInfo->ri_CopyMultiInsertBuffer = NULL;
12481249
}
12491250

src/backend/executor/execPartition.c

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -907,6 +907,15 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate,
907907
}
908908
}
909909

910+
/*
911+
* Also, if transition capture is required, store a map to convert tuples
912+
* from partition's rowtype to the root partition table's.
913+
*/
914+
if (mtstate->mt_transition_capture || mtstate->mt_oc_transition_capture)
915+
leaf_part_rri->ri_ChildToRootMap =
916+
convert_tuples_by_name(RelationGetDescr(leaf_part_rri->ri_RelationDesc),
917+
RelationGetDescr(leaf_part_rri->ri_PartitionRoot));
918+
910919
/*
911920
* Since we've just initialized this ResultRelInfo, it's not in any list
912921
* attached to the estate as yet. Add it, so that it can be found later.
@@ -976,20 +985,6 @@ ExecInitRoutingInfo(ModifyTableState *mtstate,
976985
else
977986
partrouteinfo->pi_PartitionTupleSlot = NULL;
978987

979-
/*
980-
* Also, if transition capture is required, store a map to convert tuples
981-
* from partition's rowtype to the root partition table's.
982-
*/
983-
if (mtstate &&
984-
(mtstate->mt_transition_capture || mtstate->mt_oc_transition_capture))
985-
{
986-
partrouteinfo->pi_PartitionToRootMap =
987-
convert_tuples_by_name(RelationGetDescr(partRelInfo->ri_RelationDesc),
988-
RelationGetDescr(partRelInfo->ri_PartitionRoot));
989-
}
990-
else
991-
partrouteinfo->pi_PartitionToRootMap = NULL;
992-
993988
/*
994989
* If the partition is a foreign table, let the FDW init itself for
995990
* routing tuples to the partition.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy