@@ -1415,59 +1415,6 @@ BeginCopy(ParseState *pstate,
14151415 (errcode (ERRCODE_UNDEFINED_COLUMN ),
14161416 errmsg ("table \"%s\" does not have OIDs" ,
14171417 RelationGetRelationName (cstate -> rel ))));
1418-
1419- /*
1420- * If there are any triggers with transition tables on the named
1421- * relation, we need to be prepared to capture transition tuples.
1422- */
1423- cstate -> transition_capture = MakeTransitionCaptureState (rel -> trigdesc );
1424-
1425- /* Initialize state for CopyFrom tuple routing. */
1426- if (is_from && rel -> rd_rel -> relkind == RELKIND_PARTITIONED_TABLE )
1427- {
1428- PartitionDispatch * partition_dispatch_info ;
1429- ResultRelInfo * partitions ;
1430- TupleConversionMap * * partition_tupconv_maps ;
1431- TupleTableSlot * partition_tuple_slot ;
1432- int num_parted ,
1433- num_partitions ;
1434-
1435- ExecSetupPartitionTupleRouting (rel ,
1436- 1 ,
1437- & partition_dispatch_info ,
1438- & partitions ,
1439- & partition_tupconv_maps ,
1440- & partition_tuple_slot ,
1441- & num_parted , & num_partitions );
1442- cstate -> partition_dispatch_info = partition_dispatch_info ;
1443- cstate -> num_dispatch = num_parted ;
1444- cstate -> partitions = partitions ;
1445- cstate -> num_partitions = num_partitions ;
1446- cstate -> partition_tupconv_maps = partition_tupconv_maps ;
1447- cstate -> partition_tuple_slot = partition_tuple_slot ;
1448-
1449- /*
1450- * If we are capturing transition tuples, they may need to be
1451- * converted from partition format back to partitioned table
1452- * format (this is only ever necessary if a BEFORE trigger
1453- * modifies the tuple).
1454- */
1455- if (cstate -> transition_capture != NULL )
1456- {
1457- int i ;
1458-
1459- cstate -> transition_tupconv_maps = (TupleConversionMap * * )
1460- palloc0 (sizeof (TupleConversionMap * ) *
1461- cstate -> num_partitions );
1462- for (i = 0 ; i < cstate -> num_partitions ; ++ i )
1463- {
1464- cstate -> transition_tupconv_maps [i ] =
1465- convert_tuples_by_name (RelationGetDescr (cstate -> partitions [i ].ri_RelationDesc ),
1466- RelationGetDescr (rel ),
1467- gettext_noop ("could not convert row type" ));
1468- }
1469- }
1470- }
14711418 }
14721419 else
14731420 {
@@ -2482,6 +2429,63 @@ CopyFrom(CopyState cstate)
24822429 /* Triggers might need a slot as well */
24832430 estate -> es_trig_tuple_slot = ExecInitExtraTupleSlot (estate );
24842431
2432+ /*
2433+ * If there are any triggers with transition tables on the named relation,
2434+ * we need to be prepared to capture transition tuples.
2435+ */
2436+ cstate -> transition_capture =
2437+ MakeTransitionCaptureState (cstate -> rel -> trigdesc );
2438+
2439+ /*
2440+ * If the named relation is a partitioned table, initialize state for
2441+ * CopyFrom tuple routing.
2442+ */
2443+ if (cstate -> rel -> rd_rel -> relkind == RELKIND_PARTITIONED_TABLE )
2444+ {
2445+ PartitionDispatch * partition_dispatch_info ;
2446+ ResultRelInfo * partitions ;
2447+ TupleConversionMap * * partition_tupconv_maps ;
2448+ TupleTableSlot * partition_tuple_slot ;
2449+ int num_parted ,
2450+ num_partitions ;
2451+
2452+ ExecSetupPartitionTupleRouting (cstate -> rel ,
2453+ 1 ,
2454+ estate ,
2455+ & partition_dispatch_info ,
2456+ & partitions ,
2457+ & partition_tupconv_maps ,
2458+ & partition_tuple_slot ,
2459+ & num_parted , & num_partitions );
2460+ cstate -> partition_dispatch_info = partition_dispatch_info ;
2461+ cstate -> num_dispatch = num_parted ;
2462+ cstate -> partitions = partitions ;
2463+ cstate -> num_partitions = num_partitions ;
2464+ cstate -> partition_tupconv_maps = partition_tupconv_maps ;
2465+ cstate -> partition_tuple_slot = partition_tuple_slot ;
2466+
2467+ /*
2468+ * If we are capturing transition tuples, they may need to be
2469+ * converted from partition format back to partitioned table format
2470+ * (this is only ever necessary if a BEFORE trigger modifies the
2471+ * tuple).
2472+ */
2473+ if (cstate -> transition_capture != NULL )
2474+ {
2475+ int i ;
2476+
2477+ cstate -> transition_tupconv_maps = (TupleConversionMap * * )
2478+ palloc0 (sizeof (TupleConversionMap * ) * cstate -> num_partitions );
2479+ for (i = 0 ; i < cstate -> num_partitions ; ++ i )
2480+ {
2481+ cstate -> transition_tupconv_maps [i ] =
2482+ convert_tuples_by_name (RelationGetDescr (cstate -> partitions [i ].ri_RelationDesc ),
2483+ RelationGetDescr (cstate -> rel ),
2484+ gettext_noop ("could not convert row type" ));
2485+ }
2486+ }
2487+ }
2488+
24852489 /*
24862490 * It's more efficient to prepare a bunch of tuples for insertion, and
24872491 * insert them in one heap_multi_insert() call, than call heap_insert()
0 commit comments