---------------------------------------------------------------- * ExecDelete * * DELETE is like UPDATE, except that we delete the tuple and no * index modifications are needed. * * When deleting from a table, tupleid identifies the tuple to * delete and oldtuple is NULL. When deleting from a view, * oldtuple is passed to the INSTEAD OF triggers and identifies * what to delete, an
| 1235 | * ---------------------------------------------------------------- |
| 1236 | */ |
| 1237 | static TupleTableSlot * |
| 1238 | ExecDelete(ModifyTableState *mtstate, |
| 1239 | ResultRelInfo *resultRelInfo, |
| 1240 | ItemPointer tupleid, |
| 1241 | HeapTuple oldtuple, |
| 1242 | TupleTableSlot *planSlot, |
| 1243 | EPQState *epqstate, |
| 1244 | EState *estate, |
| 1245 | int32 segid, |
| 1246 | bool processReturning, |
| 1247 | bool canSetTag, |
| 1248 | bool changingPart, |
| 1249 | bool splitUpdate, |
| 1250 | bool *tupleDeleted, |
| 1251 | TupleTableSlot **epqreturnslot) |
| 1252 | { |
| 1253 | Relation resultRelationDesc = resultRelInfo->ri_RelationDesc; |
| 1254 | TM_Result result; |
| 1255 | TM_FailureData tmfd; |
| 1256 | TupleTableSlot *slot = NULL; |
| 1257 | TransitionCaptureState *ar_delete_trig_tcs; |
| 1258 | |
| 1259 | if (tupleDeleted) |
| 1260 | *tupleDeleted = false; |
| 1261 | |
| 1262 | /* |
| 1263 | * Sanity check the distribution of the tuple to prevent |
| 1264 | * potential data corruption in case users manipulate data |
| 1265 | * incorrectly (e.g. insert data on incorrect segment through |
| 1266 | * utility mode) or there is bug in code, etc. |
| 1267 | */ |
| 1268 | if (segid != GpIdentity.segindex) |
| 1269 | elog(ERROR, |
| 1270 | "distribution key of the tuple (%u, %u) doesn't belong to " |
| 1271 | "current segment (actually from seg%d)", |
| 1272 | BlockIdGetBlockNumber(&(tupleid->ip_blkid)), |
| 1273 | tupleid->ip_posid, |
| 1274 | segid); |
| 1275 | |
| 1276 | /* BEFORE ROW DELETE Triggers */ |
| 1277 | /* |
| 1278 | * Disallow DELETE triggers on a split UPDATE. See comments in ExecInsert(). |
| 1279 | */ |
| 1280 | if (resultRelInfo->ri_TrigDesc && |
| 1281 | resultRelInfo->ri_TrigDesc->trig_delete_before_row && |
| 1282 | !splitUpdate) |
| 1283 | { |
| 1284 | bool dodelete; |
| 1285 | |
| 1286 | dodelete = ExecBRDeleteTriggers(estate, epqstate, resultRelInfo, |
| 1287 | tupleid, oldtuple, epqreturnslot); |
| 1288 | |
| 1289 | if (!dodelete) /* "do nothing" */ |
| 1290 | return NULL; |
| 1291 | } |
| 1292 | |
| 1293 | /* INSTEAD OF ROW DELETE Triggers */ |
| 1294 | if (resultRelInfo->ri_TrigDesc && |
no test coverage detected