MCPcopy Create free account
hub / github.com/apache/cloudberry / ExecCrossPartitionUpdate

Function ExecCrossPartitionUpdate

src/backend/executor/nodeModifyTable.c:1674–1817  ·  view source on GitHub ↗

* ExecCrossPartitionUpdate --- Move an updated tuple to another partition. * * This works by first deleting the old tuple from the current partition, * followed by inserting the new tuple into the root parent table, that is, * mtstate->rootResultRelInfo. It will be re-routed from there to the * correct partition. * * Returns true if the tuple has been successfully moved, or if it's found

Source from the content-addressed store, hash-verified

1672 * and call this function again or perform a regular update accordingly.
1673 */
1674static bool
1675ExecCrossPartitionUpdate(ModifyTableState *mtstate,
1676 ResultRelInfo *resultRelInfo,
1677 ItemPointer tupleid, HeapTuple oldtuple,
1678 TupleTableSlot *slot, TupleTableSlot *planSlot,
1679 EPQState *epqstate, int32 segid, bool canSetTag,
1680 TupleTableSlot **retry_slot,
1681 TupleTableSlot **inserted_tuple)
1682{
1683 EState *estate = mtstate->ps.state;
1684 TupleConversionMap *tupconv_map;
1685 bool tuple_deleted;
1686 TupleTableSlot *epqslot = NULL;
1687
1688 *inserted_tuple = NULL;
1689 *retry_slot = NULL;
1690
1691 /*
1692 * Disallow an INSERT ON CONFLICT DO UPDATE that causes the original row
1693 * to migrate to a different partition. Maybe this can be implemented
1694 * some day, but it seems a fringe feature with little redeeming value.
1695 */
1696 if (((ModifyTable *) mtstate->ps.plan)->onConflictAction == ONCONFLICT_UPDATE)
1697 ereport(ERROR,
1698 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1699 errmsg("invalid ON UPDATE specification"),
1700 errdetail("The result tuple would appear in a different partition than the original tuple.")));
1701
1702 /*
1703 * When an UPDATE is run directly on a leaf partition, simply fail with a
1704 * partition constraint violation error.
1705 */
1706 if (resultRelInfo == mtstate->rootResultRelInfo)
1707 ExecPartitionCheckEmitError(resultRelInfo, slot, estate);
1708
1709 /* Initialize tuple routing info if not already done. */
1710 if (mtstate->mt_partition_tuple_routing == NULL)
1711 {
1712 Relation rootRel = mtstate->rootResultRelInfo->ri_RelationDesc;
1713 MemoryContext oldcxt;
1714
1715 /* Things built here have to last for the query duration. */
1716 oldcxt = MemoryContextSwitchTo(estate->es_query_cxt);
1717
1718 mtstate->mt_partition_tuple_routing =
1719 ExecSetupPartitionTupleRouting(estate, rootRel);
1720
1721 /*
1722 * Before a partition's tuple can be re-routed, it must first be
1723 * converted to the root's format, so we'll need a slot for storing
1724 * such tuples.
1725 */
1726 Assert(mtstate->mt_root_tuple_slot == NULL);
1727 mtstate->mt_root_tuple_slot = table_slot_create(rootRel, NULL);
1728
1729 MemoryContextSwitchTo(oldcxt);
1730 }
1731

Callers 1

ExecUpdateFunction · 0.85

Calls 14

MemoryContextSwitchToFunction · 0.85
table_slot_createFunction · 0.85
ExecDeleteFunction · 0.85
ExecInitUpdateProjectionFunction · 0.85
ExecGetUpdateNewTupleFunction · 0.85
ExecGetChildToRootMapFunction · 0.85
execute_attr_map_slotFunction · 0.85
ExecInsertFunction · 0.85
errcodeFunction · 0.50

Tested by

no test coverage detected