---------------------------------------------------------------- * ExecInsert * * For INSERT, we have to insert the tuple into the target relation * (or partition thereof) and insert appropriate tuples into the index * relations. * * slot contains the new tuple value to be stored. * planSlot is the output of the ModifyTable's subplan; we use it * to access "junk" columns that are n
| 670 | * |
| 671 | */ |
| 672 | static TupleTableSlot * |
| 673 | ExecInsert(ModifyTableState *mtstate, |
| 674 | ResultRelInfo *resultRelInfo, |
| 675 | TupleTableSlot *slot, |
| 676 | TupleTableSlot *planSlot, |
| 677 | EState *estate, |
| 678 | bool canSetTag, |
| 679 | bool splitUpdate) |
| 680 | { |
| 681 | Relation resultRelationDesc; |
| 682 | List *recheckIndexes = NIL; |
| 683 | TupleTableSlot *result = NULL; |
| 684 | TransitionCaptureState *ar_insert_trig_tcs; |
| 685 | ModifyTable *node = (ModifyTable *) mtstate->ps.plan; |
| 686 | OnConflictAction onconflict = node->onConflictAction; |
| 687 | PartitionTupleRouting *proute = mtstate->mt_partition_tuple_routing; |
| 688 | MemoryContext oldContext; |
| 689 | |
| 690 | /* |
| 691 | * If the input result relation is a partitioned table, find the leaf |
| 692 | * partition to insert the tuple into. |
| 693 | */ |
| 694 | if (proute) |
| 695 | { |
| 696 | ResultRelInfo *partRelInfo; |
| 697 | |
| 698 | slot = ExecPrepareTupleRouting(mtstate, estate, proute, |
| 699 | resultRelInfo, slot, |
| 700 | &partRelInfo); |
| 701 | resultRelInfo = partRelInfo; |
| 702 | } |
| 703 | |
| 704 | ExecMaterializeSlot(slot); |
| 705 | |
| 706 | resultRelationDesc = resultRelInfo->ri_RelationDesc; |
| 707 | |
| 708 | /* |
| 709 | * Open the table's indexes, if we have not done so already, so that we |
| 710 | * can add new index entries for the inserted tuple. |
| 711 | */ |
| 712 | if (resultRelationDesc->rd_rel->relhasindex && |
| 713 | resultRelInfo->ri_IndexRelationDescs == NULL) |
| 714 | ExecOpenIndices(resultRelInfo, onconflict != ONCONFLICT_NONE); |
| 715 | |
| 716 | /* |
| 717 | * BEFORE ROW INSERT Triggers. |
| 718 | * |
| 719 | * Note: We fire BEFORE ROW TRIGGERS for every attempted insertion in an |
| 720 | * INSERT ... ON CONFLICT statement. We cannot check for constraint |
| 721 | * violations before firing these triggers, because they can change the |
| 722 | * values to insert. Also, they can run arbitrary user-defined code with |
| 723 | * side-effects that we can't cancel by just not inserting the tuple. |
| 724 | * |
| 725 | * Considering that the original command is UPDATE for a SplitUpdate, fire |
| 726 | * insert triggers may lead to the wrong action to be enforced. And the |
| 727 | * triggers in GPDB may require cross segments data changes, disallow the |
| 728 | * INSERT triggers on a SplitUpdate. |
| 729 | */ |
no test coverage detected