* ExecPrepareTupleRouting --- prepare for routing one tuple * * Determine the partition in which the tuple in slot is to be inserted, * and return its ResultRelInfo in *partRelInfo. The return value is * a slot holding the tuple of the partition rowtype. * * This also sets the transition table information in mtstate based on the * selected partition. */
| 2568 | * selected partition. |
| 2569 | */ |
| 2570 | static TupleTableSlot * |
| 2571 | ExecPrepareTupleRouting(ModifyTableState *mtstate, |
| 2572 | EState *estate, |
| 2573 | PartitionTupleRouting *proute, |
| 2574 | ResultRelInfo *targetRelInfo, |
| 2575 | TupleTableSlot *slot, |
| 2576 | ResultRelInfo **partRelInfo) |
| 2577 | { |
| 2578 | ResultRelInfo *partrel; |
| 2579 | TupleConversionMap *map; |
| 2580 | |
| 2581 | /* |
| 2582 | * Lookup the target partition's ResultRelInfo. If ExecFindPartition does |
| 2583 | * not find a valid partition for the tuple in 'slot' then an error is |
| 2584 | * raised. An error may also be raised if the found partition is not a |
| 2585 | * valid target for INSERTs. This is required since a partitioned table |
| 2586 | * UPDATE to another partition becomes a DELETE+INSERT. |
| 2587 | */ |
| 2588 | partrel = ExecFindPartition(mtstate, targetRelInfo, proute, slot, estate); |
| 2589 | |
| 2590 | /* |
| 2591 | * If we're capturing transition tuples, we might need to convert from the |
| 2592 | * partition rowtype to root partitioned table's rowtype. But if there |
| 2593 | * are no BEFORE triggers on the partition that could change the tuple, we |
| 2594 | * can just remember the original unconverted tuple to avoid a needless |
| 2595 | * round trip conversion. |
| 2596 | */ |
| 2597 | if (mtstate->mt_transition_capture != NULL) |
| 2598 | { |
| 2599 | bool has_before_insert_row_trig; |
| 2600 | |
| 2601 | has_before_insert_row_trig = (partrel->ri_TrigDesc && |
| 2602 | partrel->ri_TrigDesc->trig_insert_before_row); |
| 2603 | |
| 2604 | mtstate->mt_transition_capture->tcs_original_insert_tuple = |
| 2605 | !has_before_insert_row_trig ? slot : NULL; |
| 2606 | } |
| 2607 | |
| 2608 | /* |
| 2609 | * Convert the tuple, if necessary. |
| 2610 | */ |
| 2611 | map = partrel->ri_RootToPartitionMap; |
| 2612 | if (map != NULL) |
| 2613 | { |
| 2614 | TupleTableSlot *new_slot = partrel->ri_PartitionTupleSlot; |
| 2615 | |
| 2616 | slot = execute_attr_map_slot(map->attrMap, slot, new_slot); |
| 2617 | } |
| 2618 | |
| 2619 | *partRelInfo = partrel; |
| 2620 | return slot; |
| 2621 | } |
| 2622 | |
| 2623 | /* ---------------------------------------------------------------- |
| 2624 | * ExecModifyTable |
no test coverage detected