2424#include "nodes/makefuncs.h"
2525#include "partitioning/partbounds.h"
2626#include "partitioning/partprune.h"
27+ #include "rewrite/rewriteManip.h"
2728#include "utils/lsyscache.h"
2829#include "utils/partcache.h"
2930#include "utils/rel.h"
@@ -307,8 +308,12 @@ ExecInitPartitionInfo(ModifyTableState *mtstate,
307308ModifyTable * node = (ModifyTable * )mtstate -> ps .plan ;
308309Relation rootrel = resultRelInfo -> ri_RelationDesc ,
309310partrel ;
311+ Relation firstResultRel = mtstate -> resultRelInfo [0 ].ri_RelationDesc ;
310312ResultRelInfo * leaf_part_rri ;
311313MemoryContext oldContext ;
314+ AttrNumber * part_attnos = NULL ;
315+ bool found_whole_row ;
316+ bool equalTupdescs ;
312317
313318/*
314319 * We locked all the partitions in ExecSetupPartitionTupleRouting
@@ -356,6 +361,10 @@ ExecInitPartitionInfo(ModifyTableState *mtstate,
356361(node != NULL &&
357362node -> onConflictAction != ONCONFLICT_NONE ));
358363
364+ /* if tuple descs are identical, we don't need to map the attrs */
365+ equalTupdescs = equalTupleDescs (RelationGetDescr (partrel ),
366+ RelationGetDescr (firstResultRel ));
367+
359368/*
360369 * Build WITH CHECK OPTION constraints for the partition. Note that we
361370 * didn't build the withCheckOptionList for partitions within the planner,
@@ -369,7 +378,6 @@ ExecInitPartitionInfo(ModifyTableState *mtstate,
369378List * wcoExprs = NIL ;
370379ListCell * ll ;
371380int firstVarno = mtstate -> resultRelInfo [0 ].ri_RangeTableIndex ;
372- Relation firstResultRel = mtstate -> resultRelInfo [0 ].ri_RelationDesc ;
373381
374382/*
375383 * In the case of INSERT on a partitioned table, there is only one
@@ -397,8 +405,22 @@ ExecInitPartitionInfo(ModifyTableState *mtstate,
397405/*
398406 * Convert Vars in it to contain this partition's attribute numbers.
399407 */
400- wcoList = map_partition_varattnos (wcoList ,firstVarno ,
401- partrel ,firstResultRel ,NULL );
408+ if (!equalTupdescs )
409+ {
410+ part_attnos =
411+ convert_tuples_by_name_map (RelationGetDescr (partrel ),
412+ RelationGetDescr (firstResultRel ),
413+ gettext_noop ("could not convert row type" ));
414+ wcoList = (List * )
415+ map_variable_attnos ((Node * )wcoList ,
416+ firstVarno ,0 ,
417+ part_attnos ,
418+ RelationGetDescr (firstResultRel )-> natts ,
419+ RelationGetForm (partrel )-> reltype ,
420+ & found_whole_row );
421+ /* We ignore the value of found_whole_row. */
422+ }
423+
402424foreach (ll ,wcoList )
403425{
404426WithCheckOption * wco = castNode (WithCheckOption ,lfirst (ll ));
@@ -425,7 +447,6 @@ ExecInitPartitionInfo(ModifyTableState *mtstate,
425447ExprContext * econtext ;
426448List * returningList ;
427449int firstVarno = mtstate -> resultRelInfo [0 ].ri_RangeTableIndex ;
428- Relation firstResultRel = mtstate -> resultRelInfo [0 ].ri_RelationDesc ;
429450
430451/* See the comment above for WCO lists. */
431452Assert ((node -> operation == CMD_INSERT &&
@@ -443,12 +464,26 @@ ExecInitPartitionInfo(ModifyTableState *mtstate,
443464 */
444465returningList = linitial (node -> returningLists );
445466
446- /*
447- * Convert Vars in it to contain this partition's attribute numbers.
448- */
449- returningList = map_partition_varattnos (returningList ,firstVarno ,
450- partrel ,firstResultRel ,
451- NULL );
467+ if (!equalTupdescs )
468+ {
469+ /*
470+ * Convert Vars in it to contain this partition's attribute numbers.
471+ */
472+ if (part_attnos == NULL )
473+ part_attnos =
474+ convert_tuples_by_name_map (RelationGetDescr (partrel ),
475+ RelationGetDescr (firstResultRel ),
476+ gettext_noop ("could not convert row type" ));
477+ returningList = (List * )
478+ map_variable_attnos ((Node * )returningList ,
479+ firstVarno ,0 ,
480+ part_attnos ,
481+ RelationGetDescr (firstResultRel )-> natts ,
482+ RelationGetForm (partrel )-> reltype ,
483+ & found_whole_row );
484+ /* We ignore the value of found_whole_row. */
485+ }
486+
452487leaf_part_rri -> ri_returningList = returningList ;
453488
454489/*
@@ -473,7 +508,6 @@ ExecInitPartitionInfo(ModifyTableState *mtstate,
473508{
474509TupleConversionMap * map = proute -> parent_child_tupconv_maps [partidx ];
475510int firstVarno = mtstate -> resultRelInfo [0 ].ri_RangeTableIndex ;
476- Relation firstResultRel = mtstate -> resultRelInfo [0 ].ri_RelationDesc ;
477511TupleDesc partrelDesc = RelationGetDescr (partrel );
478512ExprContext * econtext = mtstate -> ps .ps_ExprContext ;
479513ListCell * lc ;
@@ -549,17 +583,33 @@ ExecInitPartitionInfo(ModifyTableState *mtstate,
549583 * target relation (firstVarno).
550584 */
551585onconflset = (List * )copyObject ((Node * )node -> onConflictSet );
552- onconflset =
553- map_partition_varattnos (onconflset ,INNER_VAR ,partrel ,
554- firstResultRel ,& found_whole_row );
555- Assert (!found_whole_row );
556- onconflset =
557- map_partition_varattnos (onconflset ,firstVarno ,partrel ,
558- firstResultRel ,& found_whole_row );
559- Assert (!found_whole_row );
560-
561- /* Finally, adjust this tlist to match the partition. */
562- onconflset = adjust_partition_tlist (onconflset ,map );
586+ if (!equalTupdescs )
587+ {
588+ if (part_attnos == NULL )
589+ part_attnos =
590+ convert_tuples_by_name_map (RelationGetDescr (partrel ),
591+ RelationGetDescr (firstResultRel ),
592+ gettext_noop ("could not convert row type" ));
593+ onconflset = (List * )
594+ map_variable_attnos ((Node * )onconflset ,
595+ INNER_VAR ,0 ,
596+ part_attnos ,
597+ RelationGetDescr (firstResultRel )-> natts ,
598+ RelationGetForm (partrel )-> reltype ,
599+ & found_whole_row );
600+ /* We ignore the value of found_whole_row. */
601+ onconflset = (List * )
602+ map_variable_attnos ((Node * )onconflset ,
603+ firstVarno ,0 ,
604+ part_attnos ,
605+ RelationGetDescr (firstResultRel )-> natts ,
606+ RelationGetForm (partrel )-> reltype ,
607+ & found_whole_row );
608+ /* We ignore the value of found_whole_row. */
609+
610+ /* Finally, adjust this tlist to match the partition. */
611+ onconflset = adjust_partition_tlist (onconflset ,map );
612+ }
563613
564614/*
565615 * Build UPDATE SET's projection info. The user of this
@@ -587,14 +637,25 @@ ExecInitPartitionInfo(ModifyTableState *mtstate,
587637List * clause ;
588638
589639clause = copyObject ((List * )node -> onConflictWhere );
590- clause = map_partition_varattnos (clause ,INNER_VAR ,
591- partrel ,firstResultRel ,
592- & found_whole_row );
593- Assert (!found_whole_row );
594- clause = map_partition_varattnos (clause ,firstVarno ,
595- partrel ,firstResultRel ,
596- & found_whole_row );
597- Assert (!found_whole_row );
640+ if (!equalTupdescs )
641+ {
642+ clause = (List * )
643+ map_variable_attnos ((Node * )clause ,
644+ INNER_VAR ,0 ,
645+ part_attnos ,
646+ RelationGetDescr (firstResultRel )-> natts ,
647+ RelationGetForm (partrel )-> reltype ,
648+ & found_whole_row );
649+ /* We ignore the value of found_whole_row. */
650+ clause = (List * )
651+ map_variable_attnos ((Node * )clause ,
652+ firstVarno ,0 ,
653+ part_attnos ,
654+ RelationGetDescr (firstResultRel )-> natts ,
655+ RelationGetForm (partrel )-> reltype ,
656+ & found_whole_row );
657+ /* We ignore the value of found_whole_row. */
658+ }
598659leaf_part_rri -> ri_onConflict -> oc_WhereClause =
599660ExecInitQual ((List * )clause ,& mtstate -> ps );
600661}