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,
307308 ModifyTable * node = (ModifyTable * ) mtstate -> ps .plan ;
308309 Relation rootrel = resultRelInfo -> ri_RelationDesc ,
309310 partrel ;
311+ Relation firstResultRel = mtstate -> resultRelInfo [0 ].ri_RelationDesc ;
310312 ResultRelInfo * leaf_part_rri ;
311313 MemoryContext 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 &&
357362 node -> 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,
369378 List * wcoExprs = NIL ;
370379 ListCell * ll ;
371380 int 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+
402424 foreach (ll , wcoList )
403425 {
404426 WithCheckOption * wco = castNode (WithCheckOption , lfirst (ll ));
@@ -425,7 +447,6 @@ ExecInitPartitionInfo(ModifyTableState *mtstate,
425447 ExprContext * econtext ;
426448 List * returningList ;
427449 int firstVarno = mtstate -> resultRelInfo [0 ].ri_RangeTableIndex ;
428- Relation firstResultRel = mtstate -> resultRelInfo [0 ].ri_RelationDesc ;
429450
430451 /* See the comment above for WCO lists. */
431452 Assert ((node -> operation == CMD_INSERT &&
@@ -443,12 +464,26 @@ ExecInitPartitionInfo(ModifyTableState *mtstate,
443464 */
444465 returningList = 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+
452487 leaf_part_rri -> ri_returningList = returningList ;
453488
454489 /*
@@ -473,7 +508,6 @@ ExecInitPartitionInfo(ModifyTableState *mtstate,
473508 {
474509 TupleConversionMap * map = proute -> parent_child_tupconv_maps [partidx ];
475510 int firstVarno = mtstate -> resultRelInfo [0 ].ri_RangeTableIndex ;
476- Relation firstResultRel = mtstate -> resultRelInfo [0 ].ri_RelationDesc ;
477511 TupleDesc partrelDesc = RelationGetDescr (partrel );
478512 ExprContext * econtext = mtstate -> ps .ps_ExprContext ;
479513 ListCell * lc ;
@@ -549,17 +583,33 @@ ExecInitPartitionInfo(ModifyTableState *mtstate,
549583 * target relation (firstVarno).
550584 */
551585 onconflset = (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,
587637 List * clause ;
588638
589639 clause = 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+ }
598659 leaf_part_rri -> ri_onConflict -> oc_WhereClause =
599660 ExecInitQual ((List * ) clause , & mtstate -> ps );
600661 }
0 commit comments