---------------------------------------------------------------- * ExecUpdate * * note: we can't run UPDATE queries with transactions * off because UPDATEs are actually INSERTs and our * scan will mistakenly loop forever, updating the tuple * it just inserted.. This should be fixed but until it * is, we don't want to get stuck in an infinite loop * which corrupts your database.. *
| 1844 | * ---------------------------------------------------------------- |
| 1845 | */ |
| 1846 | static TupleTableSlot * |
| 1847 | ExecUpdate(ModifyTableState *mtstate, |
| 1848 | ResultRelInfo *resultRelInfo, |
| 1849 | ItemPointer tupleid, |
| 1850 | HeapTuple oldtuple, |
| 1851 | TupleTableSlot *slot, |
| 1852 | TupleTableSlot *planSlot, |
| 1853 | EPQState *epqstate, |
| 1854 | EState *estate, |
| 1855 | int32 segid, /* gpdb specific parameter, check if tuple to update is from local */ |
| 1856 | bool canSetTag) |
| 1857 | { |
| 1858 | Relation resultRelationDesc = resultRelInfo->ri_RelationDesc; |
| 1859 | TM_Result result; |
| 1860 | TM_FailureData tmfd; |
| 1861 | List *recheckIndexes = NIL; |
| 1862 | |
| 1863 | /* |
| 1864 | * abort the operation if not running transactions |
| 1865 | */ |
| 1866 | if (IsBootstrapProcessingMode()) |
| 1867 | elog(ERROR, "cannot UPDATE during bootstrap"); |
| 1868 | |
| 1869 | /* |
| 1870 | * Sanity check the distribution of the tuple to prevent |
| 1871 | * potential data corruption in case users manipulate data |
| 1872 | * incorrectly (e.g. insert data on incorrect segment through |
| 1873 | * utility mode) or there is bug in code, etc. |
| 1874 | */ |
| 1875 | if (segid != GpIdentity.segindex) |
| 1876 | elog(ERROR, |
| 1877 | "distribution key of the tuple (%u, %u) doesn't belong to " |
| 1878 | "current segment (actually from seg%d)", |
| 1879 | BlockIdGetBlockNumber(&(tupleid->ip_blkid)), |
| 1880 | tupleid->ip_posid, |
| 1881 | segid); |
| 1882 | |
| 1883 | ExecMaterializeSlot(slot); |
| 1884 | |
| 1885 | /* |
| 1886 | * Open the table's indexes, if we have not done so already, so that we |
| 1887 | * can add new index entries for the updated tuple. |
| 1888 | */ |
| 1889 | if (resultRelationDesc->rd_rel->relhasindex && |
| 1890 | resultRelInfo->ri_IndexRelationDescs == NULL) |
| 1891 | ExecOpenIndices(resultRelInfo, false); |
| 1892 | |
| 1893 | /* BEFORE ROW UPDATE Triggers */ |
| 1894 | if (resultRelInfo->ri_TrigDesc && |
| 1895 | resultRelInfo->ri_TrigDesc->trig_update_before_row) |
| 1896 | { |
| 1897 | if (!ExecBRUpdateTriggers(estate, epqstate, resultRelInfo, |
| 1898 | tupleid, oldtuple, slot)) |
| 1899 | return NULL; /* "do nothing" */ |
| 1900 | } |
| 1901 | |
| 1902 | /* INSTEAD OF ROW UPDATE Triggers */ |
| 1903 | if (resultRelInfo->ri_TrigDesc && |
no test coverage detected